Mercurial > libavcodec.hg
annotate targa.c @ 9003:b595a8a59967 libavcodec
Change the type of pblocks from pointers to short array into
pointers to array of 64 DCTELEM, similarly to other block fields.
This also get rid of some casts and fixes a warning.
author | iive |
---|---|
date | Sun, 22 Feb 2009 09:02:06 +0000 |
parents | 2acf0ae7b041 |
children | 54bc8a2727b0 |
rev | line source |
---|---|
3986 | 1 /* |
2 * Targa (.tga) image decoder | |
3 * Copyright (c) 2006 Konstantin Shishkov | |
4 * | |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
8573
2acf0ae7b041
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
7040
diff
changeset
|
21 |
2acf0ae7b041
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
7040
diff
changeset
|
22 #include "libavutil/intreadwrite.h" |
3986 | 23 #include "avcodec.h" |
24 | |
25 enum TargaCompr{ | |
26 TGA_NODATA = 0, // no image data | |
27 TGA_PAL = 1, // palettized | |
28 TGA_RGB = 2, // true-color | |
29 TGA_BW = 3, // black & white or grayscale | |
30 TGA_RLE = 8, // flag pointing that data is RLE-coded | |
31 }; | |
32 | |
33 typedef struct TargaContext { | |
34 AVFrame picture; | |
35 | |
36 int width, height; | |
37 int bpp; | |
38 int color_type; | |
39 int compression_type; | |
40 } TargaContext; | |
41 | |
6281 | 42 static void targa_decode_rle(AVCodecContext *avctx, TargaContext *s, const uint8_t *src, uint8_t *dst, int w, int h, int stride, int bpp) |
3986 | 43 { |
44 int i, x, y; | |
45 int depth = (bpp + 1) >> 3; | |
46 int type, count; | |
47 int diff; | |
48 | |
49 diff = stride - w * depth; | |
50 x = y = 0; | |
51 while(y < h){ | |
52 type = *src++; | |
53 count = (type & 0x7F) + 1; | |
54 type &= 0x80; | |
55 if((x + count > w) && (x + count + 1 > (h - y) * w)){ | |
56 av_log(avctx, AV_LOG_ERROR, "Packet went out of bounds: position (%i,%i) size %i\n", x, y, count); | |
57 return; | |
58 } | |
59 for(i = 0; i < count; i++){ | |
60 switch(depth){ | |
61 case 1: | |
62 *dst = *src; | |
63 break; | |
64 case 2: | |
4364 | 65 *((uint16_t*)dst) = AV_RL16(src); |
3986 | 66 break; |
67 case 3: | |
68 dst[0] = src[0]; | |
69 dst[1] = src[1]; | |
70 dst[2] = src[2]; | |
71 break; | |
4132 | 72 case 4: |
4364 | 73 *((uint32_t*)dst) = AV_RL32(src); |
4132 | 74 break; |
3986 | 75 } |
76 dst += depth; | |
77 if(!type) | |
78 src += depth; | |
79 | |
80 x++; | |
81 if(x == w){ | |
82 x = 0; | |
83 y++; | |
84 dst += diff; | |
85 } | |
86 } | |
87 if(type) | |
88 src += depth; | |
89 } | |
90 } | |
91 | |
92 static int decode_frame(AVCodecContext *avctx, | |
93 void *data, int *data_size, | |
6281 | 94 const uint8_t *buf, int buf_size) |
3986 | 95 { |
96 TargaContext * const s = avctx->priv_data; | |
97 AVFrame *picture = data; | |
98 AVFrame * const p= (AVFrame*)&s->picture; | |
99 uint8_t *dst; | |
100 int stride; | |
101 int idlen, pal, compr, x, y, w, h, bpp, flags; | |
102 int first_clr, colors, csize; | |
103 | |
104 /* parse image header */ | |
105 idlen = *buf++; | |
106 pal = *buf++; | |
107 compr = *buf++; | |
4364 | 108 first_clr = AV_RL16(buf); buf += 2; |
109 colors = AV_RL16(buf); buf += 2; | |
3986 | 110 csize = *buf++; |
4364 | 111 x = AV_RL16(buf); buf += 2; |
112 y = AV_RL16(buf); buf += 2; | |
113 w = AV_RL16(buf); buf += 2; | |
114 h = AV_RL16(buf); buf += 2; | |
3986 | 115 bpp = *buf++; |
116 flags = *buf++; | |
117 //skip identifier if any | |
118 buf += idlen; | |
119 s->bpp = bpp; | |
120 s->width = w; | |
121 s->height = h; | |
122 switch(s->bpp){ | |
123 case 8: | |
124 avctx->pix_fmt = ((compr & (~TGA_RLE)) == TGA_BW) ? PIX_FMT_GRAY8 : PIX_FMT_PAL8; | |
125 break; | |
126 case 15: | |
127 avctx->pix_fmt = PIX_FMT_RGB555; | |
128 break; | |
129 case 16: | |
130 avctx->pix_fmt = PIX_FMT_RGB555; | |
131 break; | |
132 case 24: | |
133 avctx->pix_fmt = PIX_FMT_BGR24; | |
134 break; | |
4132 | 135 case 32: |
4494
ce643a22f049
Replace deprecated PIX_FMT names by the newer variants.
diego
parents:
4364
diff
changeset
|
136 avctx->pix_fmt = PIX_FMT_RGB32; |
4132 | 137 break; |
3986 | 138 default: |
4128 | 139 av_log(avctx, AV_LOG_ERROR, "Bit depth %i is not supported\n", s->bpp); |
3986 | 140 return -1; |
141 } | |
142 | |
143 if(s->picture.data[0]) | |
144 avctx->release_buffer(avctx, &s->picture); | |
145 | |
146 if(avcodec_check_dimensions(avctx, w, h)) | |
147 return -1; | |
148 if(w != avctx->width || h != avctx->height) | |
149 avcodec_set_dimensions(avctx, w, h); | |
150 if(avctx->get_buffer(avctx, p) < 0){ | |
151 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
152 return -1; | |
153 } | |
154 if(flags & 0x20){ | |
155 dst = p->data[0]; | |
156 stride = p->linesize[0]; | |
157 }else{ //image is upside-down | |
158 dst = p->data[0] + p->linesize[0] * (h - 1); | |
159 stride = -p->linesize[0]; | |
160 } | |
161 | |
162 if(avctx->pix_fmt == PIX_FMT_PAL8 && avctx->palctrl){ | |
163 memcpy(p->data[1], avctx->palctrl->palette, AVPALETTE_SIZE); | |
164 if(avctx->palctrl->palette_changed){ | |
165 p->palette_has_changed = 1; | |
166 avctx->palctrl->palette_changed = 0; | |
167 } | |
168 } | |
169 if(colors){ | |
170 if((colors + first_clr) > 256){ | |
171 av_log(avctx, AV_LOG_ERROR, "Incorrect palette: %i colors with offset %i\n", colors, first_clr); | |
172 return -1; | |
173 } | |
174 if(csize != 24){ | |
175 av_log(avctx, AV_LOG_ERROR, "Palette entry size %i bits is not supported\n", csize); | |
176 return -1; | |
177 } | |
178 if(avctx->pix_fmt != PIX_FMT_PAL8)//should not occur but skip palette anyway | |
179 buf += colors * ((csize + 1) >> 3); | |
180 else{ | |
181 int r, g, b, t; | |
182 int32_t *pal = ((int32_t*)p->data[1]) + first_clr; | |
183 for(t = 0; t < colors; t++){ | |
184 r = *buf++; | |
185 g = *buf++; | |
186 b = *buf++; | |
187 *pal++ = (b << 16) | (g << 8) | r; | |
188 } | |
189 p->palette_has_changed = 1; | |
190 avctx->palctrl->palette_changed = 0; | |
191 } | |
192 } | |
193 if((compr & (~TGA_RLE)) == TGA_NODATA) | |
194 memset(p->data[0], 0, p->linesize[0] * s->height); | |
195 else{ | |
196 if(compr & TGA_RLE) | |
197 targa_decode_rle(avctx, s, buf, dst, avctx->width, avctx->height, stride, bpp); | |
198 else{ | |
199 for(y = 0; y < s->height; y++){ | |
200 #ifdef WORDS_BIGENDIAN | |
201 if((s->bpp + 1) >> 3 == 2){ | |
202 uint16_t *dst16 = (uint16_t*)dst; | |
203 for(x = 0; x < s->width; x++) | |
4364 | 204 dst16[x] = AV_RL16(buf + x * 2); |
4132 | 205 }else if((s->bpp + 1) >> 3 == 4){ |
206 uint32_t *dst32 = (uint32_t*)dst; | |
207 for(x = 0; x < s->width; x++) | |
4364 | 208 dst32[x] = AV_RL32(buf + x * 4); |
3986 | 209 }else |
210 #endif | |
211 memcpy(dst, buf, s->width * ((s->bpp + 1) >> 3)); | |
212 | |
213 dst += stride; | |
214 buf += s->width * ((s->bpp + 1) >> 3); | |
215 } | |
216 } | |
217 } | |
218 | |
219 *picture= *(AVFrame*)&s->picture; | |
220 *data_size = sizeof(AVPicture); | |
221 | |
222 return buf_size; | |
223 } | |
224 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6281
diff
changeset
|
225 static av_cold int targa_init(AVCodecContext *avctx){ |
3986 | 226 TargaContext *s = avctx->priv_data; |
227 | |
228 avcodec_get_frame_defaults((AVFrame*)&s->picture); | |
229 avctx->coded_frame= (AVFrame*)&s->picture; | |
230 s->picture.data[0] = NULL; | |
231 | |
232 return 0; | |
233 } | |
234 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6281
diff
changeset
|
235 static av_cold int targa_end(AVCodecContext *avctx){ |
3986 | 236 TargaContext *s = avctx->priv_data; |
237 | |
238 if(s->picture.data[0]) | |
239 avctx->release_buffer(avctx, &s->picture); | |
240 | |
241 return 0; | |
242 } | |
243 | |
244 AVCodec targa_decoder = { | |
245 "targa", | |
246 CODEC_TYPE_VIDEO, | |
247 CODEC_ID_TARGA, | |
248 sizeof(TargaContext), | |
249 targa_init, | |
250 NULL, | |
251 targa_end, | |
252 decode_frame, | |
253 0, | |
6722 | 254 NULL, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6722
diff
changeset
|
255 .long_name = NULL_IF_CONFIG_SMALL("Truevision Targa image"), |
3986 | 256 }; |