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