Statistics
| Branch: | Revision:

ffmpeg / libavcodec / 4xm.c @ 62f68aa9

History | View | Annotate | Download (23.7 KB)

1 8809cfee Michael Niedermayer
/*
2
 * 4XM codec
3
 * Copyright (c) 2003 Michael Niedermayer
4
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 8809cfee Michael Niedermayer
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 8809cfee Michael Niedermayer
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 8809cfee Michael Niedermayer
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 8809cfee Michael Niedermayer
 */
21 115329f1 Diego Biurrun
22 8809cfee Michael Niedermayer
/**
23
 * @file 4xm.c
24
 * 4XM codec.
25
 */
26 115329f1 Diego Biurrun
27 8809cfee Michael Niedermayer
#include "avcodec.h"
28
#include "dsputil.h"
29
#include "mpegvideo.h"
30
31
//#undef NDEBUG
32
//#include <assert.h>
33
34
#define BLOCK_TYPE_VLC_BITS 5
35
#define ACDC_VLC_BITS 9
36
37
#define CFRAME_BUFFER_COUNT 100
38
39 62f68aa9 Michael Niedermayer
static const uint8_t block_type_tab[2][4][8][2]={
40
 {
41 8809cfee Michael Niedermayer
  {   //{8,4,2}x{8,4,2}
42
    { 0,1}, { 2,2}, { 6,3}, {14,4}, {30,5}, {31,5}, { 0,0}
43
  },{ //{8,4}x1
44
    { 0,1}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}, { 0,0}
45
  },{ //1x{8,4}
46
    { 0,1}, { 2,2}, { 0,0}, { 6,3}, {14,4}, {15,4}, { 0,0}
47
  },{ //1x2, 2x1
48
    { 0,1}, { 0,0}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}
49
  }
50 62f68aa9 Michael Niedermayer
 },{
51
  {  //{8,4,2}x{8,4,2}
52
    { 1,2}, { 4,3}, { 5,3}, {0,2}, {6,3}, {7,3}, {0,0}
53
  },{//{8,4}x1
54
    { 1,2}, { 0,0}, { 2,2}, {0,2}, {6,3}, {7,3}, {0,0}
55
  },{//1x{8,4}
56
    { 1,2}, { 2,2}, { 0,0}, {0,2}, {6,3}, {7,3}, {0,0}
57
  },{//1x2, 2x1
58
    { 1,2}, { 0,0}, { 0,0}, {0,2}, {2,2}, {6,3}, {7,3}
59
  }
60
 }
61 8809cfee Michael Niedermayer
};
62
63
static const uint8_t size2index[4][4]={
64
  {-1, 3, 1, 1},
65
  { 3, 0, 0, 0},
66
  { 2, 0, 0, 0},
67
  { 2, 0, 0, 0},
68
};
69
70
static const int8_t mv[256][2]={
71
{  0,  0},{  0, -1},{ -1,  0},{  1,  0},{  0,  1},{ -1, -1},{  1, -1},{ -1,  1},
72
{  1,  1},{  0, -2},{ -2,  0},{  2,  0},{  0,  2},{ -1, -2},{  1, -2},{ -2, -1},
73
{  2, -1},{ -2,  1},{  2,  1},{ -1,  2},{  1,  2},{ -2, -2},{  2, -2},{ -2,  2},
74
{  2,  2},{  0, -3},{ -3,  0},{  3,  0},{  0,  3},{ -1, -3},{  1, -3},{ -3, -1},
75
{  3, -1},{ -3,  1},{  3,  1},{ -1,  3},{  1,  3},{ -2, -3},{  2, -3},{ -3, -2},
76
{  3, -2},{ -3,  2},{  3,  2},{ -2,  3},{  2,  3},{  0, -4},{ -4,  0},{  4,  0},
77
{  0,  4},{ -1, -4},{  1, -4},{ -4, -1},{  4, -1},{  4,  1},{ -1,  4},{  1,  4},
78
{ -3, -3},{ -3,  3},{  3,  3},{ -2, -4},{ -4, -2},{  4, -2},{ -4,  2},{ -2,  4},
79
{  2,  4},{ -3, -4},{  3, -4},{  4, -3},{ -5,  0},{ -4,  3},{ -3,  4},{  3,  4},
80
{ -1, -5},{ -5, -1},{ -5,  1},{ -1,  5},{ -2, -5},{  2, -5},{  5, -2},{  5,  2},
81
{ -4, -4},{ -4,  4},{ -3, -5},{ -5, -3},{ -5,  3},{  3,  5},{ -6,  0},{  0,  6},
82
{ -6, -1},{ -6,  1},{  1,  6},{  2, -6},{ -6,  2},{  2,  6},{ -5, -4},{  5,  4},
83
{  4,  5},{ -6, -3},{  6,  3},{ -7,  0},{ -1, -7},{  5, -5},{ -7,  1},{ -1,  7},
84
{  4, -6},{  6,  4},{ -2, -7},{ -7,  2},{ -3, -7},{  7, -3},{  3,  7},{  6, -5},
85
{  0, -8},{ -1, -8},{ -7, -4},{ -8,  1},{  4,  7},{  2, -8},{ -2,  8},{  6,  6},
86
{ -8,  3},{  5, -7},{ -5,  7},{  8, -4},{  0, -9},{ -9, -1},{  1,  9},{  7, -6},
87
{ -7,  6},{ -5, -8},{ -5,  8},{ -9,  3},{  9, -4},{  7, -7},{  8, -6},{  6,  8},
88
{ 10,  1},{-10,  2},{  9, -5},{ 10, -3},{ -8, -7},{-10, -4},{  6, -9},{-11,  0},
89
{ 11,  1},{-11, -2},{ -2, 11},{  7, -9},{ -7,  9},{ 10,  6},{ -4, 11},{  8, -9},
90
{  8,  9},{  5, 11},{  7,-10},{ 12, -3},{ 11,  6},{ -9, -9},{  8, 10},{  5, 12},
91
{-11,  7},{ 13,  2},{  6,-12},{ 10,  9},{-11,  8},{ -7, 12},{  0, 14},{ 14, -2},
92
{ -9, 11},{ -6, 13},{-14, -4},{ -5,-14},{  5, 14},{-15, -1},{-14, -6},{  3,-15},
93
{ 11,-11},{ -7, 14},{ -5, 15},{  8,-14},{ 15,  6},{  3, 16},{  7,-15},{-16,  5},
94
{  0, 17},{-16, -6},{-10, 14},{-16,  7},{ 12, 13},{-16,  8},{-17,  6},{-18,  3},
95
{ -7, 17},{ 15, 11},{ 16, 10},{  2,-19},{  3,-19},{-11,-16},{-18,  8},{-19, -6},
96
{  2,-20},{-17,-11},{-10,-18},{  8, 19},{-21, -1},{-20,  7},{ -4, 21},{ 21,  5},
97
{ 15, 16},{  2,-22},{-10,-20},{-22,  5},{ 20,-11},{ -7,-22},{-12, 20},{ 23, -5},
98
{ 13,-20},{ 24, -2},{-15, 19},{-11, 22},{ 16, 19},{ 23,-10},{-18,-18},{ -9,-24},
99
{ 24,-10},{ -3, 26},{-23, 13},{-18,-20},{ 17, 21},{ -4, 27},{ 27,  6},{  1,-28},
100
{-11, 26},{-17,-23},{  7, 28},{ 11,-27},{ 29,  5},{-23,-19},{-28,-11},{-21, 22},
101
{-30,  7},{-17, 26},{-27, 16},{ 13, 29},{ 19,-26},{ 10,-31},{-14,-30},{ 20,-27},
102
{-29, 18},{-16,-31},{-28,-22},{ 21,-30},{-25, 28},{ 26,-29},{ 25,-32},{-32,-32}
103
};
104
105
// this is simply the scaled down elementwise product of the standard jpeg quantizer table and the AAN premul table
106
static const uint8_t dequant_table[64]={
107
 16, 15, 13, 19, 24, 31, 28, 17,
108
 17, 23, 25, 31, 36, 63, 45, 21,
109
 18, 24, 27, 37, 52, 59, 49, 20,
110
 16, 28, 34, 40, 60, 80, 51, 20,
111
 18, 31, 48, 66, 68, 86, 56, 21,
112
 19, 38, 56, 59, 64, 64, 48, 20,
113
 27, 48, 55, 55, 56, 51, 35, 15,
114
 20, 35, 34, 32, 31, 22, 15,  8,
115
};
116
117 62f68aa9 Michael Niedermayer
static VLC block_type_vlc[2][4];
118 8809cfee Michael Niedermayer
119
120
typedef struct CFrameBuffer{
121 191e8ca7 Måns Rullgård
    unsigned int allocated_size;
122
    unsigned int size;
123 8809cfee Michael Niedermayer
    int id;
124
    uint8_t *data;
125
}CFrameBuffer;
126
127
typedef struct FourXContext{
128
    AVCodecContext *avctx;
129
    DSPContext dsp;
130
    AVFrame current_picture, last_picture;
131
    GetBitContext pre_gb;          ///< ac/dc prefix
132
    GetBitContext gb;
133
    uint8_t *bytestream;
134
    uint16_t *wordstream;
135
    int mv[256];
136
    VLC pre_vlc;
137
    int last_dc;
138 68b51e58 Steve L'Homme
    DECLARE_ALIGNED_8(DCTELEM, block[6][64]);
139 8809cfee Michael Niedermayer
    uint8_t *bitstream_buffer;
140 f038fe8b Diego Biurrun
    unsigned int bitstream_buffer_size;
141 62f68aa9 Michael Niedermayer
    int vlc_type;
142 8809cfee Michael Niedermayer
    CFrameBuffer cfrm[CFRAME_BUFFER_COUNT];
143
} FourXContext;
144
145
146
#define FIX_1_082392200  70936
147
#define FIX_1_414213562  92682
148
#define FIX_1_847759065 121095
149
#define FIX_2_613125930 171254
150
151
#define MULTIPLY(var,const)  (((var)*(const)) >> 16)
152
153
static void idct(DCTELEM block[64]){
154
    int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
155
    int tmp10, tmp11, tmp12, tmp13;
156
    int z5, z10, z11, z12, z13;
157
    int i;
158
    int temp[64];
159 115329f1 Diego Biurrun
160 8809cfee Michael Niedermayer
    for(i=0; i<8; i++){
161
        tmp10 = block[8*0 + i] + block[8*4 + i];
162
        tmp11 = block[8*0 + i] - block[8*4 + i];
163
164
        tmp13 =          block[8*2 + i] + block[8*6 + i];
165
        tmp12 = MULTIPLY(block[8*2 + i] - block[8*6 + i], FIX_1_414213562) - tmp13;
166
167
        tmp0 = tmp10 + tmp13;
168
        tmp3 = tmp10 - tmp13;
169
        tmp1 = tmp11 + tmp12;
170
        tmp2 = tmp11 - tmp12;
171 115329f1 Diego Biurrun
172 8809cfee Michael Niedermayer
        z13 = block[8*5 + i] + block[8*3 + i];
173
        z10 = block[8*5 + i] - block[8*3 + i];
174
        z11 = block[8*1 + i] + block[8*7 + i];
175
        z12 = block[8*1 + i] - block[8*7 + i];
176
177
        tmp7  =          z11 + z13;
178
        tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
179
180
        z5    = MULTIPLY(z10 + z12, FIX_1_847759065);
181
        tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
182
        tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
183
184
        tmp6 = tmp12 - tmp7;
185
        tmp5 = tmp11 - tmp6;
186
        tmp4 = tmp10 + tmp5;
187
188
        temp[8*0 + i] = tmp0 + tmp7;
189
        temp[8*7 + i] = tmp0 - tmp7;
190
        temp[8*1 + i] = tmp1 + tmp6;
191
        temp[8*6 + i] = tmp1 - tmp6;
192
        temp[8*2 + i] = tmp2 + tmp5;
193
        temp[8*5 + i] = tmp2 - tmp5;
194
        temp[8*4 + i] = tmp3 + tmp4;
195
        temp[8*3 + i] = tmp3 - tmp4;
196
    }
197 115329f1 Diego Biurrun
198 8809cfee Michael Niedermayer
    for(i=0; i<8*8; i+=8){
199
        tmp10 = temp[0 + i] + temp[4 + i];
200
        tmp11 = temp[0 + i] - temp[4 + i];
201
202
        tmp13 = temp[2 + i] + temp[6 + i];
203
        tmp12 = MULTIPLY(temp[2 + i] - temp[6 + i], FIX_1_414213562) - tmp13;
204
205
        tmp0 = tmp10 + tmp13;
206
        tmp3 = tmp10 - tmp13;
207
        tmp1 = tmp11 + tmp12;
208
        tmp2 = tmp11 - tmp12;
209
210
        z13 = temp[5 + i] + temp[3 + i];
211
        z10 = temp[5 + i] - temp[3 + i];
212
        z11 = temp[1 + i] + temp[7 + i];
213
        z12 = temp[1 + i] - temp[7 + i];
214
215
        tmp7 = z11 + z13;
216
        tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
217
218
        z5 = MULTIPLY(z10 + z12, FIX_1_847759065);
219
        tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
220
        tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
221
222
        tmp6 = tmp12 - tmp7;
223
        tmp5 = tmp11 - tmp6;
224
        tmp4 = tmp10 + tmp5;
225
226
        block[0 + i] = (tmp0 + tmp7)>>6;
227
        block[7 + i] = (tmp0 - tmp7)>>6;
228
        block[1 + i] = (tmp1 + tmp6)>>6;
229
        block[6 + i] = (tmp1 - tmp6)>>6;
230
        block[2 + i] = (tmp2 + tmp5)>>6;
231
        block[5 + i] = (tmp2 - tmp5)>>6;
232
        block[4 + i] = (tmp3 + tmp4)>>6;
233
        block[3 + i] = (tmp3 - tmp4)>>6;
234
    }
235
}
236
237
static void init_vlcs(FourXContext *f){
238
    int i;
239
240 62f68aa9 Michael Niedermayer
    for(i=0; i<8; i++){
241
        init_vlc(&block_type_vlc[0][i], BLOCK_TYPE_VLC_BITS, 7,
242
                 &block_type_tab[0][i][0][1], 2, 1,
243
                 &block_type_tab[0][i][0][0], 2, 1, 1);
244 8809cfee Michael Niedermayer
    }
245
}
246
247
static void init_mv(FourXContext *f){
248
    int i;
249
250
    for(i=0; i<256; i++){
251
        f->mv[i] = mv[i][0] + mv[i][1]*f->current_picture.linesize[0]/2;
252
    }
253
}
254
255
static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, int dc){
256
   int i;
257
   dc*= 0x10001;
258
259
   switch(log2w){
260
   case 0:
261
        for(i=0; i<h; i++){
262
            dst[0] = scale*src[0] + dc;
263
            if(scale) src += stride;
264
            dst += stride;
265
        }
266
        break;
267
    case 1:
268
        for(i=0; i<h; i++){
269
            ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
270
            if(scale) src += stride;
271
            dst += stride;
272
        }
273
        break;
274
    case 2:
275
        for(i=0; i<h; i++){
276
            ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
277
            ((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc;
278
            if(scale) src += stride;
279
            dst += stride;
280
        }
281
        break;
282
    case 3:
283
        for(i=0; i<h; i++){
284
            ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
285
            ((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc;
286
            ((uint32_t*)dst)[2] = scale*((uint32_t*)src)[2] + dc;
287
            ((uint32_t*)dst)[3] = scale*((uint32_t*)src)[3] + dc;
288
            if(scale) src += stride;
289
            dst += stride;
290
        }
291
        break;
292
    default: assert(0);
293
    }
294
}
295
296
static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int log2w, int log2h, int stride){
297
    const int index= size2index[log2h][log2w];
298
    const int h= 1<<log2h;
299 62f68aa9 Michael Niedermayer
    int code= get_vlc2(&f->gb, block_type_vlc[f->vlc_type][index].table, BLOCK_TYPE_VLC_BITS, 1);
300 115329f1 Diego Biurrun
301 8809cfee Michael Niedermayer
    assert(code>=0 && code<=6);
302
303
    if(code == 0){
304
        src += f->mv[ *f->bytestream++ ];
305
        mcdc(dst, src, log2w, h, stride, 1, 0);
306
    }else if(code == 1){
307
        log2h--;
308
        decode_p_block(f, dst                  , src                  , log2w, log2h, stride);
309
        decode_p_block(f, dst + (stride<<log2h), src + (stride<<log2h), log2w, log2h, stride);
310
    }else if(code == 2){
311
        log2w--;
312
        decode_p_block(f, dst             , src             , log2w, log2h, stride);
313
        decode_p_block(f, dst + (1<<log2w), src + (1<<log2w), log2w, log2h, stride);
314
    }else if(code == 4){
315
        src += f->mv[ *f->bytestream++ ];
316
        mcdc(dst, src, log2w, h, stride, 1, le2me_16(*f->wordstream++));
317
    }else if(code == 5){
318
        mcdc(dst, src, log2w, h, stride, 0, le2me_16(*f->wordstream++));
319
    }else if(code == 6){
320
        if(log2w){
321
            dst[0] = le2me_16(*f->wordstream++);
322
            dst[1] = le2me_16(*f->wordstream++);
323
        }else{
324
            dst[0     ] = le2me_16(*f->wordstream++);
325
            dst[stride] = le2me_16(*f->wordstream++);
326
        }
327
    }
328
}
329
330
static int get32(void *p){
331
    return le2me_32(*(uint32_t*)p);
332
}
333
334
static int decode_p_frame(FourXContext *f, uint8_t *buf, int length){
335
    int x, y;
336
    const int width= f->avctx->width;
337
    const int height= f->avctx->height;
338
    uint16_t *src= (uint16_t*)f->last_picture.data[0];
339
    uint16_t *dst= (uint16_t*)f->current_picture.data[0];
340
    const int stride= f->current_picture.linesize[0]>>1;
341 62f68aa9 Michael Niedermayer
    unsigned int bitstream_size, bytestream_size, wordstream_size, extra;
342
343
    if(!get32(buf-4)){
344
        extra=20;
345
        bitstream_size= get32(buf+8);
346
        wordstream_size= get32(buf+12);
347
        bytestream_size= get32(buf+16);
348
        f->vlc_type= 0;
349
    }else{
350
        extra=0;
351
        bitstream_size = AV_RL16(buf-4);
352
        wordstream_size= AV_RL16(buf-2);
353
        bytestream_size= FFMAX(length - bitstream_size - wordstream_size, 0);
354
        f->vlc_type= 1;
355
    }
356 115329f1 Diego Biurrun
357 62f68aa9 Michael Niedermayer
    if(bitstream_size+ bytestream_size+ wordstream_size + extra != length
358 0ecca7a4 Michael Niedermayer
       || bitstream_size  > (1<<26)
359
       || bytestream_size > (1<<26)
360
       || wordstream_size > (1<<26)
361
       ){
362 115329f1 Diego Biurrun
        av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size,
363 8809cfee Michael Niedermayer
        bitstream_size+ bytestream_size+ wordstream_size - length);
364 0ecca7a4 Michael Niedermayer
        return -1;
365
    }
366 115329f1 Diego Biurrun
367 8809cfee Michael Niedermayer
    f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE);
368 62f68aa9 Michael Niedermayer
    f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (uint32_t*)(buf + extra), bitstream_size/4);
369 8809cfee Michael Niedermayer
    init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size);
370
371 62f68aa9 Michael Niedermayer
    f->wordstream= (uint16_t*)(buf + extra + bitstream_size);
372
    f->bytestream= buf + extra + bitstream_size + wordstream_size;
373 115329f1 Diego Biurrun
374 8809cfee Michael Niedermayer
    init_mv(f);
375 115329f1 Diego Biurrun
376 8809cfee Michael Niedermayer
    for(y=0; y<height; y+=8){
377
        for(x=0; x<width; x+=8){
378
            decode_p_block(f, dst + x, src + x, 3, 3, stride);
379
        }
380 115329f1 Diego Biurrun
        src += 8*stride;
381
        dst += 8*stride;
382 8809cfee Michael Niedermayer
    }
383 115329f1 Diego Biurrun
384 62f68aa9 Michael Niedermayer
    if(   bitstream_size != (get_bits_count(&f->gb)+31)/32*4
385
       || (((char*)f->wordstream - (char*)buf + 2)&~2) != extra + bitstream_size + wordstream_size
386
       || (((char*)f->bytestream - (char*)buf + 3)&~3) != extra + bitstream_size + wordstream_size + bytestream_size)
387 115329f1 Diego Biurrun
        av_log(f->avctx, AV_LOG_ERROR, " %d %td %td bytes left\n",
388
            bitstream_size - (get_bits_count(&f->gb)+31)/32*4,
389 62f68aa9 Michael Niedermayer
            -(((char*)f->bytestream - (char*)buf + 3)&~3) + (extra + bitstream_size + wordstream_size + bytestream_size),
390
            -(((char*)f->wordstream - (char*)buf + 2)&~2) + (extra + bitstream_size + wordstream_size)
391 8809cfee Michael Niedermayer
        );
392 115329f1 Diego Biurrun
393 8809cfee Michael Niedermayer
    return 0;
394
}
395
396
/**
397
 * decode block and dequantize.
398
 * Note this is allmost identical to mjpeg
399
 */
400
static int decode_i_block(FourXContext *f, DCTELEM *block){
401
    int code, i, j, level, val;
402
403
    /* DC coef */
404
    val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
405
    if (val>>4){
406 9b879566 Michel Bardiaux
        av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n");
407 8809cfee Michael Niedermayer
    }
408
409
    if(val)
410
        val = get_xbits(&f->gb, val);
411
412
    val = val * dequant_table[0] + f->last_dc;
413
    f->last_dc =
414
    block[0] = val;
415
    /* AC coefs */
416
    i = 1;
417
    for(;;) {
418
        code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
419 115329f1 Diego Biurrun
420 8809cfee Michael Niedermayer
        /* EOB */
421
        if (code == 0)
422
            break;
423
        if (code == 0xf0) {
424
            i += 16;
425
        } else {
426
            level = get_xbits(&f->gb, code & 0xf);
427
            i += code >> 4;
428
            if (i >= 64) {
429 9b879566 Michel Bardiaux
                av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i);
430 8809cfee Michael Niedermayer
                return 0;
431
            }
432
433
            j= ff_zigzag_direct[i];
434
            block[j] = level * dequant_table[j];
435
            i++;
436
            if (i >= 64)
437
                break;
438
        }
439
    }
440
441
    return 0;
442
}
443
444
static inline void idct_put(FourXContext *f, int x, int y){
445
    DCTELEM (*block)[64]= f->block;
446
    int stride= f->current_picture.linesize[0]>>1;
447
    int i;
448
    uint16_t *dst = ((uint16_t*)f->current_picture.data[0]) + y * stride + x;
449 115329f1 Diego Biurrun
450 b60ad448 Michael Niedermayer
    for(i=0; i<4; i++){
451
        block[i][0] += 0x80*8*8;
452
        idct(block[i]);
453
    }
454 8809cfee Michael Niedermayer
455 b60ad448 Michael Niedermayer
    if(!(f->avctx->flags&CODEC_FLAG_GRAY)){
456
        for(i=4; i<6; i++) idct(block[i]);
457
    }
458 8809cfee Michael Niedermayer
459 c9319f2e Michael Niedermayer
/* Note transform is:
460
y= ( 1b + 4g + 2r)/14
461
cb=( 3b - 2g - 1r)/14
462
cr=(-1b - 4g + 5r)/14
463 115329f1 Diego Biurrun
*/
464 8809cfee Michael Niedermayer
    for(y=0; y<8; y++){
465
        for(x=0; x<8; x++){
466
            DCTELEM *temp= block[(x>>2) + 2*(y>>2)] + 2*(x&3) + 2*8*(y&3); //FIXME optimize
467 b60ad448 Michael Niedermayer
            int cb= block[4][x + 8*y];
468
            int cr= block[5][x + 8*y];
469 8809cfee Michael Niedermayer
            int cg= (cb + cr)>>1;
470
            int y;
471 115329f1 Diego Biurrun
472 b60ad448 Michael Niedermayer
            cb+=cb;
473 115329f1 Diego Biurrun
474 8809cfee Michael Niedermayer
            y = temp[0];
475 b60ad448 Michael Niedermayer
            dst[0       ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
476 8809cfee Michael Niedermayer
            y = temp[1];
477 b60ad448 Michael Niedermayer
            dst[1       ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
478 8809cfee Michael Niedermayer
            y = temp[8];
479 b60ad448 Michael Niedermayer
            dst[  stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
480 8809cfee Michael Niedermayer
            y = temp[9];
481 b60ad448 Michael Niedermayer
            dst[1+stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
482 8809cfee Michael Niedermayer
            dst += 2;
483
        }
484
        dst += 2*stride - 2*8;
485
    }
486
}
487
488
static int decode_i_mb(FourXContext *f){
489
    int i;
490 115329f1 Diego Biurrun
491 8809cfee Michael Niedermayer
    f->dsp.clear_blocks(f->block[0]);
492 115329f1 Diego Biurrun
493 8809cfee Michael Niedermayer
    for(i=0; i<6; i++){
494
        if(decode_i_block(f, f->block[i]) < 0)
495
            return -1;
496
    }
497 115329f1 Diego Biurrun
498 8809cfee Michael Niedermayer
    return 0;
499
}
500
501
static uint8_t *read_huffman_tables(FourXContext *f, uint8_t * const buf){
502
    int frequency[512];
503
    uint8_t flag[512];
504
    int up[512];
505
    uint8_t len_tab[257];
506
    int bits_tab[257];
507
    int start, end;
508
    uint8_t *ptr= buf;
509
    int j;
510 115329f1 Diego Biurrun
511 8809cfee Michael Niedermayer
    memset(frequency, 0, sizeof(frequency));
512
    memset(up, -1, sizeof(up));
513
514
    start= *ptr++;
515
    end= *ptr++;
516
    for(;;){
517
        int i;
518 115329f1 Diego Biurrun
519 8809cfee Michael Niedermayer
        for(i=start; i<=end; i++){
520
            frequency[i]= *ptr++;
521
        }
522
        start= *ptr++;
523
        if(start==0) break;
524 115329f1 Diego Biurrun
525 8809cfee Michael Niedermayer
        end= *ptr++;
526
    }
527
    frequency[256]=1;
528
529 115329f1 Diego Biurrun
    while((ptr - buf)&3) ptr++; // 4byte align
530 8809cfee Michael Niedermayer
531
    for(j=257; j<512; j++){
532 5be8a373 Michael Niedermayer
        int min_freq[2]= {256*256, 256*256};
533
        int smallest[2]= {0, 0};
534 8809cfee Michael Niedermayer
        int i;
535
        for(i=0; i<j; i++){
536
            if(frequency[i] == 0) continue;
537 5be8a373 Michael Niedermayer
            if(frequency[i] < min_freq[1]){
538
                if(frequency[i] < min_freq[0]){
539
                    min_freq[1]= min_freq[0]; smallest[1]= smallest[0];
540
                    min_freq[0]= frequency[i];smallest[0]= i;
541
                }else{
542
                    min_freq[1]= frequency[i];smallest[1]= i;
543
                }
544 8809cfee Michael Niedermayer
            }
545
        }
546 5be8a373 Michael Niedermayer
        if(min_freq[1] == 256*256) break;
547 115329f1 Diego Biurrun
548 5be8a373 Michael Niedermayer
        frequency[j]= min_freq[0] + min_freq[1];
549 8809cfee Michael Niedermayer
        flag[ smallest[0] ]= 0;
550
        flag[ smallest[1] ]= 1;
551 115329f1 Diego Biurrun
        up[ smallest[0] ]=
552 8809cfee Michael Niedermayer
        up[ smallest[1] ]= j;
553
        frequency[ smallest[0] ]= frequency[ smallest[1] ]= 0;
554
    }
555
556
    for(j=0; j<257; j++){
557
        int node;
558
        int len=0;
559
        int bits=0;
560
561
        for(node= j; up[node] != -1; node= up[node]){
562
            bits += flag[node]<<len;
563
            len++;
564 9b879566 Michel Bardiaux
            if(len > 31) av_log(f->avctx, AV_LOG_ERROR, "vlc length overflow\n"); //can this happen at all ?
565 8809cfee Michael Niedermayer
        }
566 115329f1 Diego Biurrun
567 8809cfee Michael Niedermayer
        bits_tab[j]= bits;
568
        len_tab[j]= len;
569
    }
570 115329f1 Diego Biurrun
571
    init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257,
572 8809cfee Michael Niedermayer
             len_tab , 1, 1,
573 073c2593 Burkhard Plaum
             bits_tab, 4, 4, 0);
574 115329f1 Diego Biurrun
575 8809cfee Michael Niedermayer
    return ptr;
576
}
577
578
static int decode_i_frame(FourXContext *f, uint8_t *buf, int length){
579
    int x, y;
580
    const int width= f->avctx->width;
581
    const int height= f->avctx->height;
582
    uint16_t *dst= (uint16_t*)f->current_picture.data[0];
583
    const int stride= f->current_picture.linesize[0]>>1;
584 0ecca7a4 Michael Niedermayer
    const unsigned int bitstream_size= get32(buf);
585 154e30f6 Carl Eugen Hoyos
    const int token_count av_unused = get32(buf + bitstream_size + 8);
586 0ecca7a4 Michael Niedermayer
    unsigned int prestream_size= 4*get32(buf + bitstream_size + 4);
587 8809cfee Michael Niedermayer
    uint8_t *prestream= buf + bitstream_size + 12;
588 115329f1 Diego Biurrun
589 0ecca7a4 Michael Niedermayer
    if(prestream_size + bitstream_size + 12 != length
590
       || bitstream_size > (1<<26)
591
       || prestream_size > (1<<26)){
592 160d679c Mike Melanson
        av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length);
593 0ecca7a4 Michael Niedermayer
        return -1;
594
    }
595 115329f1 Diego Biurrun
596 8809cfee Michael Niedermayer
    prestream= read_huffman_tables(f, prestream);
597
598
    init_get_bits(&f->gb, buf + 4, 8*bitstream_size);
599
600
    prestream_size= length + buf - prestream;
601 5be8a373 Michael Niedermayer
602 8809cfee Michael Niedermayer
    f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE);
603
    f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (uint32_t*)prestream, prestream_size/4);
604
    init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size);
605
606
    f->last_dc= 0*128*8*8;
607 115329f1 Diego Biurrun
608 8809cfee Michael Niedermayer
    for(y=0; y<height; y+=16){
609
        for(x=0; x<width; x+=16){
610
            if(decode_i_mb(f) < 0)
611
                return -1;
612
613
            idct_put(f, x, y);
614
        }
615 115329f1 Diego Biurrun
        dst += 16*stride;
616 8809cfee Michael Niedermayer
    }
617
618
    if(get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256)
619 160d679c Mike Melanson
        av_log(f->avctx, AV_LOG_ERROR, "end mismatch\n");
620 115329f1 Diego Biurrun
621 8809cfee Michael Niedermayer
    return 0;
622
}
623
624 115329f1 Diego Biurrun
static int decode_frame(AVCodecContext *avctx,
625 8809cfee Michael Niedermayer
                        void *data, int *data_size,
626
                        uint8_t *buf, int buf_size)
627
{
628
    FourXContext * const f = avctx->priv_data;
629
    AVFrame *picture = data;
630
    AVFrame *p, temp;
631
    int i, frame_4cc, frame_size;
632
633
    frame_4cc= get32(buf);
634 3a1a7e32 Michael Niedermayer
    if(buf_size != get32(buf+4)+8 || buf_size < 20){
635 160d679c Mike Melanson
        av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, get32(buf+4));
636 8809cfee Michael Niedermayer
    }
637
638
    if(frame_4cc == ff_get_fourcc("cfrm")){
639
        int free_index=-1;
640
        const int data_size= buf_size - 20;
641
        const int id= get32(buf+12);
642
        const int whole_size= get32(buf+16);
643
        CFrameBuffer *cfrm;
644
645
        for(i=0; i<CFRAME_BUFFER_COUNT; i++){
646
            if(f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
647 9b879566 Michel Bardiaux
                av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id);
648 8809cfee Michael Niedermayer
        }
649 115329f1 Diego Biurrun
650 8809cfee Michael Niedermayer
        for(i=0; i<CFRAME_BUFFER_COUNT; i++){
651
            if(f->cfrm[i].id   == id) break;
652
            if(f->cfrm[i].size == 0 ) free_index= i;
653
        }
654
655
        if(i>=CFRAME_BUFFER_COUNT){
656
            i= free_index;
657
            f->cfrm[i].id= id;
658
        }
659
        cfrm= &f->cfrm[i];
660 115329f1 Diego Biurrun
661 8809cfee Michael Niedermayer
        cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE);
662 3a1a7e32 Michael Niedermayer
        if(!cfrm->data){ //explicit check needed as memcpy below might not catch a NULL
663
            av_log(f->avctx, AV_LOG_ERROR, "realloc falure");
664
            return -1;
665
        }
666 115329f1 Diego Biurrun
667 8809cfee Michael Niedermayer
        memcpy(cfrm->data + cfrm->size, buf+20, data_size);
668
        cfrm->size += data_size;
669 115329f1 Diego Biurrun
670 8809cfee Michael Niedermayer
        if(cfrm->size >= whole_size){
671
            buf= cfrm->data;
672
            frame_size= cfrm->size;
673 115329f1 Diego Biurrun
674 8809cfee Michael Niedermayer
            if(id != avctx->frame_number){
675 160d679c Mike Melanson
                av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number);
676 8809cfee Michael Niedermayer
            }
677 115329f1 Diego Biurrun
678 8809cfee Michael Niedermayer
            cfrm->size= cfrm->id= 0;
679
            frame_4cc= ff_get_fourcc("pfrm");
680
        }else
681
            return buf_size;
682
    }else{
683
        buf= buf + 12;
684
        frame_size= buf_size - 12;
685 115329f1 Diego Biurrun
    }
686 8809cfee Michael Niedermayer
687
    temp= f->current_picture;
688
    f->current_picture= f->last_picture;
689
    f->last_picture= temp;
690
691
    p= &f->current_picture;
692
    avctx->coded_frame= p;
693
694
    avctx->flags |= CODEC_FLAG_EMU_EDGE; // alternatively we would have to use our own buffer management
695
696
    if(p->data[0])
697
        avctx->release_buffer(avctx, p);
698
699
    p->reference= 1;
700
    if(avctx->get_buffer(avctx, p) < 0){
701 9b879566 Michel Bardiaux
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
702 8809cfee Michael Niedermayer
        return -1;
703
    }
704
705 62f68aa9 Michael Niedermayer
    if(frame_4cc == ff_get_fourcc("ifrm") || frame_4cc == ff_get_fourcc("ifr2")){
706 8809cfee Michael Niedermayer
        p->pict_type= I_TYPE;
707
        if(decode_i_frame(f, buf, frame_size) < 0)
708
            return -1;
709 62f68aa9 Michael Niedermayer
    }else if(frame_4cc == ff_get_fourcc("pfrm") || frame_4cc == ff_get_fourcc("pfr2")){
710 8809cfee Michael Niedermayer
        p->pict_type= P_TYPE;
711
        if(decode_p_frame(f, buf, frame_size) < 0)
712
            return -1;
713
    }else if(frame_4cc == ff_get_fourcc("snd_")){
714 9b879566 Michel Bardiaux
        av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size);
715 8809cfee Michael Niedermayer
    }else{
716 9b879566 Michel Bardiaux
        av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n", buf_size);
717 8809cfee Michael Niedermayer
    }
718
719
    p->key_frame= p->pict_type == I_TYPE;
720
721
    *picture= *p;
722
    *data_size = sizeof(AVPicture);
723
724
    emms_c();
725 115329f1 Diego Biurrun
726 8809cfee Michael Niedermayer
    return buf_size;
727
}
728
729
730
static void common_init(AVCodecContext *avctx){
731
    FourXContext * const f = avctx->priv_data;
732
733
    dsputil_init(&f->dsp, avctx);
734
735
    f->avctx= avctx;
736
}
737
738
static int decode_init(AVCodecContext *avctx){
739
    FourXContext * const f = avctx->priv_data;
740 115329f1 Diego Biurrun
741 8809cfee Michael Niedermayer
    common_init(avctx);
742
    init_vlcs(f);
743
744
    avctx->pix_fmt= PIX_FMT_RGB565;
745
746
    return 0;
747
}
748
749
750
static int decode_end(AVCodecContext *avctx){
751
    FourXContext * const f = avctx->priv_data;
752
    int i;
753
754
    av_freep(&f->bitstream_buffer);
755
    f->bitstream_buffer_size=0;
756
    for(i=0; i<CFRAME_BUFFER_COUNT; i++){
757
        av_freep(&f->cfrm[i].data);
758
        f->cfrm[i].allocated_size= 0;
759
    }
760
    free_vlc(&f->pre_vlc);
761 115329f1 Diego Biurrun
762 8809cfee Michael Niedermayer
    return 0;
763
}
764
765
AVCodec fourxm_decoder = {
766
    "4xm",
767
    CODEC_TYPE_VIDEO,
768
    CODEC_ID_4XM,
769
    sizeof(FourXContext),
770
    decode_init,
771
    NULL,
772
    decode_end,
773
    decode_frame,
774
    /*CODEC_CAP_DR1,*/
775
};