1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg 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 * FFmpeg 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 FFmpeg; 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
41static VLC j_ac_vlc[2][2][8];  //[quant<13],[intra/inter],[select]
42static VLC j_dc_vlc[2][8];     //[quant], [select]
43static VLC j_orient_vlc[2][4]; //[quant], [select]
44
45static 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
117static 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
123static 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
136static 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)
155static 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
198static 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
221l=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
222t=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    };
261static const uint8_t dc_index_offset[]  ={ 0, 1,2, 3,4, 5,7, 9,13, 17,25, 33,49, 65,97, 129,193};
262
263static 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
300static 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
352static 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}
361static 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
376static 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/*
422lut1[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
429lut2[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
438static 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
508static 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
516static 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
527static 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
651block_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
671static 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 */
692av_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 */
708av_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];
725int 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
784error:
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}
790