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