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