Coverage Report

Created: 2026-01-16 07:48

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.4M
    ((max_bits + table_bits - 1) / table_bits)
40
41
10.3M
#define DC_VLC_BITS 9
42
12.6M
#define AC_VLC_BITS 9
43
3.39M
#define OR_VLC_BITS 7
44
45
10.3M
#define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS)
46
12.6M
#define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
47
3.39M
#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
105k
{
90
105k
    memset(w->j_dc_vlc_table, 0, sizeof(w->j_dc_vlc_table));
91
105k
    memset(w->j_ac_vlc_table, 0, sizeof(w->j_ac_vlc_table));
92
105k
    w->j_orient_vlc_table = NULL;
93
105k
}
94
95
static inline void x8_select_ac_table(IntraX8Context *const w, int mode)
96
5.73M
{
97
5.73M
    int table_index;
98
99
5.73M
    av_assert2(mode < 4);
100
101
5.73M
    if (w->j_ac_vlc_table[mode])
102
5.55M
        return;
103
104
181k
    table_index       = get_bits(w->gb, 3);
105
    // 2 modes use same tables
106
181k
    w->j_ac_vlc_table[mode] = j_ac_vlc[w->quant < 13][mode >> 1][table_index];
107
181k
    av_assert2(w->j_ac_vlc_table[mode]);
108
181k
}
109
110
static inline int x8_get_orient_vlc(IntraX8Context *w)
111
3.39M
{
112
3.39M
    if (!w->j_orient_vlc_table) {
113
34.8k
        int table_index = get_bits(w->gb, 1 + (w->quant < 13));
114
34.8k
        w->j_orient_vlc_table = j_orient_vlc[w->quant < 13][table_index];
115
34.8k
    }
116
117
3.39M
    return get_vlc2(w->gb, w->j_orient_vlc_table, OR_VLC_BITS, OR_VLC_MTD);
118
3.39M
}
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
12.6M
{
170
12.6M
    int i, e;
171
172
//    x8_select_ac_table(w, mode);
173
12.6M
    i = get_vlc2(w->gb, w->j_ac_vlc_table[mode], AC_VLC_BITS, AC_VLC_MTD);
174
175
12.6M
    if (i < 46) { // [0-45]
176
12.1M
        int t, l;
177
12.1M
        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
12.1M
        *final =
192
12.1M
        t      = i > 22;
193
12.1M
        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
12.1M
        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
12.1M
        t = 0x01030F >> (l << 3);
202
203
12.1M
        *run   = i & t;
204
12.1M
        *level = l;
205
12.1M
    } else if (i < 73) { // [46-72]
206
357k
        uint32_t sm;
207
357k
        uint32_t mask;
208
209
357k
        i -= 46;
210
357k
        sm = ac_decode_table[i];
211
212
357k
        e    = get_bits(w->gb, sm & 0xF);
213
357k
        sm >>= 8;                               // 3 bits
214
357k
        mask = sm & 0xff;
215
357k
        sm >>= 8;                               // 1 bit
216
217
357k
        *run   = (sm &  0xff) + (e &  mask);    // 6 bits
218
357k
        *level = (sm >>    8) + (e & ~mask);    // 5 bits
219
357k
        *final = i > (58 - 46);
220
357k
    } else if (i < 75) { // [73-74]
221
109k
        static const uint8_t crazy_mix_runlevel[32] = {
222
109k
            0x22, 0x32, 0x33, 0x53, 0x23, 0x42, 0x43, 0x63,
223
109k
            0x24, 0x52, 0x34, 0x73, 0x25, 0x62, 0x44, 0x83,
224
109k
            0x26, 0x72, 0x35, 0x54, 0x27, 0x82, 0x45, 0x64,
225
109k
            0x28, 0x92, 0x36, 0x74, 0x29, 0xa2, 0x46, 0x84,
226
109k
        };
227
228
109k
        *final = !(i & 1);
229
109k
        e      = get_bits(w->gb, 5); // get the extra bits
230
109k
        *run   = crazy_mix_runlevel[e] >> 4;
231
109k
        *level = crazy_mix_runlevel[e] & 0x0F;
232
109k
    } else {
233
14.7k
        *level = get_bits(w->gb, 7 - 3 * (i & 1));
234
14.7k
        *run   = get_bits(w->gb, 6);
235
14.7k
        *final = get_bits1(w->gb);
236
14.7k
    }
237
12.6M
    return;
238
12.6M
}
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.3M
{
250
10.3M
    int i, e, c;
251
252
10.3M
    av_assert2(mode < 3);
253
10.3M
    if (!w->j_dc_vlc_table[mode]) {
254
206k
        int table_index = get_bits(w->gb, 3);
255
        // 4 modes, same table
256
206k
        w->j_dc_vlc_table[mode] = j_dc_vlc[w->quant < 13][table_index];
257
206k
    }
258
259
10.3M
    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.3M
    c      = i > 16;
263
10.3M
    *final = c;
264
10.3M
    i      -= 17 * c;
265
266
10.3M
    if (i <= 0) {
267
2.91M
        *level = 0;
268
2.91M
        return -i;
269
2.91M
    }
270
7.48M
    c  = (i + 1) >> 1; // hackish way to calculate dc_extra_sbits[]
271
7.48M
    c -= c > 1;
272
273
7.48M
    e = get_bits(w->gb, c); // get the extra bits
274
7.48M
    i = dc_index_offset[i] + (e >> 1);
275
276
7.48M
    e      = -(e & 1);     // 0, 0xffffff
277
7.48M
    *level =  (i ^ e) - e; // (i ^ 0) - 0, (i ^ 0xff) - (-1)
278
7.48M
    return 0;
279
10.3M
}
280
281
// end of huffman
282
283
static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma)
284
10.3M
{
285
10.3M
    int range;
286
10.3M
    int sum;
287
10.3M
    int quant;
288
289
10.3M
    w->dsp.setup_spatial_compensation(w->dest[chroma], w->scratchpad,
290
10.3M
                                      w->frame->linesize[chroma > 0],
291
10.3M
                                      &range, &sum, w->edges);
292
10.3M
    if (chroma) {
293
3.22M
        w->orient = w->chroma_orient;
294
3.22M
        quant     = w->quant_dc_chroma;
295
7.17M
    } else {
296
7.17M
        quant = w->quant;
297
7.17M
    }
298
299
10.3M
    w->flat_dc = 0;
300
10.3M
    if (range < quant || range < 3) {
301
4.74M
        w->orient = 0;
302
303
        // yep you read right, a +-1 idct error may break decoding!
304
4.74M
        if (range < 3) {
305
2.27M
            w->flat_dc      = 1;
306
2.27M
            sum            += 9;
307
            // ((1 << 17) + 9) / (8 + 8 + 1 + 2) = 6899
308
2.27M
            w->predicted_dc = sum * 6899 >> 17;
309
2.27M
        }
310
4.74M
    }
311
10.3M
    if (chroma)
312
3.22M
        return 0;
313
314
7.17M
    av_assert2(w->orient < 3);
315
7.17M
    if (range < 2 * w->quant) {
316
3.78M
        if ((w->edges & 3) == 0) {
317
2.71M
            if (w->orient == 1)
318
28.0k
                w->orient = 11;
319
2.71M
            if (w->orient == 2)
320
49.2k
                w->orient = 10;
321
2.71M
        } else {
322
1.07M
            w->orient = 0;
323
1.07M
        }
324
3.78M
        w->raw_orient = 0;
325
3.78M
    } else {
326
3.39M
        static const uint8_t prediction_table[3][12] = {
327
3.39M
            { 0, 8, 4, 10, 11, 2, 6, 9, 1, 3, 5, 7 },
328
3.39M
            { 4, 0, 8, 11, 10, 3, 5, 2, 6, 9, 1, 7 },
329
3.39M
            { 8, 0, 4, 10, 11, 1, 7, 2, 6, 9, 3, 5 },
330
3.39M
        };
331
3.39M
        w->raw_orient = x8_get_orient_vlc(w);
332
3.39M
        if (w->raw_orient < 0)
333
0
            return -1;
334
3.39M
        av_assert2(w->raw_orient < 12);
335
3.39M
        av_assert2(w->orient < 3);
336
3.39M
        w->orient=prediction_table[w->orient][w->raw_orient];
337
3.39M
    }
338
7.17M
    return 0;
339
7.17M
}
340
341
static void x8_update_predictions(IntraX8Context *const w, const int orient,
342
                                  const int est_run)
343
7.10M
{
344
7.10M
    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.10M
}
350
351
static void x8_get_prediction_chroma(IntraX8Context *const w)
352
1.61M
{
353
1.61M
    w->edges  = 1 * !(w->mb_x >> 1);
354
1.61M
    w->edges |= 2 * !(w->mb_y >> 1);
355
1.61M
    w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1)); // mb_x for chroma would always be odd
356
357
1.61M
    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.61M
    if (w->edges & 3) {
360
281k
        w->chroma_orient = 4 << ((0xCC >> w->edges) & 1);
361
281k
        return;
362
281k
    }
363
    // block[x - 1][y | 1 - 1)]
364
1.33M
    w->chroma_orient = (w->prediction_table[2 * w->mb_x - 2] & 0x03) << 2;
365
1.33M
}
366
367
static void x8_get_prediction(IntraX8Context *const w)
368
7.17M
{
369
7.17M
    int a, b, c, i;
370
371
7.17M
    w->edges  = 1 * !w->mb_x;
372
7.17M
    w->edges |= 2 * !w->mb_y;
373
7.17M
    w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1));
374
375
7.17M
    switch (w->edges & 3) {
376
5.98M
    case 0:
377
5.98M
        break;
378
179k
    case 1:
379
        // take the one from the above block[0][y - 1]
380
179k
        w->est_run = w->prediction_table[!(w->mb_y & 1)] >> 2;
381
179k
        w->orient  = 1;
382
179k
        return;
383
910k
    case 2:
384
        // take the one from the previous block[x - 1][0]
385
910k
        w->est_run = w->prediction_table[2 * w->mb_x - 2] >> 2;
386
910k
        w->orient  = 2;
387
910k
        return;
388
104k
    case 3:
389
104k
        w->est_run = 16;
390
104k
        w->orient  = 0;
391
104k
        return;
392
7.17M
    }
393
    // no edge cases
394
5.98M
    b = w->prediction_table[2 * w->mb_x     + !(w->mb_y & 1)]; // block[x    ][y - 1]
395
5.98M
    a = w->prediction_table[2 * w->mb_x - 2 +  (w->mb_y & 1)]; // block[x - 1][y    ]
396
5.98M
    c = w->prediction_table[2 * w->mb_x - 2 + !(w->mb_y & 1)]; // block[x - 1][y - 1]
397
398
5.98M
    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
5.98M
    if ((w->mb_x & w->mb_y) != 0)
403
4.78M
        w->est_run = FFMIN(c, w->est_run);
404
5.98M
    w->est_run >>= 2;
405
406
5.98M
    a &= 3;
407
5.98M
    b &= 3;
408
5.98M
    c &= 3;
409
410
5.98M
    i = (0xFFEAF4C4 >> (2 * b + 8 * a)) & 3;
411
5.98M
    if (i != 3)
412
5.92M
        w->orient = i;
413
59.1k
    else
414
59.1k
        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
5.98M
}
435
436
static void x8_ac_compensation(IntraX8Context *const w, const int direction,
437
                               const int dc_level)
438
4.97M
{
439
4.97M
    int t;
440
88.4M
#define B(x,y)  w->block[w->idsp.idct_permutation[(x) + (y) * 8]]
441
33.5M
#define T(x)  ((x) * dc_level + 0x8000) >> 16;
442
4.97M
    switch (direction) {
443
3.42M
    case 0:
444
3.42M
        t        = T(3811); // h
445
3.42M
        B(1, 0) -= t;
446
3.42M
        B(0, 1) -= t;
447
448
3.42M
        t        = T(487); // e
449
3.42M
        B(2, 0) -= t;
450
3.42M
        B(0, 2) -= t;
451
452
3.42M
        t        = T(506); // f
453
3.42M
        B(3, 0) -= t;
454
3.42M
        B(0, 3) -= t;
455
456
3.42M
        t        = T(135); // c
457
3.42M
        B(4, 0) -= t;
458
3.42M
        B(0, 4) -= t;
459
3.42M
        B(2, 1) += t;
460
3.42M
        B(1, 2) += t;
461
3.42M
        B(3, 1) += t;
462
3.42M
        B(1, 3) += t;
463
464
3.42M
        t        = T(173); // d
465
3.42M
        B(5, 0) -= t;
466
3.42M
        B(0, 5) -= t;
467
468
3.42M
        t        = T(61); // b
469
3.42M
        B(6, 0) -= t;
470
3.42M
        B(0, 6) -= t;
471
3.42M
        B(5, 1) += t;
472
3.42M
        B(1, 5) += t;
473
474
3.42M
        t        = T(42); // a
475
3.42M
        B(7, 0) -= t;
476
3.42M
        B(0, 7) -= t;
477
3.42M
        B(4, 1) += t;
478
3.42M
        B(1, 4) += t;
479
3.42M
        B(4, 4) += t;
480
481
3.42M
        t        = T(1084); // g
482
3.42M
        B(1, 1) += t;
483
3.42M
        break;
484
594k
    case 1:
485
594k
        B(0, 1) -= T(6269);
486
594k
        B(0, 3) -= T(708);
487
594k
        B(0, 5) -= T(172);
488
594k
        B(0, 7) -= T(73);
489
594k
        break;
490
951k
    case 2:
491
951k
        B(1, 0) -= T(6269);
492
951k
        B(3, 0) -= T(708);
493
951k
        B(5, 0) -= T(172);
494
951k
        B(7, 0) -= T(73);
495
951k
        break;
496
4.97M
    }
497
4.97M
#undef B
498
4.97M
#undef T
499
4.97M
}
500
501
static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst,
502
                                  const ptrdiff_t linesize)
503
2.21M
{
504
2.21M
    int k;
505
19.9M
    for (k = 0; k < 8; k++) {
506
17.6M
        memset(dst, pix, 8);
507
17.6M
        dst += linesize;
508
17.6M
    }
509
2.21M
}
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.3M
{
524
10.3M
    uint8_t *scantable;
525
10.3M
    int final, run, level;
526
10.3M
    int ac_mode, dc_mode, est_run, dc_level;
527
10.3M
    int pos, n;
528
10.3M
    int zeros_only;
529
10.3M
    int use_quant_matrix;
530
10.3M
    int sign;
531
532
10.3M
    av_assert2(w->orient < 12);
533
10.3M
    w->bdsp.clear_block(w->block);
534
535
10.3M
    if (chroma)
536
3.22M
        dc_mode = 2;
537
7.17M
    else
538
7.17M
        dc_mode = !!w->est_run; // 0, 1
539
540
10.3M
    if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final))
541
0
        return -1;
542
10.3M
    n          = 0;
543
10.3M
    zeros_only = 0;
544
10.3M
    if (!final) { // decode ac
545
3.55M
        use_quant_matrix = w->use_quant_matrix;
546
3.55M
        if (chroma) {
547
1.11M
            ac_mode = 1;
548
1.11M
            est_run = 64; // not used
549
2.43M
        } else {
550
2.43M
            if (w->raw_orient < 3)
551
2.05M
                use_quant_matrix = 0;
552
553
2.43M
            if (w->raw_orient > 4) {
554
149k
                ac_mode = 0;
555
149k
                est_run = 64;
556
2.28M
            } else {
557
2.28M
                if (w->est_run > 1) {
558
226k
                    ac_mode = 2;
559
226k
                    est_run = w->est_run;
560
2.05M
                } else {
561
2.05M
                    ac_mode = 3;
562
2.05M
                    est_run = 64;
563
2.05M
                }
564
2.28M
            }
565
2.43M
        }
566
3.55M
        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.55M
        scantable = w->permutated_scantable[(0x928548 >> (2 * w->orient)) & 3];
570
3.55M
        pos       = 0;
571
12.6M
        do {
572
12.6M
            n++;
573
12.6M
            if (n >= est_run) {
574
2.18M
                ac_mode = 3;
575
2.18M
                x8_select_ac_table(w, 3);
576
2.18M
            }
577
578
12.6M
            x8_get_ac_rlf(w, ac_mode, &run, &level, &final);
579
580
12.6M
            pos += run + 1;
581
12.6M
            if (pos > 63) {
582
                // this also handles vlc error in x8_get_ac_rlf
583
85.7k
                return -1;
584
85.7k
            }
585
12.5M
            level  = (level + 1) * w->dquant;
586
12.5M
            level += w->qsum;
587
588
12.5M
            sign  = -get_bits1(w->gb);
589
12.5M
            level = (level ^ sign) - sign;
590
591
12.5M
            if (use_quant_matrix)
592
2.54M
                level = (level * quant_table[pos]) >> 8;
593
594
12.5M
            w->block[scantable[pos]] = level;
595
12.5M
        } while (!final);
596
6.84M
    } else { // DC only
597
6.84M
        if (w->flat_dc && ((unsigned) (dc_level + 1)) < 3) { // [-1; 1]
598
1.46M
            int32_t divide_quant = !chroma ? w->divide_quant_dc_luma
599
1.46M
                                           : w->divide_quant_dc_chroma;
600
1.46M
            int32_t dc_quant     = !chroma ? w->quant
601
1.46M
                                           : w->quant_dc_chroma;
602
603
            // original intent dc_level += predicted_dc/quant;
604
            // but it got lost somewhere in the rounding
605
1.46M
            dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13;
606
607
1.46M
            dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3),
608
1.46M
                                  w->dest[chroma],
609
1.46M
                                  w->frame->linesize[!!chroma]);
610
611
1.46M
            goto block_placed;
612
1.46M
        }
613
5.38M
        zeros_only = dc_level == 0;
614
5.38M
    }
615
8.85M
    if (!chroma)
616
6.05M
        w->block[0] = dc_level * w->quant;
617
2.80M
    else
618
2.80M
        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
8.85M
    if ((unsigned int) (dc_level + 1) >= 3 && (w->edges & 3) != 3) {
622
5.04M
        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.04M
        direction = (0x6A017C >> (w->orient * 2)) & 3;
626
5.04M
        if (direction != 3) {
627
4.97M
            x8_ac_compensation(w, direction, w->block[0]);
628
4.97M
        }
629
5.04M
    }
630
631
8.85M
    if (w->flat_dc) {
632
748k
        dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma],
633
748k
                              w->frame->linesize[!!chroma]);
634
8.10M
    } else {
635
8.10M
        w->dsp.spatial_compensation[w->orient](w->scratchpad,
636
8.10M
                                               w->dest[chroma],
637
8.10M
                                               w->frame->linesize[!!chroma]);
638
8.10M
    }
639
8.85M
    if (!zeros_only)
640
7.26M
        w->idsp.idct_add(w->dest[chroma],
641
7.26M
                         w->frame->linesize[!!chroma],
642
7.26M
                         w->block);
643
644
10.3M
block_placed:
645
10.3M
    if (!chroma)
646
7.10M
        x8_update_predictions(w, w->orient, n);
647
648
10.3M
    if (w->loopfilter) {
649
9.82M
        uint8_t *ptr = w->dest[chroma];
650
9.82M
        ptrdiff_t linesize = w->frame->linesize[!!chroma];
651
652
9.82M
        if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4)))
653
7.57M
            w->dsp.h_loop_filter(ptr, linesize, w->quant);
654
655
9.82M
        if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8)))
656
8.22M
            w->dsp.v_loop_filter(ptr, linesize, w->quant);
657
9.82M
    }
658
10.3M
    return 0;
659
8.85M
}
660
661
// FIXME maybe merge with ff_*
662
static void x8_init_block_index(IntraX8Context *w, AVFrame *frame)
663
286k
{
664
    // not parent codec linesize as this would be wrong for field pics
665
    // not that IntraX8 has interlacing support ;)
666
286k
    const ptrdiff_t linesize   = frame->linesize[0];
667
286k
    const ptrdiff_t uvlinesize = frame->linesize[1];
668
669
286k
    w->dest[0] = frame->data[0];
670
286k
    w->dest[1] = frame->data[1];
671
286k
    w->dest[2] = frame->data[2];
672
673
286k
    w->dest[0] +=  w->mb_y       * linesize   << 3;
674
    // chroma blocks are on add rows
675
286k
    w->dest[1] += (w->mb_y & ~1) * uvlinesize << 2;
676
286k
    w->dest[2] += (w->mb_y & ~1) * uvlinesize << 2;
677
286k
}
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
64.3k
{
684
64.3k
    static AVOnce init_static_once = AV_ONCE_INIT;
685
686
64.3k
    w->avctx = avctx;
687
64.3k
    w->mb_width  = mb_width;
688
64.3k
    w->mb_height = mb_height;
689
64.3k
    w->block = block;
690
691
    // two rows, 2 blocks per cannon mb
692
64.3k
    w->prediction_table = av_mallocz(w->mb_width * 2 * 2);
693
64.3k
    if (!w->prediction_table)
694
0
        return AVERROR(ENOMEM);
695
696
64.3k
    ff_wmv2dsp_init(&w->idsp);
697
698
64.3k
    ff_permute_scantable(w->permutated_scantable[0], ff_wmv1_scantable[0],
699
64.3k
                         w->idsp.idct_permutation);
700
64.3k
    ff_permute_scantable(w->permutated_scantable[1], ff_wmv1_scantable[2],
701
64.3k
                         w->idsp.idct_permutation);
702
64.3k
    ff_permute_scantable(w->permutated_scantable[2], ff_wmv1_scantable[3],
703
64.3k
                         w->idsp.idct_permutation);
704
705
64.3k
    ff_intrax8dsp_init(&w->dsp);
706
64.3k
    ff_blockdsp_init(&w->bdsp);
707
708
64.3k
    ff_thread_once(&init_static_once, x8_vlc_init);
709
710
64.3k
    return 0;
711
64.3k
}
712
713
av_cold void ff_intrax8_common_end(IntraX8Context *w)
714
65.4k
{
715
65.4k
    av_freep(&w->prediction_table);
716
65.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
105k
{
723
105k
    int mb_xy;
724
725
105k
    w->gb     = gb;
726
105k
    w->dquant = dquant;
727
105k
    w->quant  = dquant >> 1;
728
105k
    w->qsum   = quant_offset;
729
105k
    w->frame  = pict->f;
730
105k
    w->loopfilter = loopfilter;
731
105k
    w->use_quant_matrix = get_bits1(w->gb);
732
733
105k
    w->mb_x = *mb_x;
734
105k
    w->mb_y = *mb_y;
735
736
105k
    w->divide_quant_dc_luma = ((1 << 16) + (w->quant >> 1)) / w->quant;
737
105k
    if (w->quant < 5) {
738
22.7k
        w->quant_dc_chroma        = w->quant;
739
22.7k
        w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
740
82.3k
    } else {
741
82.3k
        w->quant_dc_chroma        = w->quant + ((w->quant + 3) >> 3);
742
82.3k
        w->divide_quant_dc_chroma = ((1 << 16) + (w->quant_dc_chroma >> 1)) / w->quant_dc_chroma;
743
82.3k
    }
744
105k
    x8_reset_vlc_tables(w);
745
746
303k
    for (w->mb_y = 0; w->mb_y < w->mb_height * 2; w->mb_y++) {
747
286k
        x8_init_block_index(w, w->frame);
748
286k
        mb_xy = (w->mb_y >> 1) * (w->mb_width + 1);
749
286k
        if (get_bits_left(gb) < 1)
750
2.70k
            goto error;
751
7.37M
        for (w->mb_x = 0; w->mb_x < w->mb_width * 2; w->mb_x++) {
752
7.17M
            x8_get_prediction(w);
753
7.17M
            if (x8_setup_spatial_predictor(w, 0))
754
0
                goto error;
755
7.17M
            if (x8_decode_intra_mb(w, 0))
756
74.1k
                goto error;
757
758
7.10M
            if (w->mb_x & w->mb_y & 1) {
759
1.61M
                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.61M
                x8_setup_spatial_predictor(w, 1);
764
1.61M
                if (x8_decode_intra_mb(w, 1))
765
5.01k
                    goto error;
766
767
1.60M
                x8_setup_spatial_predictor(w, 2);
768
1.60M
                if (x8_decode_intra_mb(w, 2))
769
6.62k
                    goto error;
770
771
1.60M
                w->dest[1] += 8;
772
1.60M
                w->dest[2] += 8;
773
774
1.60M
                pict->qscale_table[mb_xy] = w->quant;
775
1.60M
                mb_xy++;
776
1.60M
            }
777
7.09M
            w->dest[0] += 8;
778
7.09M
        }
779
197k
        if (w->mb_y & 1)
780
87.0k
            ff_draw_horiz_band(w->avctx, w->frame, w->frame,
781
87.0k
                               (w->mb_y - 1) * 8, 16,
782
87.0k
                               PICT_FRAME, 0, lowdelay);
783
197k
    }
784
785
105k
error:
786
105k
    *mb_x = w->mb_x;
787
105k
    *mb_y = w->mb_y;
788
789
105k
    return 0;
790
105k
}