Coverage Report

Created: 2025-12-31 07:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/leaddec.c
Line
Count
Source
1
/*
2
 * LEAD MCMP decoder
3
 *
4
 * Copyright (c) 2023 Peter Ross
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 "avcodec.h"
24
#include "blockdsp.h"
25
#include "codec_internal.h"
26
#include "copy_block.h"
27
#include "decode.h"
28
#include "get_bits.h"
29
#include "idctdsp.h"
30
#include "jpegquanttables.h"
31
#include "jpegtables.h"
32
#include "leaddata.h"
33
#include "libavutil/mem.h"
34
#include "libavutil/mem_internal.h"
35
#include "libavutil/thread.h"
36
37
634k
#define LUMA_DC_BITS 9
38
690k
#define CHROMA_DC_BITS 11
39
634k
#define LUMA_AC_BITS 10
40
690k
#define CHROMA_AC_BITS 10
41
42
static VLCElem luma_dc_vlc[1 << LUMA_DC_BITS];
43
static VLCElem chroma_dc_vlc[1 << CHROMA_DC_BITS];
44
static VLCElem luma_ac_vlc[1160];
45
static VLCElem chroma_ac_vlc[1160];
46
47
static av_cold void lead_init_static_data(void)
48
1
{
49
1
    VLC_INIT_STATIC_TABLE_FROM_LENGTHS(luma_dc_vlc, LUMA_DC_BITS, FF_ARRAY_ELEMS(luma_dc_len),
50
1
                                       luma_dc_len, 1,
51
1
                                       NULL, 0, 0,
52
1
                                       0, 0);
53
1
    VLC_INIT_STATIC_TABLE_FROM_LENGTHS(chroma_dc_vlc, CHROMA_DC_BITS, FF_ARRAY_ELEMS(chroma_dc_len),
54
1
                                       chroma_dc_len, 1,
55
1
                                       NULL, 0, 0,
56
1
                                       0, 0);
57
1
    VLC_INIT_STATIC_TABLE_FROM_LENGTHS(luma_ac_vlc, LUMA_AC_BITS, FF_ARRAY_ELEMS(luma_ac_len),
58
1
                                       luma_ac_len, 1,
59
1
                                       ff_mjpeg_val_ac_luminance, 1, 1,
60
1
                                       0, 0);
61
1
    VLC_INIT_STATIC_TABLE_FROM_LENGTHS(chroma_ac_vlc, CHROMA_AC_BITS, FF_ARRAY_ELEMS(chroma_ac_len),
62
1
                                       chroma_ac_len, 1,
63
1
                                       ff_mjpeg_val_ac_chrominance, 1, 1,
64
1
                                       0, 0);
65
1
}
66
67
typedef struct LeadContext {
68
    uint8_t *bitstream_buf;
69
    unsigned int bitstream_buf_size;
70
    BlockDSPContext bdsp;
71
    IDCTDSPContext idsp;
72
    uint8_t permutated_scantable[64];
73
} LeadContext;
74
75
static av_cold int lead_decode_init(AVCodecContext * avctx)
76
1.27k
{
77
1.27k
    static AVOnce init_static_once = AV_ONCE_INIT;
78
1.27k
    LeadContext *s = avctx->priv_data;
79
80
1.27k
    if (avctx->extradata_size < 20)
81
181
        return AVERROR_INVALIDDATA;
82
83
1.09k
    ff_blockdsp_init(&s->bdsp);
84
1.09k
    ff_idctdsp_init(&s->idsp, avctx);
85
1.09k
    ff_permute_scantable(s->permutated_scantable, ff_zigzag_direct, s->idsp.idct_permutation);
86
87
1.09k
    ff_thread_once(&init_static_once, lead_init_static_data);
88
89
1.09k
    return 0;
90
1.27k
}
91
92
static void calc_dequant(uint16_t * dequant, const uint8_t * quant_tbl, int q)
93
245k
{
94
15.9M
    for (int i = 0; i < 64; i++)
95
15.7M
        dequant[i] = av_clip(q * quant_tbl[ff_zigzag_direct[i]] / 50, 2, 32767);
96
245k
}
97
98
static int decode_block(LeadContext * s, GetBitContext * gb,
99
                        const VLCElem * dc_table, int dc_bits, const VLCElem * ac_table, int ac_bits,
100
                        int16_t * dc_pred, const uint16_t * dequant,
101
                        uint8_t * dst, int stride)
102
1.32M
{
103
1.32M
    DECLARE_ALIGNED(32, int16_t, block)[64];
104
1.32M
    int size;
105
106
1.32M
    s->bdsp.clear_block(block);
107
108
1.32M
    if (get_bits_left(gb) <= 0)
109
11.5k
        return AVERROR_INVALIDDATA;
110
111
1.31M
    size = get_vlc2(gb, dc_table, dc_bits, 1);
112
1.31M
    if (size < 0)
113
270
        return AVERROR_INVALIDDATA;
114
115
1.31M
    if (size)
116
875k
        *dc_pred += get_xbits(gb, size);
117
118
1.31M
    block[0] = (1 << 10) + *dc_pred * dequant[0];
119
120
21.9M
    for (int i = 1; i < 64; i++) {
121
21.7M
        int symbol = get_vlc2(gb, ac_table, ac_bits, 2);
122
21.7M
        if (symbol < 0)
123
683
            return AVERROR_INVALIDDATA;
124
125
21.7M
        if (!symbol)
126
1.04M
            break;
127
128
20.6M
        i += symbol >> 4;
129
20.6M
        if (i >= 64)
130
1.59k
            return AVERROR_INVALIDDATA;
131
132
20.6M
        size = symbol & 0xF;
133
20.6M
        if (size)
134
20.6M
            block[s->permutated_scantable[i]] = get_xbits(gb, size) * dequant[i];
135
20.6M
    }
136
137
1.31M
    s->idsp.idct_put(dst, stride, block);
138
1.31M
    return 0;
139
1.31M
}
140
141
static int lead_decode_frame(AVCodecContext *avctx, AVFrame * frame,
142
                             int * got_frame, AVPacket * avpkt)
143
230k
{
144
230k
    LeadContext *s = avctx->priv_data;
145
230k
    const uint8_t * buf = avpkt->data;
146
230k
    int ret, format, zero = 0, yuv20p_half = 0, fields = 1, q, size;
147
230k
    GetBitContext gb;
148
230k
    int16_t dc_pred[3] = {0, 0, 0};
149
230k
    uint16_t dequant[2][64];
150
151
230k
    if (avpkt->size < 8)
152
96.4k
        return AVERROR_INVALIDDATA;
153
154
134k
    format = AV_RL16(buf + 4);
155
134k
    switch(format) {
156
33.5k
    case 0x0:
157
33.5k
        zero = 1;
158
33.5k
        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
159
33.5k
        break;
160
370
    case 0x6:
161
3.52k
    case 0x8000:
162
3.52k
        yuv20p_half = 1;
163
        // fall-through
164
4.23k
    case 0x1000:
165
4.23k
        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
166
4.23k
        break;
167
308
    case 0x1006:
168
308
        fields = 2;
169
308
        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
170
308
        break;
171
83.5k
    case 0x2000:
172
83.5k
        avctx->pix_fmt = AV_PIX_FMT_YUV444P;
173
83.5k
        break;
174
1.16k
    case 0x2006:
175
1.16k
        avctx->pix_fmt = AV_PIX_FMT_YUV444P;
176
1.16k
        fields = 2;
177
1.16k
        break;
178
11.2k
    default:
179
11.2k
        avpriv_request_sample(avctx, "unsupported format 0x%x", format);
180
11.2k
        return AVERROR_PATCHWELCOME;
181
134k
    }
182
183
122k
    q = AV_RL16(buf + 6);
184
122k
    calc_dequant(dequant[0], ff_mjpeg_std_luminance_quant_tbl, q);
185
122k
    calc_dequant(dequant[1], ff_mjpeg_std_chrominance_quant_tbl, q);
186
187
122k
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
188
2.31k
        return ret;
189
190
120k
    av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size, avpkt->size - 8);
191
120k
    if (!s->bitstream_buf)
192
0
        return AVERROR(ENOMEM);
193
194
120k
    size = 0;
195
21.3M
    for (int i = 8; i < avpkt->size; i++) {
196
21.2M
        int src = buf[i] ^ 0x80;
197
21.2M
        s->bitstream_buf[size++] = src;
198
21.2M
        if (src == 0xFF && i + 1 < avpkt->size && (buf[i + 1] ^ 0x80) == 0x00)
199
1.60k
            i++;
200
21.2M
    }
201
202
120k
    ret = init_get_bits8(&gb, s->bitstream_buf, size);
203
120k
    if (ret < 0)
204
0
        return ret;
205
206
120k
    if (avctx->pix_fmt == AV_PIX_FMT_YUV420P && zero) {
207
34.5M
        for (int mb_y = 0; mb_y < avctx->height / 8; mb_y++)
208
34.5M
            for (int mb_x = 0; mb_x < avctx->width / 16; mb_x++)
209
36.9k
                for (int b = 0; b < 4; b++) {
210
31.2k
                    int luma_block = 2;
211
31.2k
                    const VLCElem * dc_vlc = b < luma_block ? luma_dc_vlc : chroma_dc_vlc;
212
31.2k
                    int dc_bits            = b < luma_block ? LUMA_DC_BITS : CHROMA_DC_BITS;
213
31.2k
                    const VLCElem * ac_vlc = b < luma_block ? luma_ac_vlc : chroma_ac_vlc;
214
31.2k
                    int ac_bits            = b < luma_block ? LUMA_AC_BITS : CHROMA_AC_BITS;
215
31.2k
                    int plane              = b < luma_block ? 0 : b - 1;
216
31.2k
                    int x, y, yclip;
217
218
31.2k
                    if (b < luma_block) {
219
17.5k
                        y = 8*mb_y + 8*(b >> 1);
220
17.5k
                        x = 16*mb_x + 8*(b & 1);
221
17.5k
                        yclip = 0;
222
17.5k
                    } else {
223
13.6k
                        y = 4*mb_y;
224
13.6k
                        x = 8*mb_x;
225
13.6k
                        yclip = y + 8 >= avctx->height / 2;
226
13.6k
                    }
227
228
31.2k
                    if (yclip) {
229
5.10k
                        uint8_t tmp[64];
230
5.10k
                        ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
231
5.10k
                            dc_pred + plane, dequant[!(b < 4)], tmp, 8);
232
33.7k
                        for (int yy = 0; yy < 8 && y + yy < avctx->height / 2; yy++)
233
28.6k
                            memcpy(frame->data[plane] + (y+yy)*frame->linesize[plane] + x, tmp + yy, 8);
234
26.1k
                    } else {
235
26.1k
                        ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
236
26.1k
                            dc_pred + plane, dequant[!(b < 4)],
237
26.1k
                            frame->data[plane] + y*frame->linesize[plane] + x,
238
26.1k
                            frame->linesize[plane]);
239
26.1k
                    }
240
31.2k
                    if (ret < 0)
241
3.50k
                        return ret;
242
31.2k
                }
243
87.3k
    } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
244
4.51k
        for (int f = 0; f < fields; f++)
245
21.0k
        for (int mb_y = 0; mb_y < (avctx->height + 15) / 16 / fields; mb_y++)
246
112k
            for (int mb_x = 0; mb_x < (avctx->width + 15) / 16; mb_x++)
247
647k
                for (int b = 0; b < (yuv20p_half ? 4 : 6); b++) {
248
554k
                    int luma_block = yuv20p_half ? 2 : 4;
249
554k
                    const VLCElem * dc_vlc = b < luma_block ? luma_dc_vlc : chroma_dc_vlc;
250
554k
                    int dc_bits            = b < luma_block ? LUMA_DC_BITS : CHROMA_DC_BITS;
251
554k
                    const VLCElem * ac_vlc = b < luma_block ? luma_ac_vlc : chroma_ac_vlc;
252
554k
                    int ac_bits            = b < luma_block ? LUMA_AC_BITS : CHROMA_AC_BITS;
253
554k
                    int plane              = b < luma_block ? 0 : b - (yuv20p_half ? 1 : 3);
254
554k
                    int x, y;
255
256
554k
                    if (b < luma_block) {
257
367k
                        y = 16*mb_y + 8*(b >> 1);
258
367k
                        x = 16*mb_x + 8*(b & 1);
259
367k
                    } else {
260
186k
                        y = 8*mb_y;
261
186k
                        x = 8*mb_x;
262
186k
                    }
263
264
554k
                    ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
265
554k
                        dc_pred + plane, dequant[!(b < 4)],
266
554k
                        frame->data[plane] + (f + y*fields)*frame->linesize[plane] + x,
267
554k
                        (yuv20p_half && b < 2 ? 2 : 1) * fields * frame->linesize[plane]);
268
554k
                    if (ret < 0)
269
2.96k
                        return ret;
270
271
551k
                    if (yuv20p_half && b < 2)
272
11.0k
                        copy_block8(frame->data[plane] + (y + 1)*frame->linesize[plane] + x,
273
11.0k
                                    frame->data[plane] + y*frame->linesize[plane] + x,
274
11.0k
                                    2*frame->linesize[plane], 2*frame->linesize[plane], 8);
275
551k
                }
276
83.7k
    } else {
277
160k
        for (int f = 0; f < fields; f++)
278
161k
            for (int j = 0; j < (avctx->height + 7) / fields / 8; j++)
279
326k
                for (int i = 0; i < (avctx->width + 7) / 8; i++)
280
980k
                    for (int plane = 0; plane < 3; plane++) {
281
738k
                        const VLCElem * dc_vlc = !plane ? luma_dc_vlc : chroma_dc_vlc;
282
738k
                        int dc_bits            = !plane ? LUMA_DC_BITS : CHROMA_DC_BITS;
283
738k
                        const VLCElem * ac_vlc = !plane ? luma_ac_vlc : chroma_ac_vlc;
284
738k
                        int ac_bits            = !plane ? LUMA_AC_BITS : CHROMA_AC_BITS;
285
286
738k
                        ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
287
738k
                            dc_pred + plane, dequant[!!plane],
288
738k
                            frame->data[plane] + (f + 8*j*fields)*frame->linesize[plane] + 8*i,
289
738k
                            fields * frame->linesize[plane]);
290
738k
                        if (ret < 0)
291
7.60k
                            return ret;
292
738k
                    }
293
83.7k
    }
294
295
106k
    *got_frame = 1;
296
297
106k
    return avpkt->size;
298
120k
}
299
300
static av_cold int lead_decode_end(AVCodecContext * avctx)
301
1.27k
{
302
1.27k
    LeadContext *s = avctx->priv_data;
303
304
1.27k
    av_freep(&s->bitstream_buf);
305
306
1.27k
    return 0;
307
1.27k
}
308
309
const FFCodec ff_lead_decoder = {
310
    .p.name         = "lead",
311
    CODEC_LONG_NAME("LEAD MCMP"),
312
    .p.type         = AVMEDIA_TYPE_VIDEO,
313
    .p.id           = AV_CODEC_ID_LEAD,
314
    .priv_data_size = sizeof(LeadContext),
315
    .init           = lead_decode_init,
316
    .close          = lead_decode_end,
317
    FF_CODEC_DECODE_CB(lead_decode_frame),
318
    .p.capabilities = AV_CODEC_CAP_DR1,
319
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
320
};