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