Mercurial > libavcodec.hg
annotate 4xm.c @ 4630:1416371d4a6c libavcodec
add avcodec_get_context_defaults2() / avcodec_alloc_context2() which take CodecType as an additional parameter
also mark them as NOT part of the public API yet, so we can change their argument to CodecID if we decide to do so
author | michael |
---|---|
date | Wed, 07 Mar 2007 09:29:44 +0000 |
parents | 0022b81fc643 |
children | 28ebdd244a07 |
rev | line source |
---|---|
1293 | 1 /* |
2 * 4XM codec | |
3 * Copyright (c) 2003 Michael Niedermayer | |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
1293 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
1293 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
1293 | 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 | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1293 | 20 */ |
2967 | 21 |
1293 | 22 /** |
23 * @file 4xm.c | |
24 * 4XM codec. | |
25 */ | |
2967 | 26 |
1293 | 27 #include "avcodec.h" |
28 #include "dsputil.h" | |
29 #include "mpegvideo.h" | |
30 | |
31 //#undef NDEBUG | |
32 //#include <assert.h> | |
33 | |
34 #define BLOCK_TYPE_VLC_BITS 5 | |
35 #define ACDC_VLC_BITS 9 | |
36 | |
37 #define CFRAME_BUFFER_COUNT 100 | |
38 | |
39 static const uint8_t block_type_tab[4][8][2]={ | |
40 { //{8,4,2}x{8,4,2} | |
41 { 0,1}, { 2,2}, { 6,3}, {14,4}, {30,5}, {31,5}, { 0,0} | |
42 },{ //{8,4}x1 | |
43 { 0,1}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}, { 0,0} | |
44 },{ //1x{8,4} | |
45 { 0,1}, { 2,2}, { 0,0}, { 6,3}, {14,4}, {15,4}, { 0,0} | |
46 },{ //1x2, 2x1 | |
47 { 0,1}, { 0,0}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4} | |
48 } | |
49 }; | |
50 | |
51 static const uint8_t size2index[4][4]={ | |
52 {-1, 3, 1, 1}, | |
53 { 3, 0, 0, 0}, | |
54 { 2, 0, 0, 0}, | |
55 { 2, 0, 0, 0}, | |
56 }; | |
57 | |
58 static const int8_t mv[256][2]={ | |
59 { 0, 0},{ 0, -1},{ -1, 0},{ 1, 0},{ 0, 1},{ -1, -1},{ 1, -1},{ -1, 1}, | |
60 { 1, 1},{ 0, -2},{ -2, 0},{ 2, 0},{ 0, 2},{ -1, -2},{ 1, -2},{ -2, -1}, | |
61 { 2, -1},{ -2, 1},{ 2, 1},{ -1, 2},{ 1, 2},{ -2, -2},{ 2, -2},{ -2, 2}, | |
62 { 2, 2},{ 0, -3},{ -3, 0},{ 3, 0},{ 0, 3},{ -1, -3},{ 1, -3},{ -3, -1}, | |
63 { 3, -1},{ -3, 1},{ 3, 1},{ -1, 3},{ 1, 3},{ -2, -3},{ 2, -3},{ -3, -2}, | |
64 { 3, -2},{ -3, 2},{ 3, 2},{ -2, 3},{ 2, 3},{ 0, -4},{ -4, 0},{ 4, 0}, | |
65 { 0, 4},{ -1, -4},{ 1, -4},{ -4, -1},{ 4, -1},{ 4, 1},{ -1, 4},{ 1, 4}, | |
66 { -3, -3},{ -3, 3},{ 3, 3},{ -2, -4},{ -4, -2},{ 4, -2},{ -4, 2},{ -2, 4}, | |
67 { 2, 4},{ -3, -4},{ 3, -4},{ 4, -3},{ -5, 0},{ -4, 3},{ -3, 4},{ 3, 4}, | |
68 { -1, -5},{ -5, -1},{ -5, 1},{ -1, 5},{ -2, -5},{ 2, -5},{ 5, -2},{ 5, 2}, | |
69 { -4, -4},{ -4, 4},{ -3, -5},{ -5, -3},{ -5, 3},{ 3, 5},{ -6, 0},{ 0, 6}, | |
70 { -6, -1},{ -6, 1},{ 1, 6},{ 2, -6},{ -6, 2},{ 2, 6},{ -5, -4},{ 5, 4}, | |
71 { 4, 5},{ -6, -3},{ 6, 3},{ -7, 0},{ -1, -7},{ 5, -5},{ -7, 1},{ -1, 7}, | |
72 { 4, -6},{ 6, 4},{ -2, -7},{ -7, 2},{ -3, -7},{ 7, -3},{ 3, 7},{ 6, -5}, | |
73 { 0, -8},{ -1, -8},{ -7, -4},{ -8, 1},{ 4, 7},{ 2, -8},{ -2, 8},{ 6, 6}, | |
74 { -8, 3},{ 5, -7},{ -5, 7},{ 8, -4},{ 0, -9},{ -9, -1},{ 1, 9},{ 7, -6}, | |
75 { -7, 6},{ -5, -8},{ -5, 8},{ -9, 3},{ 9, -4},{ 7, -7},{ 8, -6},{ 6, 8}, | |
76 { 10, 1},{-10, 2},{ 9, -5},{ 10, -3},{ -8, -7},{-10, -4},{ 6, -9},{-11, 0}, | |
77 { 11, 1},{-11, -2},{ -2, 11},{ 7, -9},{ -7, 9},{ 10, 6},{ -4, 11},{ 8, -9}, | |
78 { 8, 9},{ 5, 11},{ 7,-10},{ 12, -3},{ 11, 6},{ -9, -9},{ 8, 10},{ 5, 12}, | |
79 {-11, 7},{ 13, 2},{ 6,-12},{ 10, 9},{-11, 8},{ -7, 12},{ 0, 14},{ 14, -2}, | |
80 { -9, 11},{ -6, 13},{-14, -4},{ -5,-14},{ 5, 14},{-15, -1},{-14, -6},{ 3,-15}, | |
81 { 11,-11},{ -7, 14},{ -5, 15},{ 8,-14},{ 15, 6},{ 3, 16},{ 7,-15},{-16, 5}, | |
82 { 0, 17},{-16, -6},{-10, 14},{-16, 7},{ 12, 13},{-16, 8},{-17, 6},{-18, 3}, | |
83 { -7, 17},{ 15, 11},{ 16, 10},{ 2,-19},{ 3,-19},{-11,-16},{-18, 8},{-19, -6}, | |
84 { 2,-20},{-17,-11},{-10,-18},{ 8, 19},{-21, -1},{-20, 7},{ -4, 21},{ 21, 5}, | |
85 { 15, 16},{ 2,-22},{-10,-20},{-22, 5},{ 20,-11},{ -7,-22},{-12, 20},{ 23, -5}, | |
86 { 13,-20},{ 24, -2},{-15, 19},{-11, 22},{ 16, 19},{ 23,-10},{-18,-18},{ -9,-24}, | |
87 { 24,-10},{ -3, 26},{-23, 13},{-18,-20},{ 17, 21},{ -4, 27},{ 27, 6},{ 1,-28}, | |
88 {-11, 26},{-17,-23},{ 7, 28},{ 11,-27},{ 29, 5},{-23,-19},{-28,-11},{-21, 22}, | |
89 {-30, 7},{-17, 26},{-27, 16},{ 13, 29},{ 19,-26},{ 10,-31},{-14,-30},{ 20,-27}, | |
90 {-29, 18},{-16,-31},{-28,-22},{ 21,-30},{-25, 28},{ 26,-29},{ 25,-32},{-32,-32} | |
91 }; | |
92 | |
93 // this is simply the scaled down elementwise product of the standard jpeg quantizer table and the AAN premul table | |
94 static const uint8_t dequant_table[64]={ | |
95 16, 15, 13, 19, 24, 31, 28, 17, | |
96 17, 23, 25, 31, 36, 63, 45, 21, | |
97 18, 24, 27, 37, 52, 59, 49, 20, | |
98 16, 28, 34, 40, 60, 80, 51, 20, | |
99 18, 31, 48, 66, 68, 86, 56, 21, | |
100 19, 38, 56, 59, 64, 64, 48, 20, | |
101 27, 48, 55, 55, 56, 51, 35, 15, | |
102 20, 35, 34, 32, 31, 22, 15, 8, | |
103 }; | |
104 | |
105 static VLC block_type_vlc[4]; | |
106 | |
107 | |
108 typedef struct CFrameBuffer{ | |
3776 | 109 unsigned int allocated_size; |
110 unsigned int size; | |
1293 | 111 int id; |
112 uint8_t *data; | |
113 }CFrameBuffer; | |
114 | |
115 typedef struct FourXContext{ | |
116 AVCodecContext *avctx; | |
117 DSPContext dsp; | |
118 AVFrame current_picture, last_picture; | |
119 GetBitContext pre_gb; ///< ac/dc prefix | |
120 GetBitContext gb; | |
121 uint8_t *bytestream; | |
122 uint16_t *wordstream; | |
123 int mv[256]; | |
124 VLC pre_vlc; | |
125 int last_dc; | |
3089 | 126 DECLARE_ALIGNED_8(DCTELEM, block[6][64]); |
1293 | 127 uint8_t *bitstream_buffer; |
3066
04b924f8f5a5
warning fixes by Luca Abeni, lucabe72 ##@## email ##.## it
diego
parents:
3036
diff
changeset
|
128 unsigned int bitstream_buffer_size; |
1293 | 129 CFrameBuffer cfrm[CFRAME_BUFFER_COUNT]; |
130 } FourXContext; | |
131 | |
132 | |
133 #define FIX_1_082392200 70936 | |
134 #define FIX_1_414213562 92682 | |
135 #define FIX_1_847759065 121095 | |
136 #define FIX_2_613125930 171254 | |
137 | |
138 #define MULTIPLY(var,const) (((var)*(const)) >> 16) | |
139 | |
140 static void idct(DCTELEM block[64]){ | |
141 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; | |
142 int tmp10, tmp11, tmp12, tmp13; | |
143 int z5, z10, z11, z12, z13; | |
144 int i; | |
145 int temp[64]; | |
2967 | 146 |
1293 | 147 for(i=0; i<8; i++){ |
148 tmp10 = block[8*0 + i] + block[8*4 + i]; | |
149 tmp11 = block[8*0 + i] - block[8*4 + i]; | |
150 | |
151 tmp13 = block[8*2 + i] + block[8*6 + i]; | |
152 tmp12 = MULTIPLY(block[8*2 + i] - block[8*6 + i], FIX_1_414213562) - tmp13; | |
153 | |
154 tmp0 = tmp10 + tmp13; | |
155 tmp3 = tmp10 - tmp13; | |
156 tmp1 = tmp11 + tmp12; | |
157 tmp2 = tmp11 - tmp12; | |
2967 | 158 |
1293 | 159 z13 = block[8*5 + i] + block[8*3 + i]; |
160 z10 = block[8*5 + i] - block[8*3 + i]; | |
161 z11 = block[8*1 + i] + block[8*7 + i]; | |
162 z12 = block[8*1 + i] - block[8*7 + i]; | |
163 | |
164 tmp7 = z11 + z13; | |
165 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); | |
166 | |
167 z5 = MULTIPLY(z10 + z12, FIX_1_847759065); | |
168 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; | |
169 tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; | |
170 | |
171 tmp6 = tmp12 - tmp7; | |
172 tmp5 = tmp11 - tmp6; | |
173 tmp4 = tmp10 + tmp5; | |
174 | |
175 temp[8*0 + i] = tmp0 + tmp7; | |
176 temp[8*7 + i] = tmp0 - tmp7; | |
177 temp[8*1 + i] = tmp1 + tmp6; | |
178 temp[8*6 + i] = tmp1 - tmp6; | |
179 temp[8*2 + i] = tmp2 + tmp5; | |
180 temp[8*5 + i] = tmp2 - tmp5; | |
181 temp[8*4 + i] = tmp3 + tmp4; | |
182 temp[8*3 + i] = tmp3 - tmp4; | |
183 } | |
2967 | 184 |
1293 | 185 for(i=0; i<8*8; i+=8){ |
186 tmp10 = temp[0 + i] + temp[4 + i]; | |
187 tmp11 = temp[0 + i] - temp[4 + i]; | |
188 | |
189 tmp13 = temp[2 + i] + temp[6 + i]; | |
190 tmp12 = MULTIPLY(temp[2 + i] - temp[6 + i], FIX_1_414213562) - tmp13; | |
191 | |
192 tmp0 = tmp10 + tmp13; | |
193 tmp3 = tmp10 - tmp13; | |
194 tmp1 = tmp11 + tmp12; | |
195 tmp2 = tmp11 - tmp12; | |
196 | |
197 z13 = temp[5 + i] + temp[3 + i]; | |
198 z10 = temp[5 + i] - temp[3 + i]; | |
199 z11 = temp[1 + i] + temp[7 + i]; | |
200 z12 = temp[1 + i] - temp[7 + i]; | |
201 | |
202 tmp7 = z11 + z13; | |
203 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); | |
204 | |
205 z5 = MULTIPLY(z10 + z12, FIX_1_847759065); | |
206 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; | |
207 tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; | |
208 | |
209 tmp6 = tmp12 - tmp7; | |
210 tmp5 = tmp11 - tmp6; | |
211 tmp4 = tmp10 + tmp5; | |
212 | |
213 block[0 + i] = (tmp0 + tmp7)>>6; | |
214 block[7 + i] = (tmp0 - tmp7)>>6; | |
215 block[1 + i] = (tmp1 + tmp6)>>6; | |
216 block[6 + i] = (tmp1 - tmp6)>>6; | |
217 block[2 + i] = (tmp2 + tmp5)>>6; | |
218 block[5 + i] = (tmp2 - tmp5)>>6; | |
219 block[4 + i] = (tmp3 + tmp4)>>6; | |
220 block[3 + i] = (tmp3 - tmp4)>>6; | |
221 } | |
222 } | |
223 | |
224 static void init_vlcs(FourXContext *f){ | |
225 int i; | |
226 | |
2370
26560d4fdb1f
Memory leak fix patch by (Burkhard Plaum <plaum >at< ipf.uni-stuttgart )dot( de>)
michael
parents:
2028
diff
changeset
|
227 for(i=0; i<4; i++){ |
2967 | 228 init_vlc(&block_type_vlc[i], BLOCK_TYPE_VLC_BITS, 7, |
2370
26560d4fdb1f
Memory leak fix patch by (Burkhard Plaum <plaum >at< ipf.uni-stuttgart )dot( de>)
michael
parents:
2028
diff
changeset
|
229 &block_type_tab[i][0][1], 2, 1, |
26560d4fdb1f
Memory leak fix patch by (Burkhard Plaum <plaum >at< ipf.uni-stuttgart )dot( de>)
michael
parents:
2028
diff
changeset
|
230 &block_type_tab[i][0][0], 2, 1, 1); |
1293 | 231 } |
232 } | |
233 | |
234 static void init_mv(FourXContext *f){ | |
235 int i; | |
236 | |
237 for(i=0; i<256; i++){ | |
238 f->mv[i] = mv[i][0] + mv[i][1]*f->current_picture.linesize[0]/2; | |
239 } | |
240 } | |
241 | |
242 static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, int dc){ | |
243 int i; | |
244 dc*= 0x10001; | |
245 | |
246 switch(log2w){ | |
247 case 0: | |
248 for(i=0; i<h; i++){ | |
249 dst[0] = scale*src[0] + dc; | |
250 if(scale) src += stride; | |
251 dst += stride; | |
252 } | |
253 break; | |
254 case 1: | |
255 for(i=0; i<h; i++){ | |
256 ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc; | |
257 if(scale) src += stride; | |
258 dst += stride; | |
259 } | |
260 break; | |
261 case 2: | |
262 for(i=0; i<h; i++){ | |
263 ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc; | |
264 ((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc; | |
265 if(scale) src += stride; | |
266 dst += stride; | |
267 } | |
268 break; | |
269 case 3: | |
270 for(i=0; i<h; i++){ | |
271 ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc; | |
272 ((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc; | |
273 ((uint32_t*)dst)[2] = scale*((uint32_t*)src)[2] + dc; | |
274 ((uint32_t*)dst)[3] = scale*((uint32_t*)src)[3] + dc; | |
275 if(scale) src += stride; | |
276 dst += stride; | |
277 } | |
278 break; | |
279 default: assert(0); | |
280 } | |
281 } | |
282 | |
283 static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int log2w, int log2h, int stride){ | |
284 const int index= size2index[log2h][log2w]; | |
285 const int h= 1<<log2h; | |
286 int code= get_vlc2(&f->gb, block_type_vlc[index].table, BLOCK_TYPE_VLC_BITS, 1); | |
2967 | 287 |
1293 | 288 assert(code>=0 && code<=6); |
289 | |
290 if(code == 0){ | |
291 src += f->mv[ *f->bytestream++ ]; | |
292 mcdc(dst, src, log2w, h, stride, 1, 0); | |
293 }else if(code == 1){ | |
294 log2h--; | |
295 decode_p_block(f, dst , src , log2w, log2h, stride); | |
296 decode_p_block(f, dst + (stride<<log2h), src + (stride<<log2h), log2w, log2h, stride); | |
297 }else if(code == 2){ | |
298 log2w--; | |
299 decode_p_block(f, dst , src , log2w, log2h, stride); | |
300 decode_p_block(f, dst + (1<<log2w), src + (1<<log2w), log2w, log2h, stride); | |
301 }else if(code == 4){ | |
302 src += f->mv[ *f->bytestream++ ]; | |
303 mcdc(dst, src, log2w, h, stride, 1, le2me_16(*f->wordstream++)); | |
304 }else if(code == 5){ | |
305 mcdc(dst, src, log2w, h, stride, 0, le2me_16(*f->wordstream++)); | |
306 }else if(code == 6){ | |
307 if(log2w){ | |
308 dst[0] = le2me_16(*f->wordstream++); | |
309 dst[1] = le2me_16(*f->wordstream++); | |
310 }else{ | |
311 dst[0 ] = le2me_16(*f->wordstream++); | |
312 dst[stride] = le2me_16(*f->wordstream++); | |
313 } | |
314 } | |
315 } | |
316 | |
317 static int get32(void *p){ | |
318 return le2me_32(*(uint32_t*)p); | |
319 } | |
320 | |
321 static int decode_p_frame(FourXContext *f, uint8_t *buf, int length){ | |
322 int x, y; | |
323 const int width= f->avctx->width; | |
324 const int height= f->avctx->height; | |
325 uint16_t *src= (uint16_t*)f->last_picture.data[0]; | |
326 uint16_t *dst= (uint16_t*)f->current_picture.data[0]; | |
327 const int stride= f->current_picture.linesize[0]>>1; | |
2422 | 328 const unsigned int bitstream_size= get32(buf+8); |
329 const unsigned int bytestream_size= get32(buf+16); | |
330 const unsigned int wordstream_size= get32(buf+12); | |
2967 | 331 |
2422 | 332 if(bitstream_size+ bytestream_size+ wordstream_size + 20 != length |
333 || bitstream_size > (1<<26) | |
334 || bytestream_size > (1<<26) | |
335 || wordstream_size > (1<<26) | |
336 ){ | |
2967 | 337 av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size, |
1293 | 338 bitstream_size+ bytestream_size+ wordstream_size - length); |
2422 | 339 return -1; |
340 } | |
2967 | 341 |
1293 | 342 f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE); |
343 f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (uint32_t*)(buf + 20), bitstream_size/4); | |
344 init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size); | |
345 | |
346 f->wordstream= (uint16_t*)(buf + 20 + bitstream_size); | |
347 f->bytestream= buf + 20 + bitstream_size + wordstream_size; | |
2967 | 348 |
1293 | 349 init_mv(f); |
2967 | 350 |
1293 | 351 for(y=0; y<height; y+=8){ |
352 for(x=0; x<width; x+=8){ | |
353 decode_p_block(f, dst + x, src + x, 3, 3, stride); | |
354 } | |
2967 | 355 src += 8*stride; |
356 dst += 8*stride; | |
1293 | 357 } |
2967 | 358 |
1293 | 359 if(bitstream_size != (get_bits_count(&f->gb)+31)/32*4) |
2967 | 360 av_log(f->avctx, AV_LOG_ERROR, " %d %td %td bytes left\n", |
361 bitstream_size - (get_bits_count(&f->gb)+31)/32*4, | |
1293 | 362 bytestream_size - (f->bytestream - (buf + 20 + bitstream_size + wordstream_size)), |
363 wordstream_size - (((uint8_t*)f->wordstream) - (buf + 20 + bitstream_size)) | |
364 ); | |
2967 | 365 |
1293 | 366 return 0; |
367 } | |
368 | |
369 /** | |
370 * decode block and dequantize. | |
371 * Note this is allmost identical to mjpeg | |
372 */ | |
373 static int decode_i_block(FourXContext *f, DCTELEM *block){ | |
374 int code, i, j, level, val; | |
375 | |
376 /* DC coef */ | |
377 val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); | |
378 if (val>>4){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
379 av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n"); |
1293 | 380 } |
381 | |
382 if(val) | |
383 val = get_xbits(&f->gb, val); | |
384 | |
385 val = val * dequant_table[0] + f->last_dc; | |
386 f->last_dc = | |
387 block[0] = val; | |
388 /* AC coefs */ | |
389 i = 1; | |
390 for(;;) { | |
391 code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); | |
2967 | 392 |
1293 | 393 /* EOB */ |
394 if (code == 0) | |
395 break; | |
396 if (code == 0xf0) { | |
397 i += 16; | |
398 } else { | |
399 level = get_xbits(&f->gb, code & 0xf); | |
400 i += code >> 4; | |
401 if (i >= 64) { | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
402 av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i); |
1293 | 403 return 0; |
404 } | |
405 | |
406 j= ff_zigzag_direct[i]; | |
407 block[j] = level * dequant_table[j]; | |
408 i++; | |
409 if (i >= 64) | |
410 break; | |
411 } | |
412 } | |
413 | |
414 return 0; | |
415 } | |
416 | |
417 static inline void idct_put(FourXContext *f, int x, int y){ | |
418 DCTELEM (*block)[64]= f->block; | |
419 int stride= f->current_picture.linesize[0]>>1; | |
420 int i; | |
421 uint16_t *dst = ((uint16_t*)f->current_picture.data[0]) + y * stride + x; | |
2967 | 422 |
1295 | 423 for(i=0; i<4; i++){ |
424 block[i][0] += 0x80*8*8; | |
425 idct(block[i]); | |
426 } | |
1293 | 427 |
1295 | 428 if(!(f->avctx->flags&CODEC_FLAG_GRAY)){ |
429 for(i=4; i<6; i++) idct(block[i]); | |
430 } | |
1293 | 431 |
1514 | 432 /* Note transform is: |
433 y= ( 1b + 4g + 2r)/14 | |
434 cb=( 3b - 2g - 1r)/14 | |
435 cr=(-1b - 4g + 5r)/14 | |
2967 | 436 */ |
1293 | 437 for(y=0; y<8; y++){ |
438 for(x=0; x<8; x++){ | |
439 DCTELEM *temp= block[(x>>2) + 2*(y>>2)] + 2*(x&3) + 2*8*(y&3); //FIXME optimize | |
1295 | 440 int cb= block[4][x + 8*y]; |
441 int cr= block[5][x + 8*y]; | |
1293 | 442 int cg= (cb + cr)>>1; |
443 int y; | |
2967 | 444 |
1295 | 445 cb+=cb; |
2967 | 446 |
1293 | 447 y = temp[0]; |
1295 | 448 dst[0 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); |
1293 | 449 y = temp[1]; |
1295 | 450 dst[1 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); |
1293 | 451 y = temp[8]; |
1295 | 452 dst[ stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); |
1293 | 453 y = temp[9]; |
1295 | 454 dst[1+stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); |
1293 | 455 dst += 2; |
456 } | |
457 dst += 2*stride - 2*8; | |
458 } | |
459 } | |
460 | |
461 static int decode_i_mb(FourXContext *f){ | |
462 int i; | |
2967 | 463 |
1293 | 464 f->dsp.clear_blocks(f->block[0]); |
2967 | 465 |
1293 | 466 for(i=0; i<6; i++){ |
467 if(decode_i_block(f, f->block[i]) < 0) | |
468 return -1; | |
469 } | |
2967 | 470 |
1293 | 471 return 0; |
472 } | |
473 | |
474 static uint8_t *read_huffman_tables(FourXContext *f, uint8_t * const buf){ | |
475 int frequency[512]; | |
476 uint8_t flag[512]; | |
477 int up[512]; | |
478 uint8_t len_tab[257]; | |
479 int bits_tab[257]; | |
480 int start, end; | |
481 uint8_t *ptr= buf; | |
482 int j; | |
2967 | 483 |
1293 | 484 memset(frequency, 0, sizeof(frequency)); |
485 memset(up, -1, sizeof(up)); | |
486 | |
487 start= *ptr++; | |
488 end= *ptr++; | |
489 for(;;){ | |
490 int i; | |
2967 | 491 |
1293 | 492 for(i=start; i<=end; i++){ |
493 frequency[i]= *ptr++; | |
494 } | |
495 start= *ptr++; | |
496 if(start==0) break; | |
2967 | 497 |
1293 | 498 end= *ptr++; |
499 } | |
500 frequency[256]=1; | |
501 | |
2967 | 502 while((ptr - buf)&3) ptr++; // 4byte align |
1293 | 503 |
504 for(j=257; j<512; j++){ | |
1294 | 505 int min_freq[2]= {256*256, 256*256}; |
506 int smallest[2]= {0, 0}; | |
1293 | 507 int i; |
508 for(i=0; i<j; i++){ | |
509 if(frequency[i] == 0) continue; | |
1294 | 510 if(frequency[i] < min_freq[1]){ |
511 if(frequency[i] < min_freq[0]){ | |
512 min_freq[1]= min_freq[0]; smallest[1]= smallest[0]; | |
513 min_freq[0]= frequency[i];smallest[0]= i; | |
514 }else{ | |
515 min_freq[1]= frequency[i];smallest[1]= i; | |
516 } | |
1293 | 517 } |
518 } | |
1294 | 519 if(min_freq[1] == 256*256) break; |
2967 | 520 |
1294 | 521 frequency[j]= min_freq[0] + min_freq[1]; |
1293 | 522 flag[ smallest[0] ]= 0; |
523 flag[ smallest[1] ]= 1; | |
2967 | 524 up[ smallest[0] ]= |
1293 | 525 up[ smallest[1] ]= j; |
526 frequency[ smallest[0] ]= frequency[ smallest[1] ]= 0; | |
527 } | |
528 | |
529 for(j=0; j<257; j++){ | |
530 int node; | |
531 int len=0; | |
532 int bits=0; | |
533 | |
534 for(node= j; up[node] != -1; node= up[node]){ | |
535 bits += flag[node]<<len; | |
536 len++; | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
537 if(len > 31) av_log(f->avctx, AV_LOG_ERROR, "vlc length overflow\n"); //can this happen at all ? |
1293 | 538 } |
2967 | 539 |
1293 | 540 bits_tab[j]= bits; |
541 len_tab[j]= len; | |
542 } | |
2967 | 543 |
544 init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257, | |
1293 | 545 len_tab , 1, 1, |
2370
26560d4fdb1f
Memory leak fix patch by (Burkhard Plaum <plaum >at< ipf.uni-stuttgart )dot( de>)
michael
parents:
2028
diff
changeset
|
546 bits_tab, 4, 4, 0); |
2967 | 547 |
1293 | 548 return ptr; |
549 } | |
550 | |
551 static int decode_i_frame(FourXContext *f, uint8_t *buf, int length){ | |
552 int x, y; | |
553 const int width= f->avctx->width; | |
554 const int height= f->avctx->height; | |
555 uint16_t *dst= (uint16_t*)f->current_picture.data[0]; | |
556 const int stride= f->current_picture.linesize[0]>>1; | |
2422 | 557 const unsigned int bitstream_size= get32(buf); |
1478 | 558 const int token_count __attribute__((unused)) = get32(buf + bitstream_size + 8); |
2422 | 559 unsigned int prestream_size= 4*get32(buf + bitstream_size + 4); |
1293 | 560 uint8_t *prestream= buf + bitstream_size + 12; |
2967 | 561 |
2422 | 562 if(prestream_size + bitstream_size + 12 != length |
563 || bitstream_size > (1<<26) | |
564 || prestream_size > (1<<26)){ | |
2628
511e3afc43e1
Ministry of English Composition, reporting for duty (and the word is "skipped", not "skiped"; "skiped" would rhyme with "hyped")
melanson
parents:
2453
diff
changeset
|
565 av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length); |
2422 | 566 return -1; |
567 } | |
2967 | 568 |
1293 | 569 prestream= read_huffman_tables(f, prestream); |
570 | |
571 init_get_bits(&f->gb, buf + 4, 8*bitstream_size); | |
572 | |
573 prestream_size= length + buf - prestream; | |
1294 | 574 |
1293 | 575 f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE); |
576 f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (uint32_t*)prestream, prestream_size/4); | |
577 init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size); | |
578 | |
579 f->last_dc= 0*128*8*8; | |
2967 | 580 |
1293 | 581 for(y=0; y<height; y+=16){ |
582 for(x=0; x<width; x+=16){ | |
583 if(decode_i_mb(f) < 0) | |
584 return -1; | |
585 | |
586 idct_put(f, x, y); | |
587 } | |
2967 | 588 dst += 16*stride; |
1293 | 589 } |
590 | |
591 if(get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256) | |
2628
511e3afc43e1
Ministry of English Composition, reporting for duty (and the word is "skipped", not "skiped"; "skiped" would rhyme with "hyped")
melanson
parents:
2453
diff
changeset
|
592 av_log(f->avctx, AV_LOG_ERROR, "end mismatch\n"); |
2967 | 593 |
1293 | 594 return 0; |
595 } | |
596 | |
2967 | 597 static int decode_frame(AVCodecContext *avctx, |
1293 | 598 void *data, int *data_size, |
599 uint8_t *buf, int buf_size) | |
600 { | |
601 FourXContext * const f = avctx->priv_data; | |
602 AVFrame *picture = data; | |
603 AVFrame *p, temp; | |
604 int i, frame_4cc, frame_size; | |
605 | |
606 frame_4cc= get32(buf); | |
3303
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3089
diff
changeset
|
607 if(buf_size != get32(buf+4)+8 || buf_size < 20){ |
2628
511e3afc43e1
Ministry of English Composition, reporting for duty (and the word is "skipped", not "skiped"; "skiped" would rhyme with "hyped")
melanson
parents:
2453
diff
changeset
|
608 av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, get32(buf+4)); |
1293 | 609 } |
610 | |
611 if(frame_4cc == ff_get_fourcc("cfrm")){ | |
612 int free_index=-1; | |
613 const int data_size= buf_size - 20; | |
614 const int id= get32(buf+12); | |
615 const int whole_size= get32(buf+16); | |
616 CFrameBuffer *cfrm; | |
617 | |
618 for(i=0; i<CFRAME_BUFFER_COUNT; i++){ | |
619 if(f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number) | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
620 av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id); |
1293 | 621 } |
2967 | 622 |
1293 | 623 for(i=0; i<CFRAME_BUFFER_COUNT; i++){ |
624 if(f->cfrm[i].id == id) break; | |
625 if(f->cfrm[i].size == 0 ) free_index= i; | |
626 } | |
627 | |
628 if(i>=CFRAME_BUFFER_COUNT){ | |
629 i= free_index; | |
630 f->cfrm[i].id= id; | |
631 } | |
632 cfrm= &f->cfrm[i]; | |
2967 | 633 |
1293 | 634 cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE); |
3303
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3089
diff
changeset
|
635 if(!cfrm->data){ //explicit check needed as memcpy below might not catch a NULL |
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3089
diff
changeset
|
636 av_log(f->avctx, AV_LOG_ERROR, "realloc falure"); |
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3089
diff
changeset
|
637 return -1; |
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3089
diff
changeset
|
638 } |
2967 | 639 |
1293 | 640 memcpy(cfrm->data + cfrm->size, buf+20, data_size); |
641 cfrm->size += data_size; | |
2967 | 642 |
1293 | 643 if(cfrm->size >= whole_size){ |
644 buf= cfrm->data; | |
645 frame_size= cfrm->size; | |
2967 | 646 |
1293 | 647 if(id != avctx->frame_number){ |
2628
511e3afc43e1
Ministry of English Composition, reporting for duty (and the word is "skipped", not "skiped"; "skiped" would rhyme with "hyped")
melanson
parents:
2453
diff
changeset
|
648 av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number); |
1293 | 649 } |
2967 | 650 |
1293 | 651 cfrm->size= cfrm->id= 0; |
652 frame_4cc= ff_get_fourcc("pfrm"); | |
653 }else | |
654 return buf_size; | |
655 }else{ | |
656 buf= buf + 12; | |
657 frame_size= buf_size - 12; | |
2967 | 658 } |
1293 | 659 |
660 temp= f->current_picture; | |
661 f->current_picture= f->last_picture; | |
662 f->last_picture= temp; | |
663 | |
664 p= &f->current_picture; | |
665 avctx->coded_frame= p; | |
666 | |
667 avctx->flags |= CODEC_FLAG_EMU_EDGE; // alternatively we would have to use our own buffer management | |
668 | |
669 if(p->data[0]) | |
670 avctx->release_buffer(avctx, p); | |
671 | |
672 p->reference= 1; | |
673 if(avctx->get_buffer(avctx, p) < 0){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
674 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
1293 | 675 return -1; |
676 } | |
677 | |
678 if(frame_4cc == ff_get_fourcc("ifrm")){ | |
679 p->pict_type= I_TYPE; | |
680 if(decode_i_frame(f, buf, frame_size) < 0) | |
681 return -1; | |
682 }else if(frame_4cc == ff_get_fourcc("pfrm")){ | |
683 p->pict_type= P_TYPE; | |
684 if(decode_p_frame(f, buf, frame_size) < 0) | |
685 return -1; | |
686 }else if(frame_4cc == ff_get_fourcc("snd_")){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
687 av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size); |
1293 | 688 }else{ |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
689 av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n", buf_size); |
1293 | 690 } |
691 | |
692 p->key_frame= p->pict_type == I_TYPE; | |
693 | |
694 *picture= *p; | |
695 *data_size = sizeof(AVPicture); | |
696 | |
697 emms_c(); | |
2967 | 698 |
1293 | 699 return buf_size; |
700 } | |
701 | |
702 | |
703 static void common_init(AVCodecContext *avctx){ | |
704 FourXContext * const f = avctx->priv_data; | |
705 | |
706 dsputil_init(&f->dsp, avctx); | |
707 | |
708 f->avctx= avctx; | |
709 } | |
710 | |
711 static int decode_init(AVCodecContext *avctx){ | |
712 FourXContext * const f = avctx->priv_data; | |
2967 | 713 |
1293 | 714 common_init(avctx); |
715 init_vlcs(f); | |
716 | |
717 avctx->pix_fmt= PIX_FMT_RGB565; | |
718 | |
719 return 0; | |
720 } | |
721 | |
722 | |
723 static int decode_end(AVCodecContext *avctx){ | |
724 FourXContext * const f = avctx->priv_data; | |
725 int i; | |
726 | |
727 av_freep(&f->bitstream_buffer); | |
728 f->bitstream_buffer_size=0; | |
729 for(i=0; i<CFRAME_BUFFER_COUNT; i++){ | |
730 av_freep(&f->cfrm[i].data); | |
731 f->cfrm[i].allocated_size= 0; | |
732 } | |
733 free_vlc(&f->pre_vlc); | |
2967 | 734 |
1293 | 735 return 0; |
736 } | |
737 | |
738 AVCodec fourxm_decoder = { | |
739 "4xm", | |
740 CODEC_TYPE_VIDEO, | |
741 CODEC_ID_4XM, | |
742 sizeof(FourXContext), | |
743 decode_init, | |
744 NULL, | |
745 decode_end, | |
746 decode_frame, | |
747 /*CODEC_CAP_DR1,*/ | |
748 }; | |
749 |