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