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