/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 | | }; |