intrax8: asserts cleanup
[ffmpeg.git] / libavcodec / intrax8.c
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 "libavutil/avassert.h"
25 #include "avcodec.h"
26 #include "get_bits.h"
27 #include "mpegvideo.h"
28 #include "msmpeg4data.h"
29 #include "intrax8huf.h"
30 #include "intrax8.h"
31
32 #define MAX_TABLE_DEPTH(table_bits, max_bits) ((max_bits+table_bits-1)/table_bits)
33
34 #define DC_VLC_BITS 9
35 #define AC_VLC_BITS 9
36 #define OR_VLC_BITS 7
37
38 #define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS)
39 #define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
40 #define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS)
41
42 static VLC j_ac_vlc[2][2][8];  //[quant<13],[intra/inter],[select]
43 static VLC j_dc_vlc[2][8];     //[quant], [select]
44 static VLC j_orient_vlc[2][4]; //[quant], [select]
45
46 static av_cold void x8_vlc_init(void){
47     int i;
48     int offset = 0;
49     int sizeidx = 0;
50     static const uint16_t sizes[8*4 + 8*2 + 2 + 4] = {
51         576, 548, 582, 618, 546, 616, 560, 642,
52         584, 582, 704, 664, 512, 544, 656, 640,
53         512, 648, 582, 566, 532, 614, 596, 648,
54         586, 552, 584, 590, 544, 578, 584, 624,
55
56         528, 528, 526, 528, 536, 528, 526, 544,
57         544, 512, 512, 528, 528, 544, 512, 544,
58
59         128, 128, 128, 128, 128, 128};
60
61     static VLC_TYPE table[28150][2];
62
63 #define  init_ac_vlc(dst,src) \
64     dst.table = &table[offset]; \
65     dst.table_allocated = sizes[sizeidx]; \
66     offset += sizes[sizeidx++]; \
67        init_vlc(&dst, \
68               AC_VLC_BITS,77, \
69               &src[1],4,2, \
70               &src[0],4,2, \
71               INIT_VLC_USE_NEW_STATIC)
72 //set ac tables
73     for(i=0;i<8;i++){
74         init_ac_vlc( j_ac_vlc[0][0][i], x8_ac0_highquant_table[i][0] );
75         init_ac_vlc( j_ac_vlc[0][1][i], x8_ac1_highquant_table[i][0] );
76         init_ac_vlc( j_ac_vlc[1][0][i], x8_ac0_lowquant_table [i][0] );
77         init_ac_vlc( j_ac_vlc[1][1][i], x8_ac1_lowquant_table [i][0] );
78     }
79 #undef init_ac_vlc
80
81 //set dc tables
82 #define init_dc_vlc(dst,src) \
83     dst.table = &table[offset]; \
84     dst.table_allocated = sizes[sizeidx]; \
85     offset += sizes[sizeidx++]; \
86         init_vlc(&dst, \
87         DC_VLC_BITS,34, \
88         &src[1],4,2, \
89         &src[0],4,2, \
90         INIT_VLC_USE_NEW_STATIC);
91     for(i=0;i<8;i++){
92         init_dc_vlc( j_dc_vlc[0][i], x8_dc_highquant_table[i][0]);
93         init_dc_vlc( j_dc_vlc[1][i], x8_dc_lowquant_table [i][0]);
94     }
95 #undef init_dc_vlc
96
97 //set orient tables
98 #define init_or_vlc(dst,src) \
99     dst.table = &table[offset]; \
100     dst.table_allocated = sizes[sizeidx]; \
101     offset += sizes[sizeidx++]; \
102     init_vlc(&dst, \
103     OR_VLC_BITS,12, \
104     &src[1],4,2, \
105     &src[0],4,2, \
106     INIT_VLC_USE_NEW_STATIC);
107     for(i=0;i<2;i++){
108         init_or_vlc( j_orient_vlc[0][i], x8_orient_highquant_table[i][0]);
109     }
110     for(i=0;i<4;i++){
111         init_or_vlc( j_orient_vlc[1][i], x8_orient_lowquant_table [i][0])
112     }
113     if (offset != sizeof(table)/sizeof(VLC_TYPE)/2)
114         av_log(NULL, AV_LOG_ERROR, "table size %i does not match needed %i\n", (int)(sizeof(table)/sizeof(VLC_TYPE)/2), offset);
115 }
116 #undef init_or_vlc
117
118 static void x8_reset_vlc_tables(IntraX8Context * w){
119     memset(w->j_dc_vlc,0,sizeof(w->j_dc_vlc));
120     memset(w->j_ac_vlc,0,sizeof(w->j_ac_vlc));
121     w->j_orient_vlc=NULL;
122 }
123
124 static inline void x8_select_ac_table(IntraX8Context * const w , int mode){
125     MpegEncContext * const s= w->s;
126     int table_index;
127
128     av_assert2(mode<4);
129
130     if( w->j_ac_vlc[mode] ) return;
131
132     table_index = get_bits(&s->gb, 3);
133     w->j_ac_vlc[mode] = &j_ac_vlc[w->quant<13][mode>>1][table_index];//2 modes use same tables
134     av_assert2(w->j_ac_vlc[mode]);
135 }
136
137 static inline int x8_get_orient_vlc(IntraX8Context * w){
138     MpegEncContext * const s= w->s;
139     int table_index;
140
141     if(!w->j_orient_vlc ){
142         table_index = get_bits(&s->gb, 1+(w->quant<13) );
143         w->j_orient_vlc = &j_orient_vlc[w->quant<13][table_index];
144     }
145
146     return get_vlc2(&s->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD);
147 }
148
149 #define extra_bits(eb) (eb)
150 #define extra_run   (0xFF<<8)
151 #define extra_level (0x00<<8)
152 #define   run_offset(r)    ((r)<<16)
153 #define level_offset(l)    ((l)<<24)
154 static const uint32_t ac_decode_table[]={
155     /*46*/ extra_bits(3) |  extra_run  | run_offset(16) | level_offset( 0),
156     /*47*/ extra_bits(3) |  extra_run  | run_offset(24) | level_offset( 0),
157     /*48*/ extra_bits(2) |  extra_run  | run_offset( 4) | level_offset( 1),
158     /*49*/ extra_bits(3) |  extra_run  | run_offset( 8) | level_offset( 1),
159
160     /*50*/ extra_bits(5) |  extra_run  | run_offset(32) | level_offset( 0),
161     /*51*/ extra_bits(4) |  extra_run  | run_offset(16) | level_offset( 1),
162
163     /*52*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
164     /*53*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 8),
165     /*54*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset(12),
166     /*55*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(16),
167     /*56*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(24),
168
169     /*57*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
170     /*58*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),
171
172     /*59*/ extra_bits(2) |  extra_run  | run_offset(16) | level_offset( 0),
173     /*60*/ extra_bits(2) |  extra_run  | run_offset(20) | level_offset( 0),
174     /*61*/ extra_bits(2) |  extra_run  | run_offset(24) | level_offset( 0),
175     /*62*/ extra_bits(2) |  extra_run  | run_offset(28) | level_offset( 0),
176     /*63*/ extra_bits(4) |  extra_run  | run_offset(32) | level_offset( 0),
177     /*64*/ extra_bits(4) |  extra_run  | run_offset(48) | level_offset( 0),
178
179     /*65*/ extra_bits(2) |  extra_run  | run_offset( 4) | level_offset( 1),
180     /*66*/ extra_bits(3) |  extra_run  | run_offset( 8) | level_offset( 1),
181     /*67*/ extra_bits(4) |  extra_run  | run_offset(16) | level_offset( 1),
182
183     /*68*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
184     /*69*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset( 8),
185     /*70*/ extra_bits(4) | extra_level | run_offset( 0) | level_offset(16),
186
187     /*71*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
188     /*72*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),
189 };
190 //extra_bits = 3bits; extra_run/level = 1 bit; run_offset = 6bits; level_offset = 5 bits;
191 #undef extra_bits
192 #undef extra_run
193 #undef extra_level
194 #undef run_offset
195 #undef level_offset
196
197 static void x8_get_ac_rlf(IntraX8Context * const w, const int mode,
198                      int * const run, int * const level, int * const final){
199     MpegEncContext *  const s= w->s;
200     int i,e;
201
202 //    x8_select_ac_table(w,mode);
203     i = get_vlc2(&s->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD);
204
205     if(i<46){ //[0-45]
206         int t,l;
207         if(i<0){
208             (*level)=(*final)=//prevent 'may be used unilitialized'
209             (*run)=64;//this would cause error exit in the ac loop
210             return;
211         }
212
213         (*final) = t = (i>22);
214         i-=23*t;
215 /*
216   i== 0-15 r=0-15 l=0 ;r=i& %01111
217   i==16-19 r=0-3  l=1 ;r=i& %00011
218   i==20-21 r=0-1  l=2 ;r=i& %00001
219   i==22    r=0    l=3 ;r=i& %00000
220 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
221 t=lut_mask[l]={0x0f,0x03,0x01,0x00}[l]; as i<256 the higher bits do not matter */
222         l=(0xE50000>>(i&(0x1E)))&3;/*0x1E or (~1) or ((i>>1)<<1)*/
223         t=(0x01030F>>(l<<3));
224
225         (*run)   = i&t;
226         (*level) = l;
227     }else if(i<73){//[46-72]
228         uint32_t sm;
229         uint32_t mask;
230
231         i-=46;
232         sm=ac_decode_table[i];
233
234         e=get_bits(&s->gb,sm&0xF);sm>>=8;//3bits
235         mask=sm&0xff;sm>>=8;             //1bit
236
237         (*run)  =(sm&0xff) + (e&( mask));//6bits
238         (*level)=(sm>>8)   + (e&(~mask));//5bits
239         (*final)=i>(58-46);
240     }else if(i<75){//[73-74]
241         static const uint8_t crazy_mix_runlevel[32]={
242         0x22,0x32,0x33,0x53,0x23,0x42,0x43,0x63,
243         0x24,0x52,0x34,0x73,0x25,0x62,0x44,0x83,
244         0x26,0x72,0x35,0x54,0x27,0x82,0x45,0x64,
245         0x28,0x92,0x36,0x74,0x29,0xa2,0x46,0x84};
246
247         (*final)=!(i&1);
248         e=get_bits(&s->gb,5);//get the extra bits
249         (*run)  =crazy_mix_runlevel[e]>>4;
250         (*level)=crazy_mix_runlevel[e]&0x0F;
251     }else{
252         (*level)=get_bits( &s->gb, 7-3*(i&1));
253         (*run)  =get_bits( &s->gb, 6);
254         (*final)=get_bits1(&s->gb);
255     }
256     return;
257 }
258
259 //static const uint8_t dc_extra_sbits[]   ={0, 1,1, 1,1, 2,2, 3,3,   4,4,   5,5,   6,6,    7,7    };
260 static const uint8_t dc_index_offset[]  ={ 0, 1,2, 3,4, 5,7, 9,13, 17,25, 33,49, 65,97, 129,193};
261
262 static int x8_get_dc_rlf(IntraX8Context * const w,int const mode, int * const level, int * const final){
263     MpegEncContext * const s= w->s;
264     int i,e,c;
265
266     av_assert2(mode<3);
267     if( !w->j_dc_vlc[mode] ) {
268         int table_index;
269         table_index = get_bits(&s->gb, 3);
270         //4 modes, same table
271         w->j_dc_vlc[mode]= &j_dc_vlc[w->quant<13][table_index];
272     }
273
274     i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD);
275
276     /*(i>=17) {i-=17;final=1;}*/
277     c= i>16;
278     (*final)=c;
279     i-=17*c;
280
281     if(i<=0){
282         (*level)=0;
283         return -i;
284     }
285     c=(i+1)>>1;//hackish way to calculate dc_extra_sbits[]
286     c-=c>1;
287
288     e=get_bits(&s->gb,c);//get the extra bits
289     i=dc_index_offset[i]+(e>>1);
290
291     e= -(e & 1);//0,0xffffff
292     (*level)= (i ^ e) - e;// (i^0)-0 , (i^0xff)-(-1)
293     return 0;
294 }
295 //end of huffman
296
297 static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma){
298     MpegEncContext * const s= w->s;
299     int range;
300     int sum;
301     int quant;
302
303     s->dsp.x8_setup_spatial_compensation(s->dest[chroma], s->edge_emu_buffer,
304                                           s->current_picture.f.linesize[chroma>0],
305                                           &range, &sum, w->edges);
306     if(chroma){
307         w->orient=w->chroma_orient;
308         quant=w->quant_dc_chroma;
309     }else{
310         quant=w->quant;
311     }
312
313     w->flat_dc=0;
314     if(range < quant || range < 3){
315         w->orient=0;
316         if(range < 3){//yep you read right, a +-1 idct error may break decoding!
317             w->flat_dc=1;
318             sum+=9;
319             w->predicted_dc = (sum*6899)>>17;//((1<<17)+9)/(8+8+1+2)=6899
320         }
321     }
322     if(chroma)
323         return 0;
324
325     av_assert2(w->orient < 3);
326     if(range < 2*w->quant){
327         if( (w->edges&3) == 0){
328             if(w->orient==1) w->orient=11;
329             if(w->orient==2) w->orient=10;
330         }else{
331             w->orient=0;
332         }
333         w->raw_orient=0;
334     }else{
335         static const uint8_t prediction_table[3][12]={
336             {0,8,4, 10,11, 2,6,9,1,3,5,7},
337             {4,0,8, 11,10, 3,5,2,6,9,1,7},
338             {8,0,4, 10,11, 1,7,2,6,9,3,5}
339         };
340         w->raw_orient=x8_get_orient_vlc(w);
341         if(w->raw_orient<0) return -1;
342         av_assert2(w->raw_orient < 12 );
343         av_assert2(w->orient<3);
344         w->orient=prediction_table[w->orient][w->raw_orient];
345     }
346     return 0;
347 }
348
349 static void x8_update_predictions(IntraX8Context * const w, const int orient, const int est_run ){
350     MpegEncContext * const s= w->s;
351
352     w->prediction_table[s->mb_x*2+(s->mb_y&1)] = (est_run<<2) + 1*(orient==4) + 2*(orient==8);
353 /*
354   y=2n+0 ->//0 2 4
355   y=2n+1 ->//1 3 5
356 */
357 }
358 static void x8_get_prediction_chroma(IntraX8Context * const w){
359     MpegEncContext * const s= w->s;
360
361     w->edges = 1*( !(s->mb_x>>1) );
362     w->edges|= 2*( !(s->mb_y>>1) );
363     w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );//mb_x for chroma would always be odd
364
365     w->raw_orient=0;
366     if(w->edges&3){//lut_co[8]={inv,4,8,8, inv,4,8,8}<- =>{1,1,0,0;1,1,0,0} => 0xCC
367         w->chroma_orient=4<<((0xCC>>w->edges)&1);
368         return;
369     }
370     w->chroma_orient = (w->prediction_table[2*s->mb_x-2] & 0x03)<<2;//block[x-1][y|1-1)]
371 }
372
373 static void x8_get_prediction(IntraX8Context * const w){
374     MpegEncContext * const s= w->s;
375     int a,b,c,i;
376
377     w->edges = 1*( !s->mb_x );
378     w->edges|= 2*( !s->mb_y );
379     w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );
380
381     switch(w->edges&3){
382         case 0:
383             break;
384         case 1:
385             //take the one from the above block[0][y-1]
386             w->est_run = w->prediction_table[!(s->mb_y&1)]>>2;
387             w->orient  = 1;
388             return;
389         case 2:
390             //take the one from the previous block[x-1][0]
391             w->est_run = w->prediction_table[2*s->mb_x-2]>>2;
392             w->orient  = 2;
393             return;
394         case 3:
395             w->est_run = 16;
396             w->orient  = 0;
397             return;
398     }
399     //no edge cases
400     b= w->prediction_table[2*s->mb_x   + !(s->mb_y&1) ];//block[x  ][y-1]
401     a= w->prediction_table[2*s->mb_x-2 +  (s->mb_y&1) ];//block[x-1][y  ]
402     c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];//block[x-1][y-1]
403
404     w->est_run = FFMIN(b,a);
405     /* This condition has nothing to do with w->edges, even if it looks
406        similar it would trigger if e.g. x=3;y=2;
407        I guess somebody wrote something wrong and it became standard. */
408     if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run);
409     w->est_run>>=2;
410
411     a&=3;
412     b&=3;
413     c&=3;
414
415     i=( 0xFFEAF4C4>>(2*b+8*a) )&3;
416     if(i!=3) w->orient=i;
417     else     w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3;
418 /*
419 lut1[b][a]={
420 ->{0, 1, 0, pad},
421   {0, 1, X, pad},
422   {2, 2, 2, pad}}
423    pad 2   2  2; pad X  1  0; pad 0  1  0 <-
424 -> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4
425
426 lut2[q>12][c]={
427   ->{0,2,1,pad},
428     {2,2,2,pad}}
429    pad 2  2  2; pad 1  2  0 <-
430 -> 11 10'10 10 '11 01'10 00=>0xEAD8
431 */
432 }
433
434
435 static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){
436     MpegEncContext * const s= w->s;
437     int t;
438 #define B(x,y)  s->block[0][s->dsp.idct_permutation[(x)+(y)*8]]
439 #define T(x)  ((x) * dc_level + 0x8000) >> 16;
440     switch(direction){
441     case 0:
442         t = T(3811);//h
443         B(1,0) -= t;
444         B(0,1) -= t;
445
446         t = T(487);//e
447         B(2,0) -= t;
448         B(0,2) -= t;
449
450         t = T(506);//f
451         B(3,0) -= t;
452         B(0,3) -= t;
453
454         t = T(135);//c
455         B(4,0) -= t;
456         B(0,4) -= t;
457         B(2,1) += t;
458         B(1,2) += t;
459         B(3,1) += t;
460         B(1,3) += t;
461
462         t = T(173);//d
463         B(5,0) -= t;
464         B(0,5) -= t;
465
466         t = T(61);//b
467         B(6,0) -= t;
468         B(0,6) -= t;
469         B(5,1) += t;
470         B(1,5) += t;
471
472         t = T(42); //a
473         B(7,0) -= t;
474         B(0,7) -= t;
475         B(4,1) += t;
476         B(1,4) += t;
477         B(4,4) += t;
478
479         t = T(1084);//g
480         B(1,1) += t;
481
482         s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
483         break;
484     case 1:
485         B(0,1) -= T(6269);
486         B(0,3) -= T( 708);
487         B(0,5) -= T( 172);
488         B(0,7) -= T(  73);
489
490         s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
491         break;
492     case 2:
493         B(1,0) -= T(6269);
494         B(3,0) -= T( 708);
495         B(5,0) -= T( 172);
496         B(7,0) -= T(  73);
497
498         s->block_last_index[0] = FFMAX(s->block_last_index[0], 7);
499         break;
500     }
501 #undef B
502 #undef T
503 }
504
505 static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){
506     int k;
507     for(k=0;k<8;k++){
508         memset(dst,pix,8);
509         dst+=linesize;
510     }
511 }
512
513 static const int16_t quant_table[64] = {
514     256, 256, 256, 256,  256, 256, 259, 262,
515     265, 269, 272, 275,  278, 282, 285, 288,
516     292, 295, 299, 303,  306, 310, 314, 317,
517     321, 325, 329, 333,  337, 341, 345, 349,
518     353, 358, 362, 366,  371, 375, 379, 384,
519     389, 393, 398, 403,  408, 413, 417, 422,
520     428, 433, 438, 443,  448, 454, 459, 465,
521     470, 476, 482, 488,  493, 499, 505, 511
522 };
523
524 static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){
525     MpegEncContext * const s= w->s;
526
527     uint8_t * scantable;
528     int final,run,level;
529     int ac_mode,dc_mode,est_run,dc_level;
530     int pos,n;
531     int zeros_only;
532     int use_quant_matrix;
533     int sign;
534
535     av_assert2(w->orient<12);
536     s->dsp.clear_block(s->block[0]);
537
538     if(chroma){
539         dc_mode=2;
540     }else{
541         dc_mode=!!w->est_run;//0,1
542     }
543
544     if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1;
545     n=0;
546     zeros_only=0;
547     if(!final){//decode ac
548         use_quant_matrix=w->use_quant_matrix;
549         if(chroma){
550             ac_mode = 1;
551             est_run = 64;//not used
552         }else{
553             if (w->raw_orient < 3){
554                 use_quant_matrix = 0;
555             }
556             if(w->raw_orient > 4){
557                 ac_mode = 0;
558                 est_run = 64;
559             }else{
560                 if(w->est_run > 1){
561                     ac_mode = 2;
562                     est_run=w->est_run;
563                 }else{
564                     ac_mode = 3;
565                     est_run = 64;
566                 }
567             }
568         }
569         x8_select_ac_table(w,ac_mode);
570         /*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<-
571         -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */
572         scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated;
573         pos=0;
574         do {
575             n++;
576             if( n >= est_run ){
577                 ac_mode=3;
578                 x8_select_ac_table(w,3);
579             }
580
581             x8_get_ac_rlf(w,ac_mode,&run,&level,&final);
582
583             pos+=run+1;
584             if(pos>63){
585                 //this also handles vlc error in x8_get_ac_rlf
586                 return -1;
587             }
588             level= (level+1) * w->dquant;
589             level+= w->qsum;
590
591             sign = - get_bits1(&s->gb);
592             level = (level ^ sign) - sign;
593
594             if(use_quant_matrix){
595                 level = (level*quant_table[pos])>>8;
596             }
597             s->block[0][ scantable[pos] ]=level;
598         }while(!final);
599
600         s->block_last_index[0]=pos;
601     }else{//DC only
602         s->block_last_index[0]=0;
603         if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1]
604             int32_t divide_quant= !chroma ? w->divide_quant_dc_luma:
605                                             w->divide_quant_dc_chroma;
606             int32_t dc_quant    = !chroma ? w->quant:
607                                             w->quant_dc_chroma;
608
609             //original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding
610             dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13;
611
612             dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3),
613                                    s->dest[chroma], s->current_picture.f.linesize[!!chroma]);
614
615             goto block_placed;
616         }
617         zeros_only = (dc_level == 0);
618     }
619     if(!chroma){
620         s->block[0][0] = dc_level*w->quant;
621     }else{
622         s->block[0][0] = dc_level*w->quant_dc_chroma;
623     }
624
625     //there is !zero_only check in the original, but dc_level check is enough
626     if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){
627         int direction;
628         /*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<-
629         -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */
630         direction= (0x6A017C>>(w->orient*2))&3;
631         if (direction != 3){
632             x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[]
633         }
634     }
635
636     if(w->flat_dc){
637         dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.f.linesize[!!chroma]);
638     }else{
639         s->dsp.x8_spatial_compensation[w->orient]( s->edge_emu_buffer,
640                                             s->dest[chroma],
641                                             s->current_picture.f.linesize[!!chroma] );
642     }
643     if(!zeros_only)
644         s->dsp.idct_add ( s->dest[chroma],
645                           s->current_picture.f.linesize[!!chroma],
646                           s->block[0] );
647
648 block_placed:
649
650     if(!chroma){
651         x8_update_predictions(w,w->orient,n);
652     }
653
654     if(s->loop_filter){
655         uint8_t* ptr = s->dest[chroma];
656         int linesize = s->current_picture.f.linesize[!!chroma];
657
658         if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){
659             s->dsp.x8_h_loop_filter(ptr, linesize, w->quant);
660         }
661         if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){
662             s->dsp.x8_v_loop_filter(ptr, linesize, w->quant);
663         }
664     }
665     return 0;
666 }
667
668 static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_*
669 //not s->linesize as this would be wrong for field pics
670 //not that IntraX8 has interlacing support ;)
671     const int linesize   = s->current_picture.f.linesize[0];
672     const int uvlinesize = s->current_picture.f.linesize[1];
673
674     s->dest[0] = s->current_picture.f.data[0];
675     s->dest[1] = s->current_picture.f.data[1];
676     s->dest[2] = s->current_picture.f.data[2];
677
678     s->dest[0] +=   s->mb_y        *   linesize << 3;
679     s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows
680     s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2;
681 }
682
683 /**
684  * Initialize IntraX8 frame decoder.
685  * Requires valid MpegEncContext with valid s->mb_width before calling.
686  * @param w pointer to IntraX8Context
687  * @param s pointer to MpegEncContext of the parent codec
688  */
689 av_cold void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s){
690
691     w->s=s;
692     x8_vlc_init();
693     av_assert0(s->mb_width>0);
694     w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb
695
696     ff_init_scantable(s->dsp.idct_permutation, &w->scantable[0], ff_wmv1_scantable[0]);
697     ff_init_scantable(s->dsp.idct_permutation, &w->scantable[1], ff_wmv1_scantable[2]);
698     ff_init_scantable(s->dsp.idct_permutation, &w->scantable[2], ff_wmv1_scantable[3]);
699 }
700
701 /**
702  * Destroy IntraX8 frame structure.
703  * @param w pointer to IntraX8Context
704  */
705 av_cold void ff_intrax8_common_end(IntraX8Context * w)
706 {
707     av_freep(&w->prediction_table);
708 }
709
710 /**
711  * Decode single IntraX8 frame.
712  * The parent codec must fill s->loopfilter and s->gb (bitstream).
713  * The parent codec must call MPV_frame_start(), ff_er_frame_start() before calling this function.
714  * The parent codec must call ff_er_frame_end(), MPV_frame_end() after calling this function.
715  * This function does not use MPV_decode_mb().
716  * lowres decoding is theoretically impossible.
717  * @param w pointer to IntraX8Context
718  * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1.
719  * @param quant_offset offset away from zero
720  */
721 //FIXME extern uint8_t ff_wmv3_dc_scale_table[32];
722 int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){
723     MpegEncContext * const s= w->s;
724     int mb_xy;
725     w->use_quant_matrix = get_bits1(&s->gb);
726
727     w->dquant = dquant;
728     w->quant  = dquant >> 1;
729     w->qsum   = quant_offset;
730
731     w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant;
732     if(w->quant < 5){
733         w->quant_dc_chroma =  w->quant;
734         w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
735     }else{
736         w->quant_dc_chroma =  w->quant+((w->quant+3)>>3);
737         w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma;
738     }
739     x8_reset_vlc_tables(w);
740
741     s->resync_mb_x=0;
742     s->resync_mb_y=0;
743
744     for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){
745         x8_init_block_index(s);
746         mb_xy=(s->mb_y>>1)*s->mb_stride;
747
748         for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){
749             x8_get_prediction(w);
750             if(x8_setup_spatial_predictor(w,0)) goto error;
751             if(x8_decode_intra_mb(w,0)) goto error;
752
753             if( s->mb_x & s->mb_y & 1 ){
754                 x8_get_prediction_chroma(w);
755
756                 /*when setting up chroma, no vlc is read,
757                 so no error condition can be reached*/
758                 x8_setup_spatial_predictor(w,1);
759                 if(x8_decode_intra_mb(w,1)) goto error;
760
761                 x8_setup_spatial_predictor(w,2);
762                 if(x8_decode_intra_mb(w,2)) goto error;
763
764                 s->dest[1]+= 8;
765                 s->dest[2]+= 8;
766
767                 /*emulate MB info in the relevant tables*/
768                 s->mbskip_table [mb_xy]=0;
769                 s->mbintra_table[mb_xy]=1;
770                 s->current_picture.f.qscale_table[mb_xy] = w->quant;
771                 mb_xy++;
772             }
773             s->dest[0]+= 8;
774         }
775         if(s->mb_y&1){
776             ff_draw_horiz_band(s, (s->mb_y-1)*8, 16);
777         }
778     }
779
780 error:
781     ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
782                         (s->mb_x>>1)-1, (s->mb_y>>1)-1,
783                         ER_MB_END );
784     return 0;
785 }