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