Libav
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 "error_resilience.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  assert(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  assert(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  assert(w->j_orient_vlc);
147  assert(w->j_orient_vlc->table);
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  assert(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  assert(w->j_dc_vlc);
277  assert(w->j_dc_vlc[mode]->table);
278 
279  i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD);
280 
281  /*(i>=17) {i-=17;final=1;}*/
282  c= i>16;
283  (*final)=c;
284  i-=17*c;
285 
286  if(i<=0){
287  (*level)=0;
288  return -i;
289  }
290  c=(i+1)>>1;//hackish way to calculate dc_extra_sbits[]
291  c-=c>1;
292 
293  e=get_bits(&s->gb,c);//get the extra bits
294  i=dc_index_offset[i]+(e>>1);
295 
296  e= -(e & 1);//0,0xffffff
297  (*level)= (i ^ e) - e;// (i^0)-0 , (i^0xff)-(-1)
298  return 0;
299 }
300 //end of huffman
301 
302 static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma){
303  MpegEncContext * const s= w->s;
304  int range;
305  int sum;
306  int quant;
307 
309  s->current_picture.f.linesize[chroma>0],
310  &range, &sum, w->edges);
311  if(chroma){
312  w->orient=w->chroma_orient;
313  quant=w->quant_dc_chroma;
314  }else{
315  quant=w->quant;
316  }
317 
318  w->flat_dc=0;
319  if(range < quant || range < 3){
320  w->orient=0;
321  if(range < 3){//yep you read right, a +-1 idct error may break decoding!
322  w->flat_dc=1;
323  sum+=9;
324  w->predicted_dc = (sum*6899)>>17;//((1<<17)+9)/(8+8+1+2)=6899
325  }
326  }
327  if(chroma)
328  return 0;
329 
330  assert(w->orient < 3);
331  if(range < 2*w->quant){
332  if( (w->edges&3) == 0){
333  if(w->orient==1) w->orient=11;
334  if(w->orient==2) w->orient=10;
335  }else{
336  w->orient=0;
337  }
338  w->raw_orient=0;
339  }else{
340  static const uint8_t prediction_table[3][12]={
341  {0,8,4, 10,11, 2,6,9,1,3,5,7},
342  {4,0,8, 11,10, 3,5,2,6,9,1,7},
343  {8,0,4, 10,11, 1,7,2,6,9,3,5}
344  };
346  if(w->raw_orient<0) return -1;
347  assert(w->raw_orient < 12 );
348  assert(w->orient<3);
349  w->orient=prediction_table[w->orient][w->raw_orient];
350  }
351  return 0;
352 }
353 
354 static void x8_update_predictions(IntraX8Context * const w, const int orient, const int est_run ){
355  MpegEncContext * const s= w->s;
356 
357  w->prediction_table[s->mb_x*2+(s->mb_y&1)] = (est_run<<2) + 1*(orient==4) + 2*(orient==8);
358 /*
359  y=2n+0 ->//0 2 4
360  y=2n+1 ->//1 3 5
361 */
362 }
364  MpegEncContext * const s= w->s;
365 
366  w->edges = 1*( !(s->mb_x>>1) );
367  w->edges|= 2*( !(s->mb_y>>1) );
368  w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );//mb_x for chroma would always be odd
369 
370  w->raw_orient=0;
371  if(w->edges&3){//lut_co[8]={inv,4,8,8, inv,4,8,8}<- =>{1,1,0,0;1,1,0,0} => 0xCC
372  w->chroma_orient=4<<((0xCC>>w->edges)&1);
373  return;
374  }
375  w->chroma_orient = (w->prediction_table[2*s->mb_x-2] & 0x03)<<2;//block[x-1][y|1-1)]
376 }
377 
378 static void x8_get_prediction(IntraX8Context * const w){
379  MpegEncContext * const s= w->s;
380  int a,b,c,i;
381 
382  w->edges = 1*( !s->mb_x );
383  w->edges|= 2*( !s->mb_y );
384  w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );
385 
386  switch(w->edges&3){
387  case 0:
388  break;
389  case 1:
390  //take the one from the above block[0][y-1]
391  w->est_run = w->prediction_table[!(s->mb_y&1)]>>2;
392  w->orient = 1;
393  return;
394  case 2:
395  //take the one from the previous block[x-1][0]
396  w->est_run = w->prediction_table[2*s->mb_x-2]>>2;
397  w->orient = 2;
398  return;
399  case 3:
400  w->est_run = 16;
401  w->orient = 0;
402  return;
403  }
404  //no edge cases
405  b= w->prediction_table[2*s->mb_x + !(s->mb_y&1) ];//block[x ][y-1]
406  a= w->prediction_table[2*s->mb_x-2 + (s->mb_y&1) ];//block[x-1][y ]
407  c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];//block[x-1][y-1]
408 
409  w->est_run = FFMIN(b,a);
410  /* This condition has nothing to do with w->edges, even if it looks
411  similar it would trigger if e.g. x=3;y=2;
412  I guess somebody wrote something wrong and it became standard. */
413  if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run);
414  w->est_run>>=2;
415 
416  a&=3;
417  b&=3;
418  c&=3;
419 
420  i=( 0xFFEAF4C4>>(2*b+8*a) )&3;
421  if(i!=3) w->orient=i;
422  else w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3;
423 /*
424 lut1[b][a]={
425 ->{0, 1, 0, pad},
426  {0, 1, X, pad},
427  {2, 2, 2, pad}}
428  pad 2 2 2; pad X 1 0; pad 0 1 0 <-
429 -> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4
430 
431 lut2[q>12][c]={
432  ->{0,2,1,pad},
433  {2,2,2,pad}}
434  pad 2 2 2; pad 1 2 0 <-
435 -> 11 10'10 10 '11 01'10 00=>0xEAD8
436 */
437 }
438 
439 
440 static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){
441  MpegEncContext * const s= w->s;
442  int t;
443 #define B(x,y) s->block[0][s->dsp.idct_permutation[(x)+(y)*8]]
444 #define T(x) ((x) * dc_level + 0x8000) >> 16;
445  switch(direction){
446  case 0:
447  t = T(3811);//h
448  B(1,0) -= t;
449  B(0,1) -= t;
450 
451  t = T(487);//e
452  B(2,0) -= t;
453  B(0,2) -= t;
454 
455  t = T(506);//f
456  B(3,0) -= t;
457  B(0,3) -= t;
458 
459  t = T(135);//c
460  B(4,0) -= t;
461  B(0,4) -= t;
462  B(2,1) += t;
463  B(1,2) += t;
464  B(3,1) += t;
465  B(1,3) += t;
466 
467  t = T(173);//d
468  B(5,0) -= t;
469  B(0,5) -= t;
470 
471  t = T(61);//b
472  B(6,0) -= t;
473  B(0,6) -= t;
474  B(5,1) += t;
475  B(1,5) += t;
476 
477  t = T(42); //a
478  B(7,0) -= t;
479  B(0,7) -= t;
480  B(4,1) += t;
481  B(1,4) += t;
482  B(4,4) += t;
483 
484  t = T(1084);//g
485  B(1,1) += t;
486 
487  s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
488  break;
489  case 1:
490  B(0,1) -= T(6269);
491  B(0,3) -= T( 708);
492  B(0,5) -= T( 172);
493  B(0,7) -= T( 73);
494 
495  s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
496  break;
497  case 2:
498  B(1,0) -= T(6269);
499  B(3,0) -= T( 708);
500  B(5,0) -= T( 172);
501  B(7,0) -= T( 73);
502 
503  s->block_last_index[0] = FFMAX(s->block_last_index[0], 7);
504  break;
505  }
506 #undef B
507 #undef T
508 }
509 
510 static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){
511  int k;
512  for(k=0;k<8;k++){
513  memset(dst,pix,8);
514  dst+=linesize;
515  }
516 }
517 
518 static const int16_t quant_table[64] = {
519  256, 256, 256, 256, 256, 256, 259, 262,
520  265, 269, 272, 275, 278, 282, 285, 288,
521  292, 295, 299, 303, 306, 310, 314, 317,
522  321, 325, 329, 333, 337, 341, 345, 349,
523  353, 358, 362, 366, 371, 375, 379, 384,
524  389, 393, 398, 403, 408, 413, 417, 422,
525  428, 433, 438, 443, 448, 454, 459, 465,
526  470, 476, 482, 488, 493, 499, 505, 511
527 };
528 
529 static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){
530  MpegEncContext * const s= w->s;
531 
532  uint8_t * scantable;
533  int final,run,level;
534  int ac_mode,dc_mode,est_run,dc_level;
535  int pos,n;
536  int zeros_only;
537  int use_quant_matrix;
538  int sign;
539 
540  assert(w->orient<12);
541  s->dsp.clear_block(s->block[0]);
542 
543  if(chroma){
544  dc_mode=2;
545  }else{
546  dc_mode=!!w->est_run;//0,1
547  }
548 
549  if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1;
550  n=0;
551  zeros_only=0;
552  if(!final){//decode ac
553  use_quant_matrix=w->use_quant_matrix;
554  if(chroma){
555  ac_mode = 1;
556  est_run = 64;//not used
557  }else{
558  if (w->raw_orient < 3){
559  use_quant_matrix = 0;
560  }
561  if(w->raw_orient > 4){
562  ac_mode = 0;
563  est_run = 64;
564  }else{
565  if(w->est_run > 1){
566  ac_mode = 2;
567  est_run=w->est_run;
568  }else{
569  ac_mode = 3;
570  est_run = 64;
571  }
572  }
573  }
574  x8_select_ac_table(w,ac_mode);
575  /*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<-
576  -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */
577  scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated;
578  pos=0;
579  do {
580  n++;
581  if( n >= est_run ){
582  ac_mode=3;
583  x8_select_ac_table(w,3);
584  }
585 
586  x8_get_ac_rlf(w,ac_mode,&run,&level,&final);
587 
588  pos+=run+1;
589  if(pos>63){
590  //this also handles vlc error in x8_get_ac_rlf
591  return -1;
592  }
593  level= (level+1) * w->dquant;
594  level+= w->qsum;
595 
596  sign = - get_bits1(&s->gb);
597  level = (level ^ sign) - sign;
598 
599  if(use_quant_matrix){
600  level = (level*quant_table[pos])>>8;
601  }
602  s->block[0][ scantable[pos] ]=level;
603  }while(!final);
604 
605  s->block_last_index[0]=pos;
606  }else{//DC only
607  s->block_last_index[0]=0;
608  if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1]
609  int32_t divide_quant= !chroma ? w->divide_quant_dc_luma:
611  int32_t dc_quant = !chroma ? w->quant:
612  w->quant_dc_chroma;
613 
614  //original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding
615  dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13;
616 
617  dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3),
618  s->dest[chroma], s->current_picture.f.linesize[!!chroma]);
619 
620  goto block_placed;
621  }
622  zeros_only = (dc_level == 0);
623  }
624  if(!chroma){
625  s->block[0][0] = dc_level*w->quant;
626  }else{
627  s->block[0][0] = dc_level*w->quant_dc_chroma;
628  }
629 
630  //there is !zero_only check in the original, but dc_level check is enough
631  if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){
632  int direction;
633  /*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<-
634  -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */
635  direction= (0x6A017C>>(w->orient*2))&3;
636  if (direction != 3){
637  x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[]
638  }
639  }
640 
641  if(w->flat_dc){
642  dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.f.linesize[!!chroma]);
643  }else{
645  s->dest[chroma],
646  s->current_picture.f.linesize[!!chroma] );
647  }
648  if(!zeros_only)
649  s->dsp.idct_add ( s->dest[chroma],
650  s->current_picture.f.linesize[!!chroma],
651  s->block[0] );
652 
653 block_placed:
654 
655  if(!chroma){
657  }
658 
659  if(s->loop_filter){
660  uint8_t* ptr = s->dest[chroma];
661  int linesize = s->current_picture.f.linesize[!!chroma];
662 
663  if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){
664  w->dsp.h_loop_filter(ptr, linesize, w->quant);
665  }
666  if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){
667  w->dsp.v_loop_filter(ptr, linesize, w->quant);
668  }
669  }
670  return 0;
671 }
672 
673 static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_*
674 //not s->linesize as this would be wrong for field pics
675 //not that IntraX8 has interlacing support ;)
676  const int linesize = s->current_picture.f.linesize[0];
677  const int uvlinesize = s->current_picture.f.linesize[1];
678 
679  s->dest[0] = s->current_picture.f.data[0];
680  s->dest[1] = s->current_picture.f.data[1];
681  s->dest[2] = s->current_picture.f.data[2];
682 
683  s->dest[0] += s->mb_y * linesize << 3;
684  s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows
685  s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2;
686 }
687 
695 
696  w->s=s;
697  x8_vlc_init();
698  assert(s->mb_width>0);
699  w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb
700 
704 
705  ff_intrax8dsp_init(&w->dsp);
706 }
707 
713 {
715 }
716 
727 int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){
728  MpegEncContext * const s= w->s;
729  int mb_xy;
730  assert(s);
731  w->use_quant_matrix = get_bits1(&s->gb);
732 
733  w->dquant = dquant;
734  w->quant = dquant >> 1;
735  w->qsum = quant_offset;
736 
737  w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant;
738  if(w->quant < 5){
739  w->quant_dc_chroma = w->quant;
741  }else{
742  w->quant_dc_chroma = w->quant+((w->quant+3)>>3);
743  w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma;
744  }
746 
747  s->resync_mb_x=0;
748  s->resync_mb_y=0;
749 
750  for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){
752  mb_xy=(s->mb_y>>1)*s->mb_stride;
753 
754  for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){
756  if(x8_setup_spatial_predictor(w,0)) goto error;
757  if(x8_decode_intra_mb(w,0)) goto error;
758 
759  if( s->mb_x & s->mb_y & 1 ){
761 
762  /*when setting up chroma, no vlc is read,
763  so no error condition can be reached*/
765  if(x8_decode_intra_mb(w,1)) goto error;
766 
768  if(x8_decode_intra_mb(w,2)) goto error;
769 
770  s->dest[1]+= 8;
771  s->dest[2]+= 8;
772 
773  /*emulate MB info in the relevant tables*/
774  s->mbskip_table [mb_xy]=0;
775  s->mbintra_table[mb_xy]=1;
776  s->current_picture.qscale_table[mb_xy] = w->quant;
777  mb_xy++;
778  }
779  s->dest[0]+= 8;
780  }
781  if(s->mb_y&1){
782  ff_mpeg_draw_horiz_band(s, (s->mb_y-1)*8, 16);
783  }
784  }
785 
786 error:
788  (s->mb_x>>1)-1, (s->mb_y>>1)-1,
789  ER_MB_END );
790  return 0;
791 }