]> git.sesse.net Git - ffmpeg/blob - libavcodec/intrax8.c
Merge commit 'e42ca48a8bddc637a4013ab253598973f07e1a5c'
[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     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 unilitialized'
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;                               // 3bits
253         mask = sm & 0xff;
254         sm >>= 8;                               // 1bit
255
256         (*run)   = (sm & 0xff) + (e & (mask));  // 6bits
257         (*level) = (sm >> 8)   + (e & (~mask)); // 5bits
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     MpegEncContext *const s = w->s;
384
385     w->prediction_table[s->mb_x * 2 + (s->mb_y & 1)] = (est_run << 2) + 1 * (orient == 4) + 2 * (orient == 8);
386 /*
387  * y = 2n + 0 -> // 0 2 4
388  * y = 2n + 1 -> // 1 3 5
389  */
390 }
391
392 static void x8_get_prediction_chroma(IntraX8Context *const w)
393 {
394     MpegEncContext *const s = w->s;
395
396     w->edges  = 1 * (!(s->mb_x >> 1));
397     w->edges |= 2 * (!(s->mb_y >> 1));
398     w->edges |= 4 * (s->mb_x >= (2 * s->mb_width - 1)); // mb_x for chroma would always be odd
399
400     w->raw_orient = 0;
401     // lut_co[8] = {inv,4,8,8, inv,4,8,8} <- => {1,1,0,0;1,1,0,0} => 0xCC
402     if (w->edges & 3) {
403         w->chroma_orient = 4 << ((0xCC >> w->edges) & 1);
404         return;
405     }
406     // block[x - 1][y | 1 - 1)]
407     w->chroma_orient = (w->prediction_table[2 * s->mb_x - 2] & 0x03) << 2;
408 }
409
410 static void x8_get_prediction(IntraX8Context *const w)
411 {
412     MpegEncContext *const s = w->s;
413     int a, b, c, i;
414
415     w->edges  = 1 * (!s->mb_x);
416     w->edges |= 2 * (!s->mb_y);
417     w->edges |= 4 * (s->mb_x >= (2 * s->mb_width - 1));
418
419     switch (w->edges & 3) {
420     case 0:
421         break;
422     case 1:
423         // take the one from the above block[0][y - 1]
424         w->est_run = w->prediction_table[!(s->mb_y & 1)] >> 2;
425         w->orient  = 1;
426         return;
427     case 2:
428         // take the one from the previous block[x - 1][0]
429         w->est_run = w->prediction_table[2 * s->mb_x - 2] >> 2;
430         w->orient  = 2;
431         return;
432     case 3:
433         w->est_run = 16;
434         w->orient  = 0;
435         return;
436     }
437     // no edge cases
438     b = w->prediction_table[2 * s->mb_x     + !(s->mb_y & 1)]; // block[x    ][y - 1]
439     a = w->prediction_table[2 * s->mb_x - 2 +  (s->mb_y & 1)]; // block[x - 1][y    ]
440     c = w->prediction_table[2 * s->mb_x - 2 + !(s->mb_y & 1)]; // block[x - 1][y - 1]
441
442     w->est_run = FFMIN(b, a);
443     /* This condition has nothing to do with w->edges, even if it looks
444      * similar it would trigger if e.g. x = 3; y = 2;
445      * I guess somebody wrote something wrong and it became standard. */
446     if ((s->mb_x & s->mb_y) != 0)
447         w->est_run = FFMIN(c, w->est_run);
448     w->est_run >>= 2;
449
450     a &= 3;
451     b &= 3;
452     c &= 3;
453
454     i = (0xFFEAF4C4 >> (2 * b + 8 * a)) & 3;
455     if (i != 3)
456         w->orient = i;
457     else
458         w->orient = (0xFFEAD8 >> (2 * c + 8 * (w->quant > 12))) & 3;
459 /*
460  * lut1[b][a] = {
461  * ->{ 0, 1, 0, pad },
462  *   { 0, 1, X, pad },
463  *   { 2, 2, 2, pad }
464  * }
465  * pad 2  2  2;
466  * pad X  1  0;
467  * pad 0  1  0 <-
468  * -> 11 10 '10 10 '11 11'01 00 '11 00'01 00 => 0xEAF4C4
469  *
470  * lut2[q>12][c] = {
471  * ->{ 0, 2, 1, pad},
472  *   { 2, 2, 2, pad}
473  * }
474  * pad 2  2  2;
475  * pad 1  2  0 <-
476  * -> 11 10'10 10 '11 01'10 00 => 0xEAD8
477  */
478 }
479
480 static void x8_ac_compensation(IntraX8Context *const w, const int direction,
481                                const int dc_level)
482 {
483     MpegEncContext *const s = w->s;
484     int t;
485 #define B(x,y)  s->block[0][w->idct_permutation[(x) + (y) * 8]]
486 #define T(x)  ((x) * dc_level + 0x8000) >> 16;
487     switch (direction) {
488     case 0:
489         t        = T(3811); // h
490         B(1, 0) -= t;
491         B(0, 1) -= t;
492
493         t        = T(487); // e
494         B(2, 0) -= t;
495         B(0, 2) -= t;
496
497         t        = T(506); // f
498         B(3, 0) -= t;
499         B(0, 3) -= t;
500
501         t        = T(135); // c
502         B(4, 0) -= t;
503         B(0, 4) -= t;
504         B(2, 1) += t;
505         B(1, 2) += t;
506         B(3, 1) += t;
507         B(1, 3) += t;
508
509         t        = T(173); // d
510         B(5, 0) -= t;
511         B(0, 5) -= t;
512
513         t        = T(61); // b
514         B(6, 0) -= t;
515         B(0, 6) -= t;
516         B(5, 1) += t;
517         B(1, 5) += t;
518
519         t        = T(42); // a
520         B(7, 0) -= t;
521         B(0, 7) -= t;
522         B(4, 1) += t;
523         B(1, 4) += t;
524         B(4, 4) += t;
525
526         t        = T(1084); // g
527         B(1, 1) += t;
528
529         s->block_last_index[0] = FFMAX(s->block_last_index[0], 7 * 8);
530         break;
531     case 1:
532         B(0, 1) -= T(6269);
533         B(0, 3) -= T(708);
534         B(0, 5) -= T(172);
535         B(0, 7) -= T(73);
536
537         s->block_last_index[0] = FFMAX(s->block_last_index[0], 7 * 8);
538         break;
539     case 2:
540         B(1, 0) -= T(6269);
541         B(3, 0) -= T(708);
542         B(5, 0) -= T(172);
543         B(7, 0) -= T(73);
544
545         s->block_last_index[0] = FFMAX(s->block_last_index[0], 7);
546         break;
547     }
548 #undef B
549 #undef T
550 }
551
552 static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst,
553                                   const int linesize)
554 {
555     int k;
556     for (k = 0; k < 8; k++) {
557         memset(dst, pix, 8);
558         dst += linesize;
559     }
560 }
561
562 static const int16_t quant_table[64] = {
563     256, 256, 256, 256, 256, 256, 259, 262,
564     265, 269, 272, 275, 278, 282, 285, 288,
565     292, 295, 299, 303, 306, 310, 314, 317,
566     321, 325, 329, 333, 337, 341, 345, 349,
567     353, 358, 362, 366, 371, 375, 379, 384,
568     389, 393, 398, 403, 408, 413, 417, 422,
569     428, 433, 438, 443, 448, 454, 459, 465,
570     470, 476, 482, 488, 493, 499, 505, 511,
571 };
572
573 static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma)
574 {
575     MpegEncContext *const s = w->s;
576
577     uint8_t *scantable;
578     int final, run, level;
579     int ac_mode, dc_mode, est_run, dc_level;
580     int pos, n;
581     int zeros_only;
582     int use_quant_matrix;
583     int sign;
584
585     av_assert2(w->orient < 12);
586     w->bdsp.clear_block(s->block[0]);
587
588     if (chroma)
589         dc_mode = 2;
590     else
591         dc_mode = !!w->est_run; // 0, 1
592
593     if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final))
594         return -1;
595     n          = 0;
596     zeros_only = 0;
597     if (!final) { // decode ac
598         use_quant_matrix = w->use_quant_matrix;
599         if (chroma) {
600             ac_mode = 1;
601             est_run = 64; // not used
602         } else {
603             if (w->raw_orient < 3)
604                 use_quant_matrix = 0;
605
606             if (w->raw_orient > 4) {
607                 ac_mode = 0;
608                 est_run = 64;
609             } else {
610                 if (w->est_run > 1) {
611                     ac_mode = 2;
612                     est_run = w->est_run;
613                 } else {
614                     ac_mode = 3;
615                     est_run = 64;
616                 }
617             }
618         }
619         x8_select_ac_table(w, ac_mode);
620         /* scantable_selector[12] = { 0, 2, 0, 1, 1, 1, 0, 2, 2, 0, 1, 2 }; <-
621          * -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 => 0x928548 */
622         scantable = w->scantable[(0x928548 >> (2 * w->orient)) & 3].permutated;
623         pos       = 0;
624         do {
625             n++;
626             if (n >= est_run) {
627                 ac_mode = 3;
628                 x8_select_ac_table(w, 3);
629             }
630
631             x8_get_ac_rlf(w, ac_mode, &run, &level, &final);
632
633             pos += run + 1;
634             if (pos > 63) {
635                 // this also handles vlc error in x8_get_ac_rlf
636                 return -1;
637             }
638             level  = (level + 1) * w->dquant;
639             level += w->qsum;
640
641             sign  = -get_bits1(w->gb);
642             level = (level ^ sign) - sign;
643
644             if (use_quant_matrix)
645                 level = (level * quant_table[pos]) >> 8;
646
647             s->block[0][scantable[pos]] = level;
648         } while (!final);
649
650         s->block_last_index[0] = pos;
651     } else { // DC only
652         s->block_last_index[0] = 0;
653         if (w->flat_dc && ((unsigned) (dc_level + 1)) < 3) { // [-1; 1]
654             int32_t divide_quant = !chroma ? w->divide_quant_dc_luma
655                                            : w->divide_quant_dc_chroma;
656             int32_t dc_quant     = !chroma ? w->quant
657                                            : w->quant_dc_chroma;
658
659             // original intent dc_level += predicted_dc/quant;
660             // but it got lost somewhere in the rounding
661             dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13;
662
663             dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3),
664                                   w->dest[chroma],
665                                   w->frame->linesize[!!chroma]);
666
667             goto block_placed;
668         }
669         zeros_only = (dc_level == 0);
670     }
671     if (!chroma)
672         s->block[0][0] = dc_level * w->quant;
673     else
674         s->block[0][0] = dc_level * w->quant_dc_chroma;
675
676     // there is !zero_only check in the original, but dc_level check is enough
677     if ((unsigned int) (dc_level + 1) >= 3 && (w->edges & 3) != 3) {
678         int direction;
679         /* ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 }; <-
680          * -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 => 0x6A017C */
681         direction = (0x6A017C >> (w->orient * 2)) & 3;
682         if (direction != 3) {
683             // modify block_last[]
684             x8_ac_compensation(w, direction, s->block[0][0]);
685         }
686     }
687
688     if (w->flat_dc) {
689         dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma],
690                               w->frame->linesize[!!chroma]);
691     } else {
692         w->dsp.spatial_compensation[w->orient](w->scratchpad,
693                                                w->dest[chroma],
694                                                w->frame->linesize[!!chroma]);
695     }
696     if (!zeros_only)
697         w->wdsp.idct_add(w->dest[chroma],
698                          w->frame->linesize[!!chroma],
699                          s->block[0]);
700
701 block_placed:
702     if (!chroma)
703         x8_update_predictions(w, w->orient, n);
704
705     if (w->loopfilter) {
706         uint8_t *ptr = w->dest[chroma];
707         int linesize = w->frame->linesize[!!chroma];
708
709         if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4)))
710             w->dsp.h_loop_filter(ptr, linesize, w->quant);
711
712         if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8)))
713             w->dsp.v_loop_filter(ptr, linesize, w->quant);
714     }
715     return 0;
716 }
717
718 // FIXME maybe merge with ff_*
719 static void x8_init_block_index(IntraX8Context *w, AVFrame *frame, int mb_y)
720 {
721     // not parent codec linesize as this would be wrong for field pics
722     // not that IntraX8 has interlacing support ;)
723     const int linesize   = frame->linesize[0];
724     const int uvlinesize = frame->linesize[1];
725
726     w->dest[0] = frame->data[0];
727     w->dest[1] = frame->data[1];
728     w->dest[2] = frame->data[2];
729
730     w->dest[0] +=  mb_y         * linesize   << 3;
731     // chroma blocks are on add rows
732     w->dest[1] += (mb_y & (~1)) * uvlinesize << 2;
733     w->dest[2] += (mb_y & (~1)) * uvlinesize << 2;
734 }
735
736 av_cold int ff_intrax8_common_init(AVCodecContext *avctx,
737                                    IntraX8Context *w, IDCTDSPContext *idsp,
738                                    MpegEncContext *const s)
739 {
740     int ret = x8_vlc_init();
741     if (ret < 0)
742         return ret;
743
744     w->avctx = avctx;
745     w->idsp = *idsp;
746     w->s = s;
747
748     //two rows, 2 blocks per cannon mb
749     w->prediction_table = av_mallocz(s->mb_width * 2 * 2);
750     if (!w->prediction_table)
751         return AVERROR(ENOMEM);
752
753     ff_wmv2dsp_init(&w->wdsp);
754
755     ff_init_scantable_permutation(w->idct_permutation,
756                                   w->wdsp.idct_perm);
757
758     ff_init_scantable(w->idct_permutation, &w->scantable[0],
759                       ff_wmv1_scantable[0]);
760     ff_init_scantable(w->idct_permutation, &w->scantable[1],
761                       ff_wmv1_scantable[2]);
762     ff_init_scantable(w->idct_permutation, &w->scantable[2],
763                       ff_wmv1_scantable[3]);
764
765     ff_intrax8dsp_init(&w->dsp);
766     ff_blockdsp_init(&w->bdsp, avctx);
767
768     return 0;
769 }
770
771 av_cold void ff_intrax8_common_end(IntraX8Context *w)
772 {
773     av_freep(&w->prediction_table);
774 }
775
776 int ff_intrax8_decode_picture(IntraX8Context *const w, Picture *pict,
777                               GetBitContext *gb,
778                               int dquant, int quant_offset, int loopfilter)
779 {
780     MpegEncContext *const s = w->s;
781     int mb_xy;
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 }