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 
x8_init_vlc(VLC * vlc,int nb_bits,int nb_codes,int * offset,const uint8_t table[][2])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 
x8_vlc_init(void)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 
x8_reset_vlc_tables(IntraX8Context * w)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 
x8_select_ac_table(IntraX8Context * const w,int mode)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 
x8_get_orient_vlc(IntraX8Context * w)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 
x8_get_ac_rlf(IntraX8Context * const w,const int mode,int * const run,int * const level,int * const final)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 
x8_get_dc_rlf(IntraX8Context * const w,const int mode,int * const level,int * const final)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 
x8_setup_spatial_predictor(IntraX8Context * const w,const int chroma)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 
x8_update_predictions(IntraX8Context * const w,const int orient,const int est_run)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 
x8_get_prediction_chroma(IntraX8Context * const w)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 
x8_get_prediction(IntraX8Context * const w)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 
x8_ac_compensation(IntraX8Context * const w,const int direction,const int dc_level)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 
dsp_x8_put_solidcolor(const uint8_t pix,uint8_t * dst,const ptrdiff_t linesize)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 
x8_decode_intra_mb(IntraX8Context * const w,const int chroma)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_*
x8_init_block_index(IntraX8Context * w,AVFrame * frame)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 
ff_intrax8_common_init(AVCodecContext * avctx,IntraX8Context * w,IDCTDSPContext * idsp,int16_t (* block)[64],int block_last_index[12],int mb_width,int mb_height)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 
ff_intrax8_common_end(IntraX8Context * w)734 av_cold void ff_intrax8_common_end(IntraX8Context *w)
735 {
736     av_freep(&w->prediction_table);
737 }
738 
ff_intrax8_decode_picture(IntraX8Context * w,Picture * pict,GetBitContext * gb,int * mb_x,int * mb_y,int dquant,int quant_offset,int loopfilter,int lowdelay)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 }
812