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