PageRenderTime 98ms CodeModel.GetById 14ms app.highlight 75ms RepoModel.GetById 1ms app.codeStats 0ms

/libavcodec/intrax8.c

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