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