FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/leaddec.c
Date: 2026-05-02 03:33:10
Exec Total Coverage
Lines: 143 165 86.7%
Functions: 6 6 100.0%
Branches: 106 123 86.2%

Line Branch Exec 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/attributes.h"
34 #include "libavutil/mem.h"
35 #include "libavutil/mem_internal.h"
36 #include "libavutil/thread.h"
37
38 #define LUMA_DC_BITS 9
39 #define CHROMA_DC_BITS 11
40 #define LUMA_AC_BITS 10
41 #define CHROMA_AC_BITS 10
42
43 static VLCElem luma_dc_vlc[1 << LUMA_DC_BITS];
44 static VLCElem chroma_dc_vlc[1 << CHROMA_DC_BITS];
45 static VLCElem luma_ac_vlc[1160];
46 static VLCElem chroma_ac_vlc[1160];
47
48 4 static av_cold void lead_init_static_data(void)
49 {
50 4 VLC_INIT_STATIC_TABLE_FROM_LENGTHS(luma_dc_vlc, LUMA_DC_BITS, FF_ARRAY_ELEMS(luma_dc_len),
51 luma_dc_len, 1,
52 NULL, 0, 0,
53 0, 0);
54 4 VLC_INIT_STATIC_TABLE_FROM_LENGTHS(chroma_dc_vlc, CHROMA_DC_BITS, FF_ARRAY_ELEMS(chroma_dc_len),
55 chroma_dc_len, 1,
56 NULL, 0, 0,
57 0, 0);
58 4 VLC_INIT_STATIC_TABLE_FROM_LENGTHS(luma_ac_vlc, LUMA_AC_BITS, FF_ARRAY_ELEMS(luma_ac_len),
59 luma_ac_len, 1,
60 ff_mjpeg_val_ac_luminance, 1, 1,
61 0, 0);
62 4 VLC_INIT_STATIC_TABLE_FROM_LENGTHS(chroma_ac_vlc, CHROMA_AC_BITS, FF_ARRAY_ELEMS(chroma_ac_len),
63 chroma_ac_len, 1,
64 ff_mjpeg_val_ac_chrominance, 1, 1,
65 0, 0);
66 4 }
67
68 typedef struct LeadContext {
69 uint8_t *bitstream_buf;
70 unsigned int bitstream_buf_size;
71 BlockDSPContext bdsp;
72 IDCTDSPContext idsp;
73 uint8_t permutated_scantable[64];
74 } LeadContext;
75
76 8 static av_cold int lead_decode_init(AVCodecContext * avctx)
77 {
78 static AVOnce init_static_once = AV_ONCE_INIT;
79 8 LeadContext *s = avctx->priv_data;
80
81
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (avctx->extradata_size < 20)
82 return AVERROR_INVALIDDATA;
83
84 8 ff_blockdsp_init(&s->bdsp);
85 8 ff_idctdsp_init(&s->idsp, avctx);
86 8 ff_permute_scantable(s->permutated_scantable, ff_zigzag_direct, s->idsp.idct_permutation);
87
88 8 ff_thread_once(&init_static_once, lead_init_static_data);
89
90 8 return 0;
91 }
92
93 16 static void calc_dequant(uint16_t * dequant, const uint8_t * quant_tbl, int q)
94 {
95
2/2
✓ Branch 0 taken 1024 times.
✓ Branch 1 taken 16 times.
1040 for (int i = 0; i < 64; i++)
96 1024 dequant[i] = av_clip(q * quant_tbl[ff_zigzag_direct[i]] / 50, 2, 32767);
97 16 }
98
99 21936 static int decode_block(LeadContext * s, GetBitContext * gb,
100 const VLCElem * dc_table, int dc_bits, const VLCElem * ac_table, int ac_bits,
101 int16_t * dc_pred, const uint16_t * dequant,
102 uint8_t * dst, int stride)
103 {
104 DECLARE_ALIGNED(32, int16_t, block)[64];
105 int size;
106
107 21936 s->bdsp.clear_block(block);
108
109
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 21936 times.
21936 if (get_bits_left(gb) <= 0)
110 return AVERROR_INVALIDDATA;
111
112 21936 size = get_vlc2(gb, dc_table, dc_bits, 1);
113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21936 times.
21936 if (size < 0)
114 return AVERROR_INVALIDDATA;
115
116
2/2
✓ Branch 0 taken 16492 times.
✓ Branch 1 taken 5444 times.
21936 if (size)
117 16492 *dc_pred += get_xbits(gb, size);
118
119 21936 block[0] = (1 << 10) + *dc_pred * dequant[0];
120
121
2/2
✓ Branch 0 taken 188020 times.
✓ Branch 1 taken 100 times.
188120 for (int i = 1; i < 64; i++) {
122 188020 int symbol = get_vlc2(gb, ac_table, ac_bits, 2);
123
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 188020 times.
188020 if (symbol < 0)
124 return AVERROR_INVALIDDATA;
125
126
2/2
✓ Branch 0 taken 21836 times.
✓ Branch 1 taken 166184 times.
188020 if (!symbol)
127 21836 break;
128
129 166184 i += symbol >> 4;
130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 166184 times.
166184 if (i >= 64)
131 return AVERROR_INVALIDDATA;
132
133 166184 size = symbol & 0xF;
134
2/2
✓ Branch 0 taken 165806 times.
✓ Branch 1 taken 378 times.
166184 if (size)
135 165806 block[s->permutated_scantable[i]] = get_xbits(gb, size) * dequant[i];
136 }
137
138 21936 s->idsp.idct_put(dst, stride, block);
139 21936 return 0;
140 }
141
142 8 static int lead_decode_frame(AVCodecContext *avctx, AVFrame * frame,
143 int * got_frame, AVPacket * avpkt)
144 {
145 8 LeadContext *s = avctx->priv_data;
146 8 const uint8_t * buf = avpkt->data;
147 8 int ret, format, zero = 0, yuv20p_half = 0, fields = 1, q, size;
148 GetBitContext gb;
149 8 int16_t dc_pred[3] = {0, 0, 0};
150 uint16_t dequant[2][64];
151
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (avpkt->size < 8)
153 return AVERROR_INVALIDDATA;
154
155 8 format = AV_RL16(buf + 4);
156
4/7
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
8 switch(format) {
157 2 case 0x0:
158 2 zero = 1;
159 2 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
160 2 break;
161 2 case 0x6:
162 case 0x8000:
163 2 yuv20p_half = 1;
164 av_fallthrough;
165 4 case 0x1000:
166 4 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
167 4 break;
168 case 0x1006:
169 fields = 2;
170 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
171 break;
172 case 0x2000:
173 avctx->pix_fmt = AV_PIX_FMT_YUV444P;
174 break;
175 2 case 0x2006:
176 2 avctx->pix_fmt = AV_PIX_FMT_YUV444P;
177 2 fields = 2;
178 2 break;
179 default:
180 avpriv_request_sample(avctx, "unsupported format 0x%x", format);
181 return AVERROR_PATCHWELCOME;
182 }
183
184 8 q = AV_RL16(buf + 6);
185 8 calc_dequant(dequant[0], ff_mjpeg_std_luminance_quant_tbl, q);
186 8 calc_dequant(dequant[1], ff_mjpeg_std_chrominance_quant_tbl, q);
187
188
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
189 return ret;
190
191 8 av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size, avpkt->size - 8);
192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!s->bitstream_buf)
193 return AVERROR(ENOMEM);
194
195 8 size = 0;
196
2/2
✓ Branch 0 taken 175058 times.
✓ Branch 1 taken 8 times.
175066 for (int i = 8; i < avpkt->size; i++) {
197 175058 int src = buf[i] ^ 0x80;
198 175058 s->bitstream_buf[size++] = src;
199
4/6
✓ Branch 0 taken 2554 times.
✓ Branch 1 taken 172504 times.
✓ Branch 2 taken 2554 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2554 times.
✗ Branch 5 not taken.
175058 if (src == 0xFF && i + 1 < avpkt->size && (buf[i + 1] ^ 0x80) == 0x00)
200 2554 i++;
201 }
202
203 8 ret = init_get_bits8(&gb, s->bitstream_buf, size);
204
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (ret < 0)
205 return ret;
206
207
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 4 times.
8 if (avctx->pix_fmt == AV_PIX_FMT_YUV420P && zero) {
208
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 2 times.
74 for (int mb_y = 0; mb_y < avctx->height / 8; mb_y++)
209
2/2
✓ Branch 0 taken 1584 times.
✓ Branch 1 taken 72 times.
1656 for (int mb_x = 0; mb_x < avctx->width / 16; mb_x++)
210
2/2
✓ Branch 0 taken 6336 times.
✓ Branch 1 taken 1584 times.
7920 for (int b = 0; b < 4; b++) {
211 6336 int luma_block = 2;
212
2/2
✓ Branch 0 taken 3168 times.
✓ Branch 1 taken 3168 times.
6336 const VLCElem * dc_vlc = b < luma_block ? luma_dc_vlc : chroma_dc_vlc;
213
2/2
✓ Branch 0 taken 3168 times.
✓ Branch 1 taken 3168 times.
6336 int dc_bits = b < luma_block ? LUMA_DC_BITS : CHROMA_DC_BITS;
214
2/2
✓ Branch 0 taken 3168 times.
✓ Branch 1 taken 3168 times.
6336 const VLCElem * ac_vlc = b < luma_block ? luma_ac_vlc : chroma_ac_vlc;
215 6336 int ac_bits = b < luma_block ? LUMA_AC_BITS : CHROMA_AC_BITS;
216
2/2
✓ Branch 0 taken 3168 times.
✓ Branch 1 taken 3168 times.
6336 int plane = b < luma_block ? 0 : b - 1;
217 int x, y, yclip;
218
219
2/2
✓ Branch 0 taken 3168 times.
✓ Branch 1 taken 3168 times.
6336 if (b < luma_block) {
220 3168 y = 8*mb_y + 8*(b >> 1);
221 3168 x = 16*mb_x + 8*(b & 1);
222 3168 yclip = 0;
223 } else {
224 3168 y = 4*mb_y;
225 3168 x = 8*mb_x;
226 3168 yclip = y + 8 >= avctx->height / 2;
227 }
228
229
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 6160 times.
6336 if (yclip) {
230 uint8_t tmp[64];
231 176 ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
232 176 dc_pred + plane, dequant[!(b < 4)], tmp, 8);
233
4/4
✓ Branch 0 taken 1144 times.
✓ Branch 1 taken 88 times.
✓ Branch 2 taken 1056 times.
✓ Branch 3 taken 88 times.
1232 for (int yy = 0; yy < 8 && y + yy < avctx->height / 2; yy++)
234 1056 memcpy(frame->data[plane] + (y+yy)*frame->linesize[plane] + x, tmp + yy, 8);
235 } else {
236 6160 ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
237 6160 dc_pred + plane, dequant[!(b < 4)],
238 6160 frame->data[plane] + y*frame->linesize[plane] + x,
239 frame->linesize[plane]);
240 }
241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6336 times.
6336 if (ret < 0)
242 return ret;
243 }
244
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
245
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (int f = 0; f < fields; f++)
246
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 4 times.
74 for (int mb_y = 0; mb_y < (avctx->height + 15) / 16 / fields; mb_y++)
247
2/2
✓ Branch 0 taken 1800 times.
✓ Branch 1 taken 70 times.
1870 for (int mb_x = 0; mb_x < (avctx->width + 15) / 16; mb_x++)
248
4/4
✓ Branch 0 taken 6000 times.
✓ Branch 1 taken 4200 times.
✓ Branch 2 taken 8400 times.
✓ Branch 3 taken 1800 times.
10200 for (int b = 0; b < (yuv20p_half ? 4 : 6); b++) {
249
2/2
✓ Branch 0 taken 4800 times.
✓ Branch 1 taken 3600 times.
8400 int luma_block = yuv20p_half ? 2 : 4;
250
2/2
✓ Branch 0 taken 4800 times.
✓ Branch 1 taken 3600 times.
8400 const VLCElem * dc_vlc = b < luma_block ? luma_dc_vlc : chroma_dc_vlc;
251
2/2
✓ Branch 0 taken 4800 times.
✓ Branch 1 taken 3600 times.
8400 int dc_bits = b < luma_block ? LUMA_DC_BITS : CHROMA_DC_BITS;
252
2/2
✓ Branch 0 taken 4800 times.
✓ Branch 1 taken 3600 times.
8400 const VLCElem * ac_vlc = b < luma_block ? luma_ac_vlc : chroma_ac_vlc;
253 8400 int ac_bits = b < luma_block ? LUMA_AC_BITS : CHROMA_AC_BITS;
254
4/4
✓ Branch 0 taken 3600 times.
✓ Branch 1 taken 4800 times.
✓ Branch 2 taken 2400 times.
✓ Branch 3 taken 1200 times.
8400 int plane = b < luma_block ? 0 : b - (yuv20p_half ? 1 : 3);
255 int x, y;
256
257
2/2
✓ Branch 0 taken 4800 times.
✓ Branch 1 taken 3600 times.
8400 if (b < luma_block) {
258 4800 y = 16*mb_y + 8*(b >> 1);
259 4800 x = 16*mb_x + 8*(b & 1);
260 } else {
261 3600 y = 8*mb_y;
262 3600 x = 8*mb_x;
263 }
264
265 8400 ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
266 8400 dc_pred + plane, dequant[!(b < 4)],
267 8400 frame->data[plane] + (f + y*fields)*frame->linesize[plane] + x,
268
4/4
✓ Branch 0 taken 4800 times.
✓ Branch 1 taken 3600 times.
✓ Branch 2 taken 2400 times.
✓ Branch 3 taken 2400 times.
8400 (yuv20p_half && b < 2 ? 2 : 1) * fields * frame->linesize[plane]);
269
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8400 times.
8400 if (ret < 0)
270 return ret;
271
272
4/4
✓ Branch 0 taken 4800 times.
✓ Branch 1 taken 3600 times.
✓ Branch 2 taken 2400 times.
✓ Branch 3 taken 2400 times.
8400 if (yuv20p_half && b < 2)
273 2400 copy_block8(frame->data[plane] + (y + 1)*frame->linesize[plane] + x,
274 2400 frame->data[plane] + y*frame->linesize[plane] + x,
275 2400 2*frame->linesize[plane], 2*frame->linesize[plane], 8);
276 }
277 } else {
278
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for (int f = 0; f < fields; f++)
279
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 4 times.
64 for (int j = 0; j < (avctx->height + 7) / fields / 8; j++)
280
2/2
✓ Branch 0 taken 2400 times.
✓ Branch 1 taken 60 times.
2460 for (int i = 0; i < (avctx->width + 7) / 8; i++)
281
2/2
✓ Branch 0 taken 7200 times.
✓ Branch 1 taken 2400 times.
9600 for (int plane = 0; plane < 3; plane++) {
282
2/2
✓ Branch 0 taken 2400 times.
✓ Branch 1 taken 4800 times.
7200 const VLCElem * dc_vlc = !plane ? luma_dc_vlc : chroma_dc_vlc;
283
2/2
✓ Branch 0 taken 2400 times.
✓ Branch 1 taken 4800 times.
7200 int dc_bits = !plane ? LUMA_DC_BITS : CHROMA_DC_BITS;
284
2/2
✓ Branch 0 taken 2400 times.
✓ Branch 1 taken 4800 times.
7200 const VLCElem * ac_vlc = !plane ? luma_ac_vlc : chroma_ac_vlc;
285 7200 int ac_bits = !plane ? LUMA_AC_BITS : CHROMA_AC_BITS;
286
287 7200 ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
288 7200 dc_pred + plane, dequant[!!plane],
289 7200 frame->data[plane] + (f + 8*j*fields)*frame->linesize[plane] + 8*i,
290 7200 fields * frame->linesize[plane]);
291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7200 times.
7200 if (ret < 0)
292 return ret;
293 }
294 }
295
296 8 *got_frame = 1;
297
298 8 return avpkt->size;
299 }
300
301 8 static av_cold int lead_decode_end(AVCodecContext * avctx)
302 {
303 8 LeadContext *s = avctx->priv_data;
304
305 8 av_freep(&s->bitstream_buf);
306
307 8 return 0;
308 }
309
310 const FFCodec ff_lead_decoder = {
311 .p.name = "lead",
312 CODEC_LONG_NAME("LEAD MCMP"),
313 .p.type = AVMEDIA_TYPE_VIDEO,
314 .p.id = AV_CODEC_ID_LEAD,
315 .priv_data_size = sizeof(LeadContext),
316 .init = lead_decode_init,
317 .close = lead_decode_end,
318 FF_CODEC_DECODE_CB(lead_decode_frame),
319 .p.capabilities = AV_CODEC_CAP_DR1,
320 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
321 };
322