/src/ffmpeg/libavcodec/hqx.c
Line | Count | 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 | 3.40M | #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 | | 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 | 3.22M | { |
129 | 3.22M | int fields = ilace ? 2 : 1; |
130 | 3.22M | int lsize = ctx->pic->linesize[plane]; |
131 | 3.22M | uint8_t *p = ctx->pic->data[plane] + x * 2; |
132 | | |
133 | 3.22M | ctx->hqxdsp.idct_put((uint16_t *)(p + y * lsize), |
134 | 3.22M | lsize * fields, block0, quant); |
135 | 3.22M | ctx->hqxdsp.idct_put((uint16_t *)(p + (y + (ilace ? 1 : 8)) * lsize), |
136 | 3.22M | lsize * fields, block1, quant); |
137 | 3.22M | } |
138 | | |
139 | | static inline void hqx_get_ac(GetBitContext *gb, const HQXAC *ac, |
140 | | int *runp, int *lev) |
141 | 330M | { |
142 | 330M | int level, run; |
143 | 330M | OPEN_READER(re, gb); |
144 | | |
145 | 330M | UPDATE_CACHE(re, gb); |
146 | 330M | GET_RL_VLC(level, run, re, gb, ac->lut, ac->bits, 2, 0); |
147 | 330M | CLOSE_READER(re, gb); |
148 | 330M | *runp = run; |
149 | 330M | *lev = level; |
150 | 330M | } |
151 | | |
152 | | static int decode_block(GetBitContext *gb, const VLCElem vlc[], |
153 | | const unsigned *quants, int dcb, |
154 | | int16_t block[64], int *last_dc) |
155 | 5.68M | { |
156 | 5.68M | int run, lev, pos = 0; |
157 | 5.68M | unsigned ac_idx, q; |
158 | 5.68M | int dc; |
159 | | |
160 | 5.68M | dc = get_vlc2(gb, vlc, HQX_DC_VLC_BITS, 2); |
161 | 5.68M | *last_dc += dc; |
162 | | |
163 | 5.68M | block[0] = sign_extend(*last_dc << (12 - dcb), 12); |
164 | | |
165 | 5.68M | 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 | 5.68M | ac_idx = q >> 29; |
169 | | |
170 | 330M | do { |
171 | 330M | hqx_get_ac(gb, &hqx_ac[ac_idx], &run, &lev); |
172 | 330M | pos += run; |
173 | 330M | if (pos > 63) |
174 | 205k | break; |
175 | 330M | block[ff_zigzag_direct[pos]] = lev * q; |
176 | 330M | } while (pos < 63); |
177 | | |
178 | 5.68M | return 0; |
179 | 5.68M | } |
180 | | |
181 | | static int hqx_decode_422(HQXContext *ctx, int slice_no, int x, int y) |
182 | 111k | { |
183 | 111k | HQXSlice *slice = &ctx->slice[slice_no]; |
184 | 111k | GetBitContext *gb = &slice->gb; |
185 | 111k | const unsigned *quants; |
186 | 111k | int flag; |
187 | 111k | int last_dc; |
188 | 111k | int i, ret; |
189 | | |
190 | 111k | memset(slice->block, 0, sizeof(*slice->block) * 8); |
191 | | |
192 | 111k | if (ctx->interlaced) |
193 | 95.8k | flag = get_bits1(gb); |
194 | 15.3k | else |
195 | 15.3k | flag = 0; |
196 | | |
197 | 111k | quants = hqx_quants[get_bits(gb, 4)]; |
198 | | |
199 | 1.00M | for (i = 0; i < 8; i++) { |
200 | 889k | if (i == 0 || i == 4 || i == 6) |
201 | 333k | last_dc = 0; |
202 | 889k | ret = decode_block(gb, ctx->dc_vlc, quants, |
203 | 889k | ctx->dcb, slice->block[i], &last_dc); |
204 | 889k | if (ret < 0) |
205 | 0 | return ret; |
206 | 889k | } |
207 | | |
208 | 111k | put_blocks(ctx, 0, x, y, flag, slice->block[0], slice->block[2], hqx_quant_luma); |
209 | 111k | put_blocks(ctx, 0, x + 8, y, flag, slice->block[1], slice->block[3], hqx_quant_luma); |
210 | 111k | put_blocks(ctx, 2, x >> 1, y, flag, slice->block[4], slice->block[5], hqx_quant_chroma); |
211 | 111k | put_blocks(ctx, 1, x >> 1, y, flag, slice->block[6], slice->block[7], hqx_quant_chroma); |
212 | | |
213 | 111k | return 0; |
214 | 111k | } |
215 | | |
216 | | static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y) |
217 | 200k | { |
218 | 200k | HQXSlice *slice = &ctx->slice[slice_no]; |
219 | 200k | GetBitContext *gb = &slice->gb; |
220 | 200k | int flag = 0; |
221 | 200k | int last_dc; |
222 | 200k | int i, ret; |
223 | | |
224 | 200k | memset(slice->block, 0, sizeof(*slice->block) * 12); |
225 | 2.60M | for (i = 0; i < 12; i++) |
226 | 2.40M | slice->block[i][0] = -0x800; |
227 | | |
228 | 200k | int cbp = get_vlc2(gb, ff_hq_cbp_vlc, HQ_CBP_VLC_BITS, 1); |
229 | 200k | if (cbp) { |
230 | 199k | const unsigned *quants; |
231 | | |
232 | 199k | if (ctx->interlaced) |
233 | 176k | flag = get_bits1(gb); |
234 | | |
235 | 199k | quants = hqx_quants[get_bits(gb, 4)]; |
236 | | |
237 | 199k | if (cbp & 0x3) // chroma CBP - top |
238 | 187k | cbp |= 0x500; |
239 | 199k | if (cbp & 0xC) // chroma CBP - bottom |
240 | 172k | cbp |= 0xA00; |
241 | 2.59M | for (i = 0; i < 12; i++) { |
242 | 2.39M | if (i == 0 || i == 4 || i == 8 || i == 10) |
243 | 798k | last_dc = 0; |
244 | 2.39M | if (cbp & (1 << i)) { |
245 | 2.06M | ret = decode_block(gb, ctx->dc_vlc, quants, |
246 | 2.06M | ctx->dcb, slice->block[i], &last_dc); |
247 | 2.06M | if (ret < 0) |
248 | 0 | return ret; |
249 | 2.06M | } |
250 | 2.39M | } |
251 | 199k | } |
252 | | |
253 | 200k | put_blocks(ctx, 3, x, y, flag, slice->block[ 0], slice->block[ 2], hqx_quant_luma); |
254 | 200k | put_blocks(ctx, 3, x + 8, y, flag, slice->block[ 1], slice->block[ 3], hqx_quant_luma); |
255 | 200k | put_blocks(ctx, 0, x, y, flag, slice->block[ 4], slice->block[ 6], hqx_quant_luma); |
256 | 200k | put_blocks(ctx, 0, x + 8, y, flag, slice->block[ 5], slice->block[ 7], hqx_quant_luma); |
257 | 200k | put_blocks(ctx, 2, x >> 1, y, flag, slice->block[ 8], slice->block[ 9], hqx_quant_chroma); |
258 | 200k | put_blocks(ctx, 1, x >> 1, y, flag, slice->block[10], slice->block[11], hqx_quant_chroma); |
259 | | |
260 | 200k | return 0; |
261 | 200k | } |
262 | | |
263 | | static int hqx_decode_444(HQXContext *ctx, int slice_no, int x, int y) |
264 | 136k | { |
265 | 136k | HQXSlice *slice = &ctx->slice[slice_no]; |
266 | 136k | GetBitContext *gb = &slice->gb; |
267 | 136k | const unsigned *quants; |
268 | 136k | int flag; |
269 | 136k | int last_dc; |
270 | 136k | int i, ret; |
271 | | |
272 | 136k | memset(slice->block, 0, sizeof(*slice->block) * 12); |
273 | | |
274 | 136k | if (ctx->interlaced) |
275 | 129k | flag = get_bits1(gb); |
276 | 6.59k | else |
277 | 6.59k | flag = 0; |
278 | | |
279 | 136k | quants = hqx_quants[get_bits(gb, 4)]; |
280 | | |
281 | 1.77M | for (i = 0; i < 12; i++) { |
282 | 1.63M | if (!(i & 3)) |
283 | 409k | last_dc = 0; |
284 | 1.63M | ret = decode_block(gb, ctx->dc_vlc, quants, |
285 | 1.63M | ctx->dcb, slice->block[i], &last_dc); |
286 | 1.63M | if (ret < 0) |
287 | 0 | return ret; |
288 | 1.63M | } |
289 | | |
290 | 136k | put_blocks(ctx, 0, x, y, flag, slice->block[0], slice->block[ 2], hqx_quant_luma); |
291 | 136k | put_blocks(ctx, 0, x + 8, y, flag, slice->block[1], slice->block[ 3], hqx_quant_luma); |
292 | 136k | put_blocks(ctx, 2, x, y, flag, slice->block[4], slice->block[ 6], hqx_quant_chroma); |
293 | 136k | put_blocks(ctx, 2, x + 8, y, flag, slice->block[5], slice->block[ 7], hqx_quant_chroma); |
294 | 136k | put_blocks(ctx, 1, x, y, flag, slice->block[8], slice->block[10], hqx_quant_chroma); |
295 | 136k | put_blocks(ctx, 1, x + 8, y, flag, slice->block[9], slice->block[11], hqx_quant_chroma); |
296 | | |
297 | 136k | return 0; |
298 | 136k | } |
299 | | |
300 | | static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y) |
301 | 94.9k | { |
302 | 94.9k | HQXSlice *slice = &ctx->slice[slice_no]; |
303 | 94.9k | GetBitContext *gb = &slice->gb; |
304 | 94.9k | int flag = 0; |
305 | 94.9k | int last_dc; |
306 | 94.9k | int i, ret; |
307 | | |
308 | 94.9k | memset(slice->block, 0, sizeof(*slice->block) * 16); |
309 | 1.61M | for (i = 0; i < 16; i++) |
310 | 1.51M | slice->block[i][0] = -0x800; |
311 | | |
312 | 94.9k | int cbp = get_vlc2(gb, ff_hq_cbp_vlc, HQ_CBP_VLC_BITS, 1); |
313 | 94.9k | if (cbp) { |
314 | 75.1k | const unsigned *quants; |
315 | | |
316 | 75.1k | if (ctx->interlaced) |
317 | 64.7k | flag = get_bits1(gb); |
318 | | |
319 | 75.1k | quants = hqx_quants[get_bits(gb, 4)]; |
320 | | |
321 | 75.1k | cbp |= cbp << 8; // chroma CBP |
322 | 1.27M | for (i = 0; i < 16; i++) { |
323 | 1.20M | if (!(i & 3)) |
324 | 300k | last_dc = 0; |
325 | 1.20M | if (cbp & (1 << i)) { |
326 | 1.09M | ret = decode_block(gb, ctx->dc_vlc, quants, |
327 | 1.09M | ctx->dcb, slice->block[i], &last_dc); |
328 | 1.09M | if (ret < 0) |
329 | 0 | return ret; |
330 | 1.09M | } |
331 | 1.20M | } |
332 | 75.1k | } |
333 | | |
334 | 94.9k | put_blocks(ctx, 3, x, y, flag, slice->block[ 0], slice->block[ 2], hqx_quant_luma); |
335 | 94.9k | put_blocks(ctx, 3, x + 8, y, flag, slice->block[ 1], slice->block[ 3], hqx_quant_luma); |
336 | 94.9k | put_blocks(ctx, 0, x, y, flag, slice->block[ 4], slice->block[ 6], hqx_quant_luma); |
337 | 94.9k | put_blocks(ctx, 0, x + 8, y, flag, slice->block[ 5], slice->block[ 7], hqx_quant_luma); |
338 | 94.9k | put_blocks(ctx, 2, x, y, flag, slice->block[ 8], slice->block[10], hqx_quant_chroma); |
339 | 94.9k | put_blocks(ctx, 2, x + 8, y, flag, slice->block[ 9], slice->block[11], hqx_quant_chroma); |
340 | 94.9k | put_blocks(ctx, 1, x, y, flag, slice->block[12], slice->block[14], hqx_quant_chroma); |
341 | 94.9k | put_blocks(ctx, 1, x + 8, y, flag, slice->block[13], slice->block[15], hqx_quant_chroma); |
342 | | |
343 | 94.9k | return 0; |
344 | 94.9k | } |
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 | | static int decode_slice(HQXContext *ctx, int slice_no) |
351 | 1.52k | { |
352 | 1.52k | int mb_w = (ctx->width + 15) >> 4; |
353 | 1.52k | int mb_h = (ctx->height + 15) >> 4; |
354 | 1.52k | int grp_w = (mb_w + 4) / 5; |
355 | 1.52k | int grp_h = (mb_h + 4) / 5; |
356 | 1.52k | int grp_h_edge = grp_w * (mb_w / grp_w); |
357 | 1.52k | int grp_v_edge = grp_h * (mb_h / grp_h); |
358 | 1.52k | int grp_v_rest = mb_w - grp_h_edge; |
359 | 1.52k | int grp_h_rest = mb_h - grp_v_edge; |
360 | 1.52k | int num_mbs = mb_w * mb_h; |
361 | 1.52k | int num_tiles = (num_mbs + 479) / 480; |
362 | 1.52k | int std_tile_blocks = num_mbs / (16 * num_tiles); |
363 | 1.52k | int g_tile = slice_no * num_tiles; |
364 | 1.52k | int blk_addr, loc_addr, mb_x, mb_y, pos, loc_row, i; |
365 | 1.52k | int tile_blocks, tile_limit, tile_no; |
366 | | |
367 | 20.6k | for (tile_no = 0; tile_no < num_tiles; tile_no++, g_tile++) { |
368 | 19.0k | tile_blocks = std_tile_blocks; |
369 | 19.0k | tile_limit = -1; |
370 | 19.0k | if (g_tile < num_mbs - std_tile_blocks * 16 * num_tiles) { |
371 | 12.9k | tile_limit = num_mbs / (16 * num_tiles); |
372 | 12.9k | tile_blocks++; |
373 | 12.9k | } |
374 | 561k | for (i = 0; i < tile_blocks; i++) { |
375 | 542k | if (i == tile_limit) |
376 | 12.9k | blk_addr = g_tile + 16 * num_tiles * i; |
377 | 529k | else |
378 | 529k | blk_addr = tile_no + 16 * num_tiles * i + |
379 | 529k | num_tiles * shuffle_16[(i + slice_no) & 0xF]; |
380 | 542k | loc_row = grp_h * (blk_addr / (grp_h * mb_w)); |
381 | 542k | loc_addr = blk_addr % (grp_h * mb_w); |
382 | 542k | if (loc_row >= grp_v_edge) { |
383 | 31.1k | mb_x = grp_w * (loc_addr / (grp_h_rest * grp_w)); |
384 | 31.1k | pos = loc_addr % (grp_h_rest * grp_w); |
385 | 511k | } else { |
386 | 511k | mb_x = grp_w * (loc_addr / (grp_h * grp_w)); |
387 | 511k | pos = loc_addr % (grp_h * grp_w); |
388 | 511k | } |
389 | 542k | if (mb_x >= grp_h_edge) { |
390 | 82.8k | mb_x += pos % grp_v_rest; |
391 | 82.8k | mb_y = loc_row + (pos / grp_v_rest); |
392 | 459k | } else { |
393 | 459k | mb_x += pos % grp_w; |
394 | 459k | mb_y = loc_row + (pos / grp_w); |
395 | 459k | } |
396 | 542k | ctx->decode_func(ctx, slice_no, mb_x * 16, mb_y * 16); |
397 | 542k | } |
398 | 19.0k | } |
399 | | |
400 | 1.52k | return 0; |
401 | 1.52k | } |
402 | | |
403 | | static int decode_slice_thread(AVCodecContext *avctx, void *arg, |
404 | | int slice_no, int threadnr) |
405 | 1.63M | { |
406 | 1.63M | HQXContext *ctx = avctx->priv_data; |
407 | 1.63M | uint32_t *slice_off = ctx->slice_off; |
408 | 1.63M | int ret; |
409 | | |
410 | 1.63M | if (slice_off[slice_no] < HQX_HEADER_SIZE || |
411 | 1.53M | slice_off[slice_no] >= slice_off[slice_no + 1] || |
412 | 1.63M | slice_off[slice_no + 1] > ctx->data_size) { |
413 | 1.63M | av_log(avctx, AV_LOG_ERROR, "Invalid slice size %d.\n", ctx->data_size); |
414 | 1.63M | return AVERROR_INVALIDDATA; |
415 | 1.63M | } |
416 | | |
417 | 1.52k | ret = init_get_bits8(&ctx->slice[slice_no].gb, |
418 | 1.52k | ctx->src + slice_off[slice_no], |
419 | 1.52k | slice_off[slice_no + 1] - slice_off[slice_no]); |
420 | 1.52k | if (ret < 0) |
421 | 0 | return ret; |
422 | | |
423 | 1.52k | return decode_slice(ctx, slice_no); |
424 | 1.52k | } |
425 | | |
426 | | static int hqx_decode_frame(AVCodecContext *avctx, AVFrame *frame, |
427 | | int *got_picture_ptr, AVPacket *avpkt) |
428 | 195k | { |
429 | 195k | HQXContext *ctx = avctx->priv_data; |
430 | 195k | const uint8_t *src = avpkt->data; |
431 | 195k | uint32_t info_tag; |
432 | 195k | int data_start, dcb_code; |
433 | 195k | int i, ret; |
434 | | |
435 | 195k | if (avpkt->size < 4 + 4) { |
436 | 66.5k | av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size); |
437 | 66.5k | return AVERROR_INVALIDDATA; |
438 | 66.5k | } |
439 | | |
440 | 129k | info_tag = AV_RL32(src); |
441 | 129k | if (info_tag == MKTAG('I', 'N', 'F', 'O')) { |
442 | 11.2k | uint32_t info_offset = AV_RL32(src + 4); |
443 | 11.2k | if (info_offset > INT_MAX || info_offset + 8 > avpkt->size) { |
444 | 893 | av_log(avctx, AV_LOG_ERROR, |
445 | 893 | "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n", |
446 | 893 | info_offset); |
447 | 893 | return AVERROR_INVALIDDATA; |
448 | 893 | } |
449 | 10.3k | ff_canopus_parse_info_tag(avctx, src + 8, info_offset); |
450 | | |
451 | 10.3k | info_offset += 8; |
452 | 10.3k | src += info_offset; |
453 | 10.3k | } |
454 | | |
455 | 128k | data_start = src - avpkt->data; |
456 | 128k | ctx->data_size = avpkt->size - data_start; |
457 | 128k | ctx->src = src; |
458 | 128k | ctx->pic = frame; |
459 | | |
460 | 128k | if (ctx->data_size < HQX_HEADER_SIZE) { |
461 | 20.1k | av_log(avctx, AV_LOG_ERROR, "Frame too small.\n"); |
462 | 20.1k | return AVERROR_INVALIDDATA; |
463 | 20.1k | } |
464 | | |
465 | 108k | if (src[0] != 'H' || src[1] != 'Q') { |
466 | 3.26k | av_log(avctx, AV_LOG_ERROR, "Not an HQX frame.\n"); |
467 | 3.26k | return AVERROR_INVALIDDATA; |
468 | 3.26k | } |
469 | 104k | ctx->interlaced = !(src[2] & 0x80); |
470 | 104k | ctx->format = src[2] & 7; |
471 | 104k | dcb_code = src[3] & 3; |
472 | 104k | ctx->width = AV_RB16(src + 4); |
473 | 104k | ctx->height = AV_RB16(src + 6); |
474 | 1.88M | for (i = 0; i < 17; i++) |
475 | 1.78M | ctx->slice_off[i] = AV_RB24(src + 8 + i * 3); |
476 | | |
477 | 104k | if (dcb_code == 0) { |
478 | 644 | av_log(avctx, AV_LOG_ERROR, "Invalid DC precision 8.\n"); |
479 | 644 | return AVERROR_INVALIDDATA; |
480 | 644 | } |
481 | 104k | ctx->dc_vlc = dcb_code == 3 ? ctx->dc11_vlc.table : dc_vlc[dcb_code - 1]; |
482 | 104k | ctx->dcb = dcb_code + 8; |
483 | 104k | ret = av_image_check_size(ctx->width, ctx->height, 0, avctx); |
484 | 104k | if (ret < 0) { |
485 | 729 | av_log(avctx, AV_LOG_ERROR, "Invalid stored dimensions %dx%d.\n", |
486 | 729 | ctx->width, ctx->height); |
487 | 729 | return AVERROR_INVALIDDATA; |
488 | 729 | } |
489 | | |
490 | 103k | avctx->coded_width = FFALIGN(ctx->width, 16); |
491 | 103k | avctx->coded_height = FFALIGN(ctx->height, 16); |
492 | 103k | avctx->width = ctx->width; |
493 | 103k | avctx->height = ctx->height; |
494 | 103k | 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 | 103k | if (avctx->coded_width / 16 * (avctx->coded_height / 16) * |
501 | 103k | (100 - avctx->discard_damaged_percentage) / 100 > 4LL * avpkt->size) |
502 | 751 | return AVERROR_INVALIDDATA; |
503 | | |
504 | 102k | switch (ctx->format) { |
505 | 9.27k | case HQX_422: |
506 | 9.27k | avctx->pix_fmt = AV_PIX_FMT_YUV422P16; |
507 | 9.27k | ctx->decode_func = hqx_decode_422; |
508 | 9.27k | break; |
509 | 82.4k | case HQX_444: |
510 | 82.4k | avctx->pix_fmt = AV_PIX_FMT_YUV444P16; |
511 | 82.4k | ctx->decode_func = hqx_decode_444; |
512 | 82.4k | break; |
513 | 1.56k | case HQX_422A: |
514 | 1.56k | avctx->pix_fmt = AV_PIX_FMT_YUVA422P16; |
515 | 1.56k | ctx->decode_func = hqx_decode_422a; |
516 | 1.56k | break; |
517 | 9.14k | case HQX_444A: |
518 | 9.14k | avctx->pix_fmt = AV_PIX_FMT_YUVA444P16; |
519 | 9.14k | ctx->decode_func = hqx_decode_444a; |
520 | 9.14k | break; |
521 | 215 | default: |
522 | 215 | av_log(avctx, AV_LOG_ERROR, "Invalid format: %d.\n", ctx->format); |
523 | 215 | return AVERROR_INVALIDDATA; |
524 | 102k | } |
525 | | |
526 | 102k | ret = ff_thread_get_buffer(avctx, frame, 0); |
527 | 102k | if (ret < 0) |
528 | 206 | return ret; |
529 | | |
530 | 102k | avctx->execute2(avctx, decode_slice_thread, NULL, NULL, 16); |
531 | | |
532 | 102k | *got_picture_ptr = 1; |
533 | | |
534 | 102k | return avpkt->size; |
535 | 102k | } |
536 | | |
537 | | static av_cold int hqx_decode_close(AVCodecContext *avctx) |
538 | 1.78k | { |
539 | 1.78k | HQXContext *ctx = avctx->priv_data; |
540 | | |
541 | 1.78k | ff_vlc_free(&ctx->dc11_vlc); |
542 | | |
543 | 1.78k | return 0; |
544 | 1.78k | } |
545 | | |
546 | | static av_cold int hqx_decode_init(AVCodecContext *avctx) |
547 | 1.78k | { |
548 | 1.78k | static AVOnce init_static_once = AV_ONCE_INIT; |
549 | 1.78k | HQXContext *ctx = avctx->priv_data; |
550 | 1.78k | int ret = vlc_init(&ctx->dc11_vlc, HQX_DC_VLC_BITS, FF_ARRAY_ELEMS(dc11_vlc_lens), |
551 | 1.78k | dc11_vlc_lens, 1, 1, dc11_vlc_bits, 2, 2, 0); |
552 | | |
553 | 1.78k | if (ret < 0) |
554 | 0 | return ret; |
555 | | |
556 | 1.78k | ff_hqxdsp_init(&ctx->hqxdsp); |
557 | | |
558 | 1.78k | ff_thread_once(&init_static_once, hqx_init_static); |
559 | | |
560 | 1.78k | return 0; |
561 | 1.78k | } |
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 | | }; |