Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
[ffmpeg-lucabe.git] / libavcodec / 4xm.c
blob0fc7a2e6d8c5ce7e4d79e99401968de03496eea4
1 /*
2 * 4XM codec
3 * Copyright (c) 2003 Michael Niedermayer
5 * This file is part of FFmpeg.
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.
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.
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
22 /**
23 * @file 4xm.c
24 * 4XM codec.
27 #include "avcodec.h"
28 #include "dsputil.h"
29 #include "bitstream.h"
30 #include "bytestream.h"
32 //#undef NDEBUG
33 //#include <assert.h>
35 #define BLOCK_TYPE_VLC_BITS 5
36 #define ACDC_VLC_BITS 9
38 #define CFRAME_BUFFER_COUNT 100
40 static const uint8_t block_type_tab[2][4][8][2]={
42 { //{8,4,2}x{8,4,2}
43 { 0,1}, { 2,2}, { 6,3}, {14,4}, {30,5}, {31,5}, { 0,0}
44 },{ //{8,4}x1
45 { 0,1}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}, { 0,0}
46 },{ //1x{8,4}
47 { 0,1}, { 2,2}, { 0,0}, { 6,3}, {14,4}, {15,4}, { 0,0}
48 },{ //1x2, 2x1
49 { 0,1}, { 0,0}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}
51 },{
52 { //{8,4,2}x{8,4,2}
53 { 1,2}, { 4,3}, { 5,3}, {0,2}, {6,3}, {7,3}, {0,0}
54 },{//{8,4}x1
55 { 1,2}, { 0,0}, { 2,2}, {0,2}, {6,3}, {7,3}, {0,0}
56 },{//1x{8,4}
57 { 1,2}, { 2,2}, { 0,0}, {0,2}, {6,3}, {7,3}, {0,0}
58 },{//1x2, 2x1
59 { 1,2}, { 0,0}, { 0,0}, {0,2}, {2,2}, {6,3}, {7,3}
64 static const uint8_t size2index[4][4]={
65 {-1, 3, 1, 1},
66 { 3, 0, 0, 0},
67 { 2, 0, 0, 0},
68 { 2, 0, 0, 0},
71 static const int8_t mv[256][2]={
72 { 0, 0},{ 0, -1},{ -1, 0},{ 1, 0},{ 0, 1},{ -1, -1},{ 1, -1},{ -1, 1},
73 { 1, 1},{ 0, -2},{ -2, 0},{ 2, 0},{ 0, 2},{ -1, -2},{ 1, -2},{ -2, -1},
74 { 2, -1},{ -2, 1},{ 2, 1},{ -1, 2},{ 1, 2},{ -2, -2},{ 2, -2},{ -2, 2},
75 { 2, 2},{ 0, -3},{ -3, 0},{ 3, 0},{ 0, 3},{ -1, -3},{ 1, -3},{ -3, -1},
76 { 3, -1},{ -3, 1},{ 3, 1},{ -1, 3},{ 1, 3},{ -2, -3},{ 2, -3},{ -3, -2},
77 { 3, -2},{ -3, 2},{ 3, 2},{ -2, 3},{ 2, 3},{ 0, -4},{ -4, 0},{ 4, 0},
78 { 0, 4},{ -1, -4},{ 1, -4},{ -4, -1},{ 4, -1},{ 4, 1},{ -1, 4},{ 1, 4},
79 { -3, -3},{ -3, 3},{ 3, 3},{ -2, -4},{ -4, -2},{ 4, -2},{ -4, 2},{ -2, 4},
80 { 2, 4},{ -3, -4},{ 3, -4},{ 4, -3},{ -5, 0},{ -4, 3},{ -3, 4},{ 3, 4},
81 { -1, -5},{ -5, -1},{ -5, 1},{ -1, 5},{ -2, -5},{ 2, -5},{ 5, -2},{ 5, 2},
82 { -4, -4},{ -4, 4},{ -3, -5},{ -5, -3},{ -5, 3},{ 3, 5},{ -6, 0},{ 0, 6},
83 { -6, -1},{ -6, 1},{ 1, 6},{ 2, -6},{ -6, 2},{ 2, 6},{ -5, -4},{ 5, 4},
84 { 4, 5},{ -6, -3},{ 6, 3},{ -7, 0},{ -1, -7},{ 5, -5},{ -7, 1},{ -1, 7},
85 { 4, -6},{ 6, 4},{ -2, -7},{ -7, 2},{ -3, -7},{ 7, -3},{ 3, 7},{ 6, -5},
86 { 0, -8},{ -1, -8},{ -7, -4},{ -8, 1},{ 4, 7},{ 2, -8},{ -2, 8},{ 6, 6},
87 { -8, 3},{ 5, -7},{ -5, 7},{ 8, -4},{ 0, -9},{ -9, -1},{ 1, 9},{ 7, -6},
88 { -7, 6},{ -5, -8},{ -5, 8},{ -9, 3},{ 9, -4},{ 7, -7},{ 8, -6},{ 6, 8},
89 { 10, 1},{-10, 2},{ 9, -5},{ 10, -3},{ -8, -7},{-10, -4},{ 6, -9},{-11, 0},
90 { 11, 1},{-11, -2},{ -2, 11},{ 7, -9},{ -7, 9},{ 10, 6},{ -4, 11},{ 8, -9},
91 { 8, 9},{ 5, 11},{ 7,-10},{ 12, -3},{ 11, 6},{ -9, -9},{ 8, 10},{ 5, 12},
92 {-11, 7},{ 13, 2},{ 6,-12},{ 10, 9},{-11, 8},{ -7, 12},{ 0, 14},{ 14, -2},
93 { -9, 11},{ -6, 13},{-14, -4},{ -5,-14},{ 5, 14},{-15, -1},{-14, -6},{ 3,-15},
94 { 11,-11},{ -7, 14},{ -5, 15},{ 8,-14},{ 15, 6},{ 3, 16},{ 7,-15},{-16, 5},
95 { 0, 17},{-16, -6},{-10, 14},{-16, 7},{ 12, 13},{-16, 8},{-17, 6},{-18, 3},
96 { -7, 17},{ 15, 11},{ 16, 10},{ 2,-19},{ 3,-19},{-11,-16},{-18, 8},{-19, -6},
97 { 2,-20},{-17,-11},{-10,-18},{ 8, 19},{-21, -1},{-20, 7},{ -4, 21},{ 21, 5},
98 { 15, 16},{ 2,-22},{-10,-20},{-22, 5},{ 20,-11},{ -7,-22},{-12, 20},{ 23, -5},
99 { 13,-20},{ 24, -2},{-15, 19},{-11, 22},{ 16, 19},{ 23,-10},{-18,-18},{ -9,-24},
100 { 24,-10},{ -3, 26},{-23, 13},{-18,-20},{ 17, 21},{ -4, 27},{ 27, 6},{ 1,-28},
101 {-11, 26},{-17,-23},{ 7, 28},{ 11,-27},{ 29, 5},{-23,-19},{-28,-11},{-21, 22},
102 {-30, 7},{-17, 26},{-27, 16},{ 13, 29},{ 19,-26},{ 10,-31},{-14,-30},{ 20,-27},
103 {-29, 18},{-16,-31},{-28,-22},{ 21,-30},{-25, 28},{ 26,-29},{ 25,-32},{-32,-32}
106 // this is simply the scaled down elementwise product of the standard jpeg quantizer table and the AAN premul table
107 static const uint8_t dequant_table[64]={
108 16, 15, 13, 19, 24, 31, 28, 17,
109 17, 23, 25, 31, 36, 63, 45, 21,
110 18, 24, 27, 37, 52, 59, 49, 20,
111 16, 28, 34, 40, 60, 80, 51, 20,
112 18, 31, 48, 66, 68, 86, 56, 21,
113 19, 38, 56, 59, 64, 64, 48, 20,
114 27, 48, 55, 55, 56, 51, 35, 15,
115 20, 35, 34, 32, 31, 22, 15, 8,
118 static VLC block_type_vlc[2][4];
121 typedef struct CFrameBuffer{
122 unsigned int allocated_size;
123 unsigned int size;
124 int id;
125 uint8_t *data;
126 }CFrameBuffer;
128 typedef struct FourXContext{
129 AVCodecContext *avctx;
130 DSPContext dsp;
131 AVFrame current_picture, last_picture;
132 GetBitContext pre_gb; ///< ac/dc prefix
133 GetBitContext gb;
134 const uint8_t *bytestream;
135 const uint16_t *wordstream;
136 int mv[256];
137 VLC pre_vlc;
138 int last_dc;
139 DECLARE_ALIGNED_8(DCTELEM, block[6][64]);
140 uint8_t *bitstream_buffer;
141 unsigned int bitstream_buffer_size;
142 int version;
143 CFrameBuffer cfrm[CFRAME_BUFFER_COUNT];
144 } FourXContext;
147 #define FIX_1_082392200 70936
148 #define FIX_1_414213562 92682
149 #define FIX_1_847759065 121095
150 #define FIX_2_613125930 171254
152 #define MULTIPLY(var,const) (((var)*(const)) >> 16)
154 static void idct(DCTELEM block[64]){
155 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
156 int tmp10, tmp11, tmp12, tmp13;
157 int z5, z10, z11, z12, z13;
158 int i;
159 int temp[64];
161 for(i=0; i<8; i++){
162 tmp10 = block[8*0 + i] + block[8*4 + i];
163 tmp11 = block[8*0 + i] - block[8*4 + i];
165 tmp13 = block[8*2 + i] + block[8*6 + i];
166 tmp12 = MULTIPLY(block[8*2 + i] - block[8*6 + i], FIX_1_414213562) - tmp13;
168 tmp0 = tmp10 + tmp13;
169 tmp3 = tmp10 - tmp13;
170 tmp1 = tmp11 + tmp12;
171 tmp2 = tmp11 - tmp12;
173 z13 = block[8*5 + i] + block[8*3 + i];
174 z10 = block[8*5 + i] - block[8*3 + i];
175 z11 = block[8*1 + i] + block[8*7 + i];
176 z12 = block[8*1 + i] - block[8*7 + i];
178 tmp7 = z11 + z13;
179 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
181 z5 = MULTIPLY(z10 + z12, FIX_1_847759065);
182 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
183 tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
185 tmp6 = tmp12 - tmp7;
186 tmp5 = tmp11 - tmp6;
187 tmp4 = tmp10 + tmp5;
189 temp[8*0 + i] = tmp0 + tmp7;
190 temp[8*7 + i] = tmp0 - tmp7;
191 temp[8*1 + i] = tmp1 + tmp6;
192 temp[8*6 + i] = tmp1 - tmp6;
193 temp[8*2 + i] = tmp2 + tmp5;
194 temp[8*5 + i] = tmp2 - tmp5;
195 temp[8*4 + i] = tmp3 + tmp4;
196 temp[8*3 + i] = tmp3 - tmp4;
199 for(i=0; i<8*8; i+=8){
200 tmp10 = temp[0 + i] + temp[4 + i];
201 tmp11 = temp[0 + i] - temp[4 + i];
203 tmp13 = temp[2 + i] + temp[6 + i];
204 tmp12 = MULTIPLY(temp[2 + i] - temp[6 + i], FIX_1_414213562) - tmp13;
206 tmp0 = tmp10 + tmp13;
207 tmp3 = tmp10 - tmp13;
208 tmp1 = tmp11 + tmp12;
209 tmp2 = tmp11 - tmp12;
211 z13 = temp[5 + i] + temp[3 + i];
212 z10 = temp[5 + i] - temp[3 + i];
213 z11 = temp[1 + i] + temp[7 + i];
214 z12 = temp[1 + i] - temp[7 + i];
216 tmp7 = z11 + z13;
217 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
219 z5 = MULTIPLY(z10 + z12, FIX_1_847759065);
220 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
221 tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
223 tmp6 = tmp12 - tmp7;
224 tmp5 = tmp11 - tmp6;
225 tmp4 = tmp10 + tmp5;
227 block[0 + i] = (tmp0 + tmp7)>>6;
228 block[7 + i] = (tmp0 - tmp7)>>6;
229 block[1 + i] = (tmp1 + tmp6)>>6;
230 block[6 + i] = (tmp1 - tmp6)>>6;
231 block[2 + i] = (tmp2 + tmp5)>>6;
232 block[5 + i] = (tmp2 - tmp5)>>6;
233 block[4 + i] = (tmp3 + tmp4)>>6;
234 block[3 + i] = (tmp3 - tmp4)>>6;
238 static av_cold void init_vlcs(FourXContext *f){
239 int i;
241 for(i=0; i<8; i++){
242 init_vlc(&block_type_vlc[0][i], BLOCK_TYPE_VLC_BITS, 7,
243 &block_type_tab[0][i][0][1], 2, 1,
244 &block_type_tab[0][i][0][0], 2, 1, 1);
248 static void init_mv(FourXContext *f){
249 int i;
251 for(i=0; i<256; i++){
252 if(f->version>1)
253 f->mv[i] = mv[i][0] + mv[i][1] *f->current_picture.linesize[0]/2;
254 else
255 f->mv[i] = (i&15) - 8 + ((i>>4)-8)*f->current_picture.linesize[0]/2;
259 static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, int dc){
260 int i;
261 dc*= 0x10001;
263 switch(log2w){
264 case 0:
265 for(i=0; i<h; i++){
266 dst[0] = scale*src[0] + dc;
267 if(scale) src += stride;
268 dst += stride;
270 break;
271 case 1:
272 for(i=0; i<h; i++){
273 ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
274 if(scale) src += stride;
275 dst += stride;
277 break;
278 case 2:
279 for(i=0; i<h; i++){
280 ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
281 ((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc;
282 if(scale) src += stride;
283 dst += stride;
285 break;
286 case 3:
287 for(i=0; i<h; i++){
288 ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
289 ((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc;
290 ((uint32_t*)dst)[2] = scale*((uint32_t*)src)[2] + dc;
291 ((uint32_t*)dst)[3] = scale*((uint32_t*)src)[3] + dc;
292 if(scale) src += stride;
293 dst += stride;
295 break;
296 default: assert(0);
300 static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int log2w, int log2h, int stride){
301 const int index= size2index[log2h][log2w];
302 const int h= 1<<log2h;
303 int code= get_vlc2(&f->gb, block_type_vlc[1-(f->version>1)][index].table, BLOCK_TYPE_VLC_BITS, 1);
304 uint16_t *start= (uint16_t*)f->last_picture.data[0];
305 uint16_t *end= start + stride*(f->avctx->height-h+1) - (1<<log2w);
307 assert(code>=0 && code<=6);
309 if(code == 0){
310 src += f->mv[ *f->bytestream++ ];
311 if(start > src || src > end){
312 av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
313 return;
315 mcdc(dst, src, log2w, h, stride, 1, 0);
316 }else if(code == 1){
317 log2h--;
318 decode_p_block(f, dst , src , log2w, log2h, stride);
319 decode_p_block(f, dst + (stride<<log2h), src + (stride<<log2h), log2w, log2h, stride);
320 }else if(code == 2){
321 log2w--;
322 decode_p_block(f, dst , src , log2w, log2h, stride);
323 decode_p_block(f, dst + (1<<log2w), src + (1<<log2w), log2w, log2h, stride);
324 }else if(code == 3 && f->version<2){
325 mcdc(dst, src, log2w, h, stride, 1, 0);
326 }else if(code == 4){
327 src += f->mv[ *f->bytestream++ ];
328 if(start > src || src > end){
329 av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
330 return;
332 mcdc(dst, src, log2w, h, stride, 1, le2me_16(*f->wordstream++));
333 }else if(code == 5){
334 mcdc(dst, src, log2w, h, stride, 0, le2me_16(*f->wordstream++));
335 }else if(code == 6){
336 if(log2w){
337 dst[0] = le2me_16(*f->wordstream++);
338 dst[1] = le2me_16(*f->wordstream++);
339 }else{
340 dst[0 ] = le2me_16(*f->wordstream++);
341 dst[stride] = le2me_16(*f->wordstream++);
346 static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){
347 int x, y;
348 const int width= f->avctx->width;
349 const int height= f->avctx->height;
350 uint16_t *src= (uint16_t*)f->last_picture.data[0];
351 uint16_t *dst= (uint16_t*)f->current_picture.data[0];
352 const int stride= f->current_picture.linesize[0]>>1;
353 unsigned int bitstream_size, bytestream_size, wordstream_size, extra;
355 if(f->version>1){
356 extra=20;
357 bitstream_size= AV_RL32(buf+8);
358 wordstream_size= AV_RL32(buf+12);
359 bytestream_size= AV_RL32(buf+16);
360 }else{
361 extra=0;
362 bitstream_size = AV_RL16(buf-4);
363 wordstream_size= AV_RL16(buf-2);
364 bytestream_size= FFMAX(length - bitstream_size - wordstream_size, 0);
367 if(bitstream_size+ bytestream_size+ wordstream_size + extra != length
368 || bitstream_size > (1<<26)
369 || bytestream_size > (1<<26)
370 || wordstream_size > (1<<26)
372 av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size,
373 bitstream_size+ bytestream_size+ wordstream_size - length);
374 return -1;
377 f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE);
378 f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (const uint32_t*)(buf + extra), bitstream_size/4);
379 init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size);
381 f->wordstream= (const uint16_t*)(buf + extra + bitstream_size);
382 f->bytestream= buf + extra + bitstream_size + wordstream_size;
384 init_mv(f);
386 for(y=0; y<height; y+=8){
387 for(x=0; x<width; x+=8){
388 decode_p_block(f, dst + x, src + x, 3, 3, stride);
390 src += 8*stride;
391 dst += 8*stride;
394 if( bitstream_size != (get_bits_count(&f->gb)+31)/32*4
395 || (((const char*)f->wordstream - (const char*)buf + 2)&~2) != extra + bitstream_size + wordstream_size
396 || (((const char*)f->bytestream - (const char*)buf + 3)&~3) != extra + bitstream_size + wordstream_size + bytestream_size)
397 av_log(f->avctx, AV_LOG_ERROR, " %d %td %td bytes left\n",
398 bitstream_size - (get_bits_count(&f->gb)+31)/32*4,
399 -(((const char*)f->bytestream - (const char*)buf + 3)&~3) + (extra + bitstream_size + wordstream_size + bytestream_size),
400 -(((const char*)f->wordstream - (const char*)buf + 2)&~2) + (extra + bitstream_size + wordstream_size)
403 return 0;
407 * decode block and dequantize.
408 * Note this is almost identical to MJPEG.
410 static int decode_i_block(FourXContext *f, DCTELEM *block){
411 int code, i, j, level, val;
413 /* DC coef */
414 val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
415 if (val>>4){
416 av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n");
419 if(val)
420 val = get_xbits(&f->gb, val);
422 val = val * dequant_table[0] + f->last_dc;
423 f->last_dc =
424 block[0] = val;
425 /* AC coefs */
426 i = 1;
427 for(;;) {
428 code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
430 /* EOB */
431 if (code == 0)
432 break;
433 if (code == 0xf0) {
434 i += 16;
435 } else {
436 level = get_xbits(&f->gb, code & 0xf);
437 i += code >> 4;
438 if (i >= 64) {
439 av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i);
440 return 0;
443 j= ff_zigzag_direct[i];
444 block[j] = level * dequant_table[j];
445 i++;
446 if (i >= 64)
447 break;
451 return 0;
454 static inline void idct_put(FourXContext *f, int x, int y){
455 DCTELEM (*block)[64]= f->block;
456 int stride= f->current_picture.linesize[0]>>1;
457 int i;
458 uint16_t *dst = ((uint16_t*)f->current_picture.data[0]) + y * stride + x;
460 for(i=0; i<4; i++){
461 block[i][0] += 0x80*8*8;
462 idct(block[i]);
465 if(!(f->avctx->flags&CODEC_FLAG_GRAY)){
466 for(i=4; i<6; i++) idct(block[i]);
469 /* Note transform is:
470 y= ( 1b + 4g + 2r)/14
471 cb=( 3b - 2g - 1r)/14
472 cr=(-1b - 4g + 5r)/14
474 for(y=0; y<8; y++){
475 for(x=0; x<8; x++){
476 DCTELEM *temp= block[(x>>2) + 2*(y>>2)] + 2*(x&3) + 2*8*(y&3); //FIXME optimize
477 int cb= block[4][x + 8*y];
478 int cr= block[5][x + 8*y];
479 int cg= (cb + cr)>>1;
480 int y;
482 cb+=cb;
484 y = temp[0];
485 dst[0 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
486 y = temp[1];
487 dst[1 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
488 y = temp[8];
489 dst[ stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
490 y = temp[9];
491 dst[1+stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
492 dst += 2;
494 dst += 2*stride - 2*8;
498 static int decode_i_mb(FourXContext *f){
499 int i;
501 f->dsp.clear_blocks(f->block[0]);
503 for(i=0; i<6; i++){
504 if(decode_i_block(f, f->block[i]) < 0)
505 return -1;
508 return 0;
511 static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const buf){
512 int frequency[512];
513 uint8_t flag[512];
514 int up[512];
515 uint8_t len_tab[257];
516 int bits_tab[257];
517 int start, end;
518 const uint8_t *ptr= buf;
519 int j;
521 memset(frequency, 0, sizeof(frequency));
522 memset(up, -1, sizeof(up));
524 start= *ptr++;
525 end= *ptr++;
526 for(;;){
527 int i;
529 for(i=start; i<=end; i++){
530 frequency[i]= *ptr++;
532 start= *ptr++;
533 if(start==0) break;
535 end= *ptr++;
537 frequency[256]=1;
539 while((ptr - buf)&3) ptr++; // 4byte align
541 for(j=257; j<512; j++){
542 int min_freq[2]= {256*256, 256*256};
543 int smallest[2]= {0, 0};
544 int i;
545 for(i=0; i<j; i++){
546 if(frequency[i] == 0) continue;
547 if(frequency[i] < min_freq[1]){
548 if(frequency[i] < min_freq[0]){
549 min_freq[1]= min_freq[0]; smallest[1]= smallest[0];
550 min_freq[0]= frequency[i];smallest[0]= i;
551 }else{
552 min_freq[1]= frequency[i];smallest[1]= i;
556 if(min_freq[1] == 256*256) break;
558 frequency[j]= min_freq[0] + min_freq[1];
559 flag[ smallest[0] ]= 0;
560 flag[ smallest[1] ]= 1;
561 up[ smallest[0] ]=
562 up[ smallest[1] ]= j;
563 frequency[ smallest[0] ]= frequency[ smallest[1] ]= 0;
566 for(j=0; j<257; j++){
567 int node;
568 int len=0;
569 int bits=0;
571 for(node= j; up[node] != -1; node= up[node]){
572 bits += flag[node]<<len;
573 len++;
574 if(len > 31) av_log(f->avctx, AV_LOG_ERROR, "vlc length overflow\n"); //can this happen at all ?
577 bits_tab[j]= bits;
578 len_tab[j]= len;
581 init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257,
582 len_tab , 1, 1,
583 bits_tab, 4, 4, 0);
585 return ptr;
588 static int mix(int c0, int c1){
589 int blue = 2*(c0&0x001F) + (c1&0x001F);
590 int green= (2*(c0&0x03E0) + (c1&0x03E0))>>5;
591 int red = 2*(c0>>10) + (c1>>10);
592 return red/3*1024 + green/3*32 + blue/3;
595 static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){
596 int x, y, x2, y2;
597 const int width= f->avctx->width;
598 const int height= f->avctx->height;
599 uint16_t *dst= (uint16_t*)f->current_picture.data[0];
600 const int stride= f->current_picture.linesize[0]>>1;
602 for(y=0; y<height; y+=16){
603 for(x=0; x<width; x+=16){
604 unsigned int color[4], bits;
605 memset(color, 0, sizeof(color));
606 //warning following is purely guessed ...
607 color[0]= bytestream_get_le16(&buf);
608 color[1]= bytestream_get_le16(&buf);
610 if(color[0]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 1\n");
611 if(color[1]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 2\n");
613 color[2]= mix(color[0], color[1]);
614 color[3]= mix(color[1], color[0]);
616 bits= bytestream_get_le32(&buf);
617 for(y2=0; y2<16; y2++){
618 for(x2=0; x2<16; x2++){
619 int index= 2*(x2>>2) + 8*(y2>>2);
620 dst[y2*stride+x2]= color[(bits>>index)&3];
623 dst+=16;
625 dst += 16*stride - width;
628 return 0;
631 static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){
632 int x, y;
633 const int width= f->avctx->width;
634 const int height= f->avctx->height;
635 uint16_t *dst= (uint16_t*)f->current_picture.data[0];
636 const int stride= f->current_picture.linesize[0]>>1;
637 const unsigned int bitstream_size= AV_RL32(buf);
638 const int token_count av_unused = AV_RL32(buf + bitstream_size + 8);
639 unsigned int prestream_size= 4*AV_RL32(buf + bitstream_size + 4);
640 const uint8_t *prestream= buf + bitstream_size + 12;
642 if(prestream_size + bitstream_size + 12 != length
643 || bitstream_size > (1<<26)
644 || prestream_size > (1<<26)){
645 av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length);
646 return -1;
649 prestream= read_huffman_tables(f, prestream);
651 init_get_bits(&f->gb, buf + 4, 8*bitstream_size);
653 prestream_size= length + buf - prestream;
655 f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE);
656 f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (const uint32_t*)prestream, prestream_size/4);
657 init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size);
659 f->last_dc= 0*128*8*8;
661 for(y=0; y<height; y+=16){
662 for(x=0; x<width; x+=16){
663 if(decode_i_mb(f) < 0)
664 return -1;
666 idct_put(f, x, y);
668 dst += 16*stride;
671 if(get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256)
672 av_log(f->avctx, AV_LOG_ERROR, "end mismatch\n");
674 return 0;
677 static int decode_frame(AVCodecContext *avctx,
678 void *data, int *data_size,
679 const uint8_t *buf, int buf_size)
681 FourXContext * const f = avctx->priv_data;
682 AVFrame *picture = data;
683 AVFrame *p, temp;
684 int i, frame_4cc, frame_size;
686 frame_4cc= AV_RL32(buf);
687 if(buf_size != AV_RL32(buf+4)+8 || buf_size < 20){
688 av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, AV_RL32(buf+4));
691 if(frame_4cc == ff_get_fourcc("cfrm")){
692 int free_index=-1;
693 const int data_size= buf_size - 20;
694 const int id= AV_RL32(buf+12);
695 const int whole_size= AV_RL32(buf+16);
696 CFrameBuffer *cfrm;
698 for(i=0; i<CFRAME_BUFFER_COUNT; i++){
699 if(f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
700 av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id);
703 for(i=0; i<CFRAME_BUFFER_COUNT; i++){
704 if(f->cfrm[i].id == id) break;
705 if(f->cfrm[i].size == 0 ) free_index= i;
708 if(i>=CFRAME_BUFFER_COUNT){
709 i= free_index;
710 f->cfrm[i].id= id;
712 cfrm= &f->cfrm[i];
714 cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE);
715 if(!cfrm->data){ //explicit check needed as memcpy below might not catch a NULL
716 av_log(f->avctx, AV_LOG_ERROR, "realloc falure");
717 return -1;
720 memcpy(cfrm->data + cfrm->size, buf+20, data_size);
721 cfrm->size += data_size;
723 if(cfrm->size >= whole_size){
724 buf= cfrm->data;
725 frame_size= cfrm->size;
727 if(id != avctx->frame_number){
728 av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number);
731 cfrm->size= cfrm->id= 0;
732 frame_4cc= ff_get_fourcc("pfrm");
733 }else
734 return buf_size;
735 }else{
736 buf= buf + 12;
737 frame_size= buf_size - 12;
740 temp= f->current_picture;
741 f->current_picture= f->last_picture;
742 f->last_picture= temp;
744 p= &f->current_picture;
745 avctx->coded_frame= p;
747 avctx->flags |= CODEC_FLAG_EMU_EDGE; // alternatively we would have to use our own buffer management
749 if(p->data[0])
750 avctx->release_buffer(avctx, p);
752 p->reference= 1;
753 if(avctx->get_buffer(avctx, p) < 0){
754 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
755 return -1;
758 if(frame_4cc == ff_get_fourcc("ifr2")){
759 p->pict_type= FF_I_TYPE;
760 if(decode_i2_frame(f, buf-4, frame_size) < 0)
761 return -1;
762 }else if(frame_4cc == ff_get_fourcc("ifrm")){
763 p->pict_type= FF_I_TYPE;
764 if(decode_i_frame(f, buf, frame_size) < 0)
765 return -1;
766 }else if(frame_4cc == ff_get_fourcc("pfrm") || frame_4cc == ff_get_fourcc("pfr2")){
767 p->pict_type= FF_P_TYPE;
768 if(decode_p_frame(f, buf, frame_size) < 0)
769 return -1;
770 }else if(frame_4cc == ff_get_fourcc("snd_")){
771 av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size);
772 }else{
773 av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n", buf_size);
776 p->key_frame= p->pict_type == FF_I_TYPE;
778 *picture= *p;
779 *data_size = sizeof(AVPicture);
781 emms_c();
783 return buf_size;
787 static void common_init(AVCodecContext *avctx){
788 FourXContext * const f = avctx->priv_data;
790 dsputil_init(&f->dsp, avctx);
792 f->avctx= avctx;
795 static av_cold int decode_init(AVCodecContext *avctx){
796 FourXContext * const f = avctx->priv_data;
798 if(avctx->extradata_size != 4 || !avctx->extradata) {
799 av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n");
800 return 1;
803 f->version= AV_RL32(avctx->extradata)>>16;
804 common_init(avctx);
805 init_vlcs(f);
807 if(f->version>2) avctx->pix_fmt= PIX_FMT_RGB565;
808 else avctx->pix_fmt= PIX_FMT_RGB555;
810 return 0;
814 static av_cold int decode_end(AVCodecContext *avctx){
815 FourXContext * const f = avctx->priv_data;
816 int i;
818 av_freep(&f->bitstream_buffer);
819 f->bitstream_buffer_size=0;
820 for(i=0; i<CFRAME_BUFFER_COUNT; i++){
821 av_freep(&f->cfrm[i].data);
822 f->cfrm[i].allocated_size= 0;
824 free_vlc(&f->pre_vlc);
826 return 0;
829 AVCodec fourxm_decoder = {
830 "4xm",
831 CODEC_TYPE_VIDEO,
832 CODEC_ID_4XM,
833 sizeof(FourXContext),
834 decode_init,
835 NULL,
836 decode_end,
837 decode_frame,
838 /*CODEC_CAP_DR1,*/
839 .long_name = NULL_IF_CONFIG_SMALL("4X Movie"),