FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/hqx.c
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 187 273 68.5%
Functions: 10 12 83.3%
Branches: 74 121 61.2%

Line Branch Exec Source
1 /*
2 * Canopus HQX decoder
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <inttypes.h>
22
23 #include "libavutil/frame.h"
24 #include "libavutil/imgutils.h"
25 #include "libavutil/mem_internal.h"
26 #include "libavutil/intreadwrite.h"
27 #include "libavutil/thread.h"
28
29 #include "avcodec.h"
30 #include "canopus.h"
31 #include "codec_internal.h"
32 #include "get_bits.h"
33 #include "thread.h"
34 #include "vlc.h"
35
36 #include "hqxdsp.h"
37 #include "hqxvlc.h"
38 #include "hq_common.h"
39
40 /* HQX has four modes - 422, 444, 422alpha and 444alpha - all 12-bit */
41 enum HQXFormat {
42 HQX_422 = 0,
43 HQX_444,
44 HQX_422A,
45 HQX_444A,
46 };
47
48 struct HQXContext;
49
50 typedef int (*mb_decode_func)(struct HQXContext *ctx,
51 int slice_no, int x, int y);
52
53 typedef struct HQXSlice {
54 GetBitContext gb;
55 DECLARE_ALIGNED(16, int16_t, block)[16][64];
56 } HQXSlice;
57
58 typedef struct HQXContext {
59 HQXDSPContext hqxdsp;
60 HQXSlice slice[16];
61
62 AVFrame *pic;
63 mb_decode_func decode_func;
64
65 int format, dcb, width, height;
66 int interlaced;
67
68 const uint8_t *src;
69 unsigned int data_size;
70 uint32_t slice_off[17];
71
72 const VLCElem *dc_vlc;
73
74 VLC dc11_vlc;
75 } HQXContext;
76
77 #define HQX_HEADER_SIZE 59
78
79 #define AC_IDX(q) ((q) >= 128 ? HQX_AC_Q128 : (q) >= 64 ? HQX_AC_Q64 : \
80 (q) >= 32 ? HQX_AC_Q32 : (q) >= 16 ? HQX_AC_Q16 : \
81 (q) >= 8 ? HQX_AC_Q8 : HQX_AC_Q0)
82
83 /* macroblock selects a group of 4 possible quants and
84 * a block can use any of those four quantisers
85 * one column is powers of 2, the other one is powers of 2 * 3,
86 * then there is the special one, powers of 2 * 5.
87 * We also encode the corresponding AC index in these tables in bits 29-31. */
88 static const unsigned hqx_quants[16][4] = {
89 #define Q(q) ((unsigned)AC_IDX(q) << 29 | (q))
90 { Q( 0x1), Q( 0x2), Q( 0x4), Q( 0x8) }, { Q( 0x1), Q( 0x3), Q( 0x6), Q( 0xC) },
91 { Q( 0x2), Q( 0x4), Q( 0x8), Q( 0x10) }, { Q( 0x3), Q( 0x6), Q( 0xC), Q( 0x18) },
92 { Q( 0x4), Q( 0x8), Q( 0x10), Q( 0x20) }, { Q( 0x6), Q( 0xC), Q( 0x18), Q( 0x30) },
93 { Q( 0x8), Q( 0x10), Q( 0x20), Q( 0x40) },
94 { Q(0xA), Q(0x14), Q(0x28), Q(0x50) },
95 { Q( 0xC), Q(0x18), Q( 0x30), Q( 0x60) },
96 { Q(0x10), Q( 0x20), Q( 0x40), Q( 0x80) }, { Q(0x18), Q(0x30), Q( 0x60), Q( 0xC0) },
97 { Q(0x20), Q( 0x40), Q( 0x80), Q(0x100) }, { Q(0x30), Q(0x60), Q( 0xC0), Q(0x180) },
98 { Q(0x40), Q( 0x80), Q(0x100), Q(0x200) }, { Q(0x60), Q(0xC0), Q(0x180), Q(0x300) },
99 { Q(0x80), Q(0x100), Q(0x200), Q(0x400) }
100 };
101
102 static const uint8_t hqx_quant_luma[64] = {
103 16, 16, 16, 19, 19, 19, 42, 44,
104 16, 16, 19, 19, 19, 38, 43, 45,
105 16, 19, 19, 19, 40, 41, 45, 48,
106 19, 19, 19, 40, 41, 42, 46, 49,
107 19, 19, 40, 41, 42, 43, 48, 101,
108 19, 38, 41, 42, 43, 44, 98, 104,
109 42, 43, 45, 46, 48, 98, 109, 116,
110 44, 45, 48, 49, 101, 104, 116, 123,
111 };
112
113 static const uint8_t hqx_quant_chroma[64] = {
114 16, 16, 19, 25, 26, 26, 42, 44,
115 16, 19, 25, 25, 26, 38, 43, 91,
116 19, 25, 26, 27, 40, 41, 91, 96,
117 25, 25, 27, 40, 41, 84, 93, 197,
118 26, 26, 40, 41, 84, 86, 191, 203,
119 26, 38, 41, 84, 86, 177, 197, 209,
120 42, 43, 91, 93, 191, 197, 219, 232,
121 44, 91, 96, 197, 203, 209, 232, 246,
122 };
123
124 110880 static inline void put_blocks(HQXContext *ctx, int plane,
125 int x, int y, int ilace,
126 int16_t *block0, int16_t *block1,
127 const uint8_t *quant)
128 {
129
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 110744 times.
110880 int fields = ilace ? 2 : 1;
130 110880 int lsize = ctx->pic->linesize[plane];
131 110880 uint8_t *p = ctx->pic->data[plane] + x * 2;
132
133 110880 ctx->hqxdsp.idct_put((uint16_t *)(p + y * lsize),
134 110880 lsize * fields, block0, quant);
135 110880 ctx->hqxdsp.idct_put((uint16_t *)(p + (y + (ilace ? 1 : 8)) * lsize),
136
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 110744 times.
110880 lsize * fields, block1, quant);
137 110880 }
138
139 2674300 static inline void hqx_get_ac(GetBitContext *gb, const HQXAC *ac,
140 int *runp, int *lev)
141 {
142 int level, run;
143 2674300 OPEN_READER(re, gb);
144
145 2674300 UPDATE_CACHE(re, gb);
146
2/2
✓ Branch 1 taken 108610 times.
✓ Branch 2 taken 2565690 times.
2674300 GET_RL_VLC(level, run, re, gb, ac->lut, ac->bits, 2, 0);
147 2674300 CLOSE_READER(re, gb);
148 2674300 *runp = run;
149 2674300 *lev = level;
150 2674300 }
151
152 144104 static int decode_block(GetBitContext *gb, const VLCElem vlc[],
153 const unsigned *quants, int dcb,
154 int16_t block[64], int *last_dc)
155 {
156 144104 int run, lev, pos = 0;
157 unsigned ac_idx, q;
158 int dc;
159
160 144104 dc = get_vlc2(gb, vlc, HQX_DC_VLC_BITS, 2);
161 144104 *last_dc += dc;
162
163 144104 block[0] = sign_extend(*last_dc << (12 - dcb), 12);
164
165 144104 q = quants[get_bits(gb, 2)];
166 // ac_idx is encoded in the high bits of quants;
167 // because block is 16 bit, we do not even need to clear said bits.
168 144104 ac_idx = q >> 29;
169
170 do {
171 2674300 hqx_get_ac(gb, &hqx_ac[ac_idx], &run, &lev);
172 2674300 pos += run;
173
2/2
✓ Branch 0 taken 140780 times.
✓ Branch 1 taken 2533520 times.
2674300 if (pos > 63)
174 140780 break;
175 2533520 block[ff_zigzag_direct[pos]] = lev * q;
176
2/2
✓ Branch 0 taken 2530196 times.
✓ Branch 1 taken 3324 times.
2533520 } while (pos < 63);
177
178 144104 return 0;
179 }
180
181 3240 static int hqx_decode_422(HQXContext *ctx, int slice_no, int x, int y)
182 {
183 3240 HQXSlice *slice = &ctx->slice[slice_no];
184 3240 GetBitContext *gb = &slice->gb;
185 const unsigned *quants;
186 int flag;
187 int last_dc;
188 int i, ret;
189
190 3240 memset(slice->block, 0, sizeof(*slice->block) * 8);
191
192
1/2
✓ Branch 0 taken 3240 times.
✗ Branch 1 not taken.
3240 if (ctx->interlaced)
193 3240 flag = get_bits1(gb);
194 else
195 flag = 0;
196
197 3240 quants = hqx_quants[get_bits(gb, 4)];
198
199
2/2
✓ Branch 0 taken 25920 times.
✓ Branch 1 taken 3240 times.
29160 for (i = 0; i < 8; i++) {
200
6/6
✓ Branch 0 taken 22680 times.
✓ Branch 1 taken 3240 times.
✓ Branch 2 taken 19440 times.
✓ Branch 3 taken 3240 times.
✓ Branch 4 taken 3240 times.
✓ Branch 5 taken 16200 times.
25920 if (i == 0 || i == 4 || i == 6)
201 9720 last_dc = 0;
202 25920 ret = decode_block(gb, ctx->dc_vlc, quants,
203 25920 ctx->dcb, slice->block[i], &last_dc);
204
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25920 times.
25920 if (ret < 0)
205 return ret;
206 }
207
208 3240 put_blocks(ctx, 0, x, y, flag, slice->block[0], slice->block[2], hqx_quant_luma);
209 3240 put_blocks(ctx, 0, x + 8, y, flag, slice->block[1], slice->block[3], hqx_quant_luma);
210 3240 put_blocks(ctx, 2, x >> 1, y, flag, slice->block[4], slice->block[5], hqx_quant_chroma);
211 3240 put_blocks(ctx, 1, x >> 1, y, flag, slice->block[6], slice->block[7], hqx_quant_chroma);
212
213 3240 return 0;
214 }
215
216 16320 static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y)
217 {
218 16320 HQXSlice *slice = &ctx->slice[slice_no];
219 16320 GetBitContext *gb = &slice->gb;
220 16320 int flag = 0;
221 int last_dc;
222 int i, ret;
223
224 16320 memset(slice->block, 0, sizeof(*slice->block) * 12);
225
2/2
✓ Branch 0 taken 195840 times.
✓ Branch 1 taken 16320 times.
212160 for (i = 0; i < 12; i++)
226 195840 slice->block[i][0] = -0x800;
227
228 16320 int cbp = get_vlc2(gb, ff_hq_cbp_vlc, HQ_CBP_VLC_BITS, 1);
229
2/2
✓ Branch 0 taken 9986 times.
✓ Branch 1 taken 6334 times.
16320 if (cbp) {
230 const unsigned *quants;
231
232
1/2
✓ Branch 0 taken 9986 times.
✗ Branch 1 not taken.
9986 if (ctx->interlaced)
233 9986 flag = get_bits1(gb);
234
235 9986 quants = hqx_quants[get_bits(gb, 4)];
236
237
2/2
✓ Branch 0 taken 9896 times.
✓ Branch 1 taken 90 times.
9986 if (cbp & 0x3) // chroma CBP - top
238 9896 cbp |= 0x500;
239
2/2
✓ Branch 0 taken 9878 times.
✓ Branch 1 taken 108 times.
9986 if (cbp & 0xC) // chroma CBP - bottom
240 9878 cbp |= 0xA00;
241
2/2
✓ Branch 0 taken 119832 times.
✓ Branch 1 taken 9986 times.
129818 for (i = 0; i < 12; i++) {
242
8/8
✓ Branch 0 taken 109846 times.
✓ Branch 1 taken 9986 times.
✓ Branch 2 taken 99860 times.
✓ Branch 3 taken 9986 times.
✓ Branch 4 taken 89874 times.
✓ Branch 5 taken 9986 times.
✓ Branch 6 taken 9986 times.
✓ Branch 7 taken 79888 times.
119832 if (i == 0 || i == 4 || i == 8 || i == 10)
243 39944 last_dc = 0;
244
2/2
✓ Branch 0 taken 118184 times.
✓ Branch 1 taken 1648 times.
119832 if (cbp & (1 << i)) {
245 118184 ret = decode_block(gb, ctx->dc_vlc, quants,
246 118184 ctx->dcb, slice->block[i], &last_dc);
247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 118184 times.
118184 if (ret < 0)
248 return ret;
249 }
250 }
251 }
252
253 16320 put_blocks(ctx, 3, x, y, flag, slice->block[ 0], slice->block[ 2], hqx_quant_luma);
254 16320 put_blocks(ctx, 3, x + 8, y, flag, slice->block[ 1], slice->block[ 3], hqx_quant_luma);
255 16320 put_blocks(ctx, 0, x, y, flag, slice->block[ 4], slice->block[ 6], hqx_quant_luma);
256 16320 put_blocks(ctx, 0, x + 8, y, flag, slice->block[ 5], slice->block[ 7], hqx_quant_luma);
257 16320 put_blocks(ctx, 2, x >> 1, y, flag, slice->block[ 8], slice->block[ 9], hqx_quant_chroma);
258 16320 put_blocks(ctx, 1, x >> 1, y, flag, slice->block[10], slice->block[11], hqx_quant_chroma);
259
260 16320 return 0;
261 }
262
263 static int hqx_decode_444(HQXContext *ctx, int slice_no, int x, int y)
264 {
265 HQXSlice *slice = &ctx->slice[slice_no];
266 GetBitContext *gb = &slice->gb;
267 const unsigned *quants;
268 int flag;
269 int last_dc;
270 int i, ret;
271
272 memset(slice->block, 0, sizeof(*slice->block) * 12);
273
274 if (ctx->interlaced)
275 flag = get_bits1(gb);
276 else
277 flag = 0;
278
279 quants = hqx_quants[get_bits(gb, 4)];
280
281 for (i = 0; i < 12; i++) {
282 if (!(i & 3))
283 last_dc = 0;
284 ret = decode_block(gb, ctx->dc_vlc, quants,
285 ctx->dcb, slice->block[i], &last_dc);
286 if (ret < 0)
287 return ret;
288 }
289
290 put_blocks(ctx, 0, x, y, flag, slice->block[0], slice->block[ 2], hqx_quant_luma);
291 put_blocks(ctx, 0, x + 8, y, flag, slice->block[1], slice->block[ 3], hqx_quant_luma);
292 put_blocks(ctx, 2, x, y, flag, slice->block[4], slice->block[ 6], hqx_quant_chroma);
293 put_blocks(ctx, 2, x + 8, y, flag, slice->block[5], slice->block[ 7], hqx_quant_chroma);
294 put_blocks(ctx, 1, x, y, flag, slice->block[8], slice->block[10], hqx_quant_chroma);
295 put_blocks(ctx, 1, x + 8, y, flag, slice->block[9], slice->block[11], hqx_quant_chroma);
296
297 return 0;
298 }
299
300 static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y)
301 {
302 HQXSlice *slice = &ctx->slice[slice_no];
303 GetBitContext *gb = &slice->gb;
304 int flag = 0;
305 int last_dc;
306 int i, ret;
307
308 memset(slice->block, 0, sizeof(*slice->block) * 16);
309 for (i = 0; i < 16; i++)
310 slice->block[i][0] = -0x800;
311
312 int cbp = get_vlc2(gb, ff_hq_cbp_vlc, HQ_CBP_VLC_BITS, 1);
313 if (cbp) {
314 const unsigned *quants;
315
316 if (ctx->interlaced)
317 flag = get_bits1(gb);
318
319 quants = hqx_quants[get_bits(gb, 4)];
320
321 cbp |= cbp << 8; // chroma CBP
322 for (i = 0; i < 16; i++) {
323 if (!(i & 3))
324 last_dc = 0;
325 if (cbp & (1 << i)) {
326 ret = decode_block(gb, ctx->dc_vlc, quants,
327 ctx->dcb, slice->block[i], &last_dc);
328 if (ret < 0)
329 return ret;
330 }
331 }
332 }
333
334 put_blocks(ctx, 3, x, y, flag, slice->block[ 0], slice->block[ 2], hqx_quant_luma);
335 put_blocks(ctx, 3, x + 8, y, flag, slice->block[ 1], slice->block[ 3], hqx_quant_luma);
336 put_blocks(ctx, 0, x, y, flag, slice->block[ 4], slice->block[ 6], hqx_quant_luma);
337 put_blocks(ctx, 0, x + 8, y, flag, slice->block[ 5], slice->block[ 7], hqx_quant_luma);
338 put_blocks(ctx, 2, x, y, flag, slice->block[ 8], slice->block[10], hqx_quant_chroma);
339 put_blocks(ctx, 2, x + 8, y, flag, slice->block[ 9], slice->block[11], hqx_quant_chroma);
340 put_blocks(ctx, 1, x, y, flag, slice->block[12], slice->block[14], hqx_quant_chroma);
341 put_blocks(ctx, 1, x + 8, y, flag, slice->block[13], slice->block[15], hqx_quant_chroma);
342
343 return 0;
344 }
345
346 static const int shuffle_16[16] = {
347 0, 5, 11, 14, 2, 7, 9, 13, 1, 4, 10, 15, 3, 6, 8, 12
348 };
349
350 64 static int decode_slice(HQXContext *ctx, int slice_no)
351 {
352 64 int mb_w = (ctx->width + 15) >> 4;
353 64 int mb_h = (ctx->height + 15) >> 4;
354 64 int grp_w = (mb_w + 4) / 5;
355 64 int grp_h = (mb_h + 4) / 5;
356 64 int grp_h_edge = grp_w * (mb_w / grp_w);
357 64 int grp_v_edge = grp_h * (mb_h / grp_h);
358 64 int grp_v_rest = mb_w - grp_h_edge;
359 64 int grp_h_rest = mb_h - grp_v_edge;
360 64 int num_mbs = mb_w * mb_h;
361 64 int num_tiles = (num_mbs + 479) / 480;
362 64 int std_tile_blocks = num_mbs / (16 * num_tiles);
363 64 int g_tile = slice_no * num_tiles;
364 int blk_addr, loc_addr, mb_x, mb_y, pos, loc_row, i;
365 int tile_blocks, tile_limit, tile_no;
366
367
2/2
✓ Branch 0 taken 672 times.
✓ Branch 1 taken 64 times.
736 for (tile_no = 0; tile_no < num_tiles; tile_no++, g_tile++) {
368 672 tile_blocks = std_tile_blocks;
369 672 tile_limit = -1;
370
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 632 times.
672 if (g_tile < num_mbs - std_tile_blocks * 16 * num_tiles) {
371 40 tile_limit = num_mbs / (16 * num_tiles);
372 40 tile_blocks++;
373 }
374
2/2
✓ Branch 0 taken 19560 times.
✓ Branch 1 taken 672 times.
20232 for (i = 0; i < tile_blocks; i++) {
375
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 19520 times.
19560 if (i == tile_limit)
376 40 blk_addr = g_tile + 16 * num_tiles * i;
377 else
378 19520 blk_addr = tile_no + 16 * num_tiles * i +
379 19520 num_tiles * shuffle_16[(i + slice_no) & 0xF];
380 19560 loc_row = grp_h * (blk_addr / (grp_h * mb_w));
381 19560 loc_addr = blk_addr % (grp_h * mb_w);
382
2/2
✓ Branch 0 taken 3240 times.
✓ Branch 1 taken 16320 times.
19560 if (loc_row >= grp_v_edge) {
383 3240 mb_x = grp_w * (loc_addr / (grp_h_rest * grp_w));
384 3240 pos = loc_addr % (grp_h_rest * grp_w);
385 } else {
386 16320 mb_x = grp_w * (loc_addr / (grp_h * grp_w));
387 16320 pos = loc_addr % (grp_h * grp_w);
388 }
389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19560 times.
19560 if (mb_x >= grp_h_edge) {
390 mb_x += pos % grp_v_rest;
391 mb_y = loc_row + (pos / grp_v_rest);
392 } else {
393 19560 mb_x += pos % grp_w;
394 19560 mb_y = loc_row + (pos / grp_w);
395 }
396 19560 ctx->decode_func(ctx, slice_no, mb_x * 16, mb_y * 16);
397 }
398 }
399
400 64 return 0;
401 }
402
403 64 static int decode_slice_thread(AVCodecContext *avctx, void *arg,
404 int slice_no, int threadnr)
405 {
406 64 HQXContext *ctx = avctx->priv_data;
407 64 uint32_t *slice_off = ctx->slice_off;
408 int ret;
409
410
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
64 if (slice_off[slice_no] < HQX_HEADER_SIZE ||
411
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
64 slice_off[slice_no] >= slice_off[slice_no + 1] ||
412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
64 slice_off[slice_no + 1] > ctx->data_size) {
413 av_log(avctx, AV_LOG_ERROR, "Invalid slice size %d.\n", ctx->data_size);
414 return AVERROR_INVALIDDATA;
415 }
416
417 64 ret = init_get_bits8(&ctx->slice[slice_no].gb,
418 64 ctx->src + slice_off[slice_no],
419 64 slice_off[slice_no + 1] - slice_off[slice_no]);
420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
64 if (ret < 0)
421 return ret;
422
423 64 return decode_slice(ctx, slice_no);
424 }
425
426 4 static int hqx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
427 int *got_picture_ptr, AVPacket *avpkt)
428 {
429 4 HQXContext *ctx = avctx->priv_data;
430 4 const uint8_t *src = avpkt->data;
431 uint32_t info_tag;
432 int data_start, dcb_code;
433 int i, ret;
434
435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (avpkt->size < 4 + 4) {
436 av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size);
437 return AVERROR_INVALIDDATA;
438 }
439
440 4 info_tag = AV_RL32(src);
441
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
442 4 uint32_t info_offset = AV_RL32(src + 4);
443
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if (info_offset > INT_MAX || info_offset + 8 > avpkt->size) {
444 av_log(avctx, AV_LOG_ERROR,
445 "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n",
446 info_offset);
447 return AVERROR_INVALIDDATA;
448 }
449 4 ff_canopus_parse_info_tag(avctx, src + 8, info_offset);
450
451 4 info_offset += 8;
452 4 src += info_offset;
453 }
454
455 4 data_start = src - avpkt->data;
456 4 ctx->data_size = avpkt->size - data_start;
457 4 ctx->src = src;
458 4 ctx->pic = frame;
459
460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (ctx->data_size < HQX_HEADER_SIZE) {
461 av_log(avctx, AV_LOG_ERROR, "Frame too small.\n");
462 return AVERROR_INVALIDDATA;
463 }
464
465
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if (src[0] != 'H' || src[1] != 'Q') {
466 av_log(avctx, AV_LOG_ERROR, "Not an HQX frame.\n");
467 return AVERROR_INVALIDDATA;
468 }
469 4 ctx->interlaced = !(src[2] & 0x80);
470 4 ctx->format = src[2] & 7;
471 4 dcb_code = src[3] & 3;
472 4 ctx->width = AV_RB16(src + 4);
473 4 ctx->height = AV_RB16(src + 6);
474
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 4 times.
72 for (i = 0; i < 17; i++)
475 68 ctx->slice_off[i] = AV_RB24(src + 8 + i * 3);
476
477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (dcb_code == 0) {
478 av_log(avctx, AV_LOG_ERROR, "Invalid DC precision 8.\n");
479 return AVERROR_INVALIDDATA;
480 }
481
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 ctx->dc_vlc = dcb_code == 3 ? ctx->dc11_vlc.table : dc_vlc[dcb_code - 1];
482 4 ctx->dcb = dcb_code + 8;
483 4 ret = av_image_check_size(ctx->width, ctx->height, 0, avctx);
484
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (ret < 0) {
485 av_log(avctx, AV_LOG_ERROR, "Invalid stored dimensions %dx%d.\n",
486 ctx->width, ctx->height);
487 return AVERROR_INVALIDDATA;
488 }
489
490 4 avctx->coded_width = FFALIGN(ctx->width, 16);
491 4 avctx->coded_height = FFALIGN(ctx->height, 16);
492 4 avctx->width = ctx->width;
493 4 avctx->height = ctx->height;
494 4 avctx->bits_per_raw_sample = 10;
495
496 //The minimum size is 2bit per macroblock
497 // hqx_decode_422 & hqx_decode_444 have a unconditionally stored 4bits hqx_quants index
498 // hqx_decode_422a & hqx_decode_444a use cbp_vlc which has a minimum length of 2 bits for its VLCs
499 // The code rejects slices overlapping in their input data
500 4 if (avctx->coded_width / 16 * (avctx->coded_height / 16) *
501
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 (100 - avctx->discard_damaged_percentage) / 100 > 4LL * avpkt->size)
502 return AVERROR_INVALIDDATA;
503
504
2/5
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 switch (ctx->format) {
505 2 case HQX_422:
506 2 avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
507 2 ctx->decode_func = hqx_decode_422;
508 2 break;
509 case HQX_444:
510 avctx->pix_fmt = AV_PIX_FMT_YUV444P16;
511 ctx->decode_func = hqx_decode_444;
512 break;
513 2 case HQX_422A:
514 2 avctx->pix_fmt = AV_PIX_FMT_YUVA422P16;
515 2 ctx->decode_func = hqx_decode_422a;
516 2 break;
517 case HQX_444A:
518 avctx->pix_fmt = AV_PIX_FMT_YUVA444P16;
519 ctx->decode_func = hqx_decode_444a;
520 break;
521 default:
522 av_log(avctx, AV_LOG_ERROR, "Invalid format: %d.\n", ctx->format);
523 return AVERROR_INVALIDDATA;
524 }
525
526 4 ret = ff_thread_get_buffer(avctx, frame, 0);
527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (ret < 0)
528 return ret;
529
530 4 avctx->execute2(avctx, decode_slice_thread, NULL, NULL, 16);
531
532 4 *got_picture_ptr = 1;
533
534 4 return avpkt->size;
535 }
536
537 4 static av_cold int hqx_decode_close(AVCodecContext *avctx)
538 {
539 4 HQXContext *ctx = avctx->priv_data;
540
541 4 ff_vlc_free(&ctx->dc11_vlc);
542
543 4 return 0;
544 }
545
546 4 static av_cold int hqx_decode_init(AVCodecContext *avctx)
547 {
548 static AVOnce init_static_once = AV_ONCE_INIT;
549 4 HQXContext *ctx = avctx->priv_data;
550 4 int ret = vlc_init(&ctx->dc11_vlc, HQX_DC_VLC_BITS, FF_ARRAY_ELEMS(dc11_vlc_lens),
551 dc11_vlc_lens, 1, 1, dc11_vlc_bits, 2, 2, 0);
552
553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (ret < 0)
554 return ret;
555
556 4 ff_hqxdsp_init(&ctx->hqxdsp);
557
558 4 ff_thread_once(&init_static_once, hqx_init_static);
559
560 4 return 0;
561 }
562
563 const FFCodec ff_hqx_decoder = {
564 .p.name = "hqx",
565 CODEC_LONG_NAME("Canopus HQX"),
566 .p.type = AVMEDIA_TYPE_VIDEO,
567 .p.id = AV_CODEC_ID_HQX,
568 .priv_data_size = sizeof(HQXContext),
569 .init = hqx_decode_init,
570 FF_CODEC_DECODE_CB(hqx_decode_frame),
571 .close = hqx_decode_close,
572 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS |
573 AV_CODEC_CAP_FRAME_THREADS,
574 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
575 };
576