Mercurial > libavcodec.hg
annotate targa.c @ 12483:0159a19bfff7 libavcodec
aacdec: Rework channel mapping compatibility hacks.
For a PCE based configuration map the channels solely based on tags.
For an indexed configuration map the channels solely based on position.
This works with all known exotic samples including al17, elem_id0, bad_concat,
and lfe_is_sce.
author | alexc |
---|---|
date | Fri, 10 Sep 2010 18:01:48 +0000 |
parents | ffb3668ff7af |
children |
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" |
12372
914f484bb476
Remove use of the deprecated function avcodec_check_dimensions(), use
stefano
parents:
11560
diff
changeset
|
23 #include "libavcore/imgutils.h" |
3986 | 24 #include "avcodec.h" |
25 | |
26 enum TargaCompr{ | |
27 TGA_NODATA = 0, // no image data | |
28 TGA_PAL = 1, // palettized | |
29 TGA_RGB = 2, // true-color | |
30 TGA_BW = 3, // black & white or grayscale | |
31 TGA_RLE = 8, // flag pointing that data is RLE-coded | |
32 }; | |
33 | |
34 typedef struct TargaContext { | |
35 AVFrame picture; | |
36 | |
37 int width, height; | |
38 int bpp; | |
39 int color_type; | |
40 int compression_type; | |
41 } TargaContext; | |
42 | |
6281 | 43 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 | 44 { |
45 int i, x, y; | |
46 int depth = (bpp + 1) >> 3; | |
47 int type, count; | |
48 int diff; | |
49 | |
50 diff = stride - w * depth; | |
51 x = y = 0; | |
52 while(y < h){ | |
53 type = *src++; | |
54 count = (type & 0x7F) + 1; | |
55 type &= 0x80; | |
56 if((x + count > w) && (x + count + 1 > (h - y) * w)){ | |
57 av_log(avctx, AV_LOG_ERROR, "Packet went out of bounds: position (%i,%i) size %i\n", x, y, count); | |
58 return; | |
59 } | |
60 for(i = 0; i < count; i++){ | |
61 switch(depth){ | |
62 case 1: | |
63 *dst = *src; | |
64 break; | |
65 case 2: | |
4364 | 66 *((uint16_t*)dst) = AV_RL16(src); |
3986 | 67 break; |
68 case 3: | |
69 dst[0] = src[0]; | |
70 dst[1] = src[1]; | |
71 dst[2] = src[2]; | |
72 break; | |
4132 | 73 case 4: |
4364 | 74 *((uint32_t*)dst) = AV_RL32(src); |
4132 | 75 break; |
3986 | 76 } |
77 dst += depth; | |
78 if(!type) | |
79 src += depth; | |
80 | |
81 x++; | |
82 if(x == w){ | |
83 x = 0; | |
84 y++; | |
85 dst += diff; | |
86 } | |
87 } | |
88 if(type) | |
89 src += depth; | |
90 } | |
91 } | |
92 | |
93 static int decode_frame(AVCodecContext *avctx, | |
94 void *data, int *data_size, | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8573
diff
changeset
|
95 AVPacket *avpkt) |
3986 | 96 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8573
diff
changeset
|
97 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8573
diff
changeset
|
98 int buf_size = avpkt->size; |
3986 | 99 TargaContext * const s = avctx->priv_data; |
100 AVFrame *picture = data; | |
101 AVFrame * const p= (AVFrame*)&s->picture; | |
102 uint8_t *dst; | |
103 int stride; | |
104 int idlen, pal, compr, x, y, w, h, bpp, flags; | |
105 int first_clr, colors, csize; | |
106 | |
107 /* parse image header */ | |
108 idlen = *buf++; | |
109 pal = *buf++; | |
110 compr = *buf++; | |
4364 | 111 first_clr = AV_RL16(buf); buf += 2; |
112 colors = AV_RL16(buf); buf += 2; | |
3986 | 113 csize = *buf++; |
4364 | 114 x = AV_RL16(buf); buf += 2; |
115 y = AV_RL16(buf); buf += 2; | |
116 w = AV_RL16(buf); buf += 2; | |
117 h = AV_RL16(buf); buf += 2; | |
3986 | 118 bpp = *buf++; |
119 flags = *buf++; | |
120 //skip identifier if any | |
121 buf += idlen; | |
122 s->bpp = bpp; | |
123 s->width = w; | |
124 s->height = h; | |
125 switch(s->bpp){ | |
126 case 8: | |
127 avctx->pix_fmt = ((compr & (~TGA_RLE)) == TGA_BW) ? PIX_FMT_GRAY8 : PIX_FMT_PAL8; | |
128 break; | |
129 case 15: | |
130 avctx->pix_fmt = PIX_FMT_RGB555; | |
131 break; | |
132 case 16: | |
133 avctx->pix_fmt = PIX_FMT_RGB555; | |
134 break; | |
135 case 24: | |
136 avctx->pix_fmt = PIX_FMT_BGR24; | |
137 break; | |
4132 | 138 case 32: |
4494
ce643a22f049
Replace deprecated PIX_FMT names by the newer variants.
diego
parents:
4364
diff
changeset
|
139 avctx->pix_fmt = PIX_FMT_RGB32; |
4132 | 140 break; |
3986 | 141 default: |
4128 | 142 av_log(avctx, AV_LOG_ERROR, "Bit depth %i is not supported\n", s->bpp); |
3986 | 143 return -1; |
144 } | |
145 | |
146 if(s->picture.data[0]) | |
147 avctx->release_buffer(avctx, &s->picture); | |
148 | |
12462
ffb3668ff7af
Use new imgutils.h API names, fix deprecation warnings.
stefano
parents:
12372
diff
changeset
|
149 if(av_image_check_size(w, h, 0, avctx)) |
3986 | 150 return -1; |
151 if(w != avctx->width || h != avctx->height) | |
152 avcodec_set_dimensions(avctx, w, h); | |
153 if(avctx->get_buffer(avctx, p) < 0){ | |
154 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
155 return -1; | |
156 } | |
157 if(flags & 0x20){ | |
158 dst = p->data[0]; | |
159 stride = p->linesize[0]; | |
160 }else{ //image is upside-down | |
161 dst = p->data[0] + p->linesize[0] * (h - 1); | |
162 stride = -p->linesize[0]; | |
163 } | |
164 | |
165 if(avctx->pix_fmt == PIX_FMT_PAL8 && avctx->palctrl){ | |
166 memcpy(p->data[1], avctx->palctrl->palette, AVPALETTE_SIZE); | |
167 if(avctx->palctrl->palette_changed){ | |
168 p->palette_has_changed = 1; | |
169 avctx->palctrl->palette_changed = 0; | |
170 } | |
171 } | |
172 if(colors){ | |
173 if((colors + first_clr) > 256){ | |
174 av_log(avctx, AV_LOG_ERROR, "Incorrect palette: %i colors with offset %i\n", colors, first_clr); | |
175 return -1; | |
176 } | |
177 if(csize != 24){ | |
178 av_log(avctx, AV_LOG_ERROR, "Palette entry size %i bits is not supported\n", csize); | |
179 return -1; | |
180 } | |
181 if(avctx->pix_fmt != PIX_FMT_PAL8)//should not occur but skip palette anyway | |
182 buf += colors * ((csize + 1) >> 3); | |
183 else{ | |
184 int r, g, b, t; | |
185 int32_t *pal = ((int32_t*)p->data[1]) + first_clr; | |
186 for(t = 0; t < colors; t++){ | |
187 r = *buf++; | |
188 g = *buf++; | |
189 b = *buf++; | |
190 *pal++ = (b << 16) | (g << 8) | r; | |
191 } | |
192 p->palette_has_changed = 1; | |
193 } | |
194 } | |
195 if((compr & (~TGA_RLE)) == TGA_NODATA) | |
196 memset(p->data[0], 0, p->linesize[0] * s->height); | |
197 else{ | |
198 if(compr & TGA_RLE) | |
199 targa_decode_rle(avctx, s, buf, dst, avctx->width, avctx->height, stride, bpp); | |
200 else{ | |
201 for(y = 0; y < s->height; y++){ | |
9985 | 202 #if HAVE_BIGENDIAN |
3986 | 203 if((s->bpp + 1) >> 3 == 2){ |
204 uint16_t *dst16 = (uint16_t*)dst; | |
205 for(x = 0; x < s->width; x++) | |
4364 | 206 dst16[x] = AV_RL16(buf + x * 2); |
4132 | 207 }else if((s->bpp + 1) >> 3 == 4){ |
208 uint32_t *dst32 = (uint32_t*)dst; | |
209 for(x = 0; x < s->width; x++) | |
4364 | 210 dst32[x] = AV_RL32(buf + x * 4); |
3986 | 211 }else |
212 #endif | |
213 memcpy(dst, buf, s->width * ((s->bpp + 1) >> 3)); | |
214 | |
215 dst += stride; | |
216 buf += s->width * ((s->bpp + 1) >> 3); | |
217 } | |
218 } | |
219 } | |
220 | |
221 *picture= *(AVFrame*)&s->picture; | |
222 *data_size = sizeof(AVPicture); | |
223 | |
224 return buf_size; | |
225 } | |
226 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6281
diff
changeset
|
227 static av_cold int targa_init(AVCodecContext *avctx){ |
3986 | 228 TargaContext *s = avctx->priv_data; |
229 | |
230 avcodec_get_frame_defaults((AVFrame*)&s->picture); | |
231 avctx->coded_frame= (AVFrame*)&s->picture; | |
232 | |
233 return 0; | |
234 } | |
235 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6281
diff
changeset
|
236 static av_cold int targa_end(AVCodecContext *avctx){ |
3986 | 237 TargaContext *s = avctx->priv_data; |
238 | |
239 if(s->picture.data[0]) | |
240 avctx->release_buffer(avctx, &s->picture); | |
241 | |
242 return 0; | |
243 } | |
244 | |
245 AVCodec targa_decoder = { | |
246 "targa", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10184
diff
changeset
|
247 AVMEDIA_TYPE_VIDEO, |
3986 | 248 CODEC_ID_TARGA, |
249 sizeof(TargaContext), | |
250 targa_init, | |
251 NULL, | |
252 targa_end, | |
253 decode_frame, | |
9810
8f56bd47d2c8
targa image decoder uses get_buffer, set CODEC_CAP_DR1
bcoudurier
parents:
9553
diff
changeset
|
254 CODEC_CAP_DR1, |
6722 | 255 NULL, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6722
diff
changeset
|
256 .long_name = NULL_IF_CONFIG_SMALL("Truevision Targa image"), |
3986 | 257 }; |