Libav 0.7.1
libavcodec/4xm.c
Go to the documentation of this file.
00001 /*
00002  * 4XM codec
00003  * Copyright (c) 2003 Michael Niedermayer
00004  *
00005  * This file is part of Libav.
00006  *
00007  * Libav is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * Libav is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with Libav; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00027 #include "libavutil/intreadwrite.h"
00028 #include "avcodec.h"
00029 #include "dsputil.h"
00030 #include "get_bits.h"
00031 #include "bytestream.h"
00032 
00033 //#undef NDEBUG
00034 //#include <assert.h>
00035 
00036 #define BLOCK_TYPE_VLC_BITS 5
00037 #define ACDC_VLC_BITS 9
00038 
00039 #define CFRAME_BUFFER_COUNT 100
00040 
00041 static const uint8_t block_type_tab[2][4][8][2]={
00042  {
00043   {   //{8,4,2}x{8,4,2}
00044     { 0,1}, { 2,2}, { 6,3}, {14,4}, {30,5}, {31,5}, { 0,0}
00045   },{ //{8,4}x1
00046     { 0,1}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}, { 0,0}
00047   },{ //1x{8,4}
00048     { 0,1}, { 2,2}, { 0,0}, { 6,3}, {14,4}, {15,4}, { 0,0}
00049   },{ //1x2, 2x1
00050     { 0,1}, { 0,0}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}
00051   }
00052  },{
00053   {  //{8,4,2}x{8,4,2}
00054     { 1,2}, { 4,3}, { 5,3}, {0,2}, {6,3}, {7,3}, {0,0}
00055   },{//{8,4}x1
00056     { 1,2}, { 0,0}, { 2,2}, {0,2}, {6,3}, {7,3}, {0,0}
00057   },{//1x{8,4}
00058     { 1,2}, { 2,2}, { 0,0}, {0,2}, {6,3}, {7,3}, {0,0}
00059   },{//1x2, 2x1
00060     { 1,2}, { 0,0}, { 0,0}, {0,2}, {2,2}, {6,3}, {7,3}
00061   }
00062  }
00063 };
00064 
00065 static const uint8_t size2index[4][4]={
00066   {-1, 3, 1, 1},
00067   { 3, 0, 0, 0},
00068   { 2, 0, 0, 0},
00069   { 2, 0, 0, 0},
00070 };
00071 
00072 static const int8_t mv[256][2]={
00073 {  0,  0},{  0, -1},{ -1,  0},{  1,  0},{  0,  1},{ -1, -1},{  1, -1},{ -1,  1},
00074 {  1,  1},{  0, -2},{ -2,  0},{  2,  0},{  0,  2},{ -1, -2},{  1, -2},{ -2, -1},
00075 {  2, -1},{ -2,  1},{  2,  1},{ -1,  2},{  1,  2},{ -2, -2},{  2, -2},{ -2,  2},
00076 {  2,  2},{  0, -3},{ -3,  0},{  3,  0},{  0,  3},{ -1, -3},{  1, -3},{ -3, -1},
00077 {  3, -1},{ -3,  1},{  3,  1},{ -1,  3},{  1,  3},{ -2, -3},{  2, -3},{ -3, -2},
00078 {  3, -2},{ -3,  2},{  3,  2},{ -2,  3},{  2,  3},{  0, -4},{ -4,  0},{  4,  0},
00079 {  0,  4},{ -1, -4},{  1, -4},{ -4, -1},{  4, -1},{  4,  1},{ -1,  4},{  1,  4},
00080 { -3, -3},{ -3,  3},{  3,  3},{ -2, -4},{ -4, -2},{  4, -2},{ -4,  2},{ -2,  4},
00081 {  2,  4},{ -3, -4},{  3, -4},{  4, -3},{ -5,  0},{ -4,  3},{ -3,  4},{  3,  4},
00082 { -1, -5},{ -5, -1},{ -5,  1},{ -1,  5},{ -2, -5},{  2, -5},{  5, -2},{  5,  2},
00083 { -4, -4},{ -4,  4},{ -3, -5},{ -5, -3},{ -5,  3},{  3,  5},{ -6,  0},{  0,  6},
00084 { -6, -1},{ -6,  1},{  1,  6},{  2, -6},{ -6,  2},{  2,  6},{ -5, -4},{  5,  4},
00085 {  4,  5},{ -6, -3},{  6,  3},{ -7,  0},{ -1, -7},{  5, -5},{ -7,  1},{ -1,  7},
00086 {  4, -6},{  6,  4},{ -2, -7},{ -7,  2},{ -3, -7},{  7, -3},{  3,  7},{  6, -5},
00087 {  0, -8},{ -1, -8},{ -7, -4},{ -8,  1},{  4,  7},{  2, -8},{ -2,  8},{  6,  6},
00088 { -8,  3},{  5, -7},{ -5,  7},{  8, -4},{  0, -9},{ -9, -1},{  1,  9},{  7, -6},
00089 { -7,  6},{ -5, -8},{ -5,  8},{ -9,  3},{  9, -4},{  7, -7},{  8, -6},{  6,  8},
00090 { 10,  1},{-10,  2},{  9, -5},{ 10, -3},{ -8, -7},{-10, -4},{  6, -9},{-11,  0},
00091 { 11,  1},{-11, -2},{ -2, 11},{  7, -9},{ -7,  9},{ 10,  6},{ -4, 11},{  8, -9},
00092 {  8,  9},{  5, 11},{  7,-10},{ 12, -3},{ 11,  6},{ -9, -9},{  8, 10},{  5, 12},
00093 {-11,  7},{ 13,  2},{  6,-12},{ 10,  9},{-11,  8},{ -7, 12},{  0, 14},{ 14, -2},
00094 { -9, 11},{ -6, 13},{-14, -4},{ -5,-14},{  5, 14},{-15, -1},{-14, -6},{  3,-15},
00095 { 11,-11},{ -7, 14},{ -5, 15},{  8,-14},{ 15,  6},{  3, 16},{  7,-15},{-16,  5},
00096 {  0, 17},{-16, -6},{-10, 14},{-16,  7},{ 12, 13},{-16,  8},{-17,  6},{-18,  3},
00097 { -7, 17},{ 15, 11},{ 16, 10},{  2,-19},{  3,-19},{-11,-16},{-18,  8},{-19, -6},
00098 {  2,-20},{-17,-11},{-10,-18},{  8, 19},{-21, -1},{-20,  7},{ -4, 21},{ 21,  5},
00099 { 15, 16},{  2,-22},{-10,-20},{-22,  5},{ 20,-11},{ -7,-22},{-12, 20},{ 23, -5},
00100 { 13,-20},{ 24, -2},{-15, 19},{-11, 22},{ 16, 19},{ 23,-10},{-18,-18},{ -9,-24},
00101 { 24,-10},{ -3, 26},{-23, 13},{-18,-20},{ 17, 21},{ -4, 27},{ 27,  6},{  1,-28},
00102 {-11, 26},{-17,-23},{  7, 28},{ 11,-27},{ 29,  5},{-23,-19},{-28,-11},{-21, 22},
00103 {-30,  7},{-17, 26},{-27, 16},{ 13, 29},{ 19,-26},{ 10,-31},{-14,-30},{ 20,-27},
00104 {-29, 18},{-16,-31},{-28,-22},{ 21,-30},{-25, 28},{ 26,-29},{ 25,-32},{-32,-32}
00105 };
00106 
00107 // this is simply the scaled down elementwise product of the standard jpeg quantizer table and the AAN premul table
00108 static const uint8_t dequant_table[64]={
00109  16, 15, 13, 19, 24, 31, 28, 17,
00110  17, 23, 25, 31, 36, 63, 45, 21,
00111  18, 24, 27, 37, 52, 59, 49, 20,
00112  16, 28, 34, 40, 60, 80, 51, 20,
00113  18, 31, 48, 66, 68, 86, 56, 21,
00114  19, 38, 56, 59, 64, 64, 48, 20,
00115  27, 48, 55, 55, 56, 51, 35, 15,
00116  20, 35, 34, 32, 31, 22, 15,  8,
00117 };
00118 
00119 static VLC block_type_vlc[2][4];
00120 
00121 
00122 typedef struct CFrameBuffer{
00123     unsigned int allocated_size;
00124     unsigned int size;
00125     int id;
00126     uint8_t *data;
00127 }CFrameBuffer;
00128 
00129 typedef struct FourXContext{
00130     AVCodecContext *avctx;
00131     DSPContext dsp;
00132     AVFrame current_picture, last_picture;
00133     GetBitContext pre_gb;          
00134     GetBitContext gb;
00135     const uint8_t *bytestream;
00136     const uint16_t *wordstream;
00137     int mv[256];
00138     VLC pre_vlc;
00139     int last_dc;
00140     DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
00141     void *bitstream_buffer;
00142     unsigned int bitstream_buffer_size;
00143     int version;
00144     CFrameBuffer cfrm[CFRAME_BUFFER_COUNT];
00145 } FourXContext;
00146 
00147 
00148 #define FIX_1_082392200  70936
00149 #define FIX_1_414213562  92682
00150 #define FIX_1_847759065 121095
00151 #define FIX_2_613125930 171254
00152 
00153 #define MULTIPLY(var,const)  (((var)*(const)) >> 16)
00154 
00155 static void idct(DCTELEM block[64]){
00156     int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
00157     int tmp10, tmp11, tmp12, tmp13;
00158     int z5, z10, z11, z12, z13;
00159     int i;
00160     int temp[64];
00161 
00162     for(i=0; i<8; i++){
00163         tmp10 = block[8*0 + i] + block[8*4 + i];
00164         tmp11 = block[8*0 + i] - block[8*4 + i];
00165 
00166         tmp13 =          block[8*2 + i] + block[8*6 + i];
00167         tmp12 = MULTIPLY(block[8*2 + i] - block[8*6 + i], FIX_1_414213562) - tmp13;
00168 
00169         tmp0 = tmp10 + tmp13;
00170         tmp3 = tmp10 - tmp13;
00171         tmp1 = tmp11 + tmp12;
00172         tmp2 = tmp11 - tmp12;
00173 
00174         z13 = block[8*5 + i] + block[8*3 + i];
00175         z10 = block[8*5 + i] - block[8*3 + i];
00176         z11 = block[8*1 + i] + block[8*7 + i];
00177         z12 = block[8*1 + i] - block[8*7 + i];
00178 
00179         tmp7  =          z11 + z13;
00180         tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
00181 
00182         z5    = MULTIPLY(z10 + z12, FIX_1_847759065);
00183         tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
00184         tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
00185 
00186         tmp6 = tmp12 - tmp7;
00187         tmp5 = tmp11 - tmp6;
00188         tmp4 = tmp10 + tmp5;
00189 
00190         temp[8*0 + i] = tmp0 + tmp7;
00191         temp[8*7 + i] = tmp0 - tmp7;
00192         temp[8*1 + i] = tmp1 + tmp6;
00193         temp[8*6 + i] = tmp1 - tmp6;
00194         temp[8*2 + i] = tmp2 + tmp5;
00195         temp[8*5 + i] = tmp2 - tmp5;
00196         temp[8*4 + i] = tmp3 + tmp4;
00197         temp[8*3 + i] = tmp3 - tmp4;
00198     }
00199 
00200     for(i=0; i<8*8; i+=8){
00201         tmp10 = temp[0 + i] + temp[4 + i];
00202         tmp11 = temp[0 + i] - temp[4 + i];
00203 
00204         tmp13 = temp[2 + i] + temp[6 + i];
00205         tmp12 = MULTIPLY(temp[2 + i] - temp[6 + i], FIX_1_414213562) - tmp13;
00206 
00207         tmp0 = tmp10 + tmp13;
00208         tmp3 = tmp10 - tmp13;
00209         tmp1 = tmp11 + tmp12;
00210         tmp2 = tmp11 - tmp12;
00211 
00212         z13 = temp[5 + i] + temp[3 + i];
00213         z10 = temp[5 + i] - temp[3 + i];
00214         z11 = temp[1 + i] + temp[7 + i];
00215         z12 = temp[1 + i] - temp[7 + i];
00216 
00217         tmp7 = z11 + z13;
00218         tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
00219 
00220         z5 = MULTIPLY(z10 + z12, FIX_1_847759065);
00221         tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
00222         tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
00223 
00224         tmp6 = tmp12 - tmp7;
00225         tmp5 = tmp11 - tmp6;
00226         tmp4 = tmp10 + tmp5;
00227 
00228         block[0 + i] = (tmp0 + tmp7)>>6;
00229         block[7 + i] = (tmp0 - tmp7)>>6;
00230         block[1 + i] = (tmp1 + tmp6)>>6;
00231         block[6 + i] = (tmp1 - tmp6)>>6;
00232         block[2 + i] = (tmp2 + tmp5)>>6;
00233         block[5 + i] = (tmp2 - tmp5)>>6;
00234         block[4 + i] = (tmp3 + tmp4)>>6;
00235         block[3 + i] = (tmp3 - tmp4)>>6;
00236     }
00237 }
00238 
00239 static av_cold void init_vlcs(FourXContext *f){
00240     static VLC_TYPE table[8][32][2];
00241     int i;
00242 
00243     for(i=0; i<8; i++){
00244         block_type_vlc[0][i].table= table[i];
00245         block_type_vlc[0][i].table_allocated= 32;
00246         init_vlc(&block_type_vlc[0][i], BLOCK_TYPE_VLC_BITS, 7,
00247                  &block_type_tab[0][i][0][1], 2, 1,
00248                  &block_type_tab[0][i][0][0], 2, 1, INIT_VLC_USE_NEW_STATIC);
00249     }
00250 }
00251 
00252 static void init_mv(FourXContext *f){
00253     int i;
00254 
00255     for(i=0; i<256; i++){
00256         if(f->version>1)
00257             f->mv[i] = mv[i][0]   + mv[i][1]  *f->current_picture.linesize[0]/2;
00258         else
00259             f->mv[i] = (i&15) - 8 + ((i>>4)-8)*f->current_picture.linesize[0]/2;
00260     }
00261 }
00262 
00263 #if HAVE_BIGENDIAN
00264 #define LE_CENTRIC_MUL(dst, src, scale, dc) \
00265     { \
00266         unsigned tmpval = AV_RN32(src);                 \
00267         tmpval = (tmpval <<  16) | (tmpval >>  16);     \
00268         tmpval = tmpval * (scale) + (dc);               \
00269         tmpval = (tmpval <<  16) | (tmpval >>  16);     \
00270         AV_WN32A(dst, tmpval);                          \
00271     }
00272 #else
00273 #define LE_CENTRIC_MUL(dst, src, scale, dc) \
00274     { \
00275         unsigned tmpval = AV_RN32(src) * (scale) + (dc); \
00276         AV_WN32A(dst, tmpval);                           \
00277     }
00278 #endif
00279 
00280 static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, int dc){
00281    int i;
00282    dc*= 0x10001;
00283 
00284    switch(log2w){
00285    case 0:
00286         for(i=0; i<h; i++){
00287             dst[0] = scale*src[0] + dc;
00288             if(scale) src += stride;
00289             dst += stride;
00290         }
00291         break;
00292     case 1:
00293         for(i=0; i<h; i++){
00294             LE_CENTRIC_MUL(dst, src, scale, dc);
00295             if(scale) src += stride;
00296             dst += stride;
00297         }
00298         break;
00299     case 2:
00300         for(i=0; i<h; i++){
00301             LE_CENTRIC_MUL(dst,     src,     scale, dc);
00302             LE_CENTRIC_MUL(dst + 2, src + 2, scale, dc);
00303             if(scale) src += stride;
00304             dst += stride;
00305         }
00306         break;
00307     case 3:
00308         for(i=0; i<h; i++){
00309             LE_CENTRIC_MUL(dst,     src,     scale, dc);
00310             LE_CENTRIC_MUL(dst + 2, src + 2, scale, dc);
00311             LE_CENTRIC_MUL(dst + 4, src + 4, scale, dc);
00312             LE_CENTRIC_MUL(dst + 6, src + 6, scale, dc);
00313             if(scale) src += stride;
00314             dst += stride;
00315         }
00316         break;
00317     default: assert(0);
00318     }
00319 }
00320 
00321 static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int log2w, int log2h, int stride){
00322     const int index= size2index[log2h][log2w];
00323     const int h= 1<<log2h;
00324     int code= get_vlc2(&f->gb, block_type_vlc[1-(f->version>1)][index].table, BLOCK_TYPE_VLC_BITS, 1);
00325     uint16_t *start= (uint16_t*)f->last_picture.data[0];
00326     uint16_t *end= start + stride*(f->avctx->height-h+1) - (1<<log2w);
00327 
00328     assert(code>=0 && code<=6);
00329 
00330     if(code == 0){
00331         src += f->mv[ *f->bytestream++ ];
00332         if(start > src || src > end){
00333             av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
00334             return;
00335         }
00336         mcdc(dst, src, log2w, h, stride, 1, 0);
00337     }else if(code == 1){
00338         log2h--;
00339         decode_p_block(f, dst                  , src                  , log2w, log2h, stride);
00340         decode_p_block(f, dst + (stride<<log2h), src + (stride<<log2h), log2w, log2h, stride);
00341     }else if(code == 2){
00342         log2w--;
00343         decode_p_block(f, dst             , src             , log2w, log2h, stride);
00344         decode_p_block(f, dst + (1<<log2w), src + (1<<log2w), log2w, log2h, stride);
00345     }else if(code == 3 && f->version<2){
00346         mcdc(dst, src, log2w, h, stride, 1, 0);
00347     }else if(code == 4){
00348         src += f->mv[ *f->bytestream++ ];
00349         if(start > src || src > end){
00350             av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
00351             return;
00352         }
00353         mcdc(dst, src, log2w, h, stride, 1, av_le2ne16(*f->wordstream++));
00354     }else if(code == 5){
00355         mcdc(dst, src, log2w, h, stride, 0, av_le2ne16(*f->wordstream++));
00356     }else if(code == 6){
00357         if(log2w){
00358             dst[0] = av_le2ne16(*f->wordstream++);
00359             dst[1] = av_le2ne16(*f->wordstream++);
00360         }else{
00361             dst[0     ] = av_le2ne16(*f->wordstream++);
00362             dst[stride] = av_le2ne16(*f->wordstream++);
00363         }
00364     }
00365 }
00366 
00367 static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){
00368     int x, y;
00369     const int width= f->avctx->width;
00370     const int height= f->avctx->height;
00371     uint16_t *src= (uint16_t*)f->last_picture.data[0];
00372     uint16_t *dst= (uint16_t*)f->current_picture.data[0];
00373     const int stride= f->current_picture.linesize[0]>>1;
00374     unsigned int bitstream_size, bytestream_size, wordstream_size, extra;
00375 
00376     if(f->version>1){
00377         extra=20;
00378         bitstream_size= AV_RL32(buf+8);
00379         wordstream_size= AV_RL32(buf+12);
00380         bytestream_size= AV_RL32(buf+16);
00381     }else{
00382         extra=0;
00383         bitstream_size = AV_RL16(buf-4);
00384         wordstream_size= AV_RL16(buf-2);
00385         bytestream_size= FFMAX(length - bitstream_size - wordstream_size, 0);
00386     }
00387 
00388     if(bitstream_size+ bytestream_size+ wordstream_size + extra != length
00389        || bitstream_size  > (1<<26)
00390        || bytestream_size > (1<<26)
00391        || wordstream_size > (1<<26)
00392        ){
00393         av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size,
00394         bitstream_size+ bytestream_size+ wordstream_size - length);
00395         return -1;
00396     }
00397 
00398     av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE);
00399     if (!f->bitstream_buffer)
00400         return AVERROR(ENOMEM);
00401     f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)(buf + extra), bitstream_size/4);
00402     init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size);
00403 
00404     f->wordstream= (const uint16_t*)(buf + extra + bitstream_size);
00405     f->bytestream= buf + extra + bitstream_size + wordstream_size;
00406 
00407     init_mv(f);
00408 
00409     for(y=0; y<height; y+=8){
00410         for(x=0; x<width; x+=8){
00411             decode_p_block(f, dst + x, src + x, 3, 3, stride);
00412         }
00413         src += 8*stride;
00414         dst += 8*stride;
00415     }
00416 
00417     if(   bitstream_size != (get_bits_count(&f->gb)+31)/32*4
00418        || (((const char*)f->wordstream - (const char*)buf + 2)&~2) != extra + bitstream_size + wordstream_size
00419        || (((const char*)f->bytestream - (const char*)buf + 3)&~3) != extra + bitstream_size + wordstream_size + bytestream_size)
00420         av_log(f->avctx, AV_LOG_ERROR, " %d %td %td bytes left\n",
00421             bitstream_size - (get_bits_count(&f->gb)+31)/32*4,
00422             -(((const char*)f->bytestream - (const char*)buf + 3)&~3) + (extra + bitstream_size + wordstream_size + bytestream_size),
00423             -(((const char*)f->wordstream - (const char*)buf + 2)&~2) + (extra + bitstream_size + wordstream_size)
00424         );
00425 
00426     return 0;
00427 }
00428 
00433 static int decode_i_block(FourXContext *f, DCTELEM *block){
00434     int code, i, j, level, val;
00435 
00436     /* DC coef */
00437     val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
00438     if (val>>4){
00439         av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n");
00440     }
00441 
00442     if(val)
00443         val = get_xbits(&f->gb, val);
00444 
00445     val = val * dequant_table[0] + f->last_dc;
00446     f->last_dc =
00447     block[0] = val;
00448     /* AC coefs */
00449     i = 1;
00450     for(;;) {
00451         code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
00452 
00453         /* EOB */
00454         if (code == 0)
00455             break;
00456         if (code == 0xf0) {
00457             i += 16;
00458         } else {
00459             level = get_xbits(&f->gb, code & 0xf);
00460             i += code >> 4;
00461             if (i >= 64) {
00462                 av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i);
00463                 return 0;
00464             }
00465 
00466             j= ff_zigzag_direct[i];
00467             block[j] = level * dequant_table[j];
00468             i++;
00469             if (i >= 64)
00470                 break;
00471         }
00472     }
00473 
00474     return 0;
00475 }
00476 
00477 static inline void idct_put(FourXContext *f, int x, int y){
00478     DCTELEM (*block)[64]= f->block;
00479     int stride= f->current_picture.linesize[0]>>1;
00480     int i;
00481     uint16_t *dst = ((uint16_t*)f->current_picture.data[0]) + y * stride + x;
00482 
00483     for(i=0; i<4; i++){
00484         block[i][0] += 0x80*8*8;
00485         idct(block[i]);
00486     }
00487 
00488     if(!(f->avctx->flags&CODEC_FLAG_GRAY)){
00489         for(i=4; i<6; i++) idct(block[i]);
00490     }
00491 
00492 /* Note transform is:
00493 y= ( 1b + 4g + 2r)/14
00494 cb=( 3b - 2g - 1r)/14
00495 cr=(-1b - 4g + 5r)/14
00496 */
00497     for(y=0; y<8; y++){
00498         for(x=0; x<8; x++){
00499             DCTELEM *temp= block[(x>>2) + 2*(y>>2)] + 2*(x&3) + 2*8*(y&3); //FIXME optimize
00500             int cb= block[4][x + 8*y];
00501             int cr= block[5][x + 8*y];
00502             int cg= (cb + cr)>>1;
00503             int y;
00504 
00505             cb+=cb;
00506 
00507             y = temp[0];
00508             dst[0       ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
00509             y = temp[1];
00510             dst[1       ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
00511             y = temp[8];
00512             dst[  stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
00513             y = temp[9];
00514             dst[1+stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
00515             dst += 2;
00516         }
00517         dst += 2*stride - 2*8;
00518     }
00519 }
00520 
00521 static int decode_i_mb(FourXContext *f){
00522     int i;
00523 
00524     f->dsp.clear_blocks(f->block[0]);
00525 
00526     for(i=0; i<6; i++){
00527         if(decode_i_block(f, f->block[i]) < 0)
00528             return -1;
00529     }
00530 
00531     return 0;
00532 }
00533 
00534 static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const buf){
00535     int frequency[512];
00536     uint8_t flag[512];
00537     int up[512];
00538     uint8_t len_tab[257];
00539     int bits_tab[257];
00540     int start, end;
00541     const uint8_t *ptr= buf;
00542     int j;
00543 
00544     memset(frequency, 0, sizeof(frequency));
00545     memset(up, -1, sizeof(up));
00546 
00547     start= *ptr++;
00548     end= *ptr++;
00549     for(;;){
00550         int i;
00551 
00552         for(i=start; i<=end; i++){
00553             frequency[i]= *ptr++;
00554         }
00555         start= *ptr++;
00556         if(start==0) break;
00557 
00558         end= *ptr++;
00559     }
00560     frequency[256]=1;
00561 
00562     while((ptr - buf)&3) ptr++; // 4byte align
00563 
00564     for(j=257; j<512; j++){
00565         int min_freq[2]= {256*256, 256*256};
00566         int smallest[2]= {0, 0};
00567         int i;
00568         for(i=0; i<j; i++){
00569             if(frequency[i] == 0) continue;
00570             if(frequency[i] < min_freq[1]){
00571                 if(frequency[i] < min_freq[0]){
00572                     min_freq[1]= min_freq[0]; smallest[1]= smallest[0];
00573                     min_freq[0]= frequency[i];smallest[0]= i;
00574                 }else{
00575                     min_freq[1]= frequency[i];smallest[1]= i;
00576                 }
00577             }
00578         }
00579         if(min_freq[1] == 256*256) break;
00580 
00581         frequency[j]= min_freq[0] + min_freq[1];
00582         flag[ smallest[0] ]= 0;
00583         flag[ smallest[1] ]= 1;
00584         up[ smallest[0] ]=
00585         up[ smallest[1] ]= j;
00586         frequency[ smallest[0] ]= frequency[ smallest[1] ]= 0;
00587     }
00588 
00589     for(j=0; j<257; j++){
00590         int node;
00591         int len=0;
00592         int bits=0;
00593 
00594         for(node= j; up[node] != -1; node= up[node]){
00595             bits += flag[node]<<len;
00596             len++;
00597             if(len > 31) av_log(f->avctx, AV_LOG_ERROR, "vlc length overflow\n"); //can this happen at all ?
00598         }
00599 
00600         bits_tab[j]= bits;
00601         len_tab[j]= len;
00602     }
00603 
00604     init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257,
00605              len_tab , 1, 1,
00606              bits_tab, 4, 4, 0);
00607 
00608     return ptr;
00609 }
00610 
00611 static int mix(int c0, int c1){
00612     int blue = 2*(c0&0x001F) + (c1&0x001F);
00613     int green= (2*(c0&0x03E0) + (c1&0x03E0))>>5;
00614     int red  = 2*(c0>>10) + (c1>>10);
00615     return red/3*1024 + green/3*32 + blue/3;
00616 }
00617 
00618 static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){
00619     int x, y, x2, y2;
00620     const int width= f->avctx->width;
00621     const int height= f->avctx->height;
00622     uint16_t *dst= (uint16_t*)f->current_picture.data[0];
00623     const int stride= f->current_picture.linesize[0]>>1;
00624 
00625     for(y=0; y<height; y+=16){
00626         for(x=0; x<width; x+=16){
00627             unsigned int color[4], bits;
00628             memset(color, 0, sizeof(color));
00629 //warning following is purely guessed ...
00630             color[0]= bytestream_get_le16(&buf);
00631             color[1]= bytestream_get_le16(&buf);
00632 
00633             if(color[0]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 1\n");
00634             if(color[1]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 2\n");
00635 
00636             color[2]= mix(color[0], color[1]);
00637             color[3]= mix(color[1], color[0]);
00638 
00639             bits= bytestream_get_le32(&buf);
00640             for(y2=0; y2<16; y2++){
00641                 for(x2=0; x2<16; x2++){
00642                     int index= 2*(x2>>2) + 8*(y2>>2);
00643                     dst[y2*stride+x2]= color[(bits>>index)&3];
00644                 }
00645             }
00646             dst+=16;
00647         }
00648         dst += 16*stride - width;
00649     }
00650 
00651     return 0;
00652 }
00653 
00654 static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){
00655     int x, y;
00656     const int width= f->avctx->width;
00657     const int height= f->avctx->height;
00658     uint16_t *dst= (uint16_t*)f->current_picture.data[0];
00659     const int stride= f->current_picture.linesize[0]>>1;
00660     const unsigned int bitstream_size= AV_RL32(buf);
00661     const int token_count av_unused = AV_RL32(buf + bitstream_size + 8);
00662     unsigned int prestream_size= 4*AV_RL32(buf + bitstream_size + 4);
00663     const uint8_t *prestream= buf + bitstream_size + 12;
00664 
00665     if(prestream_size + bitstream_size + 12 != length
00666        || bitstream_size > (1<<26)
00667        || prestream_size > (1<<26)){
00668         av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length);
00669         return -1;
00670     }
00671 
00672     prestream= read_huffman_tables(f, prestream);
00673 
00674     init_get_bits(&f->gb, buf + 4, 8*bitstream_size);
00675 
00676     prestream_size= length + buf - prestream;
00677 
00678     av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE);
00679     if (!f->bitstream_buffer)
00680         return AVERROR(ENOMEM);
00681     f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)prestream, prestream_size/4);
00682     init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size);
00683 
00684     f->last_dc= 0*128*8*8;
00685 
00686     for(y=0; y<height; y+=16){
00687         for(x=0; x<width; x+=16){
00688             if(decode_i_mb(f) < 0)
00689                 return -1;
00690 
00691             idct_put(f, x, y);
00692         }
00693         dst += 16*stride;
00694     }
00695 
00696     if(get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256)
00697         av_log(f->avctx, AV_LOG_ERROR, "end mismatch\n");
00698 
00699     return 0;
00700 }
00701 
00702 static int decode_frame(AVCodecContext *avctx,
00703                         void *data, int *data_size,
00704                         AVPacket *avpkt)
00705 {
00706     const uint8_t *buf = avpkt->data;
00707     int buf_size = avpkt->size;
00708     FourXContext * const f = avctx->priv_data;
00709     AVFrame *picture = data;
00710     AVFrame *p, temp;
00711     int i, frame_4cc, frame_size;
00712 
00713     frame_4cc= AV_RL32(buf);
00714     if(buf_size != AV_RL32(buf+4)+8 || buf_size < 20){
00715         av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, AV_RL32(buf+4));
00716     }
00717 
00718     if(frame_4cc == AV_RL32("cfrm")){
00719         int free_index=-1;
00720         const int data_size= buf_size - 20;
00721         const int id= AV_RL32(buf+12);
00722         const int whole_size= AV_RL32(buf+16);
00723         CFrameBuffer *cfrm;
00724 
00725         for(i=0; i<CFRAME_BUFFER_COUNT; i++){
00726             if(f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
00727                 av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id);
00728         }
00729 
00730         for(i=0; i<CFRAME_BUFFER_COUNT; i++){
00731             if(f->cfrm[i].id   == id) break;
00732             if(f->cfrm[i].size == 0 ) free_index= i;
00733         }
00734 
00735         if(i>=CFRAME_BUFFER_COUNT){
00736             i= free_index;
00737             f->cfrm[i].id= id;
00738         }
00739         cfrm= &f->cfrm[i];
00740 
00741         cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE);
00742         if(!cfrm->data){ //explicit check needed as memcpy below might not catch a NULL
00743             av_log(f->avctx, AV_LOG_ERROR, "realloc falure");
00744             return -1;
00745         }
00746 
00747         memcpy(cfrm->data + cfrm->size, buf+20, data_size);
00748         cfrm->size += data_size;
00749 
00750         if(cfrm->size >= whole_size){
00751             buf= cfrm->data;
00752             frame_size= cfrm->size;
00753 
00754             if(id != avctx->frame_number){
00755                 av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number);
00756             }
00757 
00758             cfrm->size= cfrm->id= 0;
00759             frame_4cc= AV_RL32("pfrm");
00760         }else
00761             return buf_size;
00762     }else{
00763         buf= buf + 12;
00764         frame_size= buf_size - 12;
00765     }
00766 
00767     temp= f->current_picture;
00768     f->current_picture= f->last_picture;
00769     f->last_picture= temp;
00770 
00771     p= &f->current_picture;
00772     avctx->coded_frame= p;
00773 
00774     avctx->flags |= CODEC_FLAG_EMU_EDGE; // alternatively we would have to use our own buffer management
00775 
00776     if(p->data[0])
00777         avctx->release_buffer(avctx, p);
00778 
00779     p->reference= 1;
00780     if(avctx->get_buffer(avctx, p) < 0){
00781         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00782         return -1;
00783     }
00784 
00785     if(frame_4cc == AV_RL32("ifr2")){
00786         p->pict_type= AV_PICTURE_TYPE_I;
00787         if(decode_i2_frame(f, buf-4, frame_size) < 0)
00788             return -1;
00789     }else if(frame_4cc == AV_RL32("ifrm")){
00790         p->pict_type= AV_PICTURE_TYPE_I;
00791         if(decode_i_frame(f, buf, frame_size) < 0)
00792             return -1;
00793     }else if(frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")){
00794         if(!f->last_picture.data[0]){
00795             f->last_picture.reference= 1;
00796             if(avctx->get_buffer(avctx, &f->last_picture) < 0){
00797                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00798                 return -1;
00799             }
00800         }
00801 
00802         p->pict_type= AV_PICTURE_TYPE_P;
00803         if(decode_p_frame(f, buf, frame_size) < 0)
00804             return -1;
00805     }else if(frame_4cc == AV_RL32("snd_")){
00806         av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size);
00807     }else{
00808         av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n", buf_size);
00809     }
00810 
00811     p->key_frame= p->pict_type == AV_PICTURE_TYPE_I;
00812 
00813     *picture= *p;
00814     *data_size = sizeof(AVPicture);
00815 
00816     emms_c();
00817 
00818     return buf_size;
00819 }
00820 
00821 
00822 static av_cold void common_init(AVCodecContext *avctx){
00823     FourXContext * const f = avctx->priv_data;
00824 
00825     dsputil_init(&f->dsp, avctx);
00826 
00827     f->avctx= avctx;
00828 }
00829 
00830 static av_cold int decode_init(AVCodecContext *avctx){
00831     FourXContext * const f = avctx->priv_data;
00832 
00833     if(avctx->extradata_size != 4 || !avctx->extradata) {
00834         av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n");
00835         return 1;
00836     }
00837 
00838     f->version= AV_RL32(avctx->extradata)>>16;
00839     common_init(avctx);
00840     init_vlcs(f);
00841 
00842     if(f->version>2) avctx->pix_fmt= PIX_FMT_RGB565;
00843     else             avctx->pix_fmt= PIX_FMT_BGR555;
00844 
00845     return 0;
00846 }
00847 
00848 
00849 static av_cold int decode_end(AVCodecContext *avctx){
00850     FourXContext * const f = avctx->priv_data;
00851     int i;
00852 
00853     av_freep(&f->bitstream_buffer);
00854     f->bitstream_buffer_size=0;
00855     for(i=0; i<CFRAME_BUFFER_COUNT; i++){
00856         av_freep(&f->cfrm[i].data);
00857         f->cfrm[i].allocated_size= 0;
00858     }
00859     free_vlc(&f->pre_vlc);
00860     if(f->current_picture.data[0])
00861         avctx->release_buffer(avctx, &f->current_picture);
00862     if(f->last_picture.data[0])
00863         avctx->release_buffer(avctx, &f->last_picture);
00864 
00865     return 0;
00866 }
00867 
00868 AVCodec ff_fourxm_decoder = {
00869     "4xm",
00870     AVMEDIA_TYPE_VIDEO,
00871     CODEC_ID_4XM,
00872     sizeof(FourXContext),
00873     decode_init,
00874     NULL,
00875     decode_end,
00876     decode_frame,
00877     CODEC_CAP_DR1,
00878     .long_name = NULL_IF_CONFIG_SMALL("4X Movie"),
00879 };
00880