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