intrax8.c
Go to the documentation of this file.
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 
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 
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 av_cold void x8_vlc_init(void){
46  int i;
47  int offset = 0;
48  int sizeidx = 0;
49  static const uint16_t sizes[8*4 + 8*2 + 2 + 4] = {
50  576, 548, 582, 618, 546, 616, 560, 642,
51  584, 582, 704, 664, 512, 544, 656, 640,
52  512, 648, 582, 566, 532, 614, 596, 648,
53  586, 552, 584, 590, 544, 578, 584, 624,
54 
55  528, 528, 526, 528, 536, 528, 526, 544,
56  544, 512, 512, 528, 528, 544, 512, 544,
57 
58  128, 128, 128, 128, 128, 128};
59 
60  static VLC_TYPE table[28150][2];
61 
62 #define init_ac_vlc(dst,src) \
63  dst.table = &table[offset]; \
64  dst.table_allocated = sizes[sizeidx]; \
65  offset += sizes[sizeidx++]; \
66  init_vlc(&dst, \
67  AC_VLC_BITS,77, \
68  &src[1],4,2, \
69  &src[0],4,2, \
70  INIT_VLC_USE_NEW_STATIC)
71 //set ac tables
72  for(i=0;i<8;i++){
73  init_ac_vlc( j_ac_vlc[0][0][i], x8_ac0_highquant_table[i][0] );
74  init_ac_vlc( j_ac_vlc[0][1][i], x8_ac1_highquant_table[i][0] );
75  init_ac_vlc( j_ac_vlc[1][0][i], x8_ac0_lowquant_table [i][0] );
76  init_ac_vlc( j_ac_vlc[1][1][i], x8_ac1_lowquant_table [i][0] );
77  }
78 #undef init_ac_vlc
79 
80 //set dc tables
81 #define init_dc_vlc(dst,src) \
82  dst.table = &table[offset]; \
83  dst.table_allocated = sizes[sizeidx]; \
84  offset += sizes[sizeidx++]; \
85  init_vlc(&dst, \
86  DC_VLC_BITS,34, \
87  &src[1],4,2, \
88  &src[0],4,2, \
89  INIT_VLC_USE_NEW_STATIC);
90  for(i=0;i<8;i++){
91  init_dc_vlc( j_dc_vlc[0][i], x8_dc_highquant_table[i][0]);
92  init_dc_vlc( j_dc_vlc[1][i], x8_dc_lowquant_table [i][0]);
93  }
94 #undef init_dc_vlc
95 
96 //set orient tables
97 #define init_or_vlc(dst,src) \
98  dst.table = &table[offset]; \
99  dst.table_allocated = sizes[sizeidx]; \
100  offset += sizes[sizeidx++]; \
101  init_vlc(&dst, \
102  OR_VLC_BITS,12, \
103  &src[1],4,2, \
104  &src[0],4,2, \
105  INIT_VLC_USE_NEW_STATIC);
106  for(i=0;i<2;i++){
107  init_or_vlc( j_orient_vlc[0][i], x8_orient_highquant_table[i][0]);
108  }
109  for(i=0;i<4;i++){
110  init_or_vlc( j_orient_vlc[1][i], x8_orient_lowquant_table [i][0])
111  }
112  if (offset != sizeof(table)/sizeof(VLC_TYPE)/2)
113  av_log(NULL, AV_LOG_ERROR, "table size %i does not match needed %i\n", (int)(sizeof(table)/sizeof(VLC_TYPE)/2), offset);
114 }
115 #undef init_or_vlc
116 
118  memset(w->j_dc_vlc,0,sizeof(w->j_dc_vlc));
119  memset(w->j_ac_vlc,0,sizeof(w->j_ac_vlc));
120  w->j_orient_vlc=NULL;
121 }
122 
123 static inline void x8_select_ac_table(IntraX8Context * const w , int mode){
124  MpegEncContext * const s= w->s;
125  int table_index;
126 
127  assert(mode<4);
128 
129  if( w->j_ac_vlc[mode] ) return;
130 
131  table_index = get_bits(&s->gb, 3);
132  w->j_ac_vlc[mode] = &j_ac_vlc[w->quant<13][mode>>1][table_index];//2 modes use same tables
133  assert(w->j_ac_vlc[mode]);
134 }
135 
136 static inline int x8_get_orient_vlc(IntraX8Context * w){
137  MpegEncContext * const s= w->s;
138  int table_index;
139 
140  if(!w->j_orient_vlc ){
141  table_index = get_bits(&s->gb, 1+(w->quant<13) );
142  w->j_orient_vlc = &j_orient_vlc[w->quant<13][table_index];
143  }
144  assert(w->j_orient_vlc);
145  assert(w->j_orient_vlc->table);
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  assert(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  assert(w->j_dc_vlc);
275  assert(w->j_dc_vlc[mode]->table);
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  assert(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  assert(w->raw_orient < 12 );
346  assert(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][s->dsp.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  assert(w->orient<12);
539  s->dsp.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  s->dsp.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  s->dsp.x8_h_loop_filter(ptr, linesize, w->quant);
663  }
664  if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){
665  s->dsp.x8_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 
693 
694  w->s=s;
695  x8_vlc_init();
696  assert(s->mb_width>0);
697  w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb
698 
702 }
703 
709 {
711 }
712 
724 //FIXME extern uint8_t 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  assert(s);
729  w->use_quant_matrix = get_bits1(&s->gb);
730 
731  w->dquant = dquant;
732  w->quant = dquant >> 1;
733  w->qsum = quant_offset;
734 
735  w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant;
736  if(w->quant < 5){
737  w->quant_dc_chroma = w->quant;
739  }else{
740  w->quant_dc_chroma = w->quant+((w->quant+3)>>3);
741  w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma;
742  }
744 
745  s->resync_mb_x=0;
746  s->resync_mb_y=0;
747 
748  for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){
750  mb_xy=(s->mb_y>>1)*s->mb_stride;
751 
752  for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){
754  if(x8_setup_spatial_predictor(w,0)) goto error;
755  if(x8_decode_intra_mb(w,0)) goto error;
756 
757  if( s->mb_x & s->mb_y & 1 ){
759 
760  /*when setting up chroma, no vlc is read,
761  so no error condition can be reached*/
763  if(x8_decode_intra_mb(w,1)) goto error;
764 
766  if(x8_decode_intra_mb(w,2)) goto error;
767 
768  s->dest[1]+= 8;
769  s->dest[2]+= 8;
770 
771  /*emulate MB info in the relevant tables*/
772  s->mbskip_table [mb_xy]=0;
773  s->mbintra_table[mb_xy]=1;
774  s->current_picture.f.qscale_table[mb_xy] = w->quant;
775  mb_xy++;
776  }
777  s->dest[0]+= 8;
778  }
779  if(s->mb_y&1){
780  ff_draw_horiz_band(s, (s->mb_y-1)*8, 16);
781  }
782  }
783 
784 error:
786  (s->mb_x>>1)-1, (s->mb_y>>1)-1,
787  ER_MB_END );
788  return 0;
789 }