• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

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