GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/cllc.c Lines: 192 240 80.0 %
Date: 2019-11-20 04:07:19 Branches: 70 98 71.4 %

Line Branch Exec Source
1
/*
2
 * Canopus Lossless Codec decoder
3
 *
4
 * Copyright (c) 2012-2013 Derek Buitenhuis
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 <inttypes.h>
24
25
#include "libavutil/intreadwrite.h"
26
#include "bswapdsp.h"
27
#include "canopus.h"
28
#include "get_bits.h"
29
#include "avcodec.h"
30
#include "internal.h"
31
#include "thread.h"
32
33
#define VLC_BITS 7
34
#define VLC_DEPTH 2
35
36
37
typedef struct CLLCContext {
38
    AVCodecContext *avctx;
39
    BswapDSPContext bdsp;
40
41
    uint8_t *swapped_buf;
42
    int      swapped_buf_size;
43
} CLLCContext;
44
45
106
static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc)
46
{
47
    uint8_t symbols[256];
48
    uint8_t bits[256];
49
    uint16_t codes[256];
50
    int num_lens, num_codes, num_codes_sum, prefix;
51
    int i, j, count;
52
53
106
    prefix        = 0;
54
106
    count         = 0;
55
106
    num_codes_sum = 0;
56
57
106
    num_lens = get_bits(gb, 5);
58
59
106
    if (num_lens > VLC_BITS * VLC_DEPTH) {
60
        vlc->table = NULL;
61
62
        av_log(ctx->avctx, AV_LOG_ERROR, "To long VLCs %d\n", num_lens);
63
        return AVERROR_INVALIDDATA;
64
    }
65
66
1545
    for (i = 0; i < num_lens; i++) {
67
1439
        num_codes      = get_bits(gb, 9);
68
1439
        num_codes_sum += num_codes;
69
70
1439
        if (num_codes_sum > 256) {
71
            vlc->table = NULL;
72
73
            av_log(ctx->avctx, AV_LOG_ERROR,
74
                   "Too many VLCs (%d) to be read.\n", num_codes_sum);
75
            return AVERROR_INVALIDDATA;
76
        }
77
78
27476
        for (j = 0; j < num_codes; j++) {
79
26037
            symbols[count] = get_bits(gb, 8);
80
26037
            bits[count]    = i + 1;
81
26037
            codes[count]   = prefix++;
82
83
26037
            count++;
84
        }
85
1439
        if (prefix > (65535 - 256)/2) {
86
            vlc->table = NULL;
87
            return AVERROR_INVALIDDATA;
88
        }
89
90
1439
        prefix <<= 1;
91
    }
92
93
106
    return ff_init_vlc_sparse(vlc, VLC_BITS, count, bits, 1, 1,
94
                              codes, 2, 2, symbols, 1, 1, 0);
95
}
96
97
/*
98
 * Unlike the RGB24 read/restore, which reads in a component at a time,
99
 * ARGB read/restore reads in ARGB quads.
100
 */
101
4320
static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left,
102
                          VLC *vlc, uint8_t *outbuf)
103
{
104
    uint8_t *dst;
105
    int pred[4];
106
    int code;
107
    int i;
108
109
4320
    OPEN_READER(bits, gb);
110
111
4320
    dst     = outbuf;
112
4320
    pred[0] = top_left[0];
113
4320
    pred[1] = top_left[1];
114
4320
    pred[2] = top_left[2];
115
4320
    pred[3] = top_left[3];
116
117
5533920
    for (i = 0; i < ctx->avctx->width; i++) {
118
        /* Always get the alpha component */
119
5529600
        UPDATE_CACHE(bits, gb);
120
5529600
        GET_VLC(code, bits, gb, vlc[0].table, VLC_BITS, VLC_DEPTH);
121
122
5529600
        pred[0] += code;
123
5529600
        dst[0]   = pred[0];
124
125
        /* Skip the components if they are  entirely transparent */
126
5529600
        if (dst[0]) {
127
            /* Red */
128
872412
            UPDATE_CACHE(bits, gb);
129
872412
            GET_VLC(code, bits, gb, vlc[1].table, VLC_BITS, VLC_DEPTH);
130
131
872412
            pred[1] += code;
132
872412
            dst[1]   = pred[1];
133
134
            /* Green */
135
872412
            UPDATE_CACHE(bits, gb);
136
872412
            GET_VLC(code, bits, gb, vlc[2].table, VLC_BITS, VLC_DEPTH);
137
138
872412
            pred[2] += code;
139
872412
            dst[2]   = pred[2];
140
141
            /* Blue */
142
872412
            UPDATE_CACHE(bits, gb);
143
872412
            GET_VLC(code, bits, gb, vlc[3].table, VLC_BITS, VLC_DEPTH);
144
145
872412
            pred[3] += code;
146
872412
            dst[3]   = pred[3];
147
        } else {
148
4657188
            dst[1] = 0;
149
4657188
            dst[2] = 0;
150
4657188
            dst[3] = 0;
151
        }
152
153
5529600
        dst += 4;
154
    }
155
156
4320
    CLOSE_READER(bits, gb);
157
158
4320
    top_left[0]  = outbuf[0];
159
160
    /* Only stash components if they are not transparent */
161
4320
    if (top_left[0]) {
162
        top_left[1] = outbuf[1];
163
        top_left[2] = outbuf[2];
164
        top_left[3] = outbuf[3];
165
    }
166
167
4320
    return 0;
168
}
169
170
23040
static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb,
171
                                     int *top_left, VLC *vlc, uint8_t *outbuf)
172
{
173
    uint8_t *dst;
174
    int pred, code;
175
    int i;
176
177
23040
    OPEN_READER(bits, gb);
178
179
23040
    dst  = outbuf;
180
23040
    pred = *top_left;
181
182
    /* Simultaneously read and restore the line */
183
14768640
    for (i = 0; i < ctx->avctx->width; i++) {
184
14745600
        UPDATE_CACHE(bits, gb);
185
14745600
        GET_VLC(code, bits, gb, vlc->table, VLC_BITS, VLC_DEPTH);
186
187
14745600
        pred  += code;
188
14745600
        dst[0] = pred;
189
14745600
        dst   += 3;
190
    }
191
192
23040
    CLOSE_READER(bits, gb);
193
194
    /* Stash the first pixel */
195
23040
    *top_left = outbuf[0];
196
197
23040
    return 0;
198
}
199
200
24480
static int read_yuv_component_line(CLLCContext *ctx, GetBitContext *gb,
201
                                   int *top_left, VLC *vlc, uint8_t *outbuf,
202
                                   int is_chroma)
203
{
204
    int pred, code;
205
    int i;
206
207
24480
    OPEN_READER(bits, gb);
208
209
24480
    pred = *top_left;
210
211
    /* Simultaneously read and restore the line */
212
10469280
    for (i = 0; i < ctx->avctx->width >> is_chroma; i++) {
213
10444800
        UPDATE_CACHE(bits, gb);
214
10444800
        GET_VLC(code, bits, gb, vlc->table, VLC_BITS, VLC_DEPTH);
215
216
10444800
        pred     += code;
217
10444800
        outbuf[i] = pred;
218
    }
219
220
24480
    CLOSE_READER(bits, gb);
221
222
    /* Stash the first pixel */
223
24480
    *top_left = outbuf[0];
224
225
24480
    return 0;
226
}
227
228
6
static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
229
{
230
6
    AVCodecContext *avctx = ctx->avctx;
231
    uint8_t *dst;
232
    int pred[4];
233
    int ret;
234
    int i, j;
235
    VLC vlc[4];
236
237
6
    pred[0] = 0;
238
6
    pred[1] = 0x80;
239
6
    pred[2] = 0x80;
240
6
    pred[3] = 0x80;
241
242
6
    dst = pic->data[0];
243
244
6
    skip_bits(gb, 16);
245
246
    /* Read in code table for each plane */
247
30
    for (i = 0; i < 4; i++) {
248
24
        ret = read_code_table(ctx, gb, &vlc[i]);
249
24
        if (ret < 0) {
250
            for (j = 0; j <= i; j++)
251
                ff_free_vlc(&vlc[j]);
252
253
            av_log(ctx->avctx, AV_LOG_ERROR,
254
                   "Could not read code table %d.\n", i);
255
            return ret;
256
        }
257
    }
258
259
    /* Read in and restore every line */
260
4326
    for (i = 0; i < avctx->height; i++) {
261
4320
        read_argb_line(ctx, gb, pred, vlc, dst);
262
263
4320
        dst += pic->linesize[0];
264
    }
265
266
30
    for (i = 0; i < 4; i++)
267
24
        ff_free_vlc(&vlc[i]);
268
269
6
    return 0;
270
}
271
272
16
static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
273
{
274
16
    AVCodecContext *avctx = ctx->avctx;
275
    uint8_t *dst;
276
    int pred[3];
277
    int ret;
278
    int i, j;
279
    VLC vlc[3];
280
281
16
    pred[0] = 0x80;
282
16
    pred[1] = 0x80;
283
16
    pred[2] = 0x80;
284
285
16
    dst = pic->data[0];
286
287
16
    skip_bits(gb, 16);
288
289
    /* Read in code table for each plane */
290
64
    for (i = 0; i < 3; i++) {
291
48
        ret = read_code_table(ctx, gb, &vlc[i]);
292
48
        if (ret < 0) {
293
            for (j = 0; j <= i; j++)
294
                ff_free_vlc(&vlc[j]);
295
296
            av_log(ctx->avctx, AV_LOG_ERROR,
297
                   "Could not read code table %d.\n", i);
298
            return ret;
299
        }
300
    }
301
302
    /* Read in and restore every line */
303
7696
    for (i = 0; i < avctx->height; i++) {
304
30720
        for (j = 0; j < 3; j++)
305
23040
            read_rgb24_component_line(ctx, gb, &pred[j], &vlc[j], &dst[j]);
306
307
7680
        dst += pic->linesize[0];
308
    }
309
310
64
    for (i = 0; i < 3; i++)
311
48
        ff_free_vlc(&vlc[i]);
312
313
16
    return 0;
314
}
315
316
17
static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
317
{
318
17
    AVCodecContext *avctx = ctx->avctx;
319
    uint8_t block;
320
    uint8_t *dst[3];
321
    int pred[3];
322
    int ret;
323
    int i, j;
324
    VLC vlc[2];
325
326
17
    pred[0] = 0x80;
327
17
    pred[1] = 0x80;
328
17
    pred[2] = 0x80;
329
330
17
    dst[0] = pic->data[0];
331
17
    dst[1] = pic->data[1];
332
17
    dst[2] = pic->data[2];
333
334
17
    skip_bits(gb, 8);
335
336
17
    block = get_bits(gb, 8);
337
17
    if (block) {
338
        avpriv_request_sample(ctx->avctx, "Blocked YUV");
339
        return AVERROR_PATCHWELCOME;
340
    }
341
342
    /* Read in code table for luma and chroma */
343
51
    for (i = 0; i < 2; i++) {
344
34
        ret = read_code_table(ctx, gb, &vlc[i]);
345
34
        if (ret < 0) {
346
            for (j = 0; j <= i; j++)
347
                ff_free_vlc(&vlc[j]);
348
349
            av_log(ctx->avctx, AV_LOG_ERROR,
350
                   "Could not read code table %d.\n", i);
351
            return ret;
352
        }
353
    }
354
355
    /* Read in and restore every line */
356
8177
    for (i = 0; i < avctx->height; i++) {
357
8160
        read_yuv_component_line(ctx, gb, &pred[0], &vlc[0], dst[0], 0); /* Y */
358
8160
        read_yuv_component_line(ctx, gb, &pred[1], &vlc[1], dst[1], 1); /* U */
359
8160
        read_yuv_component_line(ctx, gb, &pred[2], &vlc[1], dst[2], 1); /* V */
360
361
32640
        for (j = 0; j < 3; j++)
362
24480
            dst[j] += pic->linesize[j];
363
    }
364
365
51
    for (i = 0; i < 2; i++)
366
34
        ff_free_vlc(&vlc[i]);
367
368
17
    return 0;
369
}
370
371
39
static int cllc_decode_frame(AVCodecContext *avctx, void *data,
372
                             int *got_picture_ptr, AVPacket *avpkt)
373
{
374
39
    CLLCContext *ctx = avctx->priv_data;
375
39
    AVFrame *pic = data;
376
39
    ThreadFrame frame = { .f = data };
377
39
    uint8_t *src = avpkt->data;
378
    uint32_t info_tag, info_offset;
379
    int data_size;
380
    GetBitContext gb;
381
    int coding_type, ret;
382
383
39
    if (avpkt->size < 4 + 4) {
384
        av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size);
385
        return AVERROR_INVALIDDATA;
386
    }
387
388
39
    info_offset = 0;
389
39
    info_tag    = AV_RL32(src);
390
39
    if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
391
39
        info_offset = AV_RL32(src + 4);
392

39
        if (info_offset > UINT32_MAX - 8 || info_offset + 8 > avpkt->size) {
393
            av_log(avctx, AV_LOG_ERROR,
394
                   "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n",
395
                   info_offset);
396
            return AVERROR_INVALIDDATA;
397
        }
398
39
        ff_canopus_parse_info_tag(avctx, src + 8, info_offset);
399
400
39
        info_offset += 8;
401
39
        src         += info_offset;
402
    }
403
404
39
    data_size = (avpkt->size - info_offset) & ~1;
405
406
    /* Make sure our bswap16'd buffer is big enough */
407
39
    av_fast_padded_malloc(&ctx->swapped_buf,
408
39
                          &ctx->swapped_buf_size, data_size);
409
39
    if (!ctx->swapped_buf) {
410
        av_log(avctx, AV_LOG_ERROR, "Could not allocate swapped buffer.\n");
411
        return AVERROR(ENOMEM);
412
    }
413
414
    /* bswap16 the buffer since CLLC's bitreader works in 16-bit words */
415
39
    ctx->bdsp.bswap16_buf((uint16_t *) ctx->swapped_buf, (uint16_t *) src,
416
                          data_size / 2);
417
418
39
    if ((ret = init_get_bits8(&gb, ctx->swapped_buf, data_size)) < 0)
419
        return ret;
420
421
    /*
422
     * Read in coding type. The types are as follows:
423
     *
424
     * 0 - YUY2
425
     * 1 - BGR24 (Triples)
426
     * 2 - BGR24 (Quads)
427
     * 3 - BGRA
428
     */
429
39
    coding_type = (AV_RL32(src) >> 8) & 0xFF;
430
39
    av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type);
431
432
39
    if(get_bits_left(&gb) < avctx->height * avctx->width)
433
        return AVERROR_INVALIDDATA;
434
435

39
    switch (coding_type) {
436
17
    case 0:
437
17
        avctx->pix_fmt             = AV_PIX_FMT_YUV422P;
438
17
        avctx->bits_per_raw_sample = 8;
439
440
17
        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
441
            return ret;
442
443
17
        ret = decode_yuv_frame(ctx, &gb, pic);
444
17
        if (ret < 0)
445
            return ret;
446
447
17
        break;
448
16
    case 1:
449
    case 2:
450
16
        avctx->pix_fmt             = AV_PIX_FMT_RGB24;
451
16
        avctx->bits_per_raw_sample = 8;
452
453
16
        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
454
            return ret;
455
456
16
        ret = decode_rgb24_frame(ctx, &gb, pic);
457
16
        if (ret < 0)
458
            return ret;
459
460
16
        break;
461
6
    case 3:
462
6
        avctx->pix_fmt             = AV_PIX_FMT_ARGB;
463
6
        avctx->bits_per_raw_sample = 8;
464
465
6
        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
466
            return ret;
467
468
6
        ret = decode_argb_frame(ctx, &gb, pic);
469
6
        if (ret < 0)
470
            return ret;
471
472
6
        break;
473
    default:
474
        av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d.\n", coding_type);
475
        return AVERROR_INVALIDDATA;
476
    }
477
478
39
    pic->key_frame = 1;
479
39
    pic->pict_type = AV_PICTURE_TYPE_I;
480
481
39
    *got_picture_ptr = 1;
482
483
39
    return avpkt->size;
484
}
485
486
#if HAVE_THREADS
487
static int cllc_init_thread_copy(AVCodecContext *avctx)
488
{
489
    CLLCContext *ctx = avctx->priv_data;
490
491
    ctx->avctx            = avctx;
492
    ctx->swapped_buf      = NULL;
493
    ctx->swapped_buf_size = 0;
494
495
    return 0;
496
}
497
#endif
498
499
6
static av_cold int cllc_decode_close(AVCodecContext *avctx)
500
{
501
6
    CLLCContext *ctx = avctx->priv_data;
502
503
6
    av_freep(&ctx->swapped_buf);
504
505
6
    return 0;
506
}
507
508
6
static av_cold int cllc_decode_init(AVCodecContext *avctx)
509
{
510
6
    CLLCContext *ctx = avctx->priv_data;
511
512
    /* Initialize various context values */
513
6
    ctx->avctx            = avctx;
514
6
    ctx->swapped_buf      = NULL;
515
6
    ctx->swapped_buf_size = 0;
516
517
6
    ff_bswapdsp_init(&ctx->bdsp);
518
519
6
    return 0;
520
}
521
522
AVCodec ff_cllc_decoder = {
523
    .name           = "cllc",
524
    .long_name      = NULL_IF_CONFIG_SMALL("Canopus Lossless Codec"),
525
    .type           = AVMEDIA_TYPE_VIDEO,
526
    .id             = AV_CODEC_ID_CLLC,
527
    .priv_data_size = sizeof(CLLCContext),
528
    .init           = cllc_decode_init,
529
    .init_thread_copy = ONLY_IF_THREADS_ENABLED(cllc_init_thread_copy),
530
    .decode         = cllc_decode_frame,
531
    .close          = cllc_decode_close,
532
    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
533
    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
534
};