Coverage Report

Created: 2025-08-28 07:12

/src/ffmpeg/libavcodec/cllc.c
Line
Count
Source (jump to first uncovered line)
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 "libavutil/mem.h"
27
#include "bswapdsp.h"
28
#include "canopus.h"
29
#include "get_bits.h"
30
#include "avcodec.h"
31
#include "codec_internal.h"
32
#include "thread.h"
33
34
216k
#define VLC_BITS 7
35
108k
#define VLC_DEPTH 2
36
37
38
typedef struct CLLCContext {
39
    AVCodecContext *avctx;
40
    BswapDSPContext bdsp;
41
42
    uint8_t *swapped_buf;
43
    int      swapped_buf_size;
44
} CLLCContext;
45
46
static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc)
47
108k
{
48
108k
    uint8_t symbols[256];
49
108k
    uint8_t bits[256];
50
108k
    int num_lens, num_codes, num_codes_sum;
51
108k
    int i, j, count;
52
53
108k
    count         = 0;
54
108k
    num_codes_sum = 0;
55
56
108k
    num_lens = get_bits(gb, 5);
57
58
108k
    if (num_lens > VLC_BITS * VLC_DEPTH) {
59
764
        av_log(ctx->avctx, AV_LOG_ERROR, "To long VLCs %d\n", num_lens);
60
764
        return AVERROR_INVALIDDATA;
61
764
    }
62
63
133k
    for (i = 0; i < num_lens; i++) {
64
26.3k
        num_codes      = get_bits(gb, 9);
65
26.3k
        num_codes_sum += num_codes;
66
67
26.3k
        if (num_codes_sum > 256) {
68
842
            av_log(ctx->avctx, AV_LOG_ERROR,
69
842
                   "Too many VLCs (%d) to be read.\n", num_codes_sum);
70
842
            return AVERROR_INVALIDDATA;
71
842
        }
72
73
278k
        for (j = 0; j < num_codes; j++) {
74
253k
            symbols[count] = get_bits(gb, 8);
75
253k
            bits[count]    = i + 1;
76
77
253k
            count++;
78
253k
        }
79
25.5k
    }
80
81
107k
    return ff_vlc_init_from_lengths(vlc, VLC_BITS, count, bits, 1,
82
107k
                                    symbols, 1, 1, 0, 0, ctx->avctx);
83
108k
}
84
85
/*
86
 * Unlike the RGB24 read/restore, which reads in a component at a time,
87
 * ARGB read/restore reads in ARGB quads.
88
 */
89
static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left,
90
                          VLC *vlc, uint8_t *outbuf)
91
1.26M
{
92
1.26M
    uint8_t *dst;
93
1.26M
    int pred[4];
94
1.26M
    int code;
95
1.26M
    int i;
96
97
1.26M
    OPEN_READER(bits, gb);
98
99
1.26M
    dst     = outbuf;
100
1.26M
    pred[0] = top_left[0];
101
1.26M
    pred[1] = top_left[1];
102
1.26M
    pred[2] = top_left[2];
103
1.26M
    pred[3] = top_left[3];
104
105
39.0M
    for (i = 0; i < ctx->avctx->width; i++) {
106
        /* Always get the alpha component */
107
37.7M
        UPDATE_CACHE(bits, gb);
108
37.7M
        GET_VLC(code, bits, gb, vlc[0].table, VLC_BITS, VLC_DEPTH);
109
110
37.7M
        pred[0] += code;
111
37.7M
        dst[0]   = pred[0];
112
113
        /* Skip the components if they are  entirely transparent */
114
37.7M
        if (dst[0]) {
115
            /* Red */
116
37.5M
            UPDATE_CACHE(bits, gb);
117
37.5M
            GET_VLC(code, bits, gb, vlc[1].table, VLC_BITS, VLC_DEPTH);
118
119
37.5M
            pred[1] += code;
120
37.5M
            dst[1]   = pred[1];
121
122
            /* Green */
123
37.5M
            UPDATE_CACHE(bits, gb);
124
37.5M
            GET_VLC(code, bits, gb, vlc[2].table, VLC_BITS, VLC_DEPTH);
125
126
37.5M
            pred[2] += code;
127
37.5M
            dst[2]   = pred[2];
128
129
            /* Blue */
130
37.5M
            UPDATE_CACHE(bits, gb);
131
37.5M
            GET_VLC(code, bits, gb, vlc[3].table, VLC_BITS, VLC_DEPTH);
132
133
37.5M
            pred[3] += code;
134
37.5M
            dst[3]   = pred[3];
135
37.5M
        } else {
136
217k
            dst[1] = 0;
137
217k
            dst[2] = 0;
138
217k
            dst[3] = 0;
139
217k
        }
140
141
37.7M
        dst += 4;
142
37.7M
    }
143
144
1.26M
    CLOSE_READER(bits, gb);
145
146
1.26M
    top_left[0]  = outbuf[0];
147
148
    /* Only stash components if they are not transparent */
149
1.26M
    if (top_left[0]) {
150
1.25M
        top_left[1] = outbuf[1];
151
1.25M
        top_left[2] = outbuf[2];
152
1.25M
        top_left[3] = outbuf[3];
153
1.25M
    }
154
155
1.26M
    return 0;
156
1.26M
}
157
158
static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb,
159
                                     int *top_left, VLC *vlc, uint8_t *outbuf)
160
3.17M
{
161
3.17M
    uint8_t *dst;
162
3.17M
    int pred, code;
163
3.17M
    int i;
164
165
3.17M
    OPEN_READER(bits, gb);
166
167
3.17M
    dst  = outbuf;
168
3.17M
    pred = *top_left;
169
170
    /* Simultaneously read and restore the line */
171
50.8M
    for (i = 0; i < ctx->avctx->width; i++) {
172
47.6M
        UPDATE_CACHE(bits, gb);
173
47.6M
        GET_VLC(code, bits, gb, vlc->table, VLC_BITS, VLC_DEPTH);
174
175
47.6M
        pred  += code;
176
47.6M
        dst[0] = pred;
177
47.6M
        dst   += 3;
178
47.6M
    }
179
180
3.17M
    CLOSE_READER(bits, gb);
181
182
    /* Stash the first pixel */
183
3.17M
    *top_left = outbuf[0];
184
185
3.17M
    return 0;
186
3.17M
}
187
188
static int read_yuv_component_line(CLLCContext *ctx, GetBitContext *gb,
189
                                   int *top_left, VLC *vlc, uint8_t *outbuf,
190
                                   int is_chroma)
191
3.83M
{
192
3.83M
    int pred, code;
193
3.83M
    int i;
194
195
3.83M
    OPEN_READER(bits, gb);
196
197
3.83M
    pred = *top_left;
198
199
    /* Simultaneously read and restore the line */
200
59.3M
    for (i = 0; i < ctx->avctx->width >> is_chroma; i++) {
201
55.5M
        UPDATE_CACHE(bits, gb);
202
55.5M
        GET_VLC(code, bits, gb, vlc->table, VLC_BITS, VLC_DEPTH);
203
204
55.5M
        pred     += code;
205
55.5M
        outbuf[i] = pred;
206
55.5M
    }
207
208
3.83M
    CLOSE_READER(bits, gb);
209
210
    /* Stash the first pixel */
211
3.83M
    *top_left = outbuf[0];
212
213
3.83M
    return 0;
214
3.83M
}
215
216
static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
217
1.88k
{
218
1.88k
    AVCodecContext *avctx = ctx->avctx;
219
1.88k
    uint8_t *dst;
220
1.88k
    int pred[4];
221
1.88k
    int ret;
222
1.88k
    int i, j;
223
1.88k
    VLC vlc[4];
224
225
1.88k
    pred[0] = 0;
226
1.88k
    pred[1] = 0x80;
227
1.88k
    pred[2] = 0x80;
228
1.88k
    pred[3] = 0x80;
229
230
1.88k
    dst = pic->data[0];
231
232
1.88k
    skip_bits(gb, 16);
233
234
    /* Read in code table for each plane */
235
7.40k
    for (i = 0; i < 4; i++) {
236
6.34k
        ret = read_code_table(ctx, gb, &vlc[i]);
237
6.34k
        if (ret < 0) {
238
2.12k
            for (j = 0; j < i; j++)
239
1.29k
                ff_vlc_free(&vlc[j]);
240
241
829
            av_log(ctx->avctx, AV_LOG_ERROR,
242
829
                   "Could not read code table %d.\n", i);
243
829
            return ret;
244
829
        }
245
6.34k
    }
246
247
    /* Read in and restore every line */
248
1.26M
    for (i = 0; i < avctx->height; i++) {
249
1.26M
        read_argb_line(ctx, gb, pred, vlc, dst);
250
251
1.26M
        dst += pic->linesize[0];
252
1.26M
    }
253
254
5.28k
    for (i = 0; i < 4; i++)
255
4.22k
        ff_vlc_free(&vlc[i]);
256
257
1.05k
    return 0;
258
1.88k
}
259
260
static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
261
33.3k
{
262
33.3k
    AVCodecContext *avctx = ctx->avctx;
263
33.3k
    uint8_t *dst;
264
33.3k
    int pred[3];
265
33.3k
    int ret;
266
33.3k
    int i, j;
267
33.3k
    VLC vlc[3];
268
269
33.3k
    pred[0] = 0x80;
270
33.3k
    pred[1] = 0x80;
271
33.3k
    pred[2] = 0x80;
272
273
33.3k
    dst = pic->data[0];
274
275
33.3k
    skip_bits(gb, 16);
276
277
    /* Read in code table for each plane */
278
131k
    for (i = 0; i < 3; i++) {
279
98.7k
        ret = read_code_table(ctx, gb, &vlc[i]);
280
98.7k
        if (ret < 0) {
281
1.91k
            for (j = 0; j < i; j++)
282
901
                ff_vlc_free(&vlc[j]);
283
284
1.01k
            av_log(ctx->avctx, AV_LOG_ERROR,
285
1.01k
                   "Could not read code table %d.\n", i);
286
1.01k
            return ret;
287
1.01k
        }
288
98.7k
    }
289
290
    /* Read in and restore every line */
291
1.08M
    for (i = 0; i < avctx->height; i++) {
292
4.23M
        for (j = 0; j < 3; j++)
293
3.17M
            read_rgb24_component_line(ctx, gb, &pred[j], &vlc[j], &dst[j]);
294
295
1.05M
        dst += pic->linesize[0];
296
1.05M
    }
297
298
129k
    for (i = 0; i < 3; i++)
299
96.8k
        ff_vlc_free(&vlc[i]);
300
301
32.2k
    return 0;
302
33.3k
}
303
304
static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
305
3.00k
{
306
3.00k
    AVCodecContext *avctx = ctx->avctx;
307
3.00k
    uint8_t block;
308
3.00k
    uint8_t *dst[3];
309
3.00k
    int pred[3];
310
3.00k
    int ret;
311
3.00k
    int i, j;
312
3.00k
    VLC vlc[2];
313
314
3.00k
    pred[0] = 0x80;
315
3.00k
    pred[1] = 0x80;
316
3.00k
    pred[2] = 0x80;
317
318
3.00k
    dst[0] = pic->data[0];
319
3.00k
    dst[1] = pic->data[1];
320
3.00k
    dst[2] = pic->data[2];
321
322
3.00k
    skip_bits(gb, 8);
323
324
3.00k
    block = get_bits(gb, 8);
325
3.00k
    if (block) {
326
689
        avpriv_request_sample(ctx->avctx, "Blocked YUV");
327
689
        return AVERROR_PATCHWELCOME;
328
689
    }
329
330
    /* Read in code table for luma and chroma */
331
4.95k
    for (i = 0; i < 2; i++) {
332
3.82k
        ret = read_code_table(ctx, gb, &vlc[i]);
333
3.82k
        if (ret < 0) {
334
1.57k
            for (j = 0; j < i; j++)
335
388
                ff_vlc_free(&vlc[j]);
336
337
1.18k
            av_log(ctx->avctx, AV_LOG_ERROR,
338
1.18k
                   "Could not read code table %d.\n", i);
339
1.18k
            return ret;
340
1.18k
        }
341
3.82k
    }
342
343
    /* Read in and restore every line */
344
1.27M
    for (i = 0; i < avctx->height; i++) {
345
1.27M
        read_yuv_component_line(ctx, gb, &pred[0], &vlc[0], dst[0], 0); /* Y */
346
1.27M
        read_yuv_component_line(ctx, gb, &pred[1], &vlc[1], dst[1], 1); /* U */
347
1.27M
        read_yuv_component_line(ctx, gb, &pred[2], &vlc[1], dst[2], 1); /* V */
348
349
5.10M
        for (j = 0; j < 3; j++)
350
3.83M
            dst[j] += pic->linesize[j];
351
1.27M
    }
352
353
3.38k
    for (i = 0; i < 2; i++)
354
2.25k
        ff_vlc_free(&vlc[i]);
355
356
1.12k
    return 0;
357
2.31k
}
358
359
static int cllc_decode_frame(AVCodecContext *avctx, AVFrame *pic,
360
                             int *got_picture_ptr, AVPacket *avpkt)
361
466k
{
362
466k
    CLLCContext *ctx = avctx->priv_data;
363
466k
    const uint8_t *src = avpkt->data;
364
466k
    uint32_t info_tag, info_offset;
365
466k
    int data_size;
366
466k
    GetBitContext gb;
367
466k
    int coding_type, ret;
368
369
466k
    if (avpkt->size < 4 + 4) {
370
379k
        av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size);
371
379k
        return AVERROR_INVALIDDATA;
372
379k
    }
373
374
86.5k
    info_offset = 0;
375
86.5k
    info_tag    = AV_RL32(src);
376
86.5k
    if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
377
9.04k
        info_offset = AV_RL32(src + 4);
378
9.04k
        if (info_offset > UINT32_MAX - 8 || info_offset + 8 > avpkt->size) {
379
737
            av_log(avctx, AV_LOG_ERROR,
380
737
                   "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n",
381
737
                   info_offset);
382
737
            return AVERROR_INVALIDDATA;
383
737
        }
384
8.30k
        ff_canopus_parse_info_tag(avctx, src + 8, info_offset);
385
386
8.30k
        info_offset += 8;
387
8.30k
        src         += info_offset;
388
8.30k
    }
389
390
85.8k
    data_size = (avpkt->size - info_offset) & ~1;
391
392
    /* Make sure our bswap16'd buffer is big enough */
393
85.8k
    av_fast_padded_malloc(&ctx->swapped_buf,
394
85.8k
                          &ctx->swapped_buf_size, data_size);
395
85.8k
    if (!ctx->swapped_buf) {
396
0
        av_log(avctx, AV_LOG_ERROR, "Could not allocate swapped buffer.\n");
397
0
        return AVERROR(ENOMEM);
398
0
    }
399
400
    /* bswap16 the buffer since CLLC's bitreader works in 16-bit words */
401
85.8k
    ctx->bdsp.bswap16_buf((uint16_t *) ctx->swapped_buf, (uint16_t *) src,
402
85.8k
                          data_size / 2);
403
404
85.8k
    if ((ret = init_get_bits8(&gb, ctx->swapped_buf, data_size)) < 0)
405
0
        return ret;
406
407
    /*
408
     * Read in coding type. The types are as follows:
409
     *
410
     * 0 - YUY2
411
     * 1 - BGR24 (Triples)
412
     * 2 - BGR24 (Quads)
413
     * 3 - BGRA
414
     */
415
85.8k
    coding_type = (AV_RL32(src) >> 8) & 0xFF;
416
85.8k
    av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type);
417
418
85.8k
    if(get_bits_left(&gb) < avctx->height * avctx->width)
419
35.9k
        return AVERROR_INVALIDDATA;
420
421
49.8k
    switch (coding_type) {
422
10.3k
    case 0:
423
10.3k
        avctx->pix_fmt             = AV_PIX_FMT_YUV422P;
424
10.3k
        avctx->bits_per_raw_sample = 8;
425
426
10.3k
        if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
427
7.35k
            return ret;
428
429
3.00k
        ret = decode_yuv_frame(ctx, &gb, pic);
430
3.00k
        if (ret < 0)
431
1.87k
            return ret;
432
433
1.12k
        break;
434
1.37k
    case 1:
435
35.8k
    case 2:
436
35.8k
        avctx->pix_fmt             = AV_PIX_FMT_RGB24;
437
35.8k
        avctx->bits_per_raw_sample = 8;
438
439
35.8k
        if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
440
2.58k
            return ret;
441
442
33.3k
        ret = decode_rgb24_frame(ctx, &gb, pic);
443
33.3k
        if (ret < 0)
444
1.01k
            return ret;
445
446
32.2k
        break;
447
32.2k
    case 3:
448
2.26k
        avctx->pix_fmt             = AV_PIX_FMT_ARGB;
449
2.26k
        avctx->bits_per_raw_sample = 8;
450
451
2.26k
        if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
452
382
            return ret;
453
454
1.88k
        ret = decode_argb_frame(ctx, &gb, pic);
455
1.88k
        if (ret < 0)
456
829
            return ret;
457
458
1.05k
        break;
459
1.30k
    default:
460
1.30k
        av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d.\n", coding_type);
461
1.30k
        return AVERROR_INVALIDDATA;
462
49.8k
    }
463
464
34.4k
    *got_picture_ptr = 1;
465
466
34.4k
    return avpkt->size;
467
49.8k
}
468
469
static av_cold int cllc_decode_close(AVCodecContext *avctx)
470
1.73k
{
471
1.73k
    CLLCContext *ctx = avctx->priv_data;
472
473
1.73k
    av_freep(&ctx->swapped_buf);
474
475
1.73k
    return 0;
476
1.73k
}
477
478
static av_cold int cllc_decode_init(AVCodecContext *avctx)
479
1.73k
{
480
1.73k
    CLLCContext *ctx = avctx->priv_data;
481
482
    /* Initialize various context values */
483
1.73k
    ctx->avctx            = avctx;
484
1.73k
    ctx->swapped_buf      = NULL;
485
1.73k
    ctx->swapped_buf_size = 0;
486
487
1.73k
    ff_bswapdsp_init(&ctx->bdsp);
488
489
1.73k
    return 0;
490
1.73k
}
491
492
const FFCodec ff_cllc_decoder = {
493
    .p.name         = "cllc",
494
    CODEC_LONG_NAME("Canopus Lossless Codec"),
495
    .p.type         = AVMEDIA_TYPE_VIDEO,
496
    .p.id           = AV_CODEC_ID_CLLC,
497
    .priv_data_size = sizeof(CLLCContext),
498
    .init           = cllc_decode_init,
499
    FF_CODEC_DECODE_CB(cllc_decode_frame),
500
    .close          = cllc_decode_close,
501
    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
502
};