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