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