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