GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/intrax8.c Lines: 371 386 96.1 %
Date: 2021-01-21 21:11:50 Branches: 146 161 90.7 %

Line Branch Exec Source
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 "libavutil/thread.h"
26
#include "avcodec.h"
27
#include "get_bits.h"
28
#include "idctdsp.h"
29
#include "msmpeg4data.h"
30
#include "intrax8huf.h"
31
#include "intrax8.h"
32
#include "intrax8dsp.h"
33
#include "mpegutils.h"
34
35
#define VLC_BUFFER_SIZE 28150
36
37
#define MAX_TABLE_DEPTH(table_bits, max_bits) \
38
    ((max_bits + table_bits - 1) / table_bits)
39
40
#define DC_VLC_BITS 9
41
#define AC_VLC_BITS 9
42
#define OR_VLC_BITS 7
43
44
#define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS)
45
#define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
46
#define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS)
47
48
static VLC j_ac_vlc[2][2][8];  // [quant < 13], [intra / inter], [select]
49
static VLC j_dc_vlc[2][8];     // [quant], [select]
50
static VLC j_orient_vlc[2][4]; // [quant], [select]
51
52
1296
static av_cold void x8_init_vlc(VLC *vlc, int nb_bits, int nb_codes,
53
                                int *offset, const uint8_t table[][2])
54
{
55
    static VLC_TYPE vlc_buf[VLC_BUFFER_SIZE][2];
56
57
1296
    vlc->table           = &vlc_buf[*offset];
58
1296
    vlc->table_allocated = VLC_BUFFER_SIZE - *offset;
59
1296
    ff_init_vlc_from_lengths(vlc, nb_bits, nb_codes, &table[0][1], 2,
60
1296
                             &table[0][0], 2, 1, 0, INIT_VLC_STATIC_OVERLONG, NULL);
61
1296
    *offset += vlc->table_size;
62
1296
}
63
64
24
static av_cold void x8_vlc_init(void)
65
{
66
    int i;
67
24
    int offset = 0;
68
69
// set ac tables
70
72
    for (int i = 0; i < 2; i++)
71
144
        for (int j = 0; j < 2; j++)
72
864
            for (int k = 0; k < 8; k++)
73
768
                x8_init_vlc(&j_ac_vlc[i][j][k], AC_VLC_BITS, 77,
74
768
                            &offset, x8_ac_quant_table[i][j][k]);
75
76
// set dc tables
77
72
    for (int i = 0; i < 2; i++)
78
432
        for (int j = 0; j < 8; j++)
79
384
            x8_init_vlc(&j_dc_vlc[i][j], DC_VLC_BITS, 34, &offset,
80
384
                        x8_dc_quant_table[i][j]);
81
82
// set orient tables
83
72
    for (i = 0; i < 2; i++)
84
48
        x8_init_vlc(&j_orient_vlc[0][i], OR_VLC_BITS, 12,
85
48
                    &offset, x8_orient_highquant_table[i]);
86
120
    for (i = 0; i < 4; i++)
87
96
        x8_init_vlc(&j_orient_vlc[1][i], OR_VLC_BITS, 12,
88
96
                    &offset, x8_orient_lowquant_table[i]);
89
90
    av_assert2(offset == VLC_BUFFER_SIZE);
91
24
}
92
93
3
static void x8_reset_vlc_tables(IntraX8Context *w)
94
{
95
3
    memset(w->j_dc_vlc, 0, sizeof(w->j_dc_vlc));
96
3
    memset(w->j_ac_vlc, 0, sizeof(w->j_ac_vlc));
97
3
    w->j_orient_vlc = NULL;
98
3
}
99
100
3909
static inline void x8_select_ac_table(IntraX8Context *const w, int mode)
101
{
102
    int table_index;
103
104
    av_assert2(mode < 4);
105
106
3909
    if (w->j_ac_vlc[mode])
107
3897
        return;
108
109
12
    table_index       = get_bits(w->gb, 3);
110
    // 2 modes use same tables
111
12
    w->j_ac_vlc[mode] = &j_ac_vlc[w->quant < 13][mode >> 1][table_index];
112
    av_assert2(w->j_ac_vlc[mode]);
113
}
114
115
1304
static inline int x8_get_orient_vlc(IntraX8Context *w)
116
{
117
1304
    if (!w->j_orient_vlc) {
118
3
        int table_index = get_bits(w->gb, 1 + (w->quant < 13));
119
3
        w->j_orient_vlc = &j_orient_vlc[w->quant < 13][table_index];
120
    }
121
122
1304
    return get_vlc2(w->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD);
123
}
124
125
#define extra_bits(eb)  (eb)        // 3 bits
126
#define extra_run       (0xFF << 8) // 1 bit
127
#define extra_level     (0x00 << 8) // 1 bit
128
#define run_offset(r)   ((r) << 16) // 6 bits
129
#define level_offset(l) ((l) << 24) // 5 bits
130
static const uint32_t ac_decode_table[] = {
131
    /* 46 */ extra_bits(3) | extra_run   | run_offset(16) | level_offset(0),
132
    /* 47 */ extra_bits(3) | extra_run   | run_offset(24) | level_offset(0),
133
    /* 48 */ extra_bits(2) | extra_run   | run_offset(4)  | level_offset(1),
134
    /* 49 */ extra_bits(3) | extra_run   | run_offset(8)  | level_offset(1),
135
136
    /* 50 */ extra_bits(5) | extra_run   | run_offset(32) | level_offset(0),
137
    /* 51 */ extra_bits(4) | extra_run   | run_offset(16) | level_offset(1),
138
139
    /* 52 */ extra_bits(2) | extra_level | run_offset(0)  | level_offset(4),
140
    /* 53 */ extra_bits(2) | extra_level | run_offset(0)  | level_offset(8),
141
    /* 54 */ extra_bits(2) | extra_level | run_offset(0)  | level_offset(12),
142
    /* 55 */ extra_bits(3) | extra_level | run_offset(0)  | level_offset(16),
143
    /* 56 */ extra_bits(3) | extra_level | run_offset(0)  | level_offset(24),
144
145
    /* 57 */ extra_bits(2) | extra_level | run_offset(1)  | level_offset(3),
146
    /* 58 */ extra_bits(3) | extra_level | run_offset(1)  | level_offset(7),
147
148
    /* 59 */ extra_bits(2) | extra_run   | run_offset(16) | level_offset(0),
149
    /* 60 */ extra_bits(2) | extra_run   | run_offset(20) | level_offset(0),
150
    /* 61 */ extra_bits(2) | extra_run   | run_offset(24) | level_offset(0),
151
    /* 62 */ extra_bits(2) | extra_run   | run_offset(28) | level_offset(0),
152
    /* 63 */ extra_bits(4) | extra_run   | run_offset(32) | level_offset(0),
153
    /* 64 */ extra_bits(4) | extra_run   | run_offset(48) | level_offset(0),
154
155
    /* 65 */ extra_bits(2) | extra_run   | run_offset(4)  | level_offset(1),
156
    /* 66 */ extra_bits(3) | extra_run   | run_offset(8)  | level_offset(1),
157
    /* 67 */ extra_bits(4) | extra_run   | run_offset(16) | level_offset(1),
158
159
    /* 68 */ extra_bits(2) | extra_level | run_offset(0)  | level_offset(4),
160
    /* 69 */ extra_bits(3) | extra_level | run_offset(0)  | level_offset(8),
161
    /* 70 */ extra_bits(4) | extra_level | run_offset(0)  | level_offset(16),
162
163
    /* 71 */ extra_bits(2) | extra_level | run_offset(1)  | level_offset(3),
164
    /* 72 */ extra_bits(3) | extra_level | run_offset(1)  | level_offset(7),
165
};
166
#undef extra_bits
167
#undef extra_run
168
#undef extra_level
169
#undef run_offset
170
#undef level_offset
171
172
8932
static void x8_get_ac_rlf(IntraX8Context *const w, const int mode,
173
                          int *const run, int *const level, int *const final)
174
{
175
    int i, e;
176
177
//    x8_select_ac_table(w, mode);
178
8932
    i = get_vlc2(w->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD);
179
180
8932
    if (i < 46) { // [0-45]
181
        int t, l;
182
7635
        if (i < 0) {
183
            *level =
184
            *final =      // prevent 'may be used uninitialized'
185
            *run   = 64;  // this would cause error exit in the ac loop
186
            return;
187
        }
188
189
        /*
190
         * i == 0-15  r = 0-15 l = 0; r = i & %01111
191
         * i == 16-19 r = 0-3  l = 1; r = i & %00011
192
         * i == 20-21 r = 0-1  l = 2; r = i & %00001
193
         * i == 22    r = 0    l = 3; r = i & %00000
194
         */
195
196
7635
        *final =
197
7635
        t      = i > 22;
198
7635
        i     -= 23 * t;
199
200
        /* l = lut_l[i / 2] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3 }[i >> 1];
201
         *     11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000 */
202
7635
        l = (0xE50000 >> (i & 0x1E)) & 3; // 0x1E or ~1 or (i >> 1 << 1)
203
204
        /* t = lut_mask[l] = { 0x0f, 0x03, 0x01, 0x00 }[l];
205
         *     as i < 256 the higher bits do not matter */
206
7635
        t = 0x01030F >> (l << 3);
207
208
7635
        *run   = i & t;
209
7635
        *level = l;
210
1297
    } else if (i < 73) { // [46-72]
211
        uint32_t sm;
212
        uint32_t mask;
213
214
1057
        i -= 46;
215
1057
        sm = ac_decode_table[i];
216
217
1057
        e    = get_bits(w->gb, sm & 0xF);
218
1057
        sm >>= 8;                               // 3 bits
219
1057
        mask = sm & 0xff;
220
1057
        sm >>= 8;                               // 1 bit
221
222
1057
        *run   = (sm &  0xff) + (e &  mask);    // 6 bits
223
1057
        *level = (sm >>    8) + (e & ~mask);    // 5 bits
224
1057
        *final = i > (58 - 46);
225
240
    } else if (i < 75) { // [73-74]
226
        static const uint8_t crazy_mix_runlevel[32] = {
227
            0x22, 0x32, 0x33, 0x53, 0x23, 0x42, 0x43, 0x63,
228
            0x24, 0x52, 0x34, 0x73, 0x25, 0x62, 0x44, 0x83,
229
            0x26, 0x72, 0x35, 0x54, 0x27, 0x82, 0x45, 0x64,
230
            0x28, 0x92, 0x36, 0x74, 0x29, 0xa2, 0x46, 0x84,
231
        };
232
233
234
        *final = !(i & 1);
234
234
        e      = get_bits(w->gb, 5); // get the extra bits
235
234
        *run   = crazy_mix_runlevel[e] >> 4;
236
234
        *level = crazy_mix_runlevel[e] & 0x0F;
237
    } else {
238
6
        *level = get_bits(w->gb, 7 - 3 * (i & 1));
239
6
        *run   = get_bits(w->gb, 6);
240
6
        *final = get_bits1(w->gb);
241
    }
242
8932
    return;
243
}
244
245
/* static const uint8_t dc_extra_sbits[] = {
246
 *     0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
247
 * }; */
248
static const uint8_t dc_index_offset[] = {
249
    0, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
250
};
251
252
5400
static int x8_get_dc_rlf(IntraX8Context *const w, const int mode,
253
                         int *const level, int *const final)
254
{
255
    int i, e, c;
256
257
    av_assert2(mode < 3);
258
5400
    if (!w->j_dc_vlc[mode]) {
259
9
        int table_index = get_bits(w->gb, 3);
260
        // 4 modes, same table
261
9
        w->j_dc_vlc[mode] = &j_dc_vlc[w->quant < 13][table_index];
262
    }
263
264
5400
    i = get_vlc2(w->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD);
265
266
    /* (i >= 17) { i -= 17; final =1; } */
267
5400
    c      = i > 16;
268
5400
    *final = c;
269
5400
    i      -= 17 * c;
270
271
5400
    if (i <= 0) {
272
1320
        *level = 0;
273
1320
        return -i;
274
    }
275
4080
    c  = (i + 1) >> 1; // hackish way to calculate dc_extra_sbits[]
276
4080
    c -= c > 1;
277
278
4080
    e = get_bits(w->gb, c); // get the extra bits
279
4080
    i = dc_index_offset[i] + (e >> 1);
280
281
4080
    e      = -(e & 1);     // 0, 0xffffff
282
4080
    *level =  (i ^ e) - e; // (i ^ 0) - 0, (i ^ 0xff) - (-1)
283
4080
    return 0;
284
}
285
286
// end of huffman
287
288
5400
static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma)
289
{
290
    int range;
291
    int sum;
292
    int quant;
293
294
5400
    w->dsp.setup_spatial_compensation(w->dest[chroma], w->scratchpad,
295
5400
                                      w->frame->linesize[chroma > 0],
296
                                      &range, &sum, w->edges);
297
5400
    if (chroma) {
298
1800
        w->orient = w->chroma_orient;
299
1800
        quant     = w->quant_dc_chroma;
300
    } else {
301
3600
        quant = w->quant;
302
    }
303
304
5400
    w->flat_dc = 0;
305

5400
    if (range < quant || range < 3) {
306
3386
        w->orient = 0;
307
308
        // yep you read right, a +-1 idct error may break decoding!
309
3386
        if (range < 3) {
310
1365
            w->flat_dc      = 1;
311
1365
            sum            += 9;
312
            // ((1 << 17) + 9) / (8 + 8 + 1 + 2) = 6899
313
1365
            w->predicted_dc = sum * 6899 >> 17;
314
        }
315
    }
316
5400
    if (chroma)
317
1800
        return 0;
318
319
    av_assert2(w->orient < 3);
320
3600
    if (range < 2 * w->quant) {
321
2296
        if ((w->edges & 3) == 0) {
322
2102
            if (w->orient == 1)
323
6
                w->orient = 11;
324
2102
            if (w->orient == 2)
325
16
                w->orient = 10;
326
        } else {
327
194
            w->orient = 0;
328
        }
329
2296
        w->raw_orient = 0;
330
    } else {
331
        static const uint8_t prediction_table[3][12] = {
332
            { 0, 8, 4, 10, 11, 2, 6, 9, 1, 3, 5, 7 },
333
            { 4, 0, 8, 11, 10, 3, 5, 2, 6, 9, 1, 7 },
334
            { 8, 0, 4, 10, 11, 1, 7, 2, 6, 9, 3, 5 },
335
        };
336
1304
        w->raw_orient = x8_get_orient_vlc(w);
337
1304
        if (w->raw_orient < 0)
338
            return -1;
339
        av_assert2(w->raw_orient < 12);
340
        av_assert2(w->orient < 3);
341
1304
        w->orient=prediction_table[w->orient][w->raw_orient];
342
    }
343
3600
    return 0;
344
}
345
346
3600
static void x8_update_predictions(IntraX8Context *const w, const int orient,
347
                                  const int est_run)
348
{
349
3600
    w->prediction_table[w->mb_x * 2 + (w->mb_y & 1)] = (est_run << 2) + 1 * (orient == 4) + 2 * (orient == 8);
350
/*
351
 * y = 2n + 0 -> // 0 2 4
352
 * y = 2n + 1 -> // 1 3 5
353
 */
354
3600
}
355
356
900
static void x8_get_prediction_chroma(IntraX8Context *const w)
357
{
358
900
    w->edges  = 1 * !(w->mb_x >> 1);
359
900
    w->edges |= 2 * !(w->mb_y >> 1);
360
900
    w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1)); // mb_x for chroma would always be odd
361
362
900
    w->raw_orient = 0;
363
    // lut_co[8] = {inv,4,8,8, inv,4,8,8} <- => {1,1,0,0;1,1,0,0} => 0xCC
364
900
    if (w->edges & 3) {
365
102
        w->chroma_orient = 4 << ((0xCC >> w->edges) & 1);
366
102
        return;
367
    }
368
    // block[x - 1][y | 1 - 1)]
369
798
    w->chroma_orient = (w->prediction_table[2 * w->mb_x - 2] & 0x03) << 2;
370
}
371
372
3600
static void x8_get_prediction(IntraX8Context *const w)
373
{
374
    int a, b, c, i;
375
376
3600
    w->edges  = 1 * !w->mb_x;
377
3600
    w->edges |= 2 * !w->mb_y;
378
3600
    w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1));
379
380

3600
    switch (w->edges & 3) {
381
3393
    case 0:
382
3393
        break;
383
87
    case 1:
384
        // take the one from the above block[0][y - 1]
385
87
        w->est_run = w->prediction_table[!(w->mb_y & 1)] >> 2;
386
87
        w->orient  = 1;
387
87
        return;
388
117
    case 2:
389
        // take the one from the previous block[x - 1][0]
390
117
        w->est_run = w->prediction_table[2 * w->mb_x - 2] >> 2;
391
117
        w->orient  = 2;
392
117
        return;
393
3
    case 3:
394
3
        w->est_run = 16;
395
3
        w->orient  = 0;
396
3
        return;
397
    }
398
    // no edge cases
399
3393
    b = w->prediction_table[2 * w->mb_x     + !(w->mb_y & 1)]; // block[x    ][y - 1]
400
3393
    a = w->prediction_table[2 * w->mb_x - 2 +  (w->mb_y & 1)]; // block[x - 1][y    ]
401
3393
    c = w->prediction_table[2 * w->mb_x - 2 + !(w->mb_y & 1)]; // block[x - 1][y - 1]
402
403
3393
    w->est_run = FFMIN(b, a);
404
    /* This condition has nothing to do with w->edges, even if it looks
405
     * similar it would trigger if e.g. x = 3; y = 2;
406
     * I guess somebody wrote something wrong and it became standard. */
407
3393
    if ((w->mb_x & w->mb_y) != 0)
408
2565
        w->est_run = FFMIN(c, w->est_run);
409
3393
    w->est_run >>= 2;
410
411
3393
    a &= 3;
412
3393
    b &= 3;
413
3393
    c &= 3;
414
415
3393
    i = (0xFFEAF4C4 >> (2 * b + 8 * a)) & 3;
416
3393
    if (i != 3)
417
3373
        w->orient = i;
418
    else
419
20
        w->orient = (0xFFEAD8 >> (2 * c + 8 * (w->quant > 12))) & 3;
420
/*
421
 * lut1[b][a] = {
422
 * ->{ 0, 1, 0, pad },
423
 *   { 0, 1, X, pad },
424
 *   { 2, 2, 2, pad }
425
 * }
426
 * pad 2  2  2;
427
 * pad X  1  0;
428
 * pad 0  1  0 <-
429
 * -> 11 10 '10 10 '11 11'01 00 '11 00'01 00 => 0xEAF4C4
430
 *
431
 * lut2[q>12][c] = {
432
 * ->{ 0, 2, 1, pad},
433
 *   { 2, 2, 2, pad}
434
 * }
435
 * pad 2  2  2;
436
 * pad 1  2  0 <-
437
 * -> 11 10'10 10 '11 01'10 00 => 0xEAD8
438
 */
439
}
440
441
2761
static void x8_ac_compensation(IntraX8Context *const w, const int direction,
442
                               const int dc_level)
443
{
444
    int t;
445
#define B(x,y)  w->block[0][w->idct_permutation[(x) + (y) * 8]]
446
#define T(x)  ((x) * dc_level + 0x8000) >> 16;
447

2761
    switch (direction) {
448
1946
    case 0:
449
1946
        t        = T(3811); // h
450
1946
        B(1, 0) -= t;
451
1946
        B(0, 1) -= t;
452
453
1946
        t        = T(487); // e
454
1946
        B(2, 0) -= t;
455
1946
        B(0, 2) -= t;
456
457
1946
        t        = T(506); // f
458
1946
        B(3, 0) -= t;
459
1946
        B(0, 3) -= t;
460
461
1946
        t        = T(135); // c
462
1946
        B(4, 0) -= t;
463
1946
        B(0, 4) -= t;
464
1946
        B(2, 1) += t;
465
1946
        B(1, 2) += t;
466
1946
        B(3, 1) += t;
467
1946
        B(1, 3) += t;
468
469
1946
        t        = T(173); // d
470
1946
        B(5, 0) -= t;
471
1946
        B(0, 5) -= t;
472
473
1946
        t        = T(61); // b
474
1946
        B(6, 0) -= t;
475
1946
        B(0, 6) -= t;
476
1946
        B(5, 1) += t;
477
1946
        B(1, 5) += t;
478
479
1946
        t        = T(42); // a
480
1946
        B(7, 0) -= t;
481
1946
        B(0, 7) -= t;
482
1946
        B(4, 1) += t;
483
1946
        B(1, 4) += t;
484
1946
        B(4, 4) += t;
485
486
1946
        t        = T(1084); // g
487
1946
        B(1, 1) += t;
488
489
1946
        w->block_last_index[0] = FFMAX(w->block_last_index[0], 7 * 8);
490
1946
        break;
491
312
    case 1:
492
312
        B(0, 1) -= T(6269);
493
312
        B(0, 3) -= T(708);
494
312
        B(0, 5) -= T(172);
495
312
        B(0, 7) -= T(73);
496
497
312
        w->block_last_index[0] = FFMAX(w->block_last_index[0], 7 * 8);
498
312
        break;
499
503
    case 2:
500
503
        B(1, 0) -= T(6269);
501
503
        B(3, 0) -= T(708);
502
503
        B(5, 0) -= T(172);
503
503
        B(7, 0) -= T(73);
504
505
503
        w->block_last_index[0] = FFMAX(w->block_last_index[0], 7);
506
503
        break;
507
    }
508
#undef B
509
#undef T
510
2761
}
511
512
1365
static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst,
513
                                  const ptrdiff_t linesize)
514
{
515
    int k;
516
12285
    for (k = 0; k < 8; k++) {
517
10920
        memset(dst, pix, 8);
518
10920
        dst += linesize;
519
    }
520
1365
}
521
522
static const int16_t quant_table[64] = {
523
    256, 256, 256, 256, 256, 256, 259, 262,
524
    265, 269, 272, 275, 278, 282, 285, 288,
525
    292, 295, 299, 303, 306, 310, 314, 317,
526
    321, 325, 329, 333, 337, 341, 345, 349,
527
    353, 358, 362, 366, 371, 375, 379, 384,
528
    389, 393, 398, 403, 408, 413, 417, 422,
529
    428, 433, 438, 443, 448, 454, 459, 465,
530
    470, 476, 482, 488, 493, 499, 505, 511,
531
};
532
533
5400
static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma)
534
{
535
    uint8_t *scantable;
536
    int final, run, level;
537
    int ac_mode, dc_mode, est_run, dc_level;
538
    int pos, n;
539
    int zeros_only;
540
    int use_quant_matrix;
541
    int sign;
542
543
    av_assert2(w->orient < 12);
544
5400
    w->bdsp.clear_block(w->block[0]);
545
546
5400
    if (chroma)
547
1800
        dc_mode = 2;
548
    else
549
3600
        dc_mode = !!w->est_run; // 0, 1
550
551
5400
    if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final))
552
        return -1;
553
5400
    n          = 0;
554
5400
    zeros_only = 0;
555
5400
    if (!final) { // decode ac
556
1693
        use_quant_matrix = w->use_quant_matrix;
557
1693
        if (chroma) {
558
368
            ac_mode = 1;
559
368
            est_run = 64; // not used
560
        } else {
561
1325
            if (w->raw_orient < 3)
562
905
                use_quant_matrix = 0;
563
564
1325
            if (w->raw_orient > 4) {
565
124
                ac_mode = 0;
566
124
                est_run = 64;
567
            } else {
568
1201
                if (w->est_run > 1) {
569
540
                    ac_mode = 2;
570
540
                    est_run = w->est_run;
571
                } else {
572
661
                    ac_mode = 3;
573
661
                    est_run = 64;
574
                }
575
            }
576
        }
577
1693
        x8_select_ac_table(w, ac_mode);
578
        /* scantable_selector[12] = { 0, 2, 0, 1, 1, 1, 0, 2, 2, 0, 1, 2 }; <-
579
         * -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 => 0x928548 */
580
1693
        scantable = w->scantable[(0x928548 >> (2 * w->orient)) & 3].permutated;
581
1693
        pos       = 0;
582
        do {
583
8932
            n++;
584
8932
            if (n >= est_run) {
585
2216
                ac_mode = 3;
586
2216
                x8_select_ac_table(w, 3);
587
            }
588
589
8932
            x8_get_ac_rlf(w, ac_mode, &run, &level, &final);
590
591
8932
            pos += run + 1;
592
8932
            if (pos > 63) {
593
                // this also handles vlc error in x8_get_ac_rlf
594
                return -1;
595
            }
596
8932
            level  = (level + 1) * w->dquant;
597
8932
            level += w->qsum;
598
599
8932
            sign  = -get_bits1(w->gb);
600
8932
            level = (level ^ sign) - sign;
601
602
8932
            if (use_quant_matrix)
603
4784
                level = (level * quant_table[pos]) >> 8;
604
605
8932
            w->block[0][scantable[pos]] = level;
606
8932
        } while (!final);
607
608
1693
        w->block_last_index[0] = pos;
609
    } else { // DC only
610
3707
        w->block_last_index[0] = 0;
611

3707
        if (w->flat_dc && ((unsigned) (dc_level + 1)) < 3) { // [-1; 1]
612
1189
            int32_t divide_quant = !chroma ? w->divide_quant_dc_luma
613
1189
                                           : w->divide_quant_dc_chroma;
614
1189
            int32_t dc_quant     = !chroma ? w->quant
615
1189
                                           : w->quant_dc_chroma;
616
617
            // original intent dc_level += predicted_dc/quant;
618
            // but it got lost somewhere in the rounding
619
1189
            dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13;
620
621
1189
            dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3),
622
                                  w->dest[chroma],
623
1189
                                  w->frame->linesize[!!chroma]);
624
625
1189
            goto block_placed;
626
        }
627
2518
        zeros_only = dc_level == 0;
628
    }
629
4211
    if (!chroma)
630
3071
        w->block[0][0] = dc_level * w->quant;
631
    else
632
1140
        w->block[0][0] = dc_level * w->quant_dc_chroma;
633
634
    // there is !zero_only check in the original, but dc_level check is enough
635

4211
    if ((unsigned int) (dc_level + 1) >= 3 && (w->edges & 3) != 3) {
636
        int direction;
637
        /* ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 }; <-
638
         * -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 => 0x6A017C */
639
2780
        direction = (0x6A017C >> (w->orient * 2)) & 3;
640
2780
        if (direction != 3) {
641
            // modify block_last[]
642
2761
            x8_ac_compensation(w, direction, w->block[0][0]);
643
        }
644
    }
645
646
4211
    if (w->flat_dc) {
647
176
        dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma],
648
176
                              w->frame->linesize[!!chroma]);
649
    } else {
650
4035
        w->dsp.spatial_compensation[w->orient](w->scratchpad,
651
                                               w->dest[chroma],
652
4035
                                               w->frame->linesize[!!chroma]);
653
    }
654
4211
    if (!zeros_only)
655
3825
        w->wdsp.idct_add(w->dest[chroma],
656
3825
                         w->frame->linesize[!!chroma],
657
3825
                         w->block[0]);
658
659
386
block_placed:
660
5400
    if (!chroma)
661
3600
        x8_update_predictions(w, w->orient, n);
662
663
5400
    if (w->loopfilter) {
664
5400
        uint8_t *ptr = w->dest[chroma];
665
5400
        ptrdiff_t linesize = w->frame->linesize[!!chroma];
666
667

5400
        if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4)))
668
4836
            w->dsp.h_loop_filter(ptr, linesize, w->quant);
669
670

5400
        if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8)))
671
4849
            w->dsp.v_loop_filter(ptr, linesize, w->quant);
672
    }
673
5400
    return 0;
674
}
675
676
// FIXME maybe merge with ff_*
677
90
static void x8_init_block_index(IntraX8Context *w, AVFrame *frame)
678
{
679
    // not parent codec linesize as this would be wrong for field pics
680
    // not that IntraX8 has interlacing support ;)
681
90
    const ptrdiff_t linesize   = frame->linesize[0];
682
90
    const ptrdiff_t uvlinesize = frame->linesize[1];
683
684
90
    w->dest[0] = frame->data[0];
685
90
    w->dest[1] = frame->data[1];
686
90
    w->dest[2] = frame->data[2];
687
688
90
    w->dest[0] +=  w->mb_y       * linesize   << 3;
689
    // chroma blocks are on add rows
690
90
    w->dest[1] += (w->mb_y & ~1) * uvlinesize << 2;
691
90
    w->dest[2] += (w->mb_y & ~1) * uvlinesize << 2;
692
90
}
693
694
54
av_cold int ff_intrax8_common_init(AVCodecContext *avctx,
695
                                   IntraX8Context *w, IDCTDSPContext *idsp,
696
                                   int16_t (*block)[64],
697
                                   int block_last_index[12],
698
                                   int mb_width, int mb_height)
699
{
700
    static AVOnce init_static_once = AV_ONCE_INIT;
701
702
54
    w->avctx = avctx;
703
54
    w->idsp = *idsp;
704
54
    w->mb_width  = mb_width;
705
54
    w->mb_height = mb_height;
706
54
    w->block = block;
707
54
    w->block_last_index = block_last_index;
708
709
    // two rows, 2 blocks per cannon mb
710
54
    w->prediction_table = av_mallocz(w->mb_width * 2 * 2);
711
54
    if (!w->prediction_table)
712
        return AVERROR(ENOMEM);
713
714
54
    ff_wmv2dsp_init(&w->wdsp);
715
716
54
    ff_init_scantable_permutation(w->idct_permutation,
717
54
                                  w->wdsp.idct_perm);
718
719
54
    ff_init_scantable(w->idct_permutation, &w->scantable[0],
720
                      ff_wmv1_scantable[0]);
721
54
    ff_init_scantable(w->idct_permutation, &w->scantable[1],
722
                      ff_wmv1_scantable[2]);
723
54
    ff_init_scantable(w->idct_permutation, &w->scantable[2],
724
                      ff_wmv1_scantable[3]);
725
726
54
    ff_intrax8dsp_init(&w->dsp);
727
54
    ff_blockdsp_init(&w->bdsp, avctx);
728
729
54
    ff_thread_once(&init_static_once, x8_vlc_init);
730
731
54
    return 0;
732
}
733
734
66
av_cold void ff_intrax8_common_end(IntraX8Context *w)
735
{
736
66
    av_freep(&w->prediction_table);
737
66
}
738
739
3
int ff_intrax8_decode_picture(IntraX8Context *w, Picture *pict,
740
                              GetBitContext *gb, int *mb_x, int *mb_y,
741
                              int dquant, int quant_offset,
742
                              int loopfilter, int lowdelay)
743
{
744
    int mb_xy;
745
746
3
    w->gb     = gb;
747
3
    w->dquant = dquant;
748
3
    w->quant  = dquant >> 1;
749
3
    w->qsum   = quant_offset;
750
3
    w->frame  = pict->f;
751
3
    w->loopfilter = loopfilter;
752
3
    w->use_quant_matrix = get_bits1(w->gb);
753
754
3
    w->mb_x = *mb_x;
755
3
    w->mb_y = *mb_y;
756
757
3
    w->divide_quant_dc_luma = ((1 << 16) + (w->quant >> 1)) / w->quant;
758
3
    if (w->quant < 5) {
759
        w->quant_dc_chroma        = w->quant;
760
        w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
761
    } else {
762
3
        w->quant_dc_chroma        = w->quant + ((w->quant + 3) >> 3);
763
3
        w->divide_quant_dc_chroma = ((1 << 16) + (w->quant_dc_chroma >> 1)) / w->quant_dc_chroma;
764
    }
765
3
    x8_reset_vlc_tables(w);
766
767
93
    for (w->mb_y = 0; w->mb_y < w->mb_height * 2; w->mb_y++) {
768
90
        x8_init_block_index(w, w->frame);
769
90
        mb_xy = (w->mb_y >> 1) * (w->mb_width + 1);
770
90
        if (get_bits_left(gb) < 1)
771
            goto error;
772
3690
        for (w->mb_x = 0; w->mb_x < w->mb_width * 2; w->mb_x++) {
773
3600
            x8_get_prediction(w);
774
3600
            if (x8_setup_spatial_predictor(w, 0))
775
                goto error;
776
3600
            if (x8_decode_intra_mb(w, 0))
777
                goto error;
778
779
3600
            if (w->mb_x & w->mb_y & 1) {
780
900
                x8_get_prediction_chroma(w);
781
782
                /* when setting up chroma, no vlc is read,
783
                 * so no error condition can be reached */
784
900
                x8_setup_spatial_predictor(w, 1);
785
900
                if (x8_decode_intra_mb(w, 1))
786
                    goto error;
787
788
900
                x8_setup_spatial_predictor(w, 2);
789
900
                if (x8_decode_intra_mb(w, 2))
790
                    goto error;
791
792
900
                w->dest[1] += 8;
793
900
                w->dest[2] += 8;
794
795
900
                pict->qscale_table[mb_xy] = w->quant;
796
900
                mb_xy++;
797
            }
798
3600
            w->dest[0] += 8;
799
        }
800
90
        if (w->mb_y & 1)
801
45
            ff_draw_horiz_band(w->avctx, w->frame, w->frame,
802
45
                               (w->mb_y - 1) * 8, 16,
803
                               PICT_FRAME, 0, lowdelay);
804
    }
805
806
3
error:
807
3
    *mb_x = w->mb_x;
808
3
    *mb_y = w->mb_y;
809
810
3
    return 0;
811
}