GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/gdv.c Lines: 0 325 0.0 %
Date: 2021-04-18 21:26:34 Branches: 0 178 0.0 %

Line Branch Exec Source
1
/*
2
 * Gremlin Digital Video (GDV) decoder
3
 * Copyright (c) 2017 Konstantin Shishkov
4
 * Copyright (c) 2017 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 "libavutil/common.h"
24
#include "avcodec.h"
25
#include "bytestream.h"
26
#include "decode.h"
27
#include "internal.h"
28
29
typedef struct GDVContext {
30
    AVCodecContext *avctx;
31
32
    GetByteContext gb;
33
    GetByteContext g2;
34
    PutByteContext pb;
35
36
    uint32_t pal[256];
37
    uint8_t *frame;
38
    unsigned frame_size;
39
    unsigned scale_h, scale_v;
40
} GDVContext;
41
42
typedef struct Bits8 {
43
    uint8_t queue;
44
    uint8_t fill;
45
} Bits8;
46
47
typedef struct Bits32 {
48
    uint32_t queue;
49
    uint8_t  fill;
50
} Bits32;
51
52
#define PREAMBLE_SIZE 4096
53
54
static av_cold int gdv_decode_init(AVCodecContext *avctx)
55
{
56
    GDVContext *gdv = avctx->priv_data;
57
    int i, j, k;
58
59
    avctx->pix_fmt  = AV_PIX_FMT_PAL8;
60
    gdv->frame_size = avctx->width * avctx->height + PREAMBLE_SIZE;
61
    gdv->frame = av_calloc(gdv->frame_size, 1);
62
    if (!gdv->frame)
63
        return AVERROR(ENOMEM);
64
65
    for (i = 0; i < 2; i++) {
66
        for (j = 0; j < 256; j++) {
67
            for (k = 0; k < 8; k++) {
68
                gdv->frame[i * 2048 + j * 8 + k] = j;
69
            }
70
        }
71
    }
72
73
    return 0;
74
}
75
76
static void scaleup(uint8_t *dst, const uint8_t *src, int w)
77
{
78
    int x;
79
    for (x = 0; x < w - 7; x+=8) {
80
        dst[x + 0] =
81
        dst[x + 1] = src[(x>>1) + 0];
82
        dst[x + 2] =
83
        dst[x + 3] = src[(x>>1) + 1];
84
        dst[x + 4] =
85
        dst[x + 5] = src[(x>>1) + 2];
86
        dst[x + 6] =
87
        dst[x + 7] = src[(x>>1) + 3];
88
    }
89
    for (; x < w; x++) {
90
        dst[x] = src[(x>>1)];
91
    }
92
}
93
94
static void scaleup_rev(uint8_t *dst, const uint8_t *src, int w)
95
{
96
    int x;
97
98
    for (x = w - 1; (x+1) & 7; x--) {
99
        dst[x] = src[(x>>1)];
100
    }
101
    for (x -= 7; x >= 0; x -= 8) {
102
        dst[x + 6] =
103
        dst[x + 7] = src[(x>>1) + 3];
104
        dst[x + 4] =
105
        dst[x + 5] = src[(x>>1) + 2];
106
        dst[x + 2] =
107
        dst[x + 3] = src[(x>>1) + 1];
108
        dst[x + 0] =
109
        dst[x + 1] = src[(x>>1) + 0];
110
    }
111
}
112
113
static void scaledown(uint8_t *dst, const uint8_t *src, int w)
114
{
115
    int x;
116
    for (x = 0; x < w - 7; x+=8) {
117
        dst[x + 0] = src[2*x + 0];
118
        dst[x + 1] = src[2*x + 2];
119
        dst[x + 2] = src[2*x + 4];
120
        dst[x + 3] = src[2*x + 6];
121
        dst[x + 4] = src[2*x + 8];
122
        dst[x + 5] = src[2*x +10];
123
        dst[x + 6] = src[2*x +12];
124
        dst[x + 7] = src[2*x +14];
125
    }
126
    for (; x < w; x++) {
127
        dst[x] = src[2*x];
128
    }
129
}
130
131
static void rescale(GDVContext *gdv, uint8_t *dst, int w, int h, int scale_v, int scale_h)
132
{
133
    int j, y;
134
135
    if ((gdv->scale_v == scale_v) && (gdv->scale_h == scale_h)) {
136
        return;
137
    }
138
139
    if (gdv->scale_v) {
140
        for (j = 0; j < h; j++) {
141
            int y = h - j - 1;
142
            uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w;
143
            uint8_t *src1 = dst + PREAMBLE_SIZE + (y>>!!gdv->scale_h) * (w>>1);
144
145
            scaleup_rev(dst1, src1, w);
146
        }
147
    } else if (gdv->scale_h) {
148
        for (j = 0; j < h; j++) {
149
            int y = h - j - 1;
150
            uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w;
151
            uint8_t *src1 = dst + PREAMBLE_SIZE + (y>>1) * w;
152
            memcpy(dst1, src1, w);
153
        }
154
    }
155
156
    if (scale_h && scale_v) {
157
        for (y = 0; y < (h>>1); y++) {
158
            uint8_t *dst1 = dst + PREAMBLE_SIZE + y * (w>>1);
159
            uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w;
160
            scaledown(dst1, src1, w>>1);
161
        }
162
    } else if (scale_h) {
163
        for (y = 0; y < (h>>1); y++) {
164
            uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w;
165
            uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w;
166
            memcpy(dst1, src1, w);
167
        }
168
    } else if (scale_v) {
169
        for (y = 0; y < h; y++) {
170
            uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w;
171
            scaledown(dst1, dst1, w>>1);
172
        }
173
    }
174
175
    gdv->scale_v = scale_v;
176
    gdv->scale_h = scale_h;
177
}
178
179
static int read_bits2(Bits8 *bits, GetByteContext *gb)
180
{
181
    int res;
182
183
    if (bits->fill == 0) {
184
        bits->queue |= bytestream2_get_byte(gb);
185
        bits->fill   = 8;
186
    }
187
    res = bits->queue >> 6;
188
    bits->queue <<= 2;
189
    bits->fill   -= 2;
190
191
    return res;
192
}
193
194
static void fill_bits32(Bits32 *bits, GetByteContext *gb)
195
{
196
    bits->queue = bytestream2_get_le32(gb);
197
    bits->fill  = 32;
198
}
199
200
static int read_bits32(Bits32 *bits, GetByteContext *gb, int nbits)
201
{
202
    int res = bits->queue & ((1 << nbits) - 1);
203
204
    bits->queue >>= nbits;
205
    bits->fill   -= nbits;
206
    if (bits->fill <= 16) {
207
        bits->queue |= bytestream2_get_le16(gb) << bits->fill;
208
        bits->fill  += 16;
209
    }
210
211
    return res;
212
}
213
214
static void lz_copy(PutByteContext *pb, GetByteContext *g2, int offset, unsigned len)
215
{
216
    int i;
217
218
    if (offset == -1) {
219
        int c;
220
221
        bytestream2_seek(g2, bytestream2_tell_p(pb) - 1, SEEK_SET);
222
        c = bytestream2_get_byte(g2);
223
        for (i = 0; i < len; i++) {
224
            bytestream2_put_byte(pb, c);
225
        }
226
    } else if (offset < 0) {
227
        int start = bytestream2_tell_p(pb) - (-offset);
228
229
        bytestream2_seek(g2, start, SEEK_SET);
230
        for (i = 0; i < len; i++) {
231
            bytestream2_put_byte(pb, bytestream2_get_byte(g2));
232
        }
233
    } else {
234
        int start = bytestream2_tell_p(pb) + offset;
235
236
        bytestream2_seek(g2, start, SEEK_SET);
237
        for (i = 0; i < len; i++) {
238
            bytestream2_put_byte(pb, bytestream2_get_byte(g2));
239
        }
240
    }
241
}
242
243
static int decompress_2(AVCodecContext *avctx)
244
{
245
    GDVContext *gdv = avctx->priv_data;
246
    GetByteContext *gb = &gdv->gb;
247
    GetByteContext *g2 = &gdv->g2;
248
    PutByteContext *pb = &gdv->pb;
249
    Bits8 bits = { 0 };
250
    int c, i;
251
252
    bytestream2_init(g2, gdv->frame, gdv->frame_size);
253
    bytestream2_skip_p(pb, PREAMBLE_SIZE);
254
255
    for (c = 0; c < 256; c++) {
256
        for (i = 0; i < 16; i++) {
257
            gdv->frame[c * 16 + i] = c;
258
        }
259
    }
260
261
    while (bytestream2_get_bytes_left_p(pb) > 0 && bytestream2_get_bytes_left(gb) > 0) {
262
        int tag = read_bits2(&bits, gb);
263
        if (tag == 0) {
264
            bytestream2_put_byte(pb, bytestream2_get_byte(gb));
265
        } else if (tag == 1) {
266
            int b = bytestream2_get_byte(gb);
267
            int len = (b & 0xF) + 3;
268
            int top = (b >> 4) & 0xF;
269
            int off = (bytestream2_get_byte(gb) << 4) + top - 4096;
270
            lz_copy(pb, g2, off, len);
271
        } else if (tag == 2) {
272
            int len = (bytestream2_get_byte(gb)) + 2;
273
            bytestream2_skip_p(pb, len);
274
        } else {
275
            break;
276
        }
277
    }
278
279
    if (bytestream2_get_bytes_left_p(pb) > 0)
280
        return AVERROR_INVALIDDATA;
281
282
    return 0;
283
}
284
285
static int decompress_5(AVCodecContext *avctx, unsigned skip)
286
{
287
    GDVContext *gdv = avctx->priv_data;
288
    GetByteContext *gb = &gdv->gb;
289
    GetByteContext *g2 = &gdv->g2;
290
    PutByteContext *pb = &gdv->pb;
291
    Bits8 bits = { 0 };
292
293
    bytestream2_init(g2, gdv->frame, gdv->frame_size);
294
    bytestream2_skip_p(pb, skip + PREAMBLE_SIZE);
295
296
    while (bytestream2_get_bytes_left_p(pb) > 0 && bytestream2_get_bytes_left(gb) > 0) {
297
        int tag = read_bits2(&bits, gb);
298
        if (bytestream2_get_bytes_left(gb) < 1)
299
            return AVERROR_INVALIDDATA;
300
        if (tag == 0) {
301
            bytestream2_put_byte(pb, bytestream2_get_byte(gb));
302
        } else if (tag == 1) {
303
            int b = bytestream2_get_byte(gb);
304
            int len = (b & 0xF) + 3;
305
            int top = b >> 4;
306
            int off = (bytestream2_get_byte(gb) << 4) + top - 4096;
307
            lz_copy(pb, g2, off, len);
308
        } else if (tag == 2) {
309
            int len;
310
            int b = bytestream2_get_byte(gb);
311
            if (b == 0) {
312
                return 0;
313
            }
314
            if (b != 0xFF) {
315
                len = b;
316
            } else {
317
                len = bytestream2_get_le16(gb);
318
            }
319
            bytestream2_skip_p(pb, len + 1);
320
        } else {
321
            int b = bytestream2_get_byte(gb);
322
            int len = (b & 0x3) + 2;
323
            int off = -(b >> 2) - 1;
324
            lz_copy(pb, g2, off, len);
325
        }
326
    }
327
    if (bytestream2_get_bytes_left_p(pb) > 0)
328
        return AVERROR_INVALIDDATA;
329
    return 0;
330
}
331
332
static int decompress_68(AVCodecContext *avctx, unsigned skip, unsigned use8)
333
{
334
    GDVContext *gdv = avctx->priv_data;
335
    GetByteContext *gb = &gdv->gb;
336
    GetByteContext *g2 = &gdv->g2;
337
    PutByteContext *pb = &gdv->pb;
338
    Bits32 bits;
339
340
    bytestream2_init(g2, gdv->frame, gdv->frame_size);
341
    bytestream2_skip_p(pb, skip + PREAMBLE_SIZE);
342
    fill_bits32(&bits, gb);
343
344
    while (bytestream2_get_bytes_left_p(pb) > 0 && bytestream2_get_bytes_left(gb) > 0) {
345
        int tag = read_bits32(&bits, gb, 2);
346
        if (tag == 0) {
347
            int b = read_bits32(&bits, gb, 1);
348
            if (b == 0) {
349
                bytestream2_put_byte(pb, bytestream2_get_byte(gb));
350
            } else {
351
                int i, len = 2;
352
                int lbits = 0;
353
                while (1) {
354
                    int val;
355
356
                    lbits += 1;
357
                    val = read_bits32(&bits, gb, lbits);
358
                    len += val;
359
                    if (val != ((1 << lbits) - 1)) {
360
                        break;
361
                    }
362
                    if (lbits >= 16)
363
                        return AVERROR_INVALIDDATA;
364
                }
365
                for (i = 0; i < len; i++) {
366
                    bytestream2_put_byte(pb, bytestream2_get_byte(gb));
367
                }
368
            }
369
        } else if (tag == 1) {
370
            int b = read_bits32(&bits, gb, 1);
371
            int len;
372
373
            if (b == 0) {
374
                len = (read_bits32(&bits, gb, 4)) + 2;
375
            } else {
376
                int bb = bytestream2_get_byte(gb);
377
                if ((bb & 0x80) == 0) {
378
                    len = bb + 18;
379
                } else {
380
                    int top = (bb & 0x7F) << 8;
381
                    len = top + bytestream2_get_byte(gb) + 146;
382
                }
383
            }
384
            bytestream2_skip_p(pb, len);
385
        } else if (tag == 2) {
386
            int i, subtag = read_bits32(&bits, gb, 2);
387
388
            if (subtag != 3) {
389
                int top = (read_bits32(&bits, gb, 4)) << 8;
390
                int offs = top + bytestream2_get_byte(gb);
391
                if ((subtag != 0) || (offs <= 0xF80)) {
392
                    int len = (subtag) + 3;
393
                    lz_copy(pb, g2, (offs) - 4096, len);
394
                } else {
395
                    int real_off, len, c1, c2;
396
397
                    if (offs == 0xFFF) {
398
                        return 0;
399
                    }
400
401
                    real_off = ((offs >> 4) & 0x7) + 1;
402
                    len = ((offs & 0xF) + 2) * 2;
403
                    c1 = gdv->frame[bytestream2_tell_p(pb) - real_off];
404
                    c2 = gdv->frame[bytestream2_tell_p(pb) - real_off + 1];
405
                    for (i = 0; i < len/2; i++) {
406
                        bytestream2_put_byte(pb, c1);
407
                        bytestream2_put_byte(pb, c2);
408
                    }
409
                }
410
            } else {
411
                int b = bytestream2_get_byte(gb);
412
                int off = ((b & 0x7F)) + 1;
413
                int len = ((b & 0x80) == 0) ? 2 : 3;
414
415
                lz_copy(pb, g2, -off, len);
416
            }
417
        } else {
418
            int len;
419
            int off;
420
            if (use8) {
421
                int q, b = bytestream2_get_byte(gb);
422
                if ((b & 0xC0) == 0xC0) {
423
                    len = ((b & 0x3F)) + 8;
424
                    q = read_bits32(&bits, gb, 4);
425
                    off = (q << 8) + (bytestream2_get_byte(gb)) + 1;
426
                } else {
427
                    int ofs1;
428
                    if ((b & 0x80) == 0) {
429
                        len = ((b >> 4)) + 6;
430
                        ofs1 = (b & 0xF);
431
                    } else {
432
                        len = ((b & 0x3F)) + 14;
433
                        ofs1 = read_bits32(&bits, gb, 4);
434
                    }
435
                    off = (ofs1 << 8) + (bytestream2_get_byte(gb)) - 4096;
436
                }
437
            } else {
438
                int ofs1, b = bytestream2_get_byte(gb);
439
440
                if ((b >> 4) == 0xF) {
441
                    len = bytestream2_get_byte(gb) + 21;
442
                } else {
443
                    len = (b >> 4) + 6;
444
                }
445
                ofs1 = (b & 0xF);
446
                off = (ofs1 << 8) + bytestream2_get_byte(gb) - 4096;
447
            }
448
            lz_copy(pb, g2, off, len);
449
        }
450
    }
451
452
    if (bytestream2_get_bytes_left_p(pb) > 0)
453
        return AVERROR_INVALIDDATA;
454
455
    return 0;
456
}
457
458
static int gdv_decode_frame(AVCodecContext *avctx, void *data,
459
                            int *got_frame, AVPacket *avpkt)
460
{
461
    GDVContext *gdv = avctx->priv_data;
462
    GetByteContext *gb = &gdv->gb;
463
    PutByteContext *pb = &gdv->pb;
464
    AVFrame *frame = data;
465
    int ret, i;
466
    int compression;
467
    unsigned flags;
468
    uint8_t *dst;
469
470
    bytestream2_init(gb, avpkt->data, avpkt->size);
471
    bytestream2_init_writer(pb, gdv->frame, gdv->frame_size);
472
473
    flags = bytestream2_get_le32(gb);
474
    compression = flags & 0xF;
475
476
    if (compression == 4 || compression == 7 || compression > 8)
477
        return AVERROR_INVALIDDATA;
478
479
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
480
        return ret;
481
    ff_copy_palette(gdv->pal, avpkt, avctx);
482
483
    if (compression < 2 && bytestream2_get_bytes_left(gb) < 256*3)
484
        return AVERROR_INVALIDDATA;
485
    rescale(gdv, gdv->frame, avctx->width, avctx->height,
486
            !!(flags & 0x10), !!(flags & 0x20));
487
488
    switch (compression) {
489
    case 1:
490
        memset(gdv->frame + PREAMBLE_SIZE, 0, gdv->frame_size - PREAMBLE_SIZE);
491
    case 0:
492
        for (i = 0; i < 256; i++) {
493
            unsigned r = bytestream2_get_byte(gb);
494
            unsigned g = bytestream2_get_byte(gb);
495
            unsigned b = bytestream2_get_byte(gb);
496
            gdv->pal[i] = 0xFFU << 24 | r << 18 | g << 10 | b << 2;
497
        }
498
        break;
499
    case 2:
500
        ret = decompress_2(avctx);
501
        break;
502
    case 3:
503
        break;
504
    case 5:
505
        ret = decompress_5(avctx, flags >> 8);
506
        break;
507
    case 6:
508
        ret = decompress_68(avctx, flags >> 8, 0);
509
        break;
510
    case 8:
511
        ret = decompress_68(avctx, flags >> 8, 1);
512
        break;
513
    default:
514
        av_assert0(0);
515
    }
516
    if (ret < 0)
517
        return ret;
518
519
    memcpy(frame->data[1], gdv->pal, AVPALETTE_SIZE);
520
    dst = frame->data[0];
521
522
    if (!gdv->scale_v && !gdv->scale_h) {
523
        int sidx = PREAMBLE_SIZE, didx = 0;
524
        int y;
525
526
        for (y = 0; y < avctx->height; y++) {
527
            memcpy(dst + didx, gdv->frame + sidx, avctx->width);
528
            sidx += avctx->width;
529
            didx += frame->linesize[0];
530
        }
531
    } else {
532
        int sidx = PREAMBLE_SIZE, didx = 0;
533
        int y;
534
535
        for (y = 0; y < avctx->height; y++) {
536
            if (!gdv->scale_v) {
537
                memcpy(dst + didx, gdv->frame + sidx, avctx->width);
538
            } else {
539
                uint8_t *dst2 = dst + didx;
540
                uint8_t *src2 = gdv->frame + sidx;
541
542
                scaleup(dst2, src2, avctx->width);
543
            }
544
            if (!gdv->scale_h || ((y & 1) == 1)) {
545
                sidx += !gdv->scale_v ? avctx->width : avctx->width/2;
546
            }
547
            didx += frame->linesize[0];
548
        }
549
    }
550
551
    *got_frame = 1;
552
553
    return avpkt->size;
554
}
555
556
static av_cold int gdv_decode_close(AVCodecContext *avctx)
557
{
558
    GDVContext *gdv = avctx->priv_data;
559
    av_freep(&gdv->frame);
560
    return 0;
561
}
562
563
AVCodec ff_gdv_decoder = {
564
    .name           = "gdv",
565
    .long_name      = NULL_IF_CONFIG_SMALL("Gremlin Digital Video"),
566
    .type           = AVMEDIA_TYPE_VIDEO,
567
    .id             = AV_CODEC_ID_GDV,
568
    .priv_data_size = sizeof(GDVContext),
569
    .init           = gdv_decode_init,
570
    .close          = gdv_decode_close,
571
    .decode         = gdv_decode_frame,
572
    .capabilities   = AV_CODEC_CAP_DR1,
573
    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
574
};