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