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