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