FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/leaddec.c
Date: 2025-03-08 20:38:41
Exec Total Coverage
Lines: 0 165 0.0%
Functions: 0 6 0.0%
Branches: 0 123 0.0%

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/mem.h"
34 #include "libavutil/mem_internal.h"
35 #include "libavutil/thread.h"
36
37 #define LUMA_DC_BITS 9
38 #define CHROMA_DC_BITS 11
39 #define LUMA_AC_BITS 10
40 #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 {
49 VLC_INIT_STATIC_TABLE_FROM_LENGTHS(luma_dc_vlc, LUMA_DC_BITS, FF_ARRAY_ELEMS(luma_dc_len),
50 luma_dc_len, 1,
51 NULL, 0, 0,
52 0, 0);
53 VLC_INIT_STATIC_TABLE_FROM_LENGTHS(chroma_dc_vlc, CHROMA_DC_BITS, FF_ARRAY_ELEMS(chroma_dc_len),
54 chroma_dc_len, 1,
55 NULL, 0, 0,
56 0, 0);
57 VLC_INIT_STATIC_TABLE_FROM_LENGTHS(luma_ac_vlc, LUMA_AC_BITS, FF_ARRAY_ELEMS(luma_ac_len),
58 luma_ac_len, 1,
59 ff_mjpeg_val_ac_luminance, 1, 1,
60 0, 0);
61 VLC_INIT_STATIC_TABLE_FROM_LENGTHS(chroma_ac_vlc, CHROMA_AC_BITS, FF_ARRAY_ELEMS(chroma_ac_len),
62 chroma_ac_len, 1,
63 ff_mjpeg_val_ac_chrominance, 1, 1,
64 0, 0);
65 }
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 {
77 static AVOnce init_static_once = AV_ONCE_INIT;
78 LeadContext *s = avctx->priv_data;
79
80 if (avctx->extradata_size < 20)
81 return AVERROR_INVALIDDATA;
82
83 ff_blockdsp_init(&s->bdsp);
84 ff_idctdsp_init(&s->idsp, avctx);
85 ff_permute_scantable(s->permutated_scantable, ff_zigzag_direct, s->idsp.idct_permutation);
86
87 ff_thread_once(&init_static_once, lead_init_static_data);
88
89 return 0;
90 }
91
92 static void calc_dequant(uint16_t * dequant, const uint8_t * quant_tbl, int q)
93 {
94 for (int i = 0; i < 64; i++)
95 dequant[i] = av_clip(q * quant_tbl[ff_zigzag_direct[i]] / 50, 2, 32767);
96 }
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 {
103 DECLARE_ALIGNED(32, int16_t, block)[64];
104 int size;
105
106 s->bdsp.clear_block(block);
107
108 if (get_bits_left(gb) <= 0)
109 return AVERROR_INVALIDDATA;
110
111 size = get_vlc2(gb, dc_table, dc_bits, 1);
112 if (size < 0)
113 return AVERROR_INVALIDDATA;
114
115 if (size)
116 *dc_pred += get_xbits(gb, size);
117
118 block[0] = (1 << 10) + *dc_pred * dequant[0];
119
120 for (int i = 1; i < 64; i++) {
121 int symbol = get_vlc2(gb, ac_table, ac_bits, 2);
122 if (symbol < 0)
123 return AVERROR_INVALIDDATA;
124
125 if (!symbol)
126 break;
127
128 i += symbol >> 4;
129 if (i >= 64)
130 return AVERROR_INVALIDDATA;
131
132 size = symbol & 0xF;
133 if (size)
134 block[s->permutated_scantable[i]] = get_xbits(gb, size) * dequant[i];
135 }
136
137 s->idsp.idct_put(dst, stride, block);
138 return 0;
139 }
140
141 static int lead_decode_frame(AVCodecContext *avctx, AVFrame * frame,
142 int * got_frame, AVPacket * avpkt)
143 {
144 LeadContext *s = avctx->priv_data;
145 const uint8_t * buf = avpkt->data;
146 int ret, format, zero = 0, yuv20p_half = 0, fields = 1, q, size;
147 GetBitContext gb;
148 int16_t dc_pred[3] = {0, 0, 0};
149 uint16_t dequant[2][64];
150
151 if (avpkt->size < 8)
152 return AVERROR_INVALIDDATA;
153
154 format = AV_RL16(buf + 4);
155 switch(format) {
156 case 0x0:
157 zero = 1;
158 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
159 break;
160 case 0x6:
161 case 0x8000:
162 yuv20p_half = 1;
163 // fall-through
164 case 0x1000:
165 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
166 break;
167 case 0x1006:
168 fields = 2;
169 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
170 break;
171 case 0x2000:
172 avctx->pix_fmt = AV_PIX_FMT_YUV444P;
173 break;
174 case 0x2006:
175 avctx->pix_fmt = AV_PIX_FMT_YUV444P;
176 fields = 2;
177 break;
178 default:
179 avpriv_request_sample(avctx, "unsupported format 0x%x", format);
180 return AVERROR_PATCHWELCOME;
181 }
182
183 q = AV_RL16(buf + 6);
184 calc_dequant(dequant[0], ff_mjpeg_std_luminance_quant_tbl, q);
185 calc_dequant(dequant[1], ff_mjpeg_std_chrominance_quant_tbl, q);
186
187 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
188 return ret;
189
190 av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size, avpkt->size - 8);
191 if (!s->bitstream_buf)
192 return AVERROR(ENOMEM);
193
194 size = 0;
195 for (int i = 8; i < avpkt->size; i++) {
196 int src = buf[i] ^ 0x80;
197 s->bitstream_buf[size++] = src;
198 if (src == 0xFF && i + 1 < avpkt->size && (buf[i + 1] ^ 0x80) == 0x00)
199 i++;
200 }
201
202 ret = init_get_bits8(&gb, s->bitstream_buf, size);
203 if (ret < 0)
204 return ret;
205
206 if (avctx->pix_fmt == AV_PIX_FMT_YUV420P && zero) {
207 for (int mb_y = 0; mb_y < avctx->height / 8; mb_y++)
208 for (int mb_x = 0; mb_x < avctx->width / 16; mb_x++)
209 for (int b = 0; b < 4; b++) {
210 int luma_block = 2;
211 const VLCElem * dc_vlc = b < luma_block ? luma_dc_vlc : chroma_dc_vlc;
212 int dc_bits = b < luma_block ? LUMA_DC_BITS : CHROMA_DC_BITS;
213 const VLCElem * ac_vlc = b < luma_block ? luma_ac_vlc : chroma_ac_vlc;
214 int ac_bits = b < luma_block ? LUMA_AC_BITS : CHROMA_AC_BITS;
215 int plane = b < luma_block ? 0 : b - 1;
216 int x, y, yclip;
217
218 if (b < luma_block) {
219 y = 8*mb_y + 8*(b >> 1);
220 x = 16*mb_x + 8*(b & 1);
221 yclip = 0;
222 } else {
223 y = 4*mb_y;
224 x = 8*mb_x;
225 yclip = y + 8 >= avctx->height / 2;
226 }
227
228 if (yclip) {
229 uint8_t tmp[64];
230 ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
231 dc_pred + plane, dequant[!(b < 4)], tmp, 8);
232 for (int yy = 0; yy < 8 && y + yy < avctx->height / 2; yy++)
233 memcpy(frame->data[plane] + (y+yy)*frame->linesize[plane] + x, tmp + yy, 8);
234 } else {
235 ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
236 dc_pred + plane, dequant[!(b < 4)],
237 frame->data[plane] + y*frame->linesize[plane] + x,
238 frame->linesize[plane]);
239 }
240 if (ret < 0)
241 return ret;
242 }
243 } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
244 for (int f = 0; f < fields; f++)
245 for (int mb_y = 0; mb_y < (avctx->height + 15) / 16 / fields; mb_y++)
246 for (int mb_x = 0; mb_x < (avctx->width + 15) / 16; mb_x++)
247 for (int b = 0; b < (yuv20p_half ? 4 : 6); b++) {
248 int luma_block = yuv20p_half ? 2 : 4;
249 const VLCElem * dc_vlc = b < luma_block ? luma_dc_vlc : chroma_dc_vlc;
250 int dc_bits = b < luma_block ? LUMA_DC_BITS : CHROMA_DC_BITS;
251 const VLCElem * ac_vlc = b < luma_block ? luma_ac_vlc : chroma_ac_vlc;
252 int ac_bits = b < luma_block ? LUMA_AC_BITS : CHROMA_AC_BITS;
253 int plane = b < luma_block ? 0 : b - (yuv20p_half ? 1 : 3);
254 int x, y;
255
256 if (b < luma_block) {
257 y = 16*mb_y + 8*(b >> 1);
258 x = 16*mb_x + 8*(b & 1);
259 } else {
260 y = 8*mb_y;
261 x = 8*mb_x;
262 }
263
264 ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
265 dc_pred + plane, dequant[!(b < 4)],
266 frame->data[plane] + (f + y*fields)*frame->linesize[plane] + x,
267 (yuv20p_half && b < 2 ? 2 : 1) * fields * frame->linesize[plane]);
268 if (ret < 0)
269 return ret;
270
271 if (yuv20p_half && b < 2)
272 copy_block8(frame->data[plane] + (y + 1)*frame->linesize[plane] + x,
273 frame->data[plane] + y*frame->linesize[plane] + x,
274 2*frame->linesize[plane], 2*frame->linesize[plane], 8);
275 }
276 } else {
277 for (int f = 0; f < fields; f++)
278 for (int j = 0; j < (avctx->height + 7) / fields / 8; j++)
279 for (int i = 0; i < (avctx->width + 7) / 8; i++)
280 for (int plane = 0; plane < 3; plane++) {
281 const VLCElem * dc_vlc = !plane ? luma_dc_vlc : chroma_dc_vlc;
282 int dc_bits = !plane ? LUMA_DC_BITS : CHROMA_DC_BITS;
283 const VLCElem * ac_vlc = !plane ? luma_ac_vlc : chroma_ac_vlc;
284 int ac_bits = !plane ? LUMA_AC_BITS : CHROMA_AC_BITS;
285
286 ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits,
287 dc_pred + plane, dequant[!!plane],
288 frame->data[plane] + (f + 8*j*fields)*frame->linesize[plane] + 8*i,
289 fields * frame->linesize[plane]);
290 if (ret < 0)
291 return ret;
292 }
293 }
294
295 *got_frame = 1;
296
297 return avpkt->size;
298 }
299
300 static av_cold int lead_decode_end(AVCodecContext * avctx)
301 {
302 LeadContext *s = avctx->priv_data;
303
304 av_freep(&s->bitstream_buf);
305
306 return 0;
307 }
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 };
321