GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/imm4.c Lines: 0 278 0.0 %
Date: 2019-11-18 18:00:01 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/thread.h"
28
29
#include "avcodec.h"
30
#include "bswapdsp.h"
31
#include "copy_block.h"
32
#include "get_bits.h"
33
#include "idctdsp.h"
34
#include "internal.h"
35
36
typedef struct IMM4Context {
37
    BswapDSPContext bdsp;
38
    GetBitContext  gb;
39
40
    AVFrame *prev_frame;
41
    uint8_t *bitstream;
42
    int bitstream_size;
43
44
    int factor;
45
    unsigned lo;
46
    unsigned hi;
47
48
    ScanTable intra_scantable;
49
    DECLARE_ALIGNED(32, int16_t, block)[6][64];
50
    IDCTDSPContext idsp;
51
} IMM4Context;
52
53
static const uint8_t intra_cb[] = {
54
    24, 18, 12
55
};
56
57
static const uint8_t inter_cb[] = {
58
    30, 20, 15
59
};
60
61
static const uint8_t cbplo_symbols[] = {
62
    3, 4, 19, 20, 35, 36, 51, 52
63
};
64
65
static const uint8_t cbplo_bits[] = {
66
    1, 4, 3, 6, 3, 6, 3, 6
67
};
68
69
static const uint8_t cbplo_codes[] = {
70
    1, 1, 1, 1, 2, 2, 3, 3
71
};
72
73
static const uint8_t cbphi_bits[] = {
74
    4, 5, 5, 4, 5, 4, 6, 4, 5, 6, 4, 4, 4, 4, 4, 2
75
};
76
77
static const uint8_t cbphi_codes[] = {
78
    3, 5, 4, 9, 3, 7, 2, 11, 2, 3, 5, 10, 4, 8, 6, 3
79
};
80
81
static const uint8_t blktype_symbols[] = {
82
    0, 1, 2, 3, 4, 16, 17, 18, 19, 20, 32, 33, 34, 35, 48, 50, 51, 52
83
};
84
85
static const uint8_t blktype_bits[] = {
86
    1, 3, 3, 5, 6, 4, 7, 7, 8, 9, 4, 7, 7, 8, 6, 8, 7, 9
87
};
88
89
static const uint8_t blktype_codes[] = {
90
    1, 3, 2, 3, 4, 3, 7, 5, 4, 4, 2, 6, 4, 3, 5, 5, 3, 2
91
};
92
93
static const uint16_t block_symbols[] = {
94
    0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0x81, 0x82, 0x83,
95
    0x84, 0x85, 0x86, 0x101, 0x102, 0x103, 0x104, 0x181, 0x182, 0x183, 0x201, 0x202,
96
    0x203, 0x281, 0x282, 0x283, 0x301, 0x302, 0x303, 0x381, 0x382, 0x401, 0x402,
97
    0x481, 0x482, 0x501, 0x502, 0x581, 0x601, 0x681, 0x701, 0x781, 0x801, 0x881,
98
    0x901, 0x981, 0xA01, 0xA81, 0xB01, 0xB81, 0xC01, 0xC81, 0xD01, 0x4001, 0x4002,
99
    0x4003, 0x4081, 0x4082, 0x4101, 0x4181, 0x4201, 0x4281, 0x4301, 0x4381, 0x4401,
100
    0x4481, 0x4501, 0x4581, 0x4601, 0x4681, 0x4701, 0x4781, 0x4801, 0x4881, 0x4901,
101
    0x4981, 0x4A01, 0x4A81, 0x4B01, 0x4B81, 0x4C01, 0x4C81, 0x4D01, 0x4D81, 0x4E01,
102
    0x4E81, 0x4F01, 0x4F81, 0x5001, 0x5081, 0x5101, 0x5181, 0x5201, 0x5281, 0x5301,
103
    0x5381, 0x5401
104
};
105
106
static const uint8_t block_bits[] = {
107
    7, 2, 4, 6, 7, 8, 9, 9, 10, 10, 11, 11, 11, 3, 6, 8, 10, 11, 12, 4, 8,
108
    10, 12, 5, 9, 10, 5, 9, 12, 5, 10, 12, 6, 10, 12, 6, 10, 6, 10, 6,
109
    10, 7, 12, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 12, 12, 4, 9,
110
    11, 6, 11, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
111
    9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
112
    12, 12
113
};
114
115
static const uint8_t block_codes[] = {
116
    3, 2, 15, 21, 23, 31, 37, 36, 33, 32, 7, 6, 32, 6, 20, 30, 15, 33, 80,
117
    14, 29, 14, 81, 13, 35, 13, 12, 34, 82, 11, 12, 83, 19, 11, 84, 18,
118
    10, 17, 9, 16, 8, 22, 85, 21, 20, 28, 27, 33, 32, 31, 30, 29, 28,
119
    27, 26, 34, 35, 86, 87, 7, 25, 5, 15, 4, 14, 13, 12, 19, 18, 17, 16,
120
    26, 25, 24, 23, 22, 21, 20, 19, 24, 23, 22, 21, 20, 19, 18, 17, 7,
121
    6, 5, 4, 36, 37, 38, 39, 88, 89, 90, 91, 92, 93, 94, 95
122
};
123
124
static VLC cbplo_tab;
125
static VLC cbphi_tab;
126
static VLC blktype_tab;
127
static VLC block_tab;
128
129
static int get_cbphi(GetBitContext *gb, int x)
130
{
131
    int value;
132
133
    value = get_vlc2(gb, cbphi_tab.table, cbphi_tab.bits, 1);
134
    if (value < 0)
135
        return AVERROR_INVALIDDATA;
136
137
    return x ? value : 15 - value;
138
}
139
140
static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
141
                        int block, int factor, int flag, int offset, int flag2)
142
{
143
    IMM4Context *s = avctx->priv_data;
144
    const uint8_t *scantable = s->intra_scantable.permutated;
145
    int i, last, len, factor2;
146
147
    for (i = !flag; i < 64; i++) {
148
        int value;
149
150
        value = get_vlc2(gb, block_tab.table, block_tab.bits, 1);
151
        if (value < 0)
152
            return AVERROR_INVALIDDATA;
153
        if (value == 0) {
154
            last = get_bits1(gb);
155
            len = get_bits(gb, 6);
156
            factor2 = get_sbits(gb, 8);
157
        } else {
158
            factor2 = value & 0x7F;
159
            last = (value >> 14) & 1;
160
            len = (value >> 7) & 0x3F;
161
            if (get_bits1(gb))
162
                factor2 = -factor2;
163
        }
164
        i += len;
165
        if (i >= 64)
166
            break;
167
        s->block[block][scantable[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2;
168
        if (last)
169
            break;
170
    }
171
172
    if (s->hi == 2 && flag2 && block < 4) {
173
        if (flag)
174
            s->block[block][scantable[0]]  *= 2;
175
        s->block[block][scantable[1]]  *= 2;
176
        s->block[block][scantable[8]]  *= 2;
177
        s->block[block][scantable[16]] *= 2;
178
    }
179
180
    return 0;
181
}
182
183
static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
184
                         unsigned cbp, int flag, int offset, unsigned flag2)
185
{
186
    IMM4Context *s = avctx->priv_data;
187
    const uint8_t *scantable = s->intra_scantable.permutated;
188
    int ret, i;
189
190
    memset(s->block, 0, sizeof(s->block));
191
192
    for (i = 0; i < 6; i++) {
193
        if (!flag) {
194
            int x = get_bits(gb, 8);
195
196
            if (x == 255)
197
                x = 128;
198
            x *= 8;
199
200
            s->block[i][scantable[0]] = x;
201
        }
202
203
        if (cbp & (1 << (5 - i))) {
204
            ret = decode_block(avctx, gb, i, s->factor, flag, offset, flag2);
205
            if (ret < 0)
206
                return ret;
207
        }
208
    }
209
210
    return 0;
211
}
212
213
static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
214
{
215
    IMM4Context *s = avctx->priv_data;
216
    int ret, x, y, offset = 0;
217
218
    if (s->hi == 0) {
219
        if (s->lo > 2)
220
            return AVERROR_INVALIDDATA;
221
        s->factor = intra_cb[s->lo];
222
    } else {
223
        s->factor = s->lo * 2;
224
    }
225
226
    if (s->hi) {
227
        offset = s->factor;
228
        offset >>= 1;
229
        if (!(offset & 1))
230
            offset--;
231
    }
232
233
    for (y = 0; y < avctx->height; y += 16) {
234
        for (x = 0; x < avctx->width; x += 16) {
235
            unsigned flag, cbphi, cbplo;
236
237
            cbplo = get_vlc2(gb, cbplo_tab.table, cbplo_tab.bits, 1) >> 4;
238
            flag = get_bits1(gb);
239
240
            cbphi = get_cbphi(gb, 1);
241
242
            ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag);
243
            if (ret < 0)
244
                return ret;
245
246
            s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
247
                             frame->linesize[0], s->block[0]);
248
            s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
249
                             frame->linesize[0], s->block[1]);
250
            s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
251
                             frame->linesize[0], s->block[2]);
252
            s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
253
                             frame->linesize[0], s->block[3]);
254
            s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
255
                             frame->linesize[1], s->block[4]);
256
            s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
257
                             frame->linesize[2], s->block[5]);
258
        }
259
    }
260
261
    return 0;
262
}
263
264
static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
265
                        AVFrame *frame, AVFrame *prev)
266
{
267
    IMM4Context *s = avctx->priv_data;
268
    int ret, x, y, offset = 0;
269
270
    if (s->hi == 0) {
271
        if (s->lo > 2)
272
            return AVERROR_INVALIDDATA;
273
        s->factor = inter_cb[s->lo];
274
    } else {
275
        s->factor = s->lo * 2;
276
    }
277
278
    if (s->hi) {
279
        offset = s->factor;
280
        offset >>= 1;
281
        if (!(offset & 1))
282
            offset--;
283
    }
284
285
    for (y = 0; y < avctx->height; y += 16) {
286
        for (x = 0; x < avctx->width; x += 16) {
287
            int reverse, intra_block, value;
288
            unsigned cbphi, cbplo, flag2 = 0;
289
290
            if (get_bits1(gb)) {
291
                copy_block16(frame->data[0] + y * frame->linesize[0] + x,
292
                             prev->data[0] + y * prev->linesize[0] + x,
293
                             frame->linesize[0], prev->linesize[0], 16);
294
                copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
295
                            prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
296
                            frame->linesize[1], prev->linesize[1], 8);
297
                copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
298
                            prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
299
                            frame->linesize[2], prev->linesize[2], 8);
300
                continue;
301
            }
302
303
            value = get_vlc2(gb, blktype_tab.table, blktype_tab.bits, 1);
304
            if (value < 0)
305
                return AVERROR_INVALIDDATA;
306
307
            intra_block = value & 0x07;
308
            reverse = intra_block == 3;
309
            if (reverse)
310
                flag2 = get_bits1(gb);
311
312
            cbplo = value >> 4;
313
            cbphi = get_cbphi(gb, reverse);
314
            if (intra_block) {
315
                ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag2);
316
                if (ret < 0)
317
                    return ret;
318
319
                s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x,
320
                                 frame->linesize[0], s->block[0]);
321
                s->idsp.idct_put(frame->data[0] + y * frame->linesize[0] + x + 8,
322
                                 frame->linesize[0], s->block[1]);
323
                s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x,
324
                                 frame->linesize[0], s->block[2]);
325
                s->idsp.idct_put(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
326
                                 frame->linesize[0], s->block[3]);
327
                s->idsp.idct_put(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
328
                                 frame->linesize[1], s->block[4]);
329
                s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
330
                                 frame->linesize[2], s->block[5]);
331
            } else {
332
                flag2 = get_bits1(gb);
333
                skip_bits1(gb);
334
                ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset, flag2);
335
                if (ret < 0)
336
                    return ret;
337
338
                copy_block16(frame->data[0] + y * frame->linesize[0] + x,
339
                             prev->data[0] + y * prev->linesize[0] + x,
340
                             frame->linesize[0], prev->linesize[0], 16);
341
                copy_block8(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
342
                            prev->data[1] + (y >> 1) * prev->linesize[1] + (x >> 1),
343
                            frame->linesize[1], prev->linesize[1], 8);
344
                copy_block8(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
345
                            prev->data[2] + (y >> 1) * prev->linesize[2] + (x >> 1),
346
                            frame->linesize[2], prev->linesize[2], 8);
347
348
                s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x,
349
                                 frame->linesize[0], s->block[0]);
350
                s->idsp.idct_add(frame->data[0] + y * frame->linesize[0] + x + 8,
351
                                 frame->linesize[0], s->block[1]);
352
                s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x,
353
                                 frame->linesize[0], s->block[2]);
354
                s->idsp.idct_add(frame->data[0] + (y + 8) * frame->linesize[0] + x + 8,
355
                                 frame->linesize[0], s->block[3]);
356
                s->idsp.idct_add(frame->data[1] + (y >> 1) * frame->linesize[1] + (x >> 1),
357
                                 frame->linesize[1], s->block[4]);
358
                s->idsp.idct_add(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
359
                                 frame->linesize[2], s->block[5]);
360
            }
361
        }
362
    }
363
364
    return 0;
365
}
366
367
static int decode_frame(AVCodecContext *avctx, void *data,
368
                        int *got_frame, AVPacket *avpkt)
369
{
370
    IMM4Context *s = avctx->priv_data;
371
    GetBitContext *gb = &s->gb;
372
    AVFrame *frame = data;
373
    int width, height;
374
    unsigned type;
375
    int ret, scaled;
376
377
    if (avpkt->size <= 32)
378
        return AVERROR_INVALIDDATA;
379
380
    av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
381
                          FFALIGN(avpkt->size, 4));
382
    if (!s->bitstream)
383
        return AVERROR(ENOMEM);
384
385
    s->bdsp.bswap_buf((uint32_t *)s->bitstream,
386
                      (uint32_t *)avpkt->data,
387
                      (avpkt->size + 3) >> 2);
388
389
    if ((ret = init_get_bits8(gb, s->bitstream, FFALIGN(avpkt->size, 4))) < 0)
390
        return ret;
391
392
    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
393
    avctx->color_range = AVCOL_RANGE_JPEG;
394
395
    width = avctx->width;
396
    height = avctx->height;
397
398
    scaled = avpkt->data[8];
399
    if (scaled < 2) {
400
        int mode = avpkt->data[10];
401
402
        switch (mode) {
403
        case 1:
404
            width = 352;
405
            height = 240;
406
            break;
407
        case 2:
408
            width = 704;
409
            height = 240;
410
            break;
411
        case 4:
412
            width = 480;
413
            height = 704;
414
            break;
415
        case 17:
416
            width = 352;
417
            height = 288;
418
            break;
419
        case 18:
420
            width = 704;
421
            height = 288;
422
            break;
423
        default:
424
            width = 704;
425
            height = 576;
426
            break;
427
        }
428
    }
429
430
    skip_bits_long(gb, 24 * 8);
431
    type = get_bits_long(gb, 32);
432
    s->hi = get_bits(gb, 16);
433
    s->lo = get_bits(gb, 16);
434
435
    switch (type) {
436
    case 0x19781977:
437
        frame->key_frame = 1;
438
        frame->pict_type = AV_PICTURE_TYPE_I;
439
        break;
440
    case 0x12250926:
441
        frame->key_frame = 0;
442
        frame->pict_type = AV_PICTURE_TYPE_P;
443
        break;
444
    default:
445
        avpriv_request_sample(avctx, "type %X", type);
446
        return AVERROR_PATCHWELCOME;
447
    }
448
449
    if (avctx->width  != width ||
450
        avctx->height != height) {
451
        if (!frame->key_frame) {
452
            av_log(avctx, AV_LOG_ERROR, "Frame size change is unsupported.\n");
453
            return AVERROR_INVALIDDATA;
454
        }
455
        av_frame_unref(s->prev_frame);
456
    }
457
458
    ret = ff_set_dimensions(avctx, width, height);
459
    if (ret < 0)
460
        return ret;
461
462
    if ((ret = ff_get_buffer(avctx, frame, frame->key_frame ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
463
        return ret;
464
465
    if (frame->key_frame) {
466
        ret = decode_intra(avctx, gb, frame);
467
        if (ret < 0)
468
            return ret;
469
470
        av_frame_unref(s->prev_frame);
471
        if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
472
            return ret;
473
    } else {
474
        if (!s->prev_frame->data[0]) {
475
            av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
476
            return AVERROR_INVALIDDATA;
477
        }
478
479
        ret = decode_inter(avctx, gb, frame, s->prev_frame);
480
        if (ret < 0)
481
            return ret;
482
    }
483
484
    *got_frame = 1;
485
486
    return avpkt->size;
487
}
488
489
static av_cold void imm4_init_static_data(void)
490
{
491
    INIT_VLC_SPARSE_STATIC(&cbplo_tab, 9, FF_ARRAY_ELEMS(cbplo_bits),
492
                           cbplo_bits, 1, 1, cbplo_codes, 1, 1, cbplo_symbols, 1, 1, 512);
493
494
    INIT_VLC_SPARSE_STATIC(&cbphi_tab, 6, FF_ARRAY_ELEMS(cbphi_bits),
495
                           cbphi_bits, 1, 1, cbphi_codes, 1, 1, NULL, 0, 0, 64);
496
497
    INIT_VLC_SPARSE_STATIC(&blktype_tab, 9, FF_ARRAY_ELEMS(blktype_bits),
498
                           blktype_bits, 1, 1, blktype_codes, 1, 1, blktype_symbols, 1, 1, 512);
499
500
    INIT_VLC_SPARSE_STATIC(&block_tab, 12, FF_ARRAY_ELEMS(block_bits),
501
                           block_bits, 1, 1, block_codes, 1, 1, block_symbols, 2, 2, 4096);
502
}
503
504
static av_cold int decode_init(AVCodecContext *avctx)
505
{
506
    static AVOnce init_static_once = AV_ONCE_INIT;
507
    IMM4Context *s = avctx->priv_data;
508
    uint8_t table[64];
509
510
    for (int i = 0; i < 64; i++)
511
        table[i] = i;
512
513
    ff_bswapdsp_init(&s->bdsp);
514
    ff_idctdsp_init(&s->idsp, avctx);
515
    ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, table);
516
517
    s->prev_frame = av_frame_alloc();
518
    if (!s->prev_frame)
519
        return AVERROR(ENOMEM);
520
521
    ff_thread_once(&init_static_once, imm4_init_static_data);
522
523
    return 0;
524
}
525
526
static void decode_flush(AVCodecContext *avctx)
527
{
528
    IMM4Context *s = avctx->priv_data;
529
530
    av_frame_unref(s->prev_frame);
531
}
532
533
static av_cold int decode_close(AVCodecContext *avctx)
534
{
535
    IMM4Context *s = avctx->priv_data;
536
537
    av_frame_free(&s->prev_frame);
538
    av_freep(&s->bitstream);
539
    s->bitstream_size = 0;
540
541
    return 0;
542
}
543
544
AVCodec ff_imm4_decoder = {
545
    .name             = "imm4",
546
    .long_name        = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
547
    .type             = AVMEDIA_TYPE_VIDEO,
548
    .id               = AV_CODEC_ID_IMM4,
549
    .priv_data_size   = sizeof(IMM4Context),
550
    .init             = decode_init,
551
    .close            = decode_close,
552
    .decode           = decode_frame,
553
    .flush            = decode_flush,
554
    .capabilities     = AV_CODEC_CAP_DR1,
555
    .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
556
                        FF_CODEC_CAP_INIT_CLEANUP,
557
};