GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/imm4.c Lines: 0 278 0.0 %
Date: 2021-01-21 21:11:50 Branches: 0 115 0.0 %

Line Branch Exec Source
1
/*
2
 * Infinity IMM4 decoder
3
 *
4
 * Copyright (c) 2018 Paul B Mahol
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
27
#include "libavutil/mem_internal.h"
28
#include "libavutil/thread.h"
29
30
#include "avcodec.h"
31
#include "bswapdsp.h"
32
#include "copy_block.h"
33
#include "get_bits.h"
34
#include "idctdsp.h"
35
#include "internal.h"
36
37
#define CBPLO_VLC_BITS   6
38
#define CBPHI_VLC_BITS   6
39
#define BLKTYPE_VLC_BITS 9
40
#define BLOCK_VLC_BITS  12
41
42
typedef struct IMM4Context {
43
    BswapDSPContext bdsp;
44
    GetBitContext  gb;
45
46
    AVFrame *prev_frame;
47
    uint8_t *bitstream;
48
    int bitstream_size;
49
50
    int factor;
51
    unsigned lo;
52
    unsigned hi;
53
54
    ScanTable intra_scantable;
55
    DECLARE_ALIGNED(32, int16_t, block)[6][64];
56
    IDCTDSPContext idsp;
57
} IMM4Context;
58
59
static const uint8_t intra_cb[] = {
60
    24, 18, 12
61
};
62
63
static const uint8_t inter_cb[] = {
64
    30, 20, 15
65
};
66
67
static const uint8_t cbplo[][2] = {
68
    {    0,-6 }, { 0x01, 6 }, { 0x02, 6 }, { 0x03, 6 }, { 0x00, 4 },
69
    { 0x01, 3 }, { 0x02, 3 }, { 0x03, 3 }, { 0x00, 1 },
70
};
71
72
static const uint8_t cbphi_bits[] = {
73
    4, 5, 5, 4, 5, 4, 6, 4, 5, 6, 4, 4, 4, 4, 4, 2
74
};
75
76
static const uint8_t cbphi_codes[] = {
77
    3, 5, 4, 9, 3, 7, 2, 11, 2, 3, 5, 10, 4, 8, 6, 3
78
};
79
80
static const uint8_t blktype[][2] = {
81
    {    0,-8 }, { 0x34, 9 }, {    0,-9 }, { 0x14, 9 }, {    0,-9 },
82
    { 0x23, 8 }, { 0x13, 8 }, { 0x32, 8 }, { 0x33, 7 }, { 0x22, 7 },
83
    { 0x12, 7 }, { 0x21, 7 }, { 0x11, 7 }, { 0x04, 6 }, { 0x30, 6 },
84
    { 0x03, 5 }, { 0x20, 4 }, { 0x10, 4 }, { 0x02, 3 }, { 0x01, 3 },
85
    { 0x00, 1 },
86
};
87
88
static const uint16_t block_symbols[] = {
89
         0, 0x4082, 0x4003, 0x000B, 0x000A, 0x4E01, 0x4D81, 0x4D01, 0x4C81,
90
    0x0482, 0x0402, 0x0382, 0x0302, 0x0282, 0x0183, 0x0103, 0x0084, 0x000C,
91
    0x0085, 0x0B81, 0x0C01, 0x4E81, 0x4F01, 0x4F81, 0x5001, 0x0086, 0x0104,
92
    0x0203, 0x0283, 0x0303, 0x0502, 0x0C81, 0x0D01, 0x5081, 0x5101, 0x5181,
93
    0x5201, 0x5281, 0x5301, 0x5381, 0x5401, 0x0000, 0x0009, 0x0008, 0x4C01,
94
    0x4B81, 0x4B01, 0x4A81, 0x4A01, 0x4981, 0x4901, 0x4881, 0x4002, 0x0B01,
95
    0x0A81, 0x0A01, 0x0981, 0x0901, 0x0881, 0x0801, 0x0781, 0x0202, 0x0182,
96
    0x0007, 0x0006, 0x4801, 0x4781, 0x4701, 0x4681, 0x4601, 0x4581, 0x4501,
97
    0x4481, 0x0701, 0x0681, 0x0102, 0x0083, 0x0005, 0x4401, 0x4381, 0x4301,
98
    0x4281, 0x0601, 0x0581, 0x0501, 0x0004, 0x4201, 0x4181, 0x4101, 0x4081,
99
    0x0481, 0x0401, 0x0381, 0x0301, 0x0082, 0x0003, 0x0281, 0x0201, 0x0181,
100
    0x4001, 0x0001, 0x0081, 0x0101, 0x0002,
101
};
102
103
static const uint8_t block_bits[] = {
104
    -9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11,
105
    11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
106
    12, 12, 12,  7, 10, 10,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
107
     9,  9,  9,  9,  9,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
108
     8,  8,  7,  7,  7,  7,  7,  7,  7,  7,  6,  6,  6,  6,  6,  6,  6,  6,  6,
109
     6,  5,  5,  5,  4,  2,  3,  4,  4,
110
};
111
112
static VLC cbplo_tab;
113
static VLC cbphi_tab;
114
static VLC blktype_tab;
115
static VLC block_tab;
116
117
static int get_cbphi(GetBitContext *gb, int x)
118
{
119
    int value;
120
121
    value = get_vlc2(gb, cbphi_tab.table, CBPHI_VLC_BITS, 1);
122
    if (value < 0)
123
        return AVERROR_INVALIDDATA;
124
125
    return x ? value : 15 - value;
126
}
127
128
static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
129
                        int block, int factor, int flag, int offset, int flag2)
130
{
131
    IMM4Context *s = avctx->priv_data;
132
    const uint8_t *scantable = s->intra_scantable.permutated;
133
    int i, last, len, factor2;
134
135
    for (i = !flag; i < 64; i++) {
136
        int value;
137
138
        value = get_vlc2(gb, block_tab.table, BLOCK_VLC_BITS, 1);
139
        if (value < 0)
140
            return AVERROR_INVALIDDATA;
141
        if (value == 0) {
142
            last = get_bits1(gb);
143
            len = get_bits(gb, 6);
144
            factor2 = get_sbits(gb, 8);
145
        } else {
146
            factor2 = value & 0x7F;
147
            last = (value >> 14) & 1;
148
            len = (value >> 7) & 0x3F;
149
            if (get_bits1(gb))
150
                factor2 = -factor2;
151
        }
152
        i += len;
153
        if (i >= 64)
154
            break;
155
        s->block[block][scantable[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2;
156
        if (last)
157
            break;
158
    }
159
160
    if (s->hi == 2 && flag2 && block < 4) {
161
        if (flag)
162
            s->block[block][scantable[0]]  *= 2;
163
        s->block[block][scantable[1]]  *= 2;
164
        s->block[block][scantable[8]]  *= 2;
165
        s->block[block][scantable[16]] *= 2;
166
    }
167
168
    return 0;
169
}
170
171
static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
172
                         unsigned cbp, int flag, int offset, unsigned flag2)
173
{
174
    IMM4Context *s = avctx->priv_data;
175
    const uint8_t *scantable = s->intra_scantable.permutated;
176
    int ret, i;
177
178
    memset(s->block, 0, sizeof(s->block));
179
180
    for (i = 0; i < 6; i++) {
181
        if (!flag) {
182
            int x = get_bits(gb, 8);
183
184
            if (x == 255)
185
                x = 128;
186
            x *= 8;
187
188
            s->block[i][scantable[0]] = x;
189
        }
190
191
        if (cbp & (1 << (5 - i))) {
192
            ret = decode_block(avctx, gb, i, s->factor, flag, offset, flag2);
193
            if (ret < 0)
194
                return ret;
195
        }
196
    }
197
198
    return 0;
199
}
200
201
static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
202
{
203
    IMM4Context *s = avctx->priv_data;
204
    int ret, x, y, offset = 0;
205
206
    if (s->hi == 0) {
207
        if (s->lo > 2)
208
            return AVERROR_INVALIDDATA;
209
        s->factor = intra_cb[s->lo];
210
    } else {
211
        s->factor = s->lo * 2;
212
    }
213
214
    if (s->hi) {
215
        offset = s->factor;
216
        offset >>= 1;
217
        if (!(offset & 1))
218
            offset--;
219
    }
220
221
    for (y = 0; y < avctx->height; y += 16) {
222
        for (x = 0; x < avctx->width; x += 16) {
223
            unsigned flag, cbphi, cbplo;
224
225
            cbplo = get_vlc2(gb, cbplo_tab.table, CBPLO_VLC_BITS, 1);
226
            flag = get_bits1(gb);
227
228
            cbphi = get_cbphi(gb, 1);
229
230
            ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag);
231
            if (ret < 0)
232
                return ret;
233
234
            s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
235
                             frame->linesize[0], s->block[0]);
236
            s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
237
                             frame->linesize[0], s->block[1]);
238
            s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
239
                             frame->linesize[0], s->block[2]);
240
            s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
241
                             frame->linesize[0], s->block[3]);
242
            s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
243
                             frame->linesize[1], s->block[4]);
244
            s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
245
                             frame->linesize[2], s->block[5]);
246
        }
247
    }
248
249
    return 0;
250
}
251
252
static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
253
                        AVFrame *frame, AVFrame *prev)
254
{
255
    IMM4Context *s = avctx->priv_data;
256
    int ret, x, y, offset = 0;
257
258
    if (s->hi == 0) {
259
        if (s->lo > 2)
260
            return AVERROR_INVALIDDATA;
261
        s->factor = inter_cb[s->lo];
262
    } else {
263
        s->factor = s->lo * 2;
264
    }
265
266
    if (s->hi) {
267
        offset = s->factor;
268
        offset >>= 1;
269
        if (!(offset & 1))
270
            offset--;
271
    }
272
273
    for (y = 0; y < avctx->height; y += 16) {
274
        for (x = 0; x < avctx->width; x += 16) {
275
            int reverse, intra_block, value;
276
            unsigned cbphi, cbplo, flag2 = 0;
277
278
            if (get_bits1(gb)) {
279
                copy_block16(frame->data[0] + y * frame->linesize[0] + x,
280
                             prev->data[0] + y * prev->linesize[0] + x,
281
                             frame->linesize[0], prev->linesize[0], 16);
282
                copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
283
                            prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
284
                            frame->linesize[1], prev->linesize[1], 8);
285
                copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
286
                            prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
287
                            frame->linesize[2], prev->linesize[2], 8);
288
                continue;
289
            }
290
291
            value = get_vlc2(gb, blktype_tab.table, BLKTYPE_VLC_BITS, 1);
292
            if (value < 0)
293
                return AVERROR_INVALIDDATA;
294
295
            intra_block = value & 0x07;
296
            reverse = intra_block == 3;
297
            if (reverse)
298
                flag2 = get_bits1(gb);
299
300
            cbplo = value >> 4;
301
            cbphi = get_cbphi(gb, reverse);
302
            if (intra_block) {
303
                ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag2);
304
                if (ret < 0)
305
                    return ret;
306
307
                s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
308
                                 frame->linesize[0], s->block[0]);
309
                s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
310
                                 frame->linesize[0], s->block[1]);
311
                s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
312
                                 frame->linesize[0], s->block[2]);
313
                s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
314
                                 frame->linesize[0], s->block[3]);
315
                s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
316
                                 frame->linesize[1], s->block[4]);
317
                s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
318
                                 frame->linesize[2], s->block[5]);
319
            } else {
320
                flag2 = get_bits1(gb);
321
                skip_bits1(gb);
322
                ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset, flag2);
323
                if (ret < 0)
324
                    return ret;
325
326
                copy_block16(frame->data[0] + y * frame->linesize[0] + x,
327
                             prev->data[0] + y * prev->linesize[0] + x,
328
                             frame->linesize[0], prev->linesize[0], 16);
329
                copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
330
                            prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
331
                            frame->linesize[1], prev->linesize[1], 8);
332
                copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
333
                            prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
334
                            frame->linesize[2], prev->linesize[2], 8);
335
336
                s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x,
337
                                 frame->linesize[0], s->block[0]);
338
                s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x + 8,
339
                                 frame->linesize[0], s->block[1]);
340
                s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x,
341
                                 frame->linesize[0], s->block[2]);
342
                s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
343
                                 frame->linesize[0], s->block[3]);
344
                s->idsp.idct_add(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
345
                                 frame->linesize[1], s->block[4]);
346
                s->idsp.idct_add(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
347
                                 frame->linesize[2], s->block[5]);
348
            }
349
        }
350
    }
351
352
    return 0;
353
}
354
355
static int decode_frame(AVCodecContext *avctx, void *data,
356
                        int *got_frame, AVPacket *avpkt)
357
{
358
    IMM4Context *s = avctx->priv_data;
359
    GetBitContext *gb = &s->gb;
360
    AVFrame *frame = data;
361
    int width, height;
362
    unsigned type;
363
    int ret, scaled;
364
365
    if (avpkt->size <= 32)
366
        return AVERROR_INVALIDDATA;
367
368
    av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
369
                          FFALIGN(avpkt->size, 4));
370
    if (!s->bitstream)
371
        return AVERROR(ENOMEM);
372
373
    s->bdsp.bswap_buf((uint32_t *)s->bitstream,
374
                      (uint32_t *)avpkt->data,
375
                      (avpkt->size + 3) >> 2);
376
377
    if ((ret = init_get_bits8(gb, s->bitstream, FFALIGN(avpkt->size, 4))) < 0)
378
        return ret;
379
380
    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
381
    avctx->color_range = AVCOL_RANGE_JPEG;
382
383
    width = avctx->width;
384
    height = avctx->height;
385
386
    scaled = avpkt->data[8];
387
    if (scaled < 2) {
388
        int mode = avpkt->data[10];
389
390
        switch (mode) {
391
        case 1:
392
            width = 352;
393
            height = 240;
394
            break;
395
        case 2:
396
            width = 704;
397
            height = 240;
398
            break;
399
        case 4:
400
            width = 480;
401
            height = 704;
402
            break;
403
        case 17:
404
            width = 352;
405
            height = 288;
406
            break;
407
        case 18:
408
            width = 704;
409
            height = 288;
410
            break;
411
        default:
412
            width = 704;
413
            height = 576;
414
            break;
415
        }
416
    }
417
418
    skip_bits_long(gb, 24 * 8);
419
    type = get_bits_long(gb, 32);
420
    s->hi = get_bits(gb, 16);
421
    s->lo = get_bits(gb, 16);
422
423
    switch (type) {
424
    case 0x19781977:
425
        frame->key_frame = 1;
426
        frame->pict_type = AV_PICTURE_TYPE_I;
427
        break;
428
    case 0x12250926:
429
        frame->key_frame = 0;
430
        frame->pict_type = AV_PICTURE_TYPE_P;
431
        break;
432
    default:
433
        avpriv_request_sample(avctx, "type %X", type);
434
        return AVERROR_PATCHWELCOME;
435
    }
436
437
    if (avctx->width  != width ||
438
        avctx->height != height) {
439
        if (!frame->key_frame) {
440
            av_log(avctx, AV_LOG_ERROR, "Frame size change is unsupported.\n");
441
            return AVERROR_INVALIDDATA;
442
        }
443
        av_frame_unref(s->prev_frame);
444
    }
445
446
    ret = ff_set_dimensions(avctx, width, height);
447
    if (ret < 0)
448
        return ret;
449
450
    if ((ret = ff_get_buffer(avctx, frame, frame->key_frame ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
451
        return ret;
452
453
    if (frame->key_frame) {
454
        ret = decode_intra(avctx, gb, frame);
455
        if (ret < 0)
456
            return ret;
457
458
        av_frame_unref(s->prev_frame);
459
        if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
460
            return ret;
461
    } else {
462
        if (!s->prev_frame->data[0]) {
463
            av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
464
            return AVERROR_INVALIDDATA;
465
        }
466
467
        ret = decode_inter(avctx, gb, frame, s->prev_frame);
468
        if (ret < 0)
469
            return ret;
470
    }
471
472
    *got_frame = 1;
473
474
    return avpkt->size;
475
}
476
477
static av_cold void imm4_init_static_data(void)
478
{
479
    INIT_VLC_STATIC_FROM_LENGTHS(&cbplo_tab, CBPLO_VLC_BITS, FF_ARRAY_ELEMS(cbplo),
480
                                 &cbplo[0][1], 2, &cbplo[0][0], 2, 1,
481
                                 0, 0, 1 << CBPLO_VLC_BITS);
482
483
    INIT_VLC_SPARSE_STATIC(&cbphi_tab, CBPHI_VLC_BITS, FF_ARRAY_ELEMS(cbphi_bits),
484
                           cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64);
485
486
    INIT_VLC_STATIC_FROM_LENGTHS(&blktype_tab, BLKTYPE_VLC_BITS, FF_ARRAY_ELEMS(blktype),
487
                                 &blktype[0][1], 2, &blktype[0][0], 2, 1,
488
                                 0, 0, 1 << BLKTYPE_VLC_BITS);
489
490
    INIT_VLC_STATIC_FROM_LENGTHS(&block_tab, BLOCK_VLC_BITS, FF_ARRAY_ELEMS(block_bits),
491
                                 block_bits, 1, block_symbols, 2, 2,
492
                                 0, 0, 1 << BLOCK_VLC_BITS);
493
}
494
495
static av_cold int decode_init(AVCodecContext *avctx)
496
{
497
    static AVOnce init_static_once = AV_ONCE_INIT;
498
    IMM4Context *s = avctx->priv_data;
499
    uint8_t table[64];
500
501
    for (int i = 0; i < 64; i++)
502
        table[i] = i;
503
504
    ff_bswapdsp_init(&s->bdsp);
505
    ff_idctdsp_init(&s->idsp, avctx);
506
    ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, table);
507
508
    s->prev_frame = av_frame_alloc();
509
    if (!s->prev_frame)
510
        return AVERROR(ENOMEM);
511
512
    ff_thread_once(&init_static_once, imm4_init_static_data);
513
514
    return 0;
515
}
516
517
static void decode_flush(AVCodecContext *avctx)
518
{
519
    IMM4Context *s = avctx->priv_data;
520
521
    av_frame_unref(s->prev_frame);
522
}
523
524
static av_cold int decode_close(AVCodecContext *avctx)
525
{
526
    IMM4Context *s = avctx->priv_data;
527
528
    av_frame_free(&s->prev_frame);
529
    av_freep(&s->bitstream);
530
    s->bitstream_size = 0;
531
532
    return 0;
533
}
534
535
AVCodec ff_imm4_decoder = {
536
    .name             = "imm4",
537
    .long_name        = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
538
    .type             = AVMEDIA_TYPE_VIDEO,
539
    .id               = AV_CODEC_ID_IMM4,
540
    .priv_data_size   = sizeof(IMM4Context),
541
    .init             = decode_init,
542
    .close            = decode_close,
543
    .decode           = decode_frame,
544
    .flush            = decode_flush,
545
    .capabilities     = AV_CODEC_CAP_DR1,
546
    .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
547
                        FF_CODEC_CAP_INIT_CLEANUP,
548
};