Mercurial > libavcodec.hg
annotate targa.c @ 5306:abc5c130b448 libavcodec
AC-3 decoder, soc revision 32, Jul 17 09:37:32 2006 UTC by cloud9
Latest commit.
There is no error in parsing and or recovering transform coefficients.
Double checked with ac3dec.
Getting consistent results with the bit allocation routine and transform
coefficients.
The code is able to parse valid ac3 bitstreams without error from start
to end.
I have also implemented the imdct when block switching is not enabled.
However, can anybody provide an insight into how to convert float samples to
int16_t ? lrint is of no help cuz it produces output -1, 0 or 1 whereas the
output should be between -32768 to 32767.
author | jbr |
---|---|
date | Sat, 14 Jul 2007 15:48:28 +0000 |
parents | 2b72f9bc4f06 |
children | 56d2853cd7c3 |
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 */ | |
21 #include "avcodec.h" | |
22 | |
23 enum TargaCompr{ | |
24 TGA_NODATA = 0, // no image data | |
25 TGA_PAL = 1, // palettized | |
26 TGA_RGB = 2, // true-color | |
27 TGA_BW = 3, // black & white or grayscale | |
28 TGA_RLE = 8, // flag pointing that data is RLE-coded | |
29 }; | |
30 | |
31 typedef struct TargaContext { | |
32 AVFrame picture; | |
33 | |
34 int width, height; | |
35 int bpp; | |
36 int color_type; | |
37 int compression_type; | |
38 } TargaContext; | |
39 | |
40 static void targa_decode_rle(AVCodecContext *avctx, TargaContext *s, uint8_t *src, uint8_t *dst, int w, int h, int stride, int bpp) | |
41 { | |
42 int i, x, y; | |
43 int depth = (bpp + 1) >> 3; | |
44 int type, count; | |
45 int diff; | |
46 | |
47 diff = stride - w * depth; | |
48 x = y = 0; | |
49 while(y < h){ | |
50 type = *src++; | |
51 count = (type & 0x7F) + 1; | |
52 type &= 0x80; | |
53 if((x + count > w) && (x + count + 1 > (h - y) * w)){ | |
54 av_log(avctx, AV_LOG_ERROR, "Packet went out of bounds: position (%i,%i) size %i\n", x, y, count); | |
55 return; | |
56 } | |
57 for(i = 0; i < count; i++){ | |
58 switch(depth){ | |
59 case 1: | |
60 *dst = *src; | |
61 break; | |
62 case 2: | |
4364 | 63 *((uint16_t*)dst) = AV_RL16(src); |
3986 | 64 break; |
65 case 3: | |
66 dst[0] = src[0]; | |
67 dst[1] = src[1]; | |
68 dst[2] = src[2]; | |
69 break; | |
4132 | 70 case 4: |
4364 | 71 *((uint32_t*)dst) = AV_RL32(src); |
4132 | 72 break; |
3986 | 73 } |
74 dst += depth; | |
75 if(!type) | |
76 src += depth; | |
77 | |
78 x++; | |
79 if(x == w){ | |
80 x = 0; | |
81 y++; | |
82 dst += diff; | |
83 } | |
84 } | |
85 if(type) | |
86 src += depth; | |
87 } | |
88 } | |
89 | |
90 static int decode_frame(AVCodecContext *avctx, | |
91 void *data, int *data_size, | |
92 uint8_t *buf, int buf_size) | |
93 { | |
94 TargaContext * const s = avctx->priv_data; | |
95 AVFrame *picture = data; | |
96 AVFrame * const p= (AVFrame*)&s->picture; | |
97 uint8_t *dst; | |
98 int stride; | |
99 int idlen, pal, compr, x, y, w, h, bpp, flags; | |
100 int first_clr, colors, csize; | |
101 | |
102 /* parse image header */ | |
103 idlen = *buf++; | |
104 pal = *buf++; | |
105 compr = *buf++; | |
4364 | 106 first_clr = AV_RL16(buf); buf += 2; |
107 colors = AV_RL16(buf); buf += 2; | |
3986 | 108 csize = *buf++; |
4364 | 109 x = AV_RL16(buf); buf += 2; |
110 y = AV_RL16(buf); buf += 2; | |
111 w = AV_RL16(buf); buf += 2; | |
112 h = AV_RL16(buf); buf += 2; | |
3986 | 113 bpp = *buf++; |
114 flags = *buf++; | |
115 //skip identifier if any | |
116 buf += idlen; | |
117 s->bpp = bpp; | |
118 s->width = w; | |
119 s->height = h; | |
120 switch(s->bpp){ | |
121 case 8: | |
122 avctx->pix_fmt = ((compr & (~TGA_RLE)) == TGA_BW) ? PIX_FMT_GRAY8 : PIX_FMT_PAL8; | |
123 break; | |
124 case 15: | |
125 avctx->pix_fmt = PIX_FMT_RGB555; | |
126 break; | |
127 case 16: | |
128 avctx->pix_fmt = PIX_FMT_RGB555; | |
129 break; | |
130 case 24: | |
131 avctx->pix_fmt = PIX_FMT_BGR24; | |
132 break; | |
4132 | 133 case 32: |
4494
ce643a22f049
Replace deprecated PIX_FMT names by the newer variants.
diego
parents:
4364
diff
changeset
|
134 avctx->pix_fmt = PIX_FMT_RGB32; |
4132 | 135 break; |
3986 | 136 default: |
4128 | 137 av_log(avctx, AV_LOG_ERROR, "Bit depth %i is not supported\n", s->bpp); |
3986 | 138 return -1; |
139 } | |
140 | |
141 if(s->picture.data[0]) | |
142 avctx->release_buffer(avctx, &s->picture); | |
143 | |
144 if(avcodec_check_dimensions(avctx, w, h)) | |
145 return -1; | |
146 if(w != avctx->width || h != avctx->height) | |
147 avcodec_set_dimensions(avctx, w, h); | |
148 if(avctx->get_buffer(avctx, p) < 0){ | |
149 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
150 return -1; | |
151 } | |
152 if(flags & 0x20){ | |
153 dst = p->data[0]; | |
154 stride = p->linesize[0]; | |
155 }else{ //image is upside-down | |
156 dst = p->data[0] + p->linesize[0] * (h - 1); | |
157 stride = -p->linesize[0]; | |
158 } | |
159 | |
160 if(avctx->pix_fmt == PIX_FMT_PAL8 && avctx->palctrl){ | |
161 memcpy(p->data[1], avctx->palctrl->palette, AVPALETTE_SIZE); | |
162 if(avctx->palctrl->palette_changed){ | |
163 p->palette_has_changed = 1; | |
164 avctx->palctrl->palette_changed = 0; | |
165 } | |
166 } | |
167 if(colors){ | |
168 if((colors + first_clr) > 256){ | |
169 av_log(avctx, AV_LOG_ERROR, "Incorrect palette: %i colors with offset %i\n", colors, first_clr); | |
170 return -1; | |
171 } | |
172 if(csize != 24){ | |
173 av_log(avctx, AV_LOG_ERROR, "Palette entry size %i bits is not supported\n", csize); | |
174 return -1; | |
175 } | |
176 if(avctx->pix_fmt != PIX_FMT_PAL8)//should not occur but skip palette anyway | |
177 buf += colors * ((csize + 1) >> 3); | |
178 else{ | |
179 int r, g, b, t; | |
180 int32_t *pal = ((int32_t*)p->data[1]) + first_clr; | |
181 for(t = 0; t < colors; t++){ | |
182 r = *buf++; | |
183 g = *buf++; | |
184 b = *buf++; | |
185 *pal++ = (b << 16) | (g << 8) | r; | |
186 } | |
187 p->palette_has_changed = 1; | |
188 avctx->palctrl->palette_changed = 0; | |
189 } | |
190 } | |
191 if((compr & (~TGA_RLE)) == TGA_NODATA) | |
192 memset(p->data[0], 0, p->linesize[0] * s->height); | |
193 else{ | |
194 if(compr & TGA_RLE) | |
195 targa_decode_rle(avctx, s, buf, dst, avctx->width, avctx->height, stride, bpp); | |
196 else{ | |
197 for(y = 0; y < s->height; y++){ | |
198 #ifdef WORDS_BIGENDIAN | |
199 if((s->bpp + 1) >> 3 == 2){ | |
200 uint16_t *dst16 = (uint16_t*)dst; | |
201 for(x = 0; x < s->width; x++) | |
4364 | 202 dst16[x] = AV_RL16(buf + x * 2); |
4132 | 203 }else if((s->bpp + 1) >> 3 == 4){ |
204 uint32_t *dst32 = (uint32_t*)dst; | |
205 for(x = 0; x < s->width; x++) | |
4364 | 206 dst32[x] = AV_RL32(buf + x * 4); |
3986 | 207 }else |
208 #endif | |
209 memcpy(dst, buf, s->width * ((s->bpp + 1) >> 3)); | |
210 | |
211 dst += stride; | |
212 buf += s->width * ((s->bpp + 1) >> 3); | |
213 } | |
214 } | |
215 } | |
216 | |
217 *picture= *(AVFrame*)&s->picture; | |
218 *data_size = sizeof(AVPicture); | |
219 | |
220 return buf_size; | |
221 } | |
222 | |
223 static int targa_init(AVCodecContext *avctx){ | |
224 TargaContext *s = avctx->priv_data; | |
225 | |
226 avcodec_get_frame_defaults((AVFrame*)&s->picture); | |
227 avctx->coded_frame= (AVFrame*)&s->picture; | |
228 s->picture.data[0] = NULL; | |
229 | |
230 return 0; | |
231 } | |
232 | |
233 static int targa_end(AVCodecContext *avctx){ | |
234 TargaContext *s = avctx->priv_data; | |
235 | |
236 if(s->picture.data[0]) | |
237 avctx->release_buffer(avctx, &s->picture); | |
238 | |
239 return 0; | |
240 } | |
241 | |
242 AVCodec targa_decoder = { | |
243 "targa", | |
244 CODEC_TYPE_VIDEO, | |
245 CODEC_ID_TARGA, | |
246 sizeof(TargaContext), | |
247 targa_init, | |
248 NULL, | |
249 targa_end, | |
250 decode_frame, | |
251 0, | |
252 NULL | |
253 }; |