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