GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/intrax8.c Lines: 363 380 95.5 %
Date: 2019-11-18 18:00:01 Branches: 141 157 89.8 %

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 "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
45
static VLC j_ac_vlc[2][2][8];  // [quant < 13], [intra / inter], [select]
46
static VLC j_dc_vlc[2][8];     // [quant], [select]
47
static VLC j_orient_vlc[2][4]; // [quant], [select]
48
49
54
static av_cold int x8_vlc_init(void)
50
{
51
    int i;
52
54
    int offset = 0;
53
54
    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
486
    for (i = 0; i < 8; i++) {
79
432
        init_ac_vlc(j_ac_vlc[0][0][i], x8_ac0_highquant_table[i][0]);
80
432
        init_ac_vlc(j_ac_vlc[0][1][i], x8_ac1_highquant_table[i][0]);
81
432
        init_ac_vlc(j_ac_vlc[1][0][i], x8_ac0_lowquant_table[i][0]);
82
432
        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
486
    for (i = 0; i < 8; i++) {
97
432
        init_dc_vlc(j_dc_vlc[0][i], x8_dc_highquant_table[i][0]);
98
432
        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
162
    for (i = 0; i < 2; i++)
113
108
        init_or_vlc(j_orient_vlc[0][i], x8_orient_highquant_table[i][0]);
114
270
    for (i = 0; i < 4; i++)
115
216
        init_or_vlc(j_orient_vlc[1][i], x8_orient_lowquant_table[i][0]);
116
#undef init_or_vlc
117
118
54
    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
54
    return 0;
125
}
126
127
3
static void x8_reset_vlc_tables(IntraX8Context *w)
128
{
129
3
    memset(w->j_dc_vlc, 0, sizeof(w->j_dc_vlc));
130
3
    memset(w->j_ac_vlc, 0, sizeof(w->j_ac_vlc));
131
3
    w->j_orient_vlc = NULL;
132
3
}
133
134
3909
static inline void x8_select_ac_table(IntraX8Context *const w, int mode)
135
{
136
    int table_index;
137
138
    av_assert2(mode < 4);
139
140
3909
    if (w->j_ac_vlc[mode])
141
3897
        return;
142
143
12
    table_index       = get_bits(w->gb, 3);
144
    // 2 modes use same tables
145
12
    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
149
1304
static inline int x8_get_orient_vlc(IntraX8Context *w)
150
{
151
1304
    if (!w->j_orient_vlc) {
152
3
        int table_index = get_bits(w->gb, 1 + (w->quant < 13));
153
3
        w->j_orient_vlc = &j_orient_vlc[w->quant < 13][table_index];
154
    }
155
156
1304
    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
164
static 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
206
8932
static 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
8932
    i = get_vlc2(w->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD);
213
214
8932
    if (i < 46) { // [0-45]
215
        int t, l;
216
7635
        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
7635
        *final =
231
7635
        t      = i > 22;
232
7635
        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
7635
        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
7635
        t = 0x01030F >> (l << 3);
241
242
7635
        *run   = i & t;
243
7635
        *level = l;
244
1297
    } else if (i < 73) { // [46-72]
245
        uint32_t sm;
246
        uint32_t mask;
247
248
1057
        i -= 46;
249
1057
        sm = ac_decode_table[i];
250
251
1057
        e    = get_bits(w->gb, sm & 0xF);
252
1057
        sm >>= 8;                               // 3 bits
253
1057
        mask = sm & 0xff;
254
1057
        sm >>= 8;                               // 1 bit
255
256
1057
        *run   = (sm &  0xff) + (e &  mask);    // 6 bits
257
1057
        *level = (sm >>    8) + (e & ~mask);    // 5 bits
258
1057
        *final = i > (58 - 46);
259
240
    } 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
234
        *final = !(i & 1);
268
234
        e      = get_bits(w->gb, 5); // get the extra bits
269
234
        *run   = crazy_mix_runlevel[e] >> 4;
270
234
        *level = crazy_mix_runlevel[e] & 0x0F;
271
    } else {
272
6
        *level = get_bits(w->gb, 7 - 3 * (i & 1));
273
6
        *run   = get_bits(w->gb, 6);
274
6
        *final = get_bits1(w->gb);
275
    }
276
8932
    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
 * }; */
282
static 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
286
5400
static 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
5400
    if (!w->j_dc_vlc[mode]) {
293
9
        int table_index = get_bits(w->gb, 3);
294
        // 4 modes, same table
295
9
        w->j_dc_vlc[mode] = &j_dc_vlc[w->quant < 13][table_index];
296
    }
297
298
5400
    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
5400
    c      = i > 16;
302
5400
    *final = c;
303
5400
    i      -= 17 * c;
304
305
5400
    if (i <= 0) {
306
1320
        *level = 0;
307
1320
        return -i;
308
    }
309
4080
    c  = (i + 1) >> 1; // hackish way to calculate dc_extra_sbits[]
310
4080
    c -= c > 1;
311
312
4080
    e = get_bits(w->gb, c); // get the extra bits
313
4080
    i = dc_index_offset[i] + (e >> 1);
314
315
4080
    e      = -(e & 1);     // 0, 0xffffff
316
4080
    *level =  (i ^ e) - e; // (i ^ 0) - 0, (i ^ 0xff) - (-1)
317
4080
    return 0;
318
}
319
320
// end of huffman
321
322
5400
static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma)
323
{
324
    int range;
325
    int sum;
326
    int quant;
327
328
5400
    w->dsp.setup_spatial_compensation(w->dest[chroma], w->scratchpad,
329
5400
                                      w->frame->linesize[chroma > 0],
330
                                      &range, &sum, w->edges);
331
5400
    if (chroma) {
332
1800
        w->orient = w->chroma_orient;
333
1800
        quant     = w->quant_dc_chroma;
334
    } else {
335
3600
        quant = w->quant;
336
    }
337
338
5400
    w->flat_dc = 0;
339

5400
    if (range < quant || range < 3) {
340
3386
        w->orient = 0;
341
342
        // yep you read right, a +-1 idct error may break decoding!
343
3386
        if (range < 3) {
344
1365
            w->flat_dc      = 1;
345
1365
            sum            += 9;
346
            // ((1 << 17) + 9) / (8 + 8 + 1 + 2) = 6899
347
1365
            w->predicted_dc = sum * 6899 >> 17;
348
        }
349
    }
350
5400
    if (chroma)
351
1800
        return 0;
352
353
    av_assert2(w->orient < 3);
354
3600
    if (range < 2 * w->quant) {
355
2296
        if ((w->edges & 3) == 0) {
356
2102
            if (w->orient == 1)
357
6
                w->orient = 11;
358
2102
            if (w->orient == 2)
359
16
                w->orient = 10;
360
        } else {
361
194
            w->orient = 0;
362
        }
363
2296
        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
1304
        w->raw_orient = x8_get_orient_vlc(w);
371
1304
        if (w->raw_orient < 0)
372
            return -1;
373
        av_assert2(w->raw_orient < 12);
374
        av_assert2(w->orient < 3);
375
1304
        w->orient=prediction_table[w->orient][w->raw_orient];
376
    }
377
3600
    return 0;
378
}
379
380
3600
static void x8_update_predictions(IntraX8Context *const w, const int orient,
381
                                  const int est_run)
382
{
383
3600
    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
3600
}
389
390
900
static void x8_get_prediction_chroma(IntraX8Context *const w)
391
{
392
900
    w->edges  = 1 * !(w->mb_x >> 1);
393
900
    w->edges |= 2 * !(w->mb_y >> 1);
394
900
    w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1)); // mb_x for chroma would always be odd
395
396
900
    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
900
    if (w->edges & 3) {
399
102
        w->chroma_orient = 4 << ((0xCC >> w->edges) & 1);
400
102
        return;
401
    }
402
    // block[x - 1][y | 1 - 1)]
403
798
    w->chroma_orient = (w->prediction_table[2 * w->mb_x - 2] & 0x03) << 2;
404
}
405
406
3600
static void x8_get_prediction(IntraX8Context *const w)
407
{
408
    int a, b, c, i;
409
410
3600
    w->edges  = 1 * !w->mb_x;
411
3600
    w->edges |= 2 * !w->mb_y;
412
3600
    w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1));
413
414

3600
    switch (w->edges & 3) {
415
3393
    case 0:
416
3393
        break;
417
87
    case 1:
418
        // take the one from the above block[0][y - 1]
419
87
        w->est_run = w->prediction_table[!(w->mb_y & 1)] >> 2;
420
87
        w->orient  = 1;
421
87
        return;
422
117
    case 2:
423
        // take the one from the previous block[x - 1][0]
424
117
        w->est_run = w->prediction_table[2 * w->mb_x - 2] >> 2;
425
117
        w->orient  = 2;
426
117
        return;
427
3
    case 3:
428
3
        w->est_run = 16;
429
3
        w->orient  = 0;
430
3
        return;
431
    }
432
    // no edge cases
433
3393
    b = w->prediction_table[2 * w->mb_x     + !(w->mb_y & 1)]; // block[x    ][y - 1]
434
3393
    a = w->prediction_table[2 * w->mb_x - 2 +  (w->mb_y & 1)]; // block[x - 1][y    ]
435
3393
    c = w->prediction_table[2 * w->mb_x - 2 + !(w->mb_y & 1)]; // block[x - 1][y - 1]
436
437
3393
    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
3393
    if ((w->mb_x & w->mb_y) != 0)
442
2565
        w->est_run = FFMIN(c, w->est_run);
443
3393
    w->est_run >>= 2;
444
445
3393
    a &= 3;
446
3393
    b &= 3;
447
3393
    c &= 3;
448
449
3393
    i = (0xFFEAF4C4 >> (2 * b + 8 * a)) & 3;
450
3393
    if (i != 3)
451
3373
        w->orient = i;
452
    else
453
20
        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
475
2761
static 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

2761
    switch (direction) {
482
1946
    case 0:
483
1946
        t        = T(3811); // h
484
1946
        B(1, 0) -= t;
485
1946
        B(0, 1) -= t;
486
487
1946
        t        = T(487); // e
488
1946
        B(2, 0) -= t;
489
1946
        B(0, 2) -= t;
490
491
1946
        t        = T(506); // f
492
1946
        B(3, 0) -= t;
493
1946
        B(0, 3) -= t;
494
495
1946
        t        = T(135); // c
496
1946
        B(4, 0) -= t;
497
1946
        B(0, 4) -= t;
498
1946
        B(2, 1) += t;
499
1946
        B(1, 2) += t;
500
1946
        B(3, 1) += t;
501
1946
        B(1, 3) += t;
502
503
1946
        t        = T(173); // d
504
1946
        B(5, 0) -= t;
505
1946
        B(0, 5) -= t;
506
507
1946
        t        = T(61); // b
508
1946
        B(6, 0) -= t;
509
1946
        B(0, 6) -= t;
510
1946
        B(5, 1) += t;
511
1946
        B(1, 5) += t;
512
513
1946
        t        = T(42); // a
514
1946
        B(7, 0) -= t;
515
1946
        B(0, 7) -= t;
516
1946
        B(4, 1) += t;
517
1946
        B(1, 4) += t;
518
1946
        B(4, 4) += t;
519
520
1946
        t        = T(1084); // g
521
1946
        B(1, 1) += t;
522
523
1946
        w->block_last_index[0] = FFMAX(w->block_last_index[0], 7 * 8);
524
1946
        break;
525
312
    case 1:
526
312
        B(0, 1) -= T(6269);
527
312
        B(0, 3) -= T(708);
528
312
        B(0, 5) -= T(172);
529
312
        B(0, 7) -= T(73);
530
531
312
        w->block_last_index[0] = FFMAX(w->block_last_index[0], 7 * 8);
532
312
        break;
533
503
    case 2:
534
503
        B(1, 0) -= T(6269);
535
503
        B(3, 0) -= T(708);
536
503
        B(5, 0) -= T(172);
537
503
        B(7, 0) -= T(73);
538
539
503
        w->block_last_index[0] = FFMAX(w->block_last_index[0], 7);
540
503
        break;
541
    }
542
#undef B
543
#undef T
544
2761
}
545
546
1365
static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst,
547
                                  const ptrdiff_t linesize)
548
{
549
    int k;
550
12285
    for (k = 0; k < 8; k++) {
551
10920
        memset(dst, pix, 8);
552
10920
        dst += linesize;
553
    }
554
1365
}
555
556
static 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
567
5400
static 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
5400
    w->bdsp.clear_block(w->block[0]);
579
580
5400
    if (chroma)
581
1800
        dc_mode = 2;
582
    else
583
3600
        dc_mode = !!w->est_run; // 0, 1
584
585
5400
    if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final))
586
        return -1;
587
5400
    n          = 0;
588
5400
    zeros_only = 0;
589
5400
    if (!final) { // decode ac
590
1693
        use_quant_matrix = w->use_quant_matrix;
591
1693
        if (chroma) {
592
368
            ac_mode = 1;
593
368
            est_run = 64; // not used
594
        } else {
595
1325
            if (w->raw_orient < 3)
596
905
                use_quant_matrix = 0;
597
598
1325
            if (w->raw_orient > 4) {
599
124
                ac_mode = 0;
600
124
                est_run = 64;
601
            } else {
602
1201
                if (w->est_run > 1) {
603
540
                    ac_mode = 2;
604
540
                    est_run = w->est_run;
605
                } else {
606
661
                    ac_mode = 3;
607
661
                    est_run = 64;
608
                }
609
            }
610
        }
611
1693
        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
1693
        scantable = w->scantable[(0x928548 >> (2 * w->orient)) & 3].permutated;
615
1693
        pos       = 0;
616
        do {
617
8932
            n++;
618
8932
            if (n >= est_run) {
619
2216
                ac_mode = 3;
620
2216
                x8_select_ac_table(w, 3);
621
            }
622
623
8932
            x8_get_ac_rlf(w, ac_mode, &run, &level, &final);
624
625
8932
            pos += run + 1;
626
8932
            if (pos > 63) {
627
                // this also handles vlc error in x8_get_ac_rlf
628
                return -1;
629
            }
630
8932
            level  = (level + 1) * w->dquant;
631
8932
            level += w->qsum;
632
633
8932
            sign  = -get_bits1(w->gb);
634
8932
            level = (level ^ sign) - sign;
635
636
8932
            if (use_quant_matrix)
637
4784
                level = (level * quant_table[pos]) >> 8;
638
639
8932
            w->block[0][scantable[pos]] = level;
640
8932
        } while (!final);
641
642
1693
        w->block_last_index[0] = pos;
643
    } else { // DC only
644
3707
        w->block_last_index[0] = 0;
645

3707
        if (w->flat_dc && ((unsigned) (dc_level + 1)) < 3) { // [-1; 1]
646
1189
            int32_t divide_quant = !chroma ? w->divide_quant_dc_luma
647
1189
                                           : w->divide_quant_dc_chroma;
648
1189
            int32_t dc_quant     = !chroma ? w->quant
649
1189
                                           : w->quant_dc_chroma;
650
651
            // original intent dc_level += predicted_dc/quant;
652
            // but it got lost somewhere in the rounding
653
1189
            dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13;
654
655
1189
            dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3),
656
                                  w->dest[chroma],
657
1189
                                  w->frame->linesize[!!chroma]);
658
659
1189
            goto block_placed;
660
        }
661
2518
        zeros_only = dc_level == 0;
662
    }
663
4211
    if (!chroma)
664
3071
        w->block[0][0] = dc_level * w->quant;
665
    else
666
1140
        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

4211
    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
2780
        direction = (0x6A017C >> (w->orient * 2)) & 3;
674
2780
        if (direction != 3) {
675
            // modify block_last[]
676
2761
            x8_ac_compensation(w, direction, w->block[0][0]);
677
        }
678
    }
679
680
4211
    if (w->flat_dc) {
681
176
        dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma],
682
176
                              w->frame->linesize[!!chroma]);
683
    } else {
684
4035
        w->dsp.spatial_compensation[w->orient](w->scratchpad,
685
                                               w->dest[chroma],
686
4035
                                               w->frame->linesize[!!chroma]);
687
    }
688
4211
    if (!zeros_only)
689
3825
        w->wdsp.idct_add(w->dest[chroma],
690
3825
                         w->frame->linesize[!!chroma],
691
3825
                         w->block[0]);
692
693
386
block_placed:
694
5400
    if (!chroma)
695
3600
        x8_update_predictions(w, w->orient, n);
696
697
5400
    if (w->loopfilter) {
698
5400
        uint8_t *ptr = w->dest[chroma];
699
5400
        ptrdiff_t linesize = w->frame->linesize[!!chroma];
700
701

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

5400
        if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8)))
705
4849
            w->dsp.v_loop_filter(ptr, linesize, w->quant);
706
    }
707
5400
    return 0;
708
}
709
710
// FIXME maybe merge with ff_*
711
90
static 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
90
    const ptrdiff_t linesize   = frame->linesize[0];
716
90
    const ptrdiff_t uvlinesize = frame->linesize[1];
717
718
90
    w->dest[0] = frame->data[0];
719
90
    w->dest[1] = frame->data[1];
720
90
    w->dest[2] = frame->data[2];
721
722
90
    w->dest[0] +=  w->mb_y       * linesize   << 3;
723
    // chroma blocks are on add rows
724
90
    w->dest[1] += (w->mb_y & ~1) * uvlinesize << 2;
725
90
    w->dest[2] += (w->mb_y & ~1) * uvlinesize << 2;
726
90
}
727
728
54
av_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
54
    int ret = x8_vlc_init();
735
54
    if (ret < 0)
736
        return ret;
737
738
54
    w->avctx = avctx;
739
54
    w->idsp = *idsp;
740
54
    w->mb_width  = mb_width;
741
54
    w->mb_height = mb_height;
742
54
    w->block = block;
743
54
    w->block_last_index = block_last_index;
744
745
    // two rows, 2 blocks per cannon mb
746
54
    w->prediction_table = av_mallocz(w->mb_width * 2 * 2);
747
54
    if (!w->prediction_table)
748
        return AVERROR(ENOMEM);
749
750
54
    ff_wmv2dsp_init(&w->wdsp);
751
752
54
    ff_init_scantable_permutation(w->idct_permutation,
753
54
                                  w->wdsp.idct_perm);
754
755
54
    ff_init_scantable(w->idct_permutation, &w->scantable[0],
756
                      ff_wmv1_scantable[0]);
757
54
    ff_init_scantable(w->idct_permutation, &w->scantable[1],
758
                      ff_wmv1_scantable[2]);
759
54
    ff_init_scantable(w->idct_permutation, &w->scantable[2],
760
                      ff_wmv1_scantable[3]);
761
762
54
    ff_intrax8dsp_init(&w->dsp);
763
54
    ff_blockdsp_init(&w->bdsp, avctx);
764
765
54
    return 0;
766
}
767
768
66
av_cold void ff_intrax8_common_end(IntraX8Context *w)
769
{
770
66
    av_freep(&w->prediction_table);
771
66
}
772
773
3
int 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
3
    w->gb     = gb;
781
3
    w->dquant = dquant;
782
3
    w->quant  = dquant >> 1;
783
3
    w->qsum   = quant_offset;
784
3
    w->frame  = pict->f;
785
3
    w->loopfilter = loopfilter;
786
3
    w->use_quant_matrix = get_bits1(w->gb);
787
788
3
    w->mb_x = *mb_x;
789
3
    w->mb_y = *mb_y;
790
791
3
    w->divide_quant_dc_luma = ((1 << 16) + (w->quant >> 1)) / w->quant;
792
3
    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
3
        w->quant_dc_chroma        = w->quant + ((w->quant + 3) >> 3);
797
3
        w->divide_quant_dc_chroma = ((1 << 16) + (w->quant_dc_chroma >> 1)) / w->quant_dc_chroma;
798
    }
799
3
    x8_reset_vlc_tables(w);
800
801
93
    for (w->mb_y = 0; w->mb_y < w->mb_height * 2; w->mb_y++) {
802
90
        x8_init_block_index(w, w->frame);
803
90
        mb_xy = (w->mb_y >> 1) * (w->mb_width + 1);
804
3690
        for (w->mb_x = 0; w->mb_x < w->mb_width * 2; w->mb_x++) {
805
3600
            x8_get_prediction(w);
806
3600
            if (x8_setup_spatial_predictor(w, 0))
807
                goto error;
808
3600
            if (x8_decode_intra_mb(w, 0))
809
                goto error;
810
811
3600
            if (w->mb_x & w->mb_y & 1) {
812
900
                x8_get_prediction_chroma(w);
813
814
                /* when setting up chroma, no vlc is read,
815
                 * so no error condition can be reached */
816
900
                x8_setup_spatial_predictor(w, 1);
817
900
                if (x8_decode_intra_mb(w, 1))
818
                    goto error;
819
820
900
                x8_setup_spatial_predictor(w, 2);
821
900
                if (x8_decode_intra_mb(w, 2))
822
                    goto error;
823
824
900
                w->dest[1] += 8;
825
900
                w->dest[2] += 8;
826
827
900
                pict->qscale_table[mb_xy] = w->quant;
828
900
                mb_xy++;
829
            }
830
3600
            w->dest[0] += 8;
831
        }
832
90
        if (w->mb_y & 1)
833
45
            ff_draw_horiz_band(w->avctx, w->frame, w->frame,
834
45
                               (w->mb_y - 1) * 8, 16,
835
                               PICT_FRAME, 0, lowdelay);
836
    }
837
838
3
error:
839
3
    *mb_x = w->mb_x;
840
3
    *mb_y = w->mb_y;
841
842
3
    return 0;
843
}