Coverage Report

Created: 2026-07-25 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/intrax8.c
Line
Count
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/mem.h"
26
#include "libavutil/thread.h"
27
#include "avcodec.h"
28
#include "get_bits.h"
29
#include "idctdsp.h"
30
#include "msmpeg4_vc1_data.h"
31
#include "intrax8huf.h"
32
#include "intrax8.h"
33
#include "intrax8dsp.h"
34
#include "mpegutils.h"
35
36
#define VLC_BUFFER_SIZE 28150
37
38
#define MAX_TABLE_DEPTH(table_bits, max_bits) \
39
26.0M
    ((max_bits + table_bits - 1) / table_bits)
40
41
10.8M
#define DC_VLC_BITS 9
42
11.5M
#define AC_VLC_BITS 9
43
3.70M
#define OR_VLC_BITS 7
44
45
10.8M
#define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS)
46
11.5M
#define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
47
3.70M
#define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS)
48
49
static const VLCElem *j_ac_vlc[2][2][8];  // [quant < 13], [intra / inter], [select]
50
static const VLCElem *j_dc_vlc[2][8];     // [quant], [select]
51
static const VLCElem *j_orient_vlc[2][4]; // [quant], [select]
52
53
static av_cold const VLCElem *x8_init_vlc(VLCInitState *state, int nb_bits,
54
                                          int nb_codes, const uint8_t table[][2])
55
324
{
56
324
    return ff_vlc_init_tables_from_lengths(state, nb_bits, nb_codes, &table[0][1], 2,
57
324
                                           &table[0][0], 2, 1, 0, 0);
58
324
}
59
60
static av_cold void x8_vlc_init(void)
61
6
{
62
6
    static VLCElem vlc_buf[VLC_BUFFER_SIZE];
63
6
    VLCInitState state = VLC_INIT_STATE(vlc_buf);
64
6
    int i;
65
66
// set ac tables
67
18
    for (int i = 0; i < 2; i++)
68
36
        for (int j = 0; j < 2; j++)
69
216
            for (int k = 0; k < 8; k++)
70
192
                j_ac_vlc[i][j][k] = x8_init_vlc(&state, AC_VLC_BITS, 77,
71
192
                                                x8_ac_quant_table[i][j][k]);
72
73
// set dc tables
74
18
    for (int i = 0; i < 2; i++)
75
108
        for (int j = 0; j < 8; j++)
76
96
            j_dc_vlc[i][j] = x8_init_vlc(&state, DC_VLC_BITS, 34,
77
96
                                         x8_dc_quant_table[i][j]);
78
79
// set orient tables
80
18
    for (i = 0; i < 2; i++)
81
12
        j_orient_vlc[0][i] = x8_init_vlc(&state, OR_VLC_BITS, 12,
82
12
                                         x8_orient_highquant_table[i]);
83
30
    for (i = 0; i < 4; i++)
84
24
        j_orient_vlc[1][i] = x8_init_vlc(&state, OR_VLC_BITS, 12,
85
24
                                         x8_orient_lowquant_table[i]);
86
6
}
87
88
static void x8_reset_vlc_tables(IntraX8Context *w)
89
75.8k
{
90
75.8k
    memset(w->j_dc_vlc_table, 0, sizeof(w->j_dc_vlc_table));
91
75.8k
    memset(w->j_ac_vlc_table, 0, sizeof(w->j_ac_vlc_table));
92
75.8k
    w->j_orient_vlc_table = NULL;
93
75.8k
}
94
95
static inline void x8_select_ac_table(IntraX8Context *const w, int mode)
96
5.56M
{
97
5.56M
    int table_index;
98
99
5.56M
    av_assert2(mode < 4);
100
101
5.56M
    if (w->j_ac_vlc_table[mode])
102
5.42M
        return;
103
104
145k
    table_index       = get_bits(w->gb, 3);
105
    // 2 modes use same tables
106
145k
    w->j_ac_vlc_table[mode] = j_ac_vlc[w->quant < 13][mode >> 1][table_index];
107
145k
    av_assert2(w->j_ac_vlc_table[mode]);
108
145k
}
109
110
static inline int x8_get_orient_vlc(IntraX8Context *w)
111
3.70M
{
112
3.70M
    if (!w->j_orient_vlc_table) {
113
28.0k
        int table_index = get_bits(w->gb, 1 + (w->quant < 13));
114
28.0k
        w->j_orient_vlc_table = j_orient_vlc[w->quant < 13][table_index];
115
28.0k
    }
116
117
3.70M
    return get_vlc2(w->gb, w->j_orient_vlc_table, OR_VLC_BITS, OR_VLC_MTD);
118
3.70M
}
119
120
#define extra_bits(eb)  (eb)        // 3 bits
121
#define extra_run       (0xFF << 8) // 1 bit
122
#define extra_level     (0x00 << 8) // 1 bit
123
#define run_offset(r)   ((r) << 16) // 6 bits
124
#define level_offset(l) ((l) << 24) // 5 bits
125
static const uint32_t ac_decode_table[] = {
126
    /* 46 */ extra_bits(3) | extra_run   | run_offset(16) | level_offset(0),
127
    /* 47 */ extra_bits(3) | extra_run   | run_offset(24) | level_offset(0),
128
    /* 48 */ extra_bits(2) | extra_run   | run_offset(4)  | level_offset(1),
129
    /* 49 */ extra_bits(3) | extra_run   | run_offset(8)  | level_offset(1),
130
131
    /* 50 */ extra_bits(5) | extra_run   | run_offset(32) | level_offset(0),
132
    /* 51 */ extra_bits(4) | extra_run   | run_offset(16) | level_offset(1),
133
134
    /* 52 */ extra_bits(2) | extra_level | run_offset(0)  | level_offset(4),
135
    /* 53 */ extra_bits(2) | extra_level | run_offset(0)  | level_offset(8),
136
    /* 54 */ extra_bits(2) | extra_level | run_offset(0)  | level_offset(12),
137
    /* 55 */ extra_bits(3) | extra_level | run_offset(0)  | level_offset(16),
138
    /* 56 */ extra_bits(3) | extra_level | run_offset(0)  | level_offset(24),
139
140
    /* 57 */ extra_bits(2) | extra_level | run_offset(1)  | level_offset(3),
141
    /* 58 */ extra_bits(3) | extra_level | run_offset(1)  | level_offset(7),
142
143
    /* 59 */ extra_bits(2) | extra_run   | run_offset(16) | level_offset(0),
144
    /* 60 */ extra_bits(2) | extra_run   | run_offset(20) | level_offset(0),
145
    /* 61 */ extra_bits(2) | extra_run   | run_offset(24) | level_offset(0),
146
    /* 62 */ extra_bits(2) | extra_run   | run_offset(28) | level_offset(0),
147
    /* 63 */ extra_bits(4) | extra_run   | run_offset(32) | level_offset(0),
148
    /* 64 */ extra_bits(4) | extra_run   | run_offset(48) | level_offset(0),
149
150
    /* 65 */ extra_bits(2) | extra_run   | run_offset(4)  | level_offset(1),
151
    /* 66 */ extra_bits(3) | extra_run   | run_offset(8)  | level_offset(1),
152
    /* 67 */ extra_bits(4) | extra_run   | run_offset(16) | level_offset(1),
153
154
    /* 68 */ extra_bits(2) | extra_level | run_offset(0)  | level_offset(4),
155
    /* 69 */ extra_bits(3) | extra_level | run_offset(0)  | level_offset(8),
156
    /* 70 */ extra_bits(4) | extra_level | run_offset(0)  | level_offset(16),
157
158
    /* 71 */ extra_bits(2) | extra_level | run_offset(1)  | level_offset(3),
159
    /* 72 */ extra_bits(3) | extra_level | run_offset(1)  | level_offset(7),
160
};
161
#undef extra_bits
162
#undef extra_run
163
#undef extra_level
164
#undef run_offset
165
#undef level_offset
166
167
static void x8_get_ac_rlf(IntraX8Context *const w, const int mode,
168
                          int *const run, int *const level, int *const final)
169
11.5M
{
170
11.5M
    int i, e;
171
172
//    x8_select_ac_table(w, mode);
173
11.5M
    i = get_vlc2(w->gb, w->j_ac_vlc_table[mode], AC_VLC_BITS, AC_VLC_MTD);
174
175
11.5M
    if (i < 46) { // [0-45]
176
11.0M
        int t, l;
177
11.0M
        if (i < 0) {
178
0
            *level =
179
0
            *final =      // prevent 'may be used uninitialized'
180
0
            *run   = 64;  // this would cause error exit in the ac loop
181
0
            return;
182
0
        }
183
184
        /*
185
         * i == 0-15  r = 0-15 l = 0; r = i & %01111
186
         * i == 16-19 r = 0-3  l = 1; r = i & %00011
187
         * i == 20-21 r = 0-1  l = 2; r = i & %00001
188
         * i == 22    r = 0    l = 3; r = i & %00000
189
         */
190
191
11.0M
        *final =
192
11.0M
        t      = i > 22;
193
11.0M
        i     -= 23 * t;
194
195
        /* l = lut_l[i / 2] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3 }[i >> 1];
196
         *     11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000 */
197
11.0M
        l = (0xE50000 >> (i & 0x1E)) & 3; // 0x1E or ~1 or (i >> 1 << 1)
198
199
        /* t = lut_mask[l] = { 0x0f, 0x03, 0x01, 0x00 }[l];
200
         *     as i < 256 the higher bits do not matter */
201
11.0M
        t = 0x01030F >> (l << 3);
202
203
11.0M
        *run   = i & t;
204
11.0M
        *level = l;
205
11.0M
    } else if (i < 73) { // [46-72]
206
360k
        uint32_t sm;
207
360k
        uint32_t mask;
208
209
360k
        i -= 46;
210
360k
        sm = ac_decode_table[i];
211
212
360k
        e    = get_bits(w->gb, sm & 0xF);
213
360k
        sm >>= 8;                               // 3 bits
214
360k
        mask = sm & 0xff;
215
360k
        sm >>= 8;                               // 1 bit
216
217
360k
        *run   = (sm &  0xff) + (e &  mask);    // 6 bits
218
360k
        *level = (sm >>    8) + (e & ~mask);    // 5 bits
219
360k
        *final = i > (58 - 46);
220
360k
    } else if (i < 75) { // [73-74]
221
103k
        static const uint8_t crazy_mix_runlevel[32] = {
222
103k
            0x22, 0x32, 0x33, 0x53, 0x23, 0x42, 0x43, 0x63,
223
103k
            0x24, 0x52, 0x34, 0x73, 0x25, 0x62, 0x44, 0x83,
224
103k
            0x26, 0x72, 0x35, 0x54, 0x27, 0x82, 0x45, 0x64,
225
103k
            0x28, 0x92, 0x36, 0x74, 0x29, 0xa2, 0x46, 0x84,
226
103k
        };
227
228
103k
        *final = !(i & 1);
229
103k
        e      = get_bits(w->gb, 5); // get the extra bits
230
103k
        *run   = crazy_mix_runlevel[e] >> 4;
231
103k
        *level = crazy_mix_runlevel[e] & 0x0F;
232
103k
    } else {
233
15.2k
        *level = get_bits(w->gb, 7 - 3 * (i & 1));
234
15.2k
        *run   = get_bits(w->gb, 6);
235
15.2k
        *final = get_bits1(w->gb);
236
15.2k
    }
237
11.5M
    return;
238
11.5M
}
239
240
/* static const uint8_t dc_extra_sbits[] = {
241
 *     0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
242
 * }; */
243
static const uint8_t dc_index_offset[] = {
244
    0, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
245
};
246
247
static int x8_get_dc_rlf(IntraX8Context *const w, const int mode,
248
                         int *const level, int *const final)
249
10.8M
{
250
10.8M
    int i, e, c;
251
252
10.8M
    av_assert2(mode < 3);
253
10.8M
    if (!w->j_dc_vlc_table[mode]) {
254
134k
        int table_index = get_bits(w->gb, 3);
255
        // 4 modes, same table
256
134k
        w->j_dc_vlc_table[mode] = j_dc_vlc[w->quant < 13][table_index];
257
134k
    }
258
259
10.8M
    i = get_vlc2(w->gb, w->j_dc_vlc_table[mode], DC_VLC_BITS, DC_VLC_MTD);
260
261
    /* (i >= 17) { i -= 17; final =1; } */
262
10.8M
    c      = i > 16;
263
10.8M
    *final = c;
264
10.8M
    i      -= 17 * c;
265
266
10.8M
    if (i <= 0) {
267
3.18M
        *level = 0;
268
3.18M
        return -i;
269
3.18M
    }
270
7.64M
    c  = (i + 1) >> 1; // hackish way to calculate dc_extra_sbits[]
271
7.64M
    c -= c > 1;
272
273
7.64M
    e = get_bits(w->gb, c); // get the extra bits
274
7.64M
    i = dc_index_offset[i] + (e >> 1);
275
276
7.64M
    e      = -(e & 1);     // 0, 0xffffff
277
7.64M
    *level =  (i ^ e) - e; // (i ^ 0) - 0, (i ^ 0xff) - (-1)
278
7.64M
    return 0;
279
10.8M
}
280
281
// end of huffman
282
283
static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma)
284
10.8M
{
285
10.8M
    int range;
286
10.8M
    int sum;
287
10.8M
    int quant;
288
289
10.8M
    w->dsp.setup_spatial_compensation(w->dest[chroma], w->scratchpad,
290
10.8M
                                      w->frame->linesize[chroma > 0],
291
10.8M
                                      &range, &sum, w->edges);
292
10.8M
    if (chroma) {
293
3.39M
        w->orient = w->chroma_orient;
294
3.39M
        quant     = w->quant_dc_chroma;
295
7.43M
    } else {
296
7.43M
        quant = w->quant;
297
7.43M
    }
298
299
10.8M
    w->flat_dc = 0;
300
10.8M
    if (range < quant || range < 3) {
301
4.63M
        w->orient = 0;
302
303
        // yep you read right, a +-1 idct error may break decoding!
304
4.63M
        if (range < 3) {
305
2.14M
            w->flat_dc      = 1;
306
2.14M
            sum            += 9;
307
            // ((1 << 17) + 9) / (8 + 8 + 1 + 2) = 6899
308
2.14M
            w->predicted_dc = sum * 6899 >> 17;
309
2.14M
        }
310
4.63M
    }
311
10.8M
    if (chroma)
312
3.39M
        return 0;
313
314
7.43M
    av_assert2(w->orient < 3);
315
7.43M
    if (range < 2 * w->quant) {
316
3.72M
        if ((w->edges & 3) == 0) {
317
2.78M
            if (w->orient == 1)
318
31.5k
                w->orient = 11;
319
2.78M
            if (w->orient == 2)
320
53.9k
                w->orient = 10;
321
2.78M
        } else {
322
939k
            w->orient = 0;
323
939k
        }
324
3.72M
        w->raw_orient = 0;
325
3.72M
    } else {
326
3.70M
        static const uint8_t prediction_table[3][12] = {
327
3.70M
            { 0, 8, 4, 10, 11, 2, 6, 9, 1, 3, 5, 7 },
328
3.70M
            { 4, 0, 8, 11, 10, 3, 5, 2, 6, 9, 1, 7 },
329
3.70M
            { 8, 0, 4, 10, 11, 1, 7, 2, 6, 9, 3, 5 },
330
3.70M
        };
331
3.70M
        w->raw_orient = x8_get_orient_vlc(w);
332
3.70M
        if (w->raw_orient < 0)
333
0
            return -1;
334
3.70M
        av_assert2(w->raw_orient < 12);
335
3.70M
        av_assert2(w->orient < 3);
336
3.70M
        w->orient=prediction_table[w->orient][w->raw_orient];
337
3.70M
    }
338
7.43M
    return 0;
339
7.43M
}
340
341
static void x8_update_predictions(IntraX8Context *const w, const int orient,
342
                                  const int est_run)
343
7.37M
{
344
7.37M
    w->prediction_table[w->mb_x * 2 + (w->mb_y & 1)] = (est_run << 2) + 1 * (orient == 4) + 2 * (orient == 8);
345
/*
346
 * y = 2n + 0 -> // 0 2 4
347
 * y = 2n + 1 -> // 1 3 5
348
 */
349
7.37M
}
350
351
static void x8_get_prediction_chroma(IntraX8Context *const w)
352
1.69M
{
353
1.69M
    w->edges  = 1 * !(w->mb_x >> 1);
354
1.69M
    w->edges |= 2 * !(w->mb_y >> 1);
355
1.69M
    w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1)); // mb_x for chroma would always be odd
356
357
1.69M
    w->raw_orient = 0;
358
    // lut_co[8] = {inv,4,8,8, inv,4,8,8} <- => {1,1,0,0;1,1,0,0} => 0xCC
359
1.69M
    if (w->edges & 3) {
360
246k
        w->chroma_orient = 4 << ((0xCC >> w->edges) & 1);
361
246k
        return;
362
246k
    }
363
    // block[x - 1][y | 1 - 1)]
364
1.45M
    w->chroma_orient = (w->prediction_table[2 * w->mb_x - 2] & 0x03) << 2;
365
1.45M
}
366
367
static void x8_get_prediction(IntraX8Context *const w)
368
7.43M
{
369
7.43M
    int a, b, c, i;
370
371
7.43M
    w->edges  = 1 * !w->mb_x;
372
7.43M
    w->edges |= 2 * !w->mb_y;
373
7.43M
    w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1));
374
375
7.43M
    switch (w->edges & 3) {
376
6.39M
    case 0:
377
6.39M
        break;
378
166k
    case 1:
379
        // take the one from the above block[0][y - 1]
380
166k
        w->est_run = w->prediction_table[!(w->mb_y & 1)] >> 2;
381
166k
        w->orient  = 1;
382
166k
        return;
383
804k
    case 2:
384
        // take the one from the previous block[x - 1][0]
385
804k
        w->est_run = w->prediction_table[2 * w->mb_x - 2] >> 2;
386
804k
        w->orient  = 2;
387
804k
        return;
388
75.3k
    case 3:
389
75.3k
        w->est_run = 16;
390
75.3k
        w->orient  = 0;
391
75.3k
        return;
392
7.43M
    }
393
    // no edge cases
394
6.39M
    b = w->prediction_table[2 * w->mb_x     + !(w->mb_y & 1)]; // block[x    ][y - 1]
395
6.39M
    a = w->prediction_table[2 * w->mb_x - 2 +  (w->mb_y & 1)]; // block[x - 1][y    ]
396
6.39M
    c = w->prediction_table[2 * w->mb_x - 2 + !(w->mb_y & 1)]; // block[x - 1][y - 1]
397
398
6.39M
    w->est_run = FFMIN(b, a);
399
    /* This condition has nothing to do with w->edges, even if it looks
400
     * similar it would trigger if e.g. x = 3; y = 2;
401
     * I guess somebody wrote something wrong and it became standard. */
402
6.39M
    if ((w->mb_x & w->mb_y) != 0)
403
5.15M
        w->est_run = FFMIN(c, w->est_run);
404
6.39M
    w->est_run >>= 2;
405
406
6.39M
    a &= 3;
407
6.39M
    b &= 3;
408
6.39M
    c &= 3;
409
410
6.39M
    i = (0xFFEAF4C4 >> (2 * b + 8 * a)) & 3;
411
6.39M
    if (i != 3)
412
6.32M
        w->orient = i;
413
63.9k
    else
414
63.9k
        w->orient = (0xFFEAD8 >> (2 * c + 8 * (w->quant > 12))) & 3;
415
/*
416
 * lut1[b][a] = {
417
 * ->{ 0, 1, 0, pad },
418
 *   { 0, 1, X, pad },
419
 *   { 2, 2, 2, pad }
420
 * }
421
 * pad 2  2  2;
422
 * pad X  1  0;
423
 * pad 0  1  0 <-
424
 * -> 11 10 '10 10 '11 11'01 00 '11 00'01 00 => 0xEAF4C4
425
 *
426
 * lut2[q>12][c] = {
427
 * ->{ 0, 2, 1, pad},
428
 *   { 2, 2, 2, pad}
429
 * }
430
 * pad 2  2  2;
431
 * pad 1  2  0 <-
432
 * -> 11 10'10 10 '11 01'10 00 => 0xEAD8
433
 */
434
6.39M
}
435
436
static void x8_ac_compensation(IntraX8Context *const w, const int direction,
437
                               const int dc_level)
438
5.22M
{
439
5.22M
    int t;
440
91.8M
#define B(x,y)  w->block[w->idsp.idct_permutation[(x) + (y) * 8]]
441
35.1M
#define T(x)  ((x) * dc_level + 0x8000) >> 16;
442
5.22M
    switch (direction) {
443
3.54M
    case 0:
444
3.54M
        t        = T(3811); // h
445
3.54M
        B(1, 0) -= t;
446
3.54M
        B(0, 1) -= t;
447
448
3.54M
        t        = T(487); // e
449
3.54M
        B(2, 0) -= t;
450
3.54M
        B(0, 2) -= t;
451
452
3.54M
        t        = T(506); // f
453
3.54M
        B(3, 0) -= t;
454
3.54M
        B(0, 3) -= t;
455
456
3.54M
        t        = T(135); // c
457
3.54M
        B(4, 0) -= t;
458
3.54M
        B(0, 4) -= t;
459
3.54M
        B(2, 1) += t;
460
3.54M
        B(1, 2) += t;
461
3.54M
        B(3, 1) += t;
462
3.54M
        B(1, 3) += t;
463
464
3.54M
        t        = T(173); // d
465
3.54M
        B(5, 0) -= t;
466
3.54M
        B(0, 5) -= t;
467
468
3.54M
        t        = T(61); // b
469
3.54M
        B(6, 0) -= t;
470
3.54M
        B(0, 6) -= t;
471
3.54M
        B(5, 1) += t;
472
3.54M
        B(1, 5) += t;
473
474
3.54M
        t        = T(42); // a
475
3.54M
        B(7, 0) -= t;
476
3.54M
        B(0, 7) -= t;
477
3.54M
        B(4, 1) += t;
478
3.54M
        B(1, 4) += t;
479
3.54M
        B(4, 4) += t;
480
481
3.54M
        t        = T(1084); // g
482
3.54M
        B(1, 1) += t;
483
3.54M
        break;
484
658k
    case 1:
485
658k
        B(0, 1) -= T(6269);
486
658k
        B(0, 3) -= T(708);
487
658k
        B(0, 5) -= T(172);
488
658k
        B(0, 7) -= T(73);
489
658k
        break;
490
1.02M
    case 2:
491
1.02M
        B(1, 0) -= T(6269);
492
1.02M
        B(3, 0) -= T(708);
493
1.02M
        B(5, 0) -= T(172);
494
1.02M
        B(7, 0) -= T(73);
495
1.02M
        break;
496
5.22M
    }
497
5.22M
#undef B
498
5.22M
#undef T
499
5.22M
}
500
501
static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst,
502
                                  const ptrdiff_t linesize)
503
2.09M
{
504
2.09M
    int k;
505
18.8M
    for (k = 0; k < 8; k++) {
506
16.7M
        memset(dst, pix, 8);
507
16.7M
        dst += linesize;
508
16.7M
    }
509
2.09M
}
510
511
static const int16_t quant_table[64] = {
512
    256, 256, 256, 256, 256, 256, 259, 262,
513
    265, 269, 272, 275, 278, 282, 285, 288,
514
    292, 295, 299, 303, 306, 310, 314, 317,
515
    321, 325, 329, 333, 337, 341, 345, 349,
516
    353, 358, 362, 366, 371, 375, 379, 384,
517
    389, 393, 398, 403, 408, 413, 417, 422,
518
    428, 433, 438, 443, 448, 454, 459, 465,
519
    470, 476, 482, 488, 493, 499, 505, 511,
520
};
521
522
static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma)
523
10.8M
{
524
10.8M
    uint8_t *scantable;
525
10.8M
    int final, run, level;
526
10.8M
    int ac_mode, dc_mode, est_run, dc_level;
527
10.8M
    int pos, n;
528
10.8M
    int zeros_only;
529
10.8M
    int use_quant_matrix;
530
10.8M
    int sign;
531
532
10.8M
    av_assert2(w->orient < 12);
533
10.8M
    w->bdsp.clear_block(w->block);
534
535
10.8M
    if (chroma)
536
3.39M
        dc_mode = 2;
537
7.43M
    else
538
7.43M
        dc_mode = !!w->est_run; // 0, 1
539
540
10.8M
    if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final))
541
0
        return -1;
542
10.8M
    n          = 0;
543
10.8M
    zeros_only = 0;
544
10.8M
    if (!final) { // decode ac
545
3.67M
        use_quant_matrix = w->use_quant_matrix;
546
3.67M
        if (chroma) {
547
1.16M
            ac_mode = 1;
548
1.16M
            est_run = 64; // not used
549
2.51M
        } else {
550
2.51M
            if (w->raw_orient < 3)
551
2.11M
                use_quant_matrix = 0;
552
553
2.51M
            if (w->raw_orient > 4) {
554
149k
                ac_mode = 0;
555
149k
                est_run = 64;
556
2.36M
            } else {
557
2.36M
                if (w->est_run > 1) {
558
210k
                    ac_mode = 2;
559
210k
                    est_run = w->est_run;
560
2.15M
                } else {
561
2.15M
                    ac_mode = 3;
562
2.15M
                    est_run = 64;
563
2.15M
                }
564
2.36M
            }
565
2.51M
        }
566
3.67M
        x8_select_ac_table(w, ac_mode);
567
        /* scantable_selector[12] = { 0, 2, 0, 1, 1, 1, 0, 2, 2, 0, 1, 2 }; <-
568
         * -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 => 0x928548 */
569
3.67M
        scantable = w->permutated_scantable[(0x928548 >> (2 * w->orient)) & 3];
570
3.67M
        pos       = 0;
571
11.5M
        do {
572
11.5M
            n++;
573
11.5M
            if (n >= est_run) {
574
1.89M
                ac_mode = 3;
575
1.89M
                x8_select_ac_table(w, 3);
576
1.89M
            }
577
578
11.5M
            x8_get_ac_rlf(w, ac_mode, &run, &level, &final);
579
580
11.5M
            pos += run + 1;
581
11.5M
            if (pos > 63) {
582
                // this also handles vlc error in x8_get_ac_rlf
583
70.9k
                return -1;
584
70.9k
            }
585
11.4M
            level  = (level + 1) * w->dquant;
586
11.4M
            level += w->qsum;
587
588
11.4M
            sign  = -get_bits1(w->gb);
589
11.4M
            level = (level ^ sign) - sign;
590
591
11.4M
            if (use_quant_matrix)
592
2.48M
                level = (level * quant_table[pos]) >> 8;
593
594
11.4M
            w->block[scantable[pos]] = level;
595
11.4M
        } while (!final);
596
7.15M
    } else { // DC only
597
7.15M
        if (w->flat_dc && ((unsigned) (dc_level + 1)) < 3) { // [-1; 1]
598
1.39M
            int32_t divide_quant = !chroma ? w->divide_quant_dc_luma
599
1.39M
                                           : w->divide_quant_dc_chroma;
600
1.39M
            int32_t dc_quant     = !chroma ? w->quant
601
1.39M
                                           : w->quant_dc_chroma;
602
603
            // original intent dc_level += predicted_dc/quant;
604
            // but it got lost somewhere in the rounding
605
1.39M
            dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13;
606
607
1.39M
            dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3),
608
1.39M
                                  w->dest[chroma],
609
1.39M
                                  w->frame->linesize[!!chroma]);
610
611
1.39M
            goto block_placed;
612
1.39M
        }
613
5.75M
        zeros_only = dc_level == 0;
614
5.75M
    }
615
9.36M
    if (!chroma)
616
6.36M
        w->block[0] = dc_level * w->quant;
617
2.99M
    else
618
2.99M
        w->block[0] = dc_level * w->quant_dc_chroma;
619
620
    // there is !zero_only check in the original, but dc_level check is enough
621
9.36M
    if ((unsigned int) (dc_level + 1) >= 3 && (w->edges & 3) != 3) {
622
5.31M
        int direction;
623
        /* ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 }; <-
624
         * -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 => 0x6A017C */
625
5.31M
        direction = (0x6A017C >> (w->orient * 2)) & 3;
626
5.31M
        if (direction != 3) {
627
5.22M
            x8_ac_compensation(w, direction, w->block[0]);
628
5.22M
        }
629
5.31M
    }
630
631
9.36M
    if (w->flat_dc) {
632
696k
        dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma],
633
696k
                              w->frame->linesize[!!chroma]);
634
8.66M
    } else {
635
8.66M
        w->dsp.spatial_compensation[w->orient](w->scratchpad,
636
8.66M
                                               w->dest[chroma],
637
8.66M
                                               w->frame->linesize[!!chroma]);
638
8.66M
    }
639
9.36M
    if (!zeros_only)
640
7.49M
        w->idsp.idct_add(w->dest[chroma],
641
7.49M
                         w->frame->linesize[!!chroma],
642
7.49M
                         w->block);
643
644
10.7M
block_placed:
645
10.7M
    if (!chroma)
646
7.37M
        x8_update_predictions(w, w->orient, n);
647
648
10.7M
    if (w->loopfilter) {
649
10.3M
        uint8_t *ptr = w->dest[chroma];
650
10.3M
        ptrdiff_t linesize = w->frame->linesize[!!chroma];
651
652
10.3M
        if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4)))
653
8.03M
            w->dsp.h_loop_filter(ptr, linesize, w->quant);
654
655
10.3M
        if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8)))
656
8.56M
            w->dsp.v_loop_filter(ptr, linesize, w->quant);
657
10.3M
    }
658
10.7M
    return 0;
659
9.36M
}
660
661
// FIXME maybe merge with ff_*
662
static void x8_init_block_index(IntraX8Context *w, AVFrame *frame)
663
244k
{
664
    // not parent codec linesize as this would be wrong for field pics
665
    // not that IntraX8 has interlacing support ;)
666
244k
    const ptrdiff_t linesize   = frame->linesize[0];
667
244k
    const ptrdiff_t uvlinesize = frame->linesize[1];
668
669
244k
    w->dest[0] = frame->data[0];
670
244k
    w->dest[1] = frame->data[1];
671
244k
    w->dest[2] = frame->data[2];
672
673
244k
    w->dest[0] +=  w->mb_y       * linesize   << 3;
674
    // chroma blocks are on add rows
675
244k
    w->dest[1] += (w->mb_y & ~1) * uvlinesize << 2;
676
244k
    w->dest[2] += (w->mb_y & ~1) * uvlinesize << 2;
677
244k
}
678
679
av_cold int ff_intrax8_common_init(AVCodecContext *avctx,
680
                                   IntraX8Context *w,
681
                                   int16_t block[64],
682
                                   int mb_width, int mb_height)
683
61.4k
{
684
61.4k
    static AVOnce init_static_once = AV_ONCE_INIT;
685
686
61.4k
    w->avctx = avctx;
687
61.4k
    w->mb_width  = mb_width;
688
61.4k
    w->mb_height = mb_height;
689
61.4k
    w->block = block;
690
691
    // two rows, 2 blocks per cannon mb
692
61.4k
    w->prediction_table = av_mallocz(w->mb_width * 2 * 2);
693
61.4k
    if (!w->prediction_table)
694
0
        return AVERROR(ENOMEM);
695
696
61.4k
    ff_wmv2dsp_init(&w->idsp);
697
698
61.4k
    ff_permute_scantable(w->permutated_scantable[0], ff_wmv1_scantable[0],
699
61.4k
                         w->idsp.idct_permutation);
700
61.4k
    ff_permute_scantable(w->permutated_scantable[1], ff_wmv1_scantable[2],
701
61.4k
                         w->idsp.idct_permutation);
702
61.4k
    ff_permute_scantable(w->permutated_scantable[2], ff_wmv1_scantable[3],
703
61.4k
                         w->idsp.idct_permutation);
704
705
61.4k
    ff_intrax8dsp_init(&w->dsp);
706
61.4k
    ff_blockdsp_init(&w->bdsp);
707
708
61.4k
    ff_thread_once(&init_static_once, x8_vlc_init);
709
710
61.4k
    return 0;
711
61.4k
}
712
713
av_cold void ff_intrax8_common_end(IntraX8Context *w)
714
62.4k
{
715
62.4k
    av_freep(&w->prediction_table);
716
62.4k
}
717
718
int ff_intrax8_decode_picture(IntraX8Context *w, MPVPicture *pict,
719
                              GetBitContext *gb, int *mb_x, int *mb_y,
720
                              int dquant, int quant_offset,
721
                              int loopfilter, int lowdelay)
722
75.8k
{
723
75.8k
    int mb_xy;
724
725
75.8k
    w->gb     = gb;
726
75.8k
    w->dquant = dquant;
727
75.8k
    w->quant  = dquant >> 1;
728
75.8k
    w->qsum   = quant_offset;
729
75.8k
    w->frame  = pict->f;
730
75.8k
    w->loopfilter = loopfilter;
731
75.8k
    w->use_quant_matrix = get_bits1(w->gb);
732
733
75.8k
    w->mb_x = *mb_x;
734
75.8k
    w->mb_y = *mb_y;
735
736
75.8k
    w->divide_quant_dc_luma = ((1 << 16) + (w->quant >> 1)) / w->quant;
737
75.8k
    if (w->quant < 5) {
738
19.8k
        w->quant_dc_chroma        = w->quant;
739
19.8k
        w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
740
56.0k
    } else {
741
56.0k
        w->quant_dc_chroma        = w->quant + ((w->quant + 3) >> 3);
742
56.0k
        w->divide_quant_dc_chroma = ((1 << 16) + (w->quant_dc_chroma >> 1)) / w->quant_dc_chroma;
743
56.0k
    }
744
75.8k
    x8_reset_vlc_tables(w);
745
746
246k
    for (w->mb_y = 0; w->mb_y < w->mb_height * 2; w->mb_y++) {
747
244k
        x8_init_block_index(w, w->frame);
748
244k
        mb_xy = (w->mb_y >> 1) * (w->mb_width + 1);
749
244k
        if (get_bits_left(gb) < 1)
750
2.03k
            goto error;
751
7.60M
        for (w->mb_x = 0; w->mb_x < w->mb_width * 2; w->mb_x++) {
752
7.43M
            x8_get_prediction(w);
753
7.43M
            if (x8_setup_spatial_predictor(w, 0))
754
0
                goto error;
755
7.43M
            if (x8_decode_intra_mb(w, 0))
756
62.8k
                goto error;
757
758
7.37M
            if (w->mb_x & w->mb_y & 1) {
759
1.69M
                x8_get_prediction_chroma(w);
760
761
                /* when setting up chroma, no vlc is read,
762
                 * so no error condition can be reached */
763
1.69M
                x8_setup_spatial_predictor(w, 1);
764
1.69M
                if (x8_decode_intra_mb(w, 1))
765
3.73k
                    goto error;
766
767
1.69M
                x8_setup_spatial_predictor(w, 2);
768
1.69M
                if (x8_decode_intra_mb(w, 2))
769
4.34k
                    goto error;
770
771
1.69M
                w->dest[1] += 8;
772
1.69M
                w->dest[2] += 8;
773
774
1.69M
                pict->qscale_table[mb_xy] = w->quant;
775
1.69M
                mb_xy++;
776
1.69M
            }
777
7.36M
            w->dest[0] += 8;
778
7.36M
        }
779
171k
        if (w->mb_y & 1)
780
76.6k
            ff_draw_horiz_band(w->avctx, w->frame, w->frame,
781
76.6k
                               (w->mb_y - 1) * 8, 16,
782
76.6k
                               PICT_FRAME, 0, lowdelay);
783
171k
    }
784
785
75.8k
error:
786
75.8k
    *mb_x = w->mb_x;
787
75.8k
    *mb_y = w->mb_y;
788
789
75.8k
    return 0;
790
75.8k
}