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

Generated on Thu Aug 28 16:44:14 2008 for libextractor by  doxygen 1.5.1