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