Statistics
| Branch: | Revision:

ffmpeg / libavcodec / intrax8.c @ 2912e87a

History | View | Annotate | Download (24.7 KB)

1
/*
2
 * This file is part of Libav.
3
 *
4
 * Libav is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * Libav is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with Libav; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
 */
18

    
19
/**
20
 * @file
21
 * @brief IntraX8 (J-Frame) subdecoder, used by WMV2 and VC-1
22
 */
23

    
24
#include "avcodec.h"
25
#include "get_bits.h"
26
#include "mpegvideo.h"
27
#include "msmpeg4data.h"
28
#include "intrax8huf.h"
29
#include "intrax8.h"
30

    
31
#define MAX_TABLE_DEPTH(table_bits, max_bits) ((max_bits+table_bits-1)/table_bits)
32

    
33
#define DC_VLC_BITS 9
34
#define AC_VLC_BITS 9
35
#define OR_VLC_BITS 7
36

    
37
#define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS)
38
#define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
39
#define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS)
40

    
41
static VLC j_ac_vlc[2][2][8];  //[quant<13],[intra/inter],[select]
42
static VLC j_dc_vlc[2][8];     //[quant], [select]
43
static VLC j_orient_vlc[2][4]; //[quant], [select]
44

    
45
static av_cold void x8_vlc_init(void){
46
    int i;
47
    int offset = 0;
48
    int sizeidx = 0;
49
    static const uint16_t sizes[8*4 + 8*2 + 2 + 4] = {
50
        576, 548, 582, 618, 546, 616, 560, 642,
51
        584, 582, 704, 664, 512, 544, 656, 640,
52
        512, 648, 582, 566, 532, 614, 596, 648,
53
        586, 552, 584, 590, 544, 578, 584, 624,
54

    
55
        528, 528, 526, 528, 536, 528, 526, 544,
56
        544, 512, 512, 528, 528, 544, 512, 544,
57

    
58
        128, 128, 128, 128, 128, 128};
59

    
60
    static VLC_TYPE table[28150][2];
61

    
62
#define  init_ac_vlc(dst,src) \
63
    dst.table = &table[offset]; \
64
    dst.table_allocated = sizes[sizeidx]; \
65
    offset += sizes[sizeidx++]; \
66
       init_vlc(&dst, \
67
              AC_VLC_BITS,77, \
68
              &src[1],4,2, \
69
              &src[0],4,2, \
70
              INIT_VLC_USE_NEW_STATIC)
71
//set ac tables
72
    for(i=0;i<8;i++){
73
        init_ac_vlc( j_ac_vlc[0][0][i], x8_ac0_highquant_table[i][0] );
74
        init_ac_vlc( j_ac_vlc[0][1][i], x8_ac1_highquant_table[i][0] );
75
        init_ac_vlc( j_ac_vlc[1][0][i], x8_ac0_lowquant_table [i][0] );
76
        init_ac_vlc( j_ac_vlc[1][1][i], x8_ac1_lowquant_table [i][0] );
77
    }
78
#undef init_ac_vlc
79

    
80
//set dc tables
81
#define init_dc_vlc(dst,src) \
82
    dst.table = &table[offset]; \
83
    dst.table_allocated = sizes[sizeidx]; \
84
    offset += sizes[sizeidx++]; \
85
        init_vlc(&dst, \
86
        DC_VLC_BITS,34, \
87
        &src[1],4,2, \
88
        &src[0],4,2, \
89
        INIT_VLC_USE_NEW_STATIC);
90
    for(i=0;i<8;i++){
91
        init_dc_vlc( j_dc_vlc[0][i], x8_dc_highquant_table[i][0]);
92
        init_dc_vlc( j_dc_vlc[1][i], x8_dc_lowquant_table [i][0]);
93
    }
94
#undef init_dc_vlc
95

    
96
//set orient tables
97
#define init_or_vlc(dst,src) \
98
    dst.table = &table[offset]; \
99
    dst.table_allocated = sizes[sizeidx]; \
100
    offset += sizes[sizeidx++]; \
101
    init_vlc(&dst, \
102
    OR_VLC_BITS,12, \
103
    &src[1],4,2, \
104
    &src[0],4,2, \
105
    INIT_VLC_USE_NEW_STATIC);
106
    for(i=0;i<2;i++){
107
        init_or_vlc( j_orient_vlc[0][i], x8_orient_highquant_table[i][0]);
108
    }
109
    for(i=0;i<4;i++){
110
        init_or_vlc( j_orient_vlc[1][i], x8_orient_lowquant_table [i][0])
111
    }
112
    if (offset != sizeof(table)/sizeof(VLC_TYPE)/2)
113
        av_log(NULL, AV_LOG_ERROR, "table size %i does not match needed %i\n", (int)(sizeof(table)/sizeof(VLC_TYPE)/2), offset);
114
}
115
#undef init_or_vlc
116

    
117
static void x8_reset_vlc_tables(IntraX8Context * w){
118
    memset(w->j_dc_vlc,0,sizeof(w->j_dc_vlc));
119
    memset(w->j_ac_vlc,0,sizeof(w->j_ac_vlc));
120
    w->j_orient_vlc=NULL;
121
}
122

    
123
static inline void x8_select_ac_table(IntraX8Context * const w , int mode){
124
    MpegEncContext * const s= w->s;
125
    int table_index;
126

    
127
    assert(mode<4);
128

    
129
    if( w->j_ac_vlc[mode] ) return;
130

    
131
    table_index = get_bits(&s->gb, 3);
132
    w->j_ac_vlc[mode] = &j_ac_vlc[w->quant<13][mode>>1][table_index];//2 modes use same tables
133
    assert(w->j_ac_vlc[mode]);
134
}
135

    
136
static inline int x8_get_orient_vlc(IntraX8Context * w){
137
    MpegEncContext * const s= w->s;
138
    int table_index;
139

    
140
    if(!w->j_orient_vlc ){
141
        table_index = get_bits(&s->gb, 1+(w->quant<13) );
142
        w->j_orient_vlc = &j_orient_vlc[w->quant<13][table_index];
143
    }
144
    assert(w->j_orient_vlc);
145
    assert(w->j_orient_vlc->table);
146

    
147
    return get_vlc2(&s->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD);
148
}
149

    
150
#define extra_bits(eb) (eb)
151
#define extra_run   (0xFF<<8)
152
#define extra_level (0x00<<8)
153
#define   run_offset(r)    ((r)<<16)
154
#define level_offset(l)    ((l)<<24)
155
static const uint32_t ac_decode_table[]={
156
    /*46*/ extra_bits(3) |  extra_run  | run_offset(16) | level_offset( 0),
157
    /*47*/ extra_bits(3) |  extra_run  | run_offset(24) | level_offset( 0),
158
    /*48*/ extra_bits(2) |  extra_run  | run_offset( 4) | level_offset( 1),
159
    /*49*/ extra_bits(3) |  extra_run  | run_offset( 8) | level_offset( 1),
160

    
161
    /*50*/ extra_bits(5) |  extra_run  | run_offset(32) | level_offset( 0),
162
    /*51*/ extra_bits(4) |  extra_run  | run_offset(16) | level_offset( 1),
163

    
164
    /*52*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
165
    /*53*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 8),
166
    /*54*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset(12),
167
    /*55*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(16),
168
    /*56*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(24),
169

    
170
    /*57*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
171
    /*58*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),
172

    
173
    /*59*/ extra_bits(2) |  extra_run  | run_offset(16) | level_offset( 0),
174
    /*60*/ extra_bits(2) |  extra_run  | run_offset(20) | level_offset( 0),
175
    /*61*/ extra_bits(2) |  extra_run  | run_offset(24) | level_offset( 0),
176
    /*62*/ extra_bits(2) |  extra_run  | run_offset(28) | level_offset( 0),
177
    /*63*/ extra_bits(4) |  extra_run  | run_offset(32) | level_offset( 0),
178
    /*64*/ extra_bits(4) |  extra_run  | run_offset(48) | level_offset( 0),
179

    
180
    /*65*/ extra_bits(2) |  extra_run  | run_offset( 4) | level_offset( 1),
181
    /*66*/ extra_bits(3) |  extra_run  | run_offset( 8) | level_offset( 1),
182
    /*67*/ extra_bits(4) |  extra_run  | run_offset(16) | level_offset( 1),
183

    
184
    /*68*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
185
    /*69*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset( 8),
186
    /*70*/ extra_bits(4) | extra_level | run_offset( 0) | level_offset(16),
187

    
188
    /*71*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
189
    /*72*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),
190
};
191
//extra_bits = 3bits; extra_run/level = 1 bit; run_offset = 6bits; level_offset = 5 bits;
192
#undef extra_bits
193
#undef extra_run
194
#undef extra_level
195
#undef run_offset
196
#undef level_offset
197

    
198
static void x8_get_ac_rlf(IntraX8Context * const w, const int mode,
199
                     int * const run, int * const level, int * const final){
200
    MpegEncContext *  const s= w->s;
201
    int i,e;
202

    
203
//    x8_select_ac_table(w,mode);
204
    i = get_vlc2(&s->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD);
205

    
206
    if(i<46){ //[0-45]
207
        int t,l;
208
        if(i<0){
209
            (*level)=(*final)=//prevent 'may be used unilitialized'
210
            (*run)=64;//this would cause error exit in the ac loop
211
            return;
212
        }
213

    
214
        (*final) = t = (i>22);
215
        i-=23*t;
216
/*
217
  i== 0-15 r=0-15 l=0 ;r=i& %01111
218
  i==16-19 r=0-3  l=1 ;r=i& %00011
219
  i==20-21 r=0-1  l=2 ;r=i& %00001
220
  i==22    r=0    l=3 ;r=i& %00000
221
l=lut_l[i/2]={0,0,0,0,0,0,0,0,1,1,2,3}[i>>1];// 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000
222
t=lut_mask[l]={0x0f,0x03,0x01,0x00}[l]; as i<256 the higher bits do not matter */
223
        l=(0xE50000>>(i&(0x1E)))&3;/*0x1E or (~1) or ((i>>1)<<1)*/
224
        t=(0x01030F>>(l<<3));
225

    
226
        (*run)   = i&t;
227
        (*level) = l;
228
    }else if(i<73){//[46-72]
229
        uint32_t sm;
230
        uint32_t mask;
231

    
232
        i-=46;
233
        sm=ac_decode_table[i];
234

    
235
        e=get_bits(&s->gb,sm&0xF);sm>>=8;//3bits
236
        mask=sm&0xff;sm>>=8;             //1bit
237

    
238
        (*run)  =(sm&0xff) + (e&( mask));//6bits
239
        (*level)=(sm>>8)   + (e&(~mask));//5bits
240
        (*final)=i>(58-46);
241
    }else if(i<75){//[73-74]
242
        static const uint8_t crazy_mix_runlevel[32]={
243
        0x22,0x32,0x33,0x53,0x23,0x42,0x43,0x63,
244
        0x24,0x52,0x34,0x73,0x25,0x62,0x44,0x83,
245
        0x26,0x72,0x35,0x54,0x27,0x82,0x45,0x64,
246
        0x28,0x92,0x36,0x74,0x29,0xa2,0x46,0x84};
247

    
248
        (*final)=!(i&1);
249
        e=get_bits(&s->gb,5);//get the extra bits
250
        (*run)  =crazy_mix_runlevel[e]>>4;
251
        (*level)=crazy_mix_runlevel[e]&0x0F;
252
    }else{
253
        (*level)=get_bits( &s->gb, 7-3*(i&1));
254
        (*run)  =get_bits( &s->gb, 6);
255
        (*final)=get_bits1(&s->gb);
256
    }
257
    return;
258
}
259

    
260
//static const uint8_t dc_extra_sbits[]   ={0, 1,1, 1,1, 2,2, 3,3,   4,4,   5,5,   6,6,    7,7    };
261
static const uint8_t dc_index_offset[]  ={ 0, 1,2, 3,4, 5,7, 9,13, 17,25, 33,49, 65,97, 129,193};
262

    
263
static int x8_get_dc_rlf(IntraX8Context * const w,int const mode, int * const level, int * const final){
264
    MpegEncContext * const s= w->s;
265
    int i,e,c;
266

    
267
    assert(mode<3);
268
    if( !w->j_dc_vlc[mode] ) {
269
        int table_index;
270
        table_index = get_bits(&s->gb, 3);
271
        //4 modes, same table
272
        w->j_dc_vlc[mode]= &j_dc_vlc[w->quant<13][table_index];
273
    }
274
    assert(w->j_dc_vlc);
275
    assert(w->j_dc_vlc[mode]->table);
276

    
277
    i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD);
278

    
279
    /*(i>=17) {i-=17;final=1;}*/
280
    c= i>16;
281
    (*final)=c;
282
    i-=17*c;
283

    
284
    if(i<=0){
285
        (*level)=0;
286
        return -i;
287
    }
288
    c=(i+1)>>1;//hackish way to calculate dc_extra_sbits[]
289
    c-=c>1;
290

    
291
    e=get_bits(&s->gb,c);//get the extra bits
292
    i=dc_index_offset[i]+(e>>1);
293

    
294
    e= -(e & 1);//0,0xffffff
295
    (*level)= (i ^ e) - e;// (i^0)-0 , (i^0xff)-(-1)
296
    return 0;
297
}
298
//end of huffman
299

    
300
static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma){
301
    MpegEncContext * const s= w->s;
302
    int range;
303
    int sum;
304
    int quant;
305

    
306
    s->dsp.x8_setup_spatial_compensation(s->dest[chroma], s->edge_emu_buffer,
307
                                          s->current_picture.linesize[chroma>0],
308
                                          &range, &sum, w->edges);
309
    if(chroma){
310
        w->orient=w->chroma_orient;
311
        quant=w->quant_dc_chroma;
312
    }else{
313
        quant=w->quant;
314
    }
315

    
316
    w->flat_dc=0;
317
    if(range < quant || range < 3){
318
        w->orient=0;
319
        if(range < 3){//yep you read right, a +-1 idct error may break decoding!
320
            w->flat_dc=1;
321
            sum+=9;
322
            w->predicted_dc = (sum*6899)>>17;//((1<<17)+9)/(8+8+1+2)=6899
323
        }
324
    }
325
    if(chroma)
326
        return 0;
327

    
328
    assert(w->orient < 3);
329
    if(range < 2*w->quant){
330
        if( (w->edges&3) == 0){
331
            if(w->orient==1) w->orient=11;
332
            if(w->orient==2) w->orient=10;
333
        }else{
334
            w->orient=0;
335
        }
336
        w->raw_orient=0;
337
    }else{
338
        static const uint8_t prediction_table[3][12]={
339
            {0,8,4, 10,11, 2,6,9,1,3,5,7},
340
            {4,0,8, 11,10, 3,5,2,6,9,1,7},
341
            {8,0,4, 10,11, 1,7,2,6,9,3,5}
342
        };
343
        w->raw_orient=x8_get_orient_vlc(w);
344
        if(w->raw_orient<0) return -1;
345
        assert(w->raw_orient < 12 );
346
        assert(w->orient<3);
347
        w->orient=prediction_table[w->orient][w->raw_orient];
348
    }
349
    return 0;
350
}
351

    
352
static void x8_update_predictions(IntraX8Context * const w, const int orient, const int est_run ){
353
    MpegEncContext * const s= w->s;
354

    
355
    w->prediction_table[s->mb_x*2+(s->mb_y&1)] = (est_run<<2) + 1*(orient==4) + 2*(orient==8);
356
/*
357
  y=2n+0 ->//0 2 4
358
  y=2n+1 ->//1 3 5
359
*/
360
}
361
static void x8_get_prediction_chroma(IntraX8Context * const w){
362
    MpegEncContext * const s= w->s;
363

    
364
    w->edges = 1*( !(s->mb_x>>1) );
365
    w->edges|= 2*( !(s->mb_y>>1) );
366
    w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );//mb_x for chroma would always be odd
367

    
368
    w->raw_orient=0;
369
    if(w->edges&3){//lut_co[8]={inv,4,8,8, inv,4,8,8}<- =>{1,1,0,0;1,1,0,0} => 0xCC
370
        w->chroma_orient=4<<((0xCC>>w->edges)&1);
371
        return;
372
    }
373
    w->chroma_orient = (w->prediction_table[2*s->mb_x-2] & 0x03)<<2;//block[x-1][y|1-1)]
374
}
375

    
376
static void x8_get_prediction(IntraX8Context * const w){
377
    MpegEncContext * const s= w->s;
378
    int a,b,c,i;
379

    
380
    w->edges = 1*( !s->mb_x );
381
    w->edges|= 2*( !s->mb_y );
382
    w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );
383

    
384
    switch(w->edges&3){
385
        case 0:
386
            break;
387
        case 1:
388
            //take the one from the above block[0][y-1]
389
            w->est_run = w->prediction_table[!(s->mb_y&1)]>>2;
390
            w->orient  = 1;
391
            return;
392
        case 2:
393
            //take the one from the previous block[x-1][0]
394
            w->est_run = w->prediction_table[2*s->mb_x-2]>>2;
395
            w->orient  = 2;
396
            return;
397
        case 3:
398
            w->est_run = 16;
399
            w->orient  = 0;
400
            return;
401
    }
402
    //no edge cases
403
    b= w->prediction_table[2*s->mb_x   + !(s->mb_y&1) ];//block[x  ][y-1]
404
    a= w->prediction_table[2*s->mb_x-2 +  (s->mb_y&1) ];//block[x-1][y  ]
405
    c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];//block[x-1][y-1]
406

    
407
    w->est_run = FFMIN(b,a);
408
    /* This condition has nothing to do with w->edges, even if it looks
409
       similar it would trigger if e.g. x=3;y=2;
410
       I guess somebody wrote something wrong and it became standard. */
411
    if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run);
412
    w->est_run>>=2;
413

    
414
    a&=3;
415
    b&=3;
416
    c&=3;
417

    
418
    i=( 0xFFEAF4C4>>(2*b+8*a) )&3;
419
    if(i!=3) w->orient=i;
420
    else     w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3;
421
/*
422
lut1[b][a]={
423
->{0, 1, 0, pad},
424
  {0, 1, X, pad},
425
  {2, 2, 2, pad}}
426
   pad 2   2  2; pad X  1  0; pad 0  1  0 <-
427
-> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4
428

429
lut2[q>12][c]={
430
  ->{0,2,1,pad},
431
    {2,2,2,pad}}
432
   pad 2  2  2; pad 1  2  0 <-
433
-> 11 10'10 10 '11 01'10 00=>0xEAD8
434
*/
435
}
436

    
437

    
438
static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){
439
    MpegEncContext * const s= w->s;
440
    int t;
441
#define B(x,y)  s->block[0][s->dsp.idct_permutation[(x)+(y)*8]]
442
#define T(x)  ((x) * dc_level + 0x8000) >> 16;
443
    switch(direction){
444
    case 0:
445
        t = T(3811);//h
446
        B(1,0) -= t;
447
        B(0,1) -= t;
448

    
449
        t = T(487);//e
450
        B(2,0) -= t;
451
        B(0,2) -= t;
452

    
453
        t = T(506);//f
454
        B(3,0) -= t;
455
        B(0,3) -= t;
456

    
457
        t = T(135);//c
458
        B(4,0) -= t;
459
        B(0,4) -= t;
460
        B(2,1) += t;
461
        B(1,2) += t;
462
        B(3,1) += t;
463
        B(1,3) += t;
464

    
465
        t = T(173);//d
466
        B(5,0) -= t;
467
        B(0,5) -= t;
468

    
469
        t = T(61);//b
470
        B(6,0) -= t;
471
        B(0,6) -= t;
472
        B(5,1) += t;
473
        B(1,5) += t;
474

    
475
        t = T(42); //a
476
        B(7,0) -= t;
477
        B(0,7) -= t;
478
        B(4,1) += t;
479
        B(1,4) += t;
480
        B(4,4) += t;
481

    
482
        t = T(1084);//g
483
        B(1,1) += t;
484

    
485
        s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
486
        break;
487
    case 1:
488
        B(0,1) -= T(6269);
489
        B(0,3) -= T( 708);
490
        B(0,5) -= T( 172);
491
        B(0,7) -= T(  73);
492

    
493
        s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
494
        break;
495
    case 2:
496
        B(1,0) -= T(6269);
497
        B(3,0) -= T( 708);
498
        B(5,0) -= T( 172);
499
        B(7,0) -= T(  73);
500

    
501
        s->block_last_index[0] = FFMAX(s->block_last_index[0], 7);
502
        break;
503
    }
504
#undef B
505
#undef T
506
}
507

    
508
static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){
509
    int k;
510
    for(k=0;k<8;k++){
511
        memset(dst,pix,8);
512
        dst+=linesize;
513
    }
514
}
515

    
516
static const int16_t quant_table[64] = {
517
    256, 256, 256, 256,  256, 256, 259, 262,
518
    265, 269, 272, 275,  278, 282, 285, 288,
519
    292, 295, 299, 303,  306, 310, 314, 317,
520
    321, 325, 329, 333,  337, 341, 345, 349,
521
    353, 358, 362, 366,  371, 375, 379, 384,
522
    389, 393, 398, 403,  408, 413, 417, 422,
523
    428, 433, 438, 443,  448, 454, 459, 465,
524
    470, 476, 482, 488,  493, 499, 505, 511
525
};
526

    
527
static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){
528
    MpegEncContext * const s= w->s;
529

    
530
    uint8_t * scantable;
531
    int final,run,level;
532
    int ac_mode,dc_mode,est_run,dc_level;
533
    int pos,n;
534
    int zeros_only;
535
    int use_quant_matrix;
536
    int sign;
537

    
538
    assert(w->orient<12);
539
    s->dsp.clear_block(s->block[0]);
540

    
541
    if(chroma){
542
        dc_mode=2;
543
    }else{
544
        dc_mode=!!w->est_run;//0,1
545
    }
546

    
547
    if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1;
548
    n=0;
549
    zeros_only=0;
550
    if(!final){//decode ac
551
        use_quant_matrix=w->use_quant_matrix;
552
        if(chroma){
553
            ac_mode = 1;
554
            est_run = 64;//not used
555
        }else{
556
            if (w->raw_orient < 3){
557
                use_quant_matrix = 0;
558
            }
559
            if(w->raw_orient > 4){
560
                ac_mode = 0;
561
                est_run = 64;
562
            }else{
563
                if(w->est_run > 1){
564
                    ac_mode = 2;
565
                    est_run=w->est_run;
566
                }else{
567
                    ac_mode = 3;
568
                    est_run = 64;
569
                }
570
            }
571
        }
572
        x8_select_ac_table(w,ac_mode);
573
        /*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<-
574
        -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */
575
        scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated;
576
        pos=0;
577
        do {
578
            n++;
579
            if( n >= est_run ){
580
                ac_mode=3;
581
                x8_select_ac_table(w,3);
582
            }
583

    
584
            x8_get_ac_rlf(w,ac_mode,&run,&level,&final);
585

    
586
            pos+=run+1;
587
            if(pos>63){
588
                //this also handles vlc error in x8_get_ac_rlf
589
                return -1;
590
            }
591
            level= (level+1) * w->dquant;
592
            level+= w->qsum;
593

    
594
            sign = - get_bits1(&s->gb);
595
            level = (level ^ sign) - sign;
596

    
597
            if(use_quant_matrix){
598
                level = (level*quant_table[pos])>>8;
599
            }
600
            s->block[0][ scantable[pos] ]=level;
601
        }while(!final);
602

    
603
        s->block_last_index[0]=pos;
604
    }else{//DC only
605
        s->block_last_index[0]=0;
606
        if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1]
607
            int32_t divide_quant= !chroma ? w->divide_quant_dc_luma:
608
                                            w->divide_quant_dc_chroma;
609
            int32_t dc_quant    = !chroma ? w->quant:
610
                                            w->quant_dc_chroma;
611

    
612
            //original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding
613
            dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13;
614

    
615
            dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3),
616
                                   s->dest[chroma], s->current_picture.linesize[!!chroma]);
617

    
618
            goto block_placed;
619
        }
620
        zeros_only = (dc_level == 0);
621
    }
622
    if(!chroma){
623
        s->block[0][0] = dc_level*w->quant;
624
    }else{
625
        s->block[0][0] = dc_level*w->quant_dc_chroma;
626
    }
627

    
628
    //there is !zero_only check in the original, but dc_level check is enough
629
    if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){
630
        int direction;
631
        /*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<-
632
        -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */
633
        direction= (0x6A017C>>(w->orient*2))&3;
634
        if (direction != 3){
635
            x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[]
636
        }
637
    }
638

    
639
    if(w->flat_dc){
640
        dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.linesize[!!chroma]);
641
    }else{
642
        s->dsp.x8_spatial_compensation[w->orient]( s->edge_emu_buffer,
643
                                            s->dest[chroma],
644
                                            s->current_picture.linesize[!!chroma] );
645
    }
646
    if(!zeros_only)
647
        s->dsp.idct_add ( s->dest[chroma],
648
                          s->current_picture.linesize[!!chroma],
649
                          s->block[0] );
650

    
651
block_placed:
652

    
653
    if(!chroma){
654
        x8_update_predictions(w,w->orient,n);
655
    }
656

    
657
    if(s->loop_filter){
658
        uint8_t* ptr = s->dest[chroma];
659
        int linesize = s->current_picture.linesize[!!chroma];
660

    
661
        if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){
662
            s->dsp.x8_h_loop_filter(ptr, linesize, w->quant);
663
        }
664
        if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){
665
            s->dsp.x8_v_loop_filter(ptr, linesize, w->quant);
666
        }
667
    }
668
    return 0;
669
}
670

    
671
static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_*
672
//not s->linesize as this would be wrong for field pics
673
//not that IntraX8 has interlacing support ;)
674
    const int linesize  = s->current_picture.linesize[0];
675
    const int uvlinesize= s->current_picture.linesize[1];
676

    
677
    s->dest[0] = s->current_picture.data[0];
678
    s->dest[1] = s->current_picture.data[1];
679
    s->dest[2] = s->current_picture.data[2];
680

    
681
    s->dest[0] +=   s->mb_y        *   linesize << 3;
682
    s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows
683
    s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2;
684
}
685

    
686
/**
687
 * Initialize IntraX8 frame decoder.
688
 * Requires valid MpegEncContext with valid s->mb_width before calling.
689
 * @param w pointer to IntraX8Context
690
 * @param s pointer to MpegEncContext of the parent codec
691
 */
692
av_cold void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s){
693

    
694
    w->s=s;
695
    x8_vlc_init();
696
    assert(s->mb_width>0);
697
    w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb
698

    
699
    ff_init_scantable(s->dsp.idct_permutation, &w->scantable[0], wmv1_scantable[0]);
700
    ff_init_scantable(s->dsp.idct_permutation, &w->scantable[1], wmv1_scantable[2]);
701
    ff_init_scantable(s->dsp.idct_permutation, &w->scantable[2], wmv1_scantable[3]);
702
}
703

    
704
/**
705
 * Destroy IntraX8 frame structure.
706
 * @param w pointer to IntraX8Context
707
 */
708
av_cold void ff_intrax8_common_end(IntraX8Context * w)
709
{
710
    av_freep(&w->prediction_table);
711
}
712

    
713
/**
714
 * Decode single IntraX8 frame.
715
 * The parent codec must fill s->loopfilter and s->gb (bitstream).
716
 * The parent codec must call MPV_frame_start(), ff_er_frame_start() before calling this function.
717
 * The parent codec must call ff_er_frame_end(), MPV_frame_end() after calling this function.
718
 * This function does not use MPV_decode_mb().
719
 * lowres decoding is theoretically impossible.
720
 * @param w pointer to IntraX8Context
721
 * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1.
722
 * @param quant_offset offset away from zero
723
 */
724
//FIXME extern uint8_t wmv3_dc_scale_table[32];
725
int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){
726
    MpegEncContext * const s= w->s;
727
    int mb_xy;
728
    assert(s);
729
    w->use_quant_matrix = get_bits1(&s->gb);
730

    
731
    w->dquant = dquant;
732
    w->quant  = dquant >> 1;
733
    w->qsum   = quant_offset;
734

    
735
    w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant;
736
    if(w->quant < 5){
737
        w->quant_dc_chroma =  w->quant;
738
        w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
739
    }else{
740
        w->quant_dc_chroma =  w->quant+((w->quant+3)>>3);
741
        w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma;
742
    }
743
    x8_reset_vlc_tables(w);
744

    
745
    s->resync_mb_x=0;
746
    s->resync_mb_y=0;
747

    
748
    for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){
749
        x8_init_block_index(s);
750
        mb_xy=(s->mb_y>>1)*s->mb_stride;
751

    
752
        for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){
753
            x8_get_prediction(w);
754
            if(x8_setup_spatial_predictor(w,0)) goto error;
755
            if(x8_decode_intra_mb(w,0)) goto error;
756

    
757
            if( s->mb_x & s->mb_y & 1 ){
758
                x8_get_prediction_chroma(w);
759

    
760
                /*when setting up chroma, no vlc is read,
761
                so no error condition can be reached*/
762
                x8_setup_spatial_predictor(w,1);
763
                if(x8_decode_intra_mb(w,1)) goto error;
764

    
765
                x8_setup_spatial_predictor(w,2);
766
                if(x8_decode_intra_mb(w,2)) goto error;
767

    
768
                s->dest[1]+= 8;
769
                s->dest[2]+= 8;
770

    
771
                /*emulate MB info in the relevant tables*/
772
                s->mbskip_table [mb_xy]=0;
773
                s->mbintra_table[mb_xy]=1;
774
                s->current_picture.qscale_table[mb_xy]=w->quant;
775
                mb_xy++;
776
            }
777
            s->dest[0]+= 8;
778
        }
779
        if(s->mb_y&1){
780
            ff_draw_horiz_band(s, (s->mb_y-1)*8, 16);
781
        }
782
    }
783

    
784
error:
785
    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
786
                        (s->mb_x>>1)-1, (s->mb_y>>1)-1,
787
                        (AC_END|DC_END|MV_END) );
788
    return 0;
789
}