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     GetByteContext g;
00136     GetByteContext g2;
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, unsigned 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[bytestream2_get_byte(&f->g)];
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         if (start > src || src > end) {
00347             av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
00348             return;
00349         }
00350         mcdc(dst, src, log2w, h, stride, 1, 0);
00351     }else if(code == 4){
00352         src += f->mv[bytestream2_get_byte(&f->g)];
00353         if(start > src || src > end){
00354             av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
00355             return;
00356         }
00357         mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16(&f->g2));
00358     }else if(code == 5){
00359         if (start > src || src > end) {
00360             av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
00361             return;
00362         }
00363         mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16(&f->g2));
00364     }else if(code == 6){
00365         if(log2w){
00366             dst[0] = bytestream2_get_le16(&f->g2);
00367             dst[1] = bytestream2_get_le16(&f->g2);
00368         }else{
00369             dst[0     ] = bytestream2_get_le16(&f->g2);
00370             dst[stride] = bytestream2_get_le16(&f->g2);
00371         }
00372     }
00373 }
00374 
00375 static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){
00376     int x, y;
00377     const int width= f->avctx->width;
00378     const int height= f->avctx->height;
00379     uint16_t *src= (uint16_t*)f->last_picture.data[0];
00380     uint16_t *dst= (uint16_t*)f->current_picture.data[0];
00381     const int stride= f->current_picture.linesize[0]>>1;
00382     unsigned int bitstream_size, bytestream_size, wordstream_size, extra, bytestream_offset, wordstream_offset;
00383 
00384     if(f->version>1){
00385         if (length < 20)
00386             return AVERROR_INVALIDDATA;
00387         extra=20;
00388         bitstream_size= AV_RL32(buf+8);
00389         wordstream_size= AV_RL32(buf+12);
00390         bytestream_size= AV_RL32(buf+16);
00391     }else{
00392         extra=0;
00393         bitstream_size = AV_RL16(buf-4);
00394         wordstream_size= AV_RL16(buf-2);
00395         bytestream_size= FFMAX(length - bitstream_size - wordstream_size, 0);
00396     }
00397 
00398     if(bitstream_size+ bytestream_size+ wordstream_size + extra != length
00399        || bitstream_size  > (1<<26)
00400        || bytestream_size > (1<<26)
00401        || wordstream_size > (1<<26)
00402        ){
00403         av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size,
00404         bitstream_size+ bytestream_size+ wordstream_size - length);
00405         return -1;
00406     }
00407 
00408     av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE);
00409     if (!f->bitstream_buffer)
00410         return AVERROR(ENOMEM);
00411     f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)(buf + extra), bitstream_size/4);
00412     memset((uint8_t*)f->bitstream_buffer + bitstream_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
00413     init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size);
00414 
00415     wordstream_offset = extra + bitstream_size;
00416     bytestream_offset = extra + bitstream_size + wordstream_size;
00417     bytestream2_init(&f->g2, buf + wordstream_offset, length - wordstream_offset);
00418     bytestream2_init(&f->g,  buf + bytestream_offset, length - bytestream_offset);
00419 
00420     init_mv(f);
00421 
00422     for(y=0; y<height; y+=8){
00423         for(x=0; x<width; x+=8){
00424             decode_p_block(f, dst + x, src + x, 3, 3, stride);
00425         }
00426         src += 8*stride;
00427         dst += 8*stride;
00428     }
00429 
00430     return 0;
00431 }
00432 
00437 static int decode_i_block(FourXContext *f, DCTELEM *block){
00438     int code, i, j, level, val;
00439 
00440     /* DC coef */
00441     val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
00442     if (val>>4){
00443         av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n");
00444     }
00445 
00446     if(val)
00447         val = get_xbits(&f->gb, val);
00448 
00449     val = val * dequant_table[0] + f->last_dc;
00450     f->last_dc =
00451     block[0] = val;
00452     /* AC coefs */
00453     i = 1;
00454     for(;;) {
00455         code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
00456 
00457         /* EOB */
00458         if (code == 0)
00459             break;
00460         if (code == 0xf0) {
00461             i += 16;
00462         } else {
00463             level = get_xbits(&f->gb, code & 0xf);
00464             i += code >> 4;
00465             if (i >= 64) {
00466                 av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i);
00467                 return 0;
00468             }
00469 
00470             j= ff_zigzag_direct[i];
00471             block[j] = level * dequant_table[j];
00472             i++;
00473             if (i >= 64)
00474                 break;
00475         }
00476     }
00477 
00478     return 0;
00479 }
00480 
00481 static inline void idct_put(FourXContext *f, int x, int y){
00482     DCTELEM (*block)[64]= f->block;
00483     int stride= f->current_picture.linesize[0]>>1;
00484     int i;
00485     uint16_t *dst = ((uint16_t*)f->current_picture.data[0]) + y * stride + x;
00486 
00487     for(i=0; i<4; i++){
00488         block[i][0] += 0x80*8*8;
00489         idct(block[i]);
00490     }
00491 
00492     if(!(f->avctx->flags&CODEC_FLAG_GRAY)){
00493         for(i=4; i<6; i++) idct(block[i]);
00494     }
00495 
00496 /* Note transform is:
00497 y= ( 1b + 4g + 2r)/14
00498 cb=( 3b - 2g - 1r)/14
00499 cr=(-1b - 4g + 5r)/14
00500 */
00501     for(y=0; y<8; y++){
00502         for(x=0; x<8; x++){
00503             DCTELEM *temp= block[(x>>2) + 2*(y>>2)] + 2*(x&3) + 2*8*(y&3); //FIXME optimize
00504             int cb= block[4][x + 8*y];
00505             int cr= block[5][x + 8*y];
00506             int cg= (cb + cr)>>1;
00507             int y;
00508 
00509             cb+=cb;
00510 
00511             y = temp[0];
00512             dst[0       ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
00513             y = temp[1];
00514             dst[1       ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
00515             y = temp[8];
00516             dst[  stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
00517             y = temp[9];
00518             dst[1+stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
00519             dst += 2;
00520         }
00521         dst += 2*stride - 2*8;
00522     }
00523 }
00524 
00525 static int decode_i_mb(FourXContext *f){
00526     int i;
00527 
00528     f->dsp.clear_blocks(f->block[0]);
00529 
00530     for(i=0; i<6; i++){
00531         if(decode_i_block(f, f->block[i]) < 0)
00532             return -1;
00533     }
00534 
00535     return 0;
00536 }
00537 
00538 static const uint8_t *read_huffman_tables(FourXContext *f,
00539                                           const uint8_t * const buf,
00540                                           int len)
00541 {
00542     int frequency[512];
00543     uint8_t flag[512];
00544     int up[512];
00545     uint8_t len_tab[257];
00546     int bits_tab[257];
00547     int start, end;
00548     const uint8_t *ptr= buf;
00549     int j;
00550 
00551     memset(frequency, 0, sizeof(frequency));
00552     memset(up, -1, sizeof(up));
00553 
00554     start= *ptr++;
00555     end= *ptr++;
00556     for(;;){
00557         int i;
00558 
00559         len -= end - start + 1;
00560 
00561         if (end < start || len < 0)
00562             return NULL;
00563 
00564         for(i=start; i<=end; i++){
00565             frequency[i]= *ptr++;
00566         }
00567         start= *ptr++;
00568         if(start==0) break;
00569 
00570         if (--len < 0)
00571             return NULL;
00572 
00573         end= *ptr++;
00574     }
00575     frequency[256]=1;
00576 
00577     while((ptr - buf)&3) ptr++; // 4byte align
00578 
00579     for(j=257; j<512; j++){
00580         int min_freq[2]= {256*256, 256*256};
00581         int smallest[2]= {0, 0};
00582         int i;
00583         for(i=0; i<j; i++){
00584             if(frequency[i] == 0) continue;
00585             if(frequency[i] < min_freq[1]){
00586                 if(frequency[i] < min_freq[0]){
00587                     min_freq[1]= min_freq[0]; smallest[1]= smallest[0];
00588                     min_freq[0]= frequency[i];smallest[0]= i;
00589                 }else{
00590                     min_freq[1]= frequency[i];smallest[1]= i;
00591                 }
00592             }
00593         }
00594         if(min_freq[1] == 256*256) break;
00595 
00596         frequency[j]= min_freq[0] + min_freq[1];
00597         flag[ smallest[0] ]= 0;
00598         flag[ smallest[1] ]= 1;
00599         up[ smallest[0] ]=
00600         up[ smallest[1] ]= j;
00601         frequency[ smallest[0] ]= frequency[ smallest[1] ]= 0;
00602     }
00603 
00604     for(j=0; j<257; j++){
00605         int node;
00606         int len=0;
00607         int bits=0;
00608 
00609         for(node= j; up[node] != -1; node= up[node]){
00610             bits += flag[node]<<len;
00611             len++;
00612             if(len > 31) av_log(f->avctx, AV_LOG_ERROR, "vlc length overflow\n"); //can this happen at all ?
00613         }
00614 
00615         bits_tab[j]= bits;
00616         len_tab[j]= len;
00617     }
00618 
00619     if (init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257,
00620                  len_tab , 1, 1,
00621                  bits_tab, 4, 4, 0))
00622         return NULL;
00623 
00624     return ptr;
00625 }
00626 
00627 static int mix(int c0, int c1){
00628     int blue = 2*(c0&0x001F) + (c1&0x001F);
00629     int green= (2*(c0&0x03E0) + (c1&0x03E0))>>5;
00630     int red  = 2*(c0>>10) + (c1>>10);
00631     return red/3*1024 + green/3*32 + blue/3;
00632 }
00633 
00634 static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){
00635     int x, y, x2, y2;
00636     const int width= f->avctx->width;
00637     const int height= f->avctx->height;
00638     const int mbs = (FFALIGN(width, 16) >> 4) * (FFALIGN(height, 16) >> 4);
00639     uint16_t *dst= (uint16_t*)f->current_picture.data[0];
00640     const int stride= f->current_picture.linesize[0]>>1;
00641     GetByteContext g3;
00642 
00643     if(length < mbs * 8) {
00644         av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n");
00645         return AVERROR_INVALIDDATA;
00646     }
00647     bytestream2_init(&g3, buf, length);
00648 
00649     for(y=0; y<height; y+=16){
00650         for(x=0; x<width; x+=16){
00651             unsigned int color[4], bits;
00652             memset(color, 0, sizeof(color));
00653 //warning following is purely guessed ...
00654             color[0]= bytestream2_get_le16u(&g3);
00655             color[1]= bytestream2_get_le16u(&g3);
00656 
00657             if(color[0]&0x8000) av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n");
00658             if(color[1]&0x8000) av_log(f->avctx, AV_LOG_ERROR, "unk bit 2\n");
00659 
00660             color[2]= mix(color[0], color[1]);
00661             color[3]= mix(color[1], color[0]);
00662 
00663             bits= bytestream2_get_le32u(&g3);
00664             for(y2=0; y2<16; y2++){
00665                 for(x2=0; x2<16; x2++){
00666                     int index= 2*(x2>>2) + 8*(y2>>2);
00667                     dst[y2*stride+x2]= color[(bits>>index)&3];
00668                 }
00669             }
00670             dst+=16;
00671         }
00672         dst += 16 * stride - x;
00673     }
00674 
00675     return 0;
00676 }
00677 
00678 static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){
00679     int x, y;
00680     const int width= f->avctx->width;
00681     const int height= f->avctx->height;
00682     const unsigned int bitstream_size= AV_RL32(buf);
00683     int token_count av_unused;
00684     unsigned int prestream_size;
00685     const uint8_t *prestream;
00686 
00687     if (bitstream_size > (1 << 26))
00688         return AVERROR_INVALIDDATA;
00689 
00690     if (length < bitstream_size + 12) {
00691         av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n");
00692         return AVERROR_INVALIDDATA;
00693     }
00694 
00695     token_count    = AV_RL32(buf + bitstream_size + 8);
00696     prestream_size = 4 * AV_RL32(buf + bitstream_size + 4);
00697     prestream      = buf + bitstream_size + 12;
00698 
00699     if(prestream_size + bitstream_size + 12 != length
00700        || prestream_size > (1<<26)){
00701         av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length);
00702         return -1;
00703     }
00704 
00705     prestream = read_huffman_tables(f, prestream, prestream_size);
00706     if (!prestream) {
00707         av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n");
00708         return AVERROR_INVALIDDATA;
00709     }
00710 
00711     init_get_bits(&f->gb, buf + 4, 8*bitstream_size);
00712 
00713     prestream_size= length + buf - prestream;
00714 
00715     av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE);
00716     if (!f->bitstream_buffer)
00717         return AVERROR(ENOMEM);
00718     f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)prestream, prestream_size/4);
00719     memset((uint8_t*)f->bitstream_buffer + prestream_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
00720     init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size);
00721 
00722     f->last_dc= 0*128*8*8;
00723 
00724     for(y=0; y<height; y+=16){
00725         for(x=0; x<width; x+=16){
00726             if(decode_i_mb(f) < 0)
00727                 return -1;
00728 
00729             idct_put(f, x, y);
00730         }
00731     }
00732 
00733     if(get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256)
00734         av_log(f->avctx, AV_LOG_ERROR, "end mismatch\n");
00735 
00736     return 0;
00737 }
00738 
00739 static int decode_frame(AVCodecContext *avctx,
00740                         void *data, int *data_size,
00741                         AVPacket *avpkt)
00742 {
00743     const uint8_t *buf = avpkt->data;
00744     int buf_size = avpkt->size;
00745     FourXContext * const f = avctx->priv_data;
00746     AVFrame *picture = data;
00747     AVFrame *p, temp;
00748     int i, frame_4cc, frame_size;
00749 
00750     if (buf_size < 20)
00751         return AVERROR_INVALIDDATA;
00752 
00753     if (avctx->width % 16 || avctx->height % 16) {
00754         av_log(avctx, AV_LOG_ERROR,
00755                "Dimensions non-multiple of 16 are invalid.\n");
00756         return AVERROR_INVALIDDATA;
00757     }
00758 
00759     if (buf_size < AV_RL32(buf + 4) + 8) {
00760         av_log(f->avctx, AV_LOG_ERROR,
00761                "size mismatch %d %d\n", buf_size, AV_RL32(buf + 4));
00762     }
00763 
00764     frame_4cc = AV_RL32(buf);
00765 
00766     if(frame_4cc == AV_RL32("cfrm")){
00767         int free_index=-1;
00768         int id, whole_size;
00769         const int data_size = buf_size - 20;
00770         CFrameBuffer *cfrm;
00771 
00772         if (data_size < 0)
00773             return AVERROR_INVALIDDATA;
00774 
00775         id         = AV_RL32(buf + 12);
00776         whole_size = AV_RL32(buf + 16);
00777 
00778         for(i=0; i<CFRAME_BUFFER_COUNT; i++){
00779             if(f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
00780                 av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id);
00781         }
00782 
00783         for(i=0; i<CFRAME_BUFFER_COUNT; i++){
00784             if(f->cfrm[i].id   == id) break;
00785             if(f->cfrm[i].size == 0 ) free_index= i;
00786         }
00787 
00788         if(i>=CFRAME_BUFFER_COUNT){
00789             i= free_index;
00790             f->cfrm[i].id= id;
00791         }
00792         cfrm= &f->cfrm[i];
00793 
00794         cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE);
00795         if(!cfrm->data){ //explicit check needed as memcpy below might not catch a NULL
00796             av_log(f->avctx, AV_LOG_ERROR, "realloc falure");
00797             return -1;
00798         }
00799 
00800         memcpy(cfrm->data + cfrm->size, buf+20, data_size);
00801         cfrm->size += data_size;
00802 
00803         if(cfrm->size >= whole_size){
00804             buf= cfrm->data;
00805             frame_size= cfrm->size;
00806 
00807             if(id != avctx->frame_number){
00808                 av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number);
00809             }
00810 
00811             if (f->version <= 1)
00812                 return AVERROR_INVALIDDATA;
00813 
00814             cfrm->size= cfrm->id= 0;
00815             frame_4cc= AV_RL32("pfrm");
00816         }else
00817             return buf_size;
00818     }else{
00819         buf= buf + 12;
00820         frame_size= buf_size - 12;
00821     }
00822 
00823     temp= f->current_picture;
00824     f->current_picture= f->last_picture;
00825     f->last_picture= temp;
00826 
00827     p= &f->current_picture;
00828     avctx->coded_frame= p;
00829 
00830     avctx->flags |= CODEC_FLAG_EMU_EDGE; // alternatively we would have to use our own buffer management
00831 
00832     if(p->data[0])
00833         avctx->release_buffer(avctx, p);
00834 
00835     p->reference= 1;
00836     if(avctx->get_buffer(avctx, p) < 0){
00837         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00838         return -1;
00839     }
00840 
00841     if(frame_4cc == AV_RL32("ifr2")){
00842         p->pict_type= AV_PICTURE_TYPE_I;
00843         if(decode_i2_frame(f, buf-4, frame_size + 4) < 0)
00844             return -1;
00845     }else if(frame_4cc == AV_RL32("ifrm")){
00846         p->pict_type= AV_PICTURE_TYPE_I;
00847         if(decode_i_frame(f, buf, frame_size) < 0)
00848             return -1;
00849     }else if(frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")){
00850         if(!f->last_picture.data[0]){
00851             f->last_picture.reference= 1;
00852             if(avctx->get_buffer(avctx, &f->last_picture) < 0){
00853                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00854                 return -1;
00855             }
00856             memset(f->last_picture.data[0], 0, avctx->height * FFABS(f->last_picture.linesize[0]));
00857         }
00858 
00859         p->pict_type= AV_PICTURE_TYPE_P;
00860         if(decode_p_frame(f, buf, frame_size) < 0)
00861             return -1;
00862     }else if(frame_4cc == AV_RL32("snd_")){
00863         av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size);
00864     }else{
00865         av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n", buf_size);
00866     }
00867 
00868     p->key_frame= p->pict_type == AV_PICTURE_TYPE_I;
00869 
00870     *picture= *p;
00871     *data_size = sizeof(AVPicture);
00872 
00873     emms_c();
00874 
00875     return buf_size;
00876 }
00877 
00878 
00879 static av_cold void common_init(AVCodecContext *avctx){
00880     FourXContext * const f = avctx->priv_data;
00881 
00882     dsputil_init(&f->dsp, avctx);
00883 
00884     f->avctx= avctx;
00885 }
00886 
00887 static av_cold int decode_init(AVCodecContext *avctx){
00888     FourXContext * const f = avctx->priv_data;
00889 
00890     if(avctx->extradata_size != 4 || !avctx->extradata) {
00891         av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n");
00892         return 1;
00893     }
00894 
00895     f->version= AV_RL32(avctx->extradata)>>16;
00896     common_init(avctx);
00897     init_vlcs(f);
00898 
00899     if(f->version>2) avctx->pix_fmt= PIX_FMT_RGB565;
00900     else             avctx->pix_fmt= PIX_FMT_BGR555;
00901 
00902     return 0;
00903 }
00904 
00905 
00906 static av_cold int decode_end(AVCodecContext *avctx){
00907     FourXContext * const f = avctx->priv_data;
00908     int i;
00909 
00910     av_freep(&f->bitstream_buffer);
00911     f->bitstream_buffer_size=0;
00912     for(i=0; i<CFRAME_BUFFER_COUNT; i++){
00913         av_freep(&f->cfrm[i].data);
00914         f->cfrm[i].allocated_size= 0;
00915     }
00916     ff_free_vlc(&f->pre_vlc);
00917     if(f->current_picture.data[0])
00918         avctx->release_buffer(avctx, &f->current_picture);
00919     if(f->last_picture.data[0])
00920         avctx->release_buffer(avctx, &f->last_picture);
00921 
00922     return 0;
00923 }
00924 
00925 AVCodec ff_fourxm_decoder = {
00926     .name           = "4xm",
00927     .type           = AVMEDIA_TYPE_VIDEO,
00928     .id             = CODEC_ID_4XM,
00929     .priv_data_size = sizeof(FourXContext),
00930     .init           = decode_init,
00931     .close          = decode_end,
00932     .decode         = decode_frame,
00933     .capabilities   = CODEC_CAP_DR1,
00934     .long_name = NULL_IF_CONFIG_SMALL("4X Movie"),
00935 };
00936