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
25
31
34
35 /* HQX has four modes - 422, 444, 422alpha and 444alpha - all 12-bit */
41 };
42
43 #define HQX_HEADER_SIZE 59
44
45 /* macroblock selects a group of 4 possible quants and
46 * a block can use any of those four quantisers
47 * one column is powers of 2, the other one is powers of 2 * 3,
48 * then there is the special one, powers of 2 * 5 */
50 { 0x1, 0x2, 0x4, 0x8 }, { 0x1, 0x3, 0x6, 0xC },
51 { 0x2, 0x4, 0x8, 0x10 }, { 0x3, 0x6, 0xC, 0x18 },
52 { 0x4, 0x8, 0x10, 0x20 }, { 0x6, 0xC, 0x18, 0x30 },
53 { 0x8, 0x10, 0x20, 0x40 },
54 { 0xA, 0x14, 0x28, 0x50 },
55 { 0xC, 0x18, 0x30, 0x60 },
56 { 0x10, 0x20, 0x40, 0x80 }, { 0x18, 0x30, 0x60, 0xC0 },
57 { 0x20, 0x40, 0x80, 0x100 }, { 0x30, 0x60, 0xC0, 0x180 },
58 { 0x40, 0x80, 0x100, 0x200 }, { 0x60, 0xC0, 0x180, 0x300 },
59 { 0x80, 0x100, 0x200, 0x400 }
60 };
61
63 16, 16, 16, 19, 19, 19, 42, 44,
64 16, 16, 19, 19, 19, 38, 43, 45,
65 16, 19, 19, 19, 40, 41, 45, 48,
66 19, 19, 19, 40, 41, 42, 46, 49,
67 19, 19, 40, 41, 42, 43, 48, 101,
68 19, 38, 41, 42, 43, 44, 98, 104,
69 42, 43, 45, 46, 48, 98, 109, 116,
70 44, 45, 48, 49, 101, 104, 116, 123,
71 };
72
74 16, 16, 19, 25, 26, 26, 42, 44,
75 16, 19, 25, 25, 26, 38, 43, 91,
76 19, 25, 26, 27, 40, 41, 91, 96,
77 25, 25, 27, 40, 41, 84, 93, 197,
78 26, 26, 40, 41, 84, 86, 191, 203,
79 26, 38, 41, 84, 86, 177, 197, 209,
80 42, 43, 91, 93, 191, 197, 219, 232,
81 44, 91, 96, 197, 203, 209, 232, 246,
82 };
83
85 int x, int y, int ilace,
86 int16_t *block0, int16_t *
block1,
88 {
89 int fields = ilace ? 2 : 1;
92
94 lsize * fields, block0, quant);
95 ctx->
hqxdsp.
idct_put((uint16_t *)(p + (y + (ilace ? 1 : 8)) * lsize),
96 lsize * fields, block1, quant);
97 }
98
101 {
103
109 }
113 }
114
116 const int *quants, int dcb,
117 int16_t
block[64],
int *last_dc)
118 {
120 int ac_idx;
121 int run, lev, pos = 1;
122
123 memset(block, 0, 64 * sizeof(*block));
125 if (dc < 0)
128
129 block[0] =
sign_extend(*last_dc << (12 - dcb), 12);
130
132 if (q >= 128)
134 else if (q >= 64)
136 else if (q >= 32)
138 else if (q >= 16)
140 else if (q >= 8)
142 else
144
145 do {
148 if (pos >= 64)
149 break;
151 } while (pos < 64);
152
153 return 0;
154 }
155
157 {
160 const int *quants;
162 int last_dc;
163 int i, ret;
164
167 else
168 flag = 0;
169
171
172 for (i = 0; i < 8; i++) {
173 int vlc_index = ctx->
dcb - 9;
174 if (i == 0 || i == 4 || i == 6)
175 last_dc = 0;
177 ctx->
dcb, slice->
block[i], &last_dc);
178 if (ret < 0)
179 return ret;
180 }
181
186
187 return 0;
188 }
189
191 {
194 const int *quants;
196 int last_dc;
197 int i, ret;
198 int cbp;
199
201
202 for (i = 0; i < 12; i++)
203 memset(slice->
block[i], 0,
sizeof(**slice->
block) * 64);
204 for (i = 0; i < 12; i++)
205 slice->
block[i][0] = -0x800;
209
211
212 cbp |= cbp << 4; // alpha CBP
213 if (cbp & 0x3) // chroma CBP - top
214 cbp |= 0x500;
215 if (cbp & 0xC) // chroma CBP - bottom
216 cbp |= 0xA00;
217 for (i = 0; i < 12; i++) {
218 if (i == 0 || i == 4 || i == 8 || i == 10)
219 last_dc = 0;
220 if (cbp & (1 << i)) {
221 int vlc_index = ctx->
dcb - 9;
223 ctx->
dcb, slice->
block[i], &last_dc);
224 if (ret < 0)
225 return ret;
226 }
227 }
228 }
229
236
237 return 0;
238 }
239
241 {
244 const int *quants;
246 int last_dc;
247 int i, ret;
248
251 else
252 flag = 0;
253
255
256 for (i = 0; i < 12; i++) {
257 int vlc_index = ctx->
dcb - 9;
258 if (i == 0 || i == 4 || i == 8)
259 last_dc = 0;
261 ctx->
dcb, slice->
block[i], &last_dc);
262 if (ret < 0)
263 return ret;
264 }
265
272
273 return 0;
274 }
275
277 {
280 const int *quants;
282 int last_dc;
283 int i, ret;
284 int cbp;
285
287
288 for (i = 0; i < 16; i++)
289 memset(slice->
block[i], 0,
sizeof(**slice->
block) * 64);
290 for (i = 0; i < 16; i++)
291 slice->
block[i][0] = -0x800;
295
297
298 cbp |= cbp << 4; // alpha CBP
299 cbp |= cbp << 8; // chroma CBP
300 for (i = 0; i < 16; i++) {
301 if (i == 0 || i == 4 || i == 8 || i == 12)
302 last_dc = 0;
303 if (cbp & (1 << i)) {
304 int vlc_index = ctx->
dcb - 9;
306 ctx->
dcb, slice->
block[i], &last_dc);
307 if (ret < 0)
308 return ret;
309 }
310 }
311 }
312
321
322 return 0;
323 }
324
326 0, 5, 11, 14, 2, 7, 9, 13, 1, 4, 10, 15, 3, 6, 8, 12
327 };
328
330 {
331 int mb_w = (ctx->
width + 15) >> 4;
332 int mb_h = (ctx->
height + 15) >> 4;
333 int grp_w = (mb_w + 4) / 5;
334 int grp_h = (mb_h + 4) / 5;
335 int grp_h_edge = grp_w * (mb_w / grp_w);
336 int grp_v_edge = grp_h * (mb_h / grp_h);
337 int grp_v_rest = mb_w - grp_h_edge;
338 int grp_h_rest = mb_h - grp_v_edge;
339 int num_mbs = mb_w * mb_h;
340 int num_tiles = (num_mbs + 479) / 480;
341 int std_tile_blocks = num_mbs / (16 * num_tiles);
342 int g_tile = slice_no * num_tiles;
343 int blk_addr, loc_addr, mb_x, mb_y, pos, loc_row, i;
344 int tile_blocks, tile_limit, tile_no;
345
346 for (tile_no = 0; tile_no < num_tiles; tile_no++, g_tile++) {
347 tile_blocks = std_tile_blocks;
348 tile_limit = -1;
349 if (g_tile < num_mbs - std_tile_blocks * 16 * num_tiles) {
350 tile_limit = num_mbs / (16 * num_tiles);
351 tile_blocks++;
352 }
353 for (i = 0; i < tile_blocks; i++) {
354 if (i == tile_limit)
355 blk_addr = g_tile + 16 * num_tiles * i;
356 else
357 blk_addr = tile_no + 16 * num_tiles * i +
359 loc_row = grp_h * (blk_addr / (grp_h * mb_w));
360 loc_addr = blk_addr % (grp_h * mb_w);
361 if (loc_row >= grp_v_edge) {
362 mb_x = grp_w * (loc_addr / (grp_h_rest * grp_w));
363 pos = loc_addr % (grp_h_rest * grp_w);
364 } else {
365 mb_x = grp_w * (loc_addr / (grp_h * grp_w));
366 pos = loc_addr % (grp_h * grp_w);
367 }
368 if (mb_x >= grp_h_edge) {
369 mb_x += pos % grp_v_rest;
370 mb_y = loc_row + (pos / grp_v_rest);
371 } else {
372 mb_x += pos % grp_w;
373 mb_y = loc_row + (pos / grp_w);
374 }
375 ctx->
decode_func(ctx, slice_no, mb_x * 16, mb_y * 16);
376 }
377 }
378
379 return 0;
380 }
381
383 int slice_no, int threadnr)
384 {
387 int ret;
388
390 slice_off[slice_no] >= slice_off[slice_no + 1] ||
391 slice_off[slice_no + 1] > ctx->
data_size) {
394 }
395
397 ctx->
src + slice_off[slice_no],
398 slice_off[slice_no + 1] - slice_off[slice_no]);
399 if (ret < 0)
400 return ret;
401
403 }
404
406 int *got_picture_ptr,
AVPacket *avpkt)
407 {
411 uint32_t info_tag;
412 int data_start;
413 int i, ret;
414
415 if (avpkt->
size < 4 + 4) {
418 }
419
421 if (info_tag ==
MKTAG(
'I',
'N',
'F',
'O')) {
422 uint32_t info_offset =
AV_RL32(src + 4);
423 if (info_offset > INT_MAX || info_offset + 8 > avpkt->
size) {
425 "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n",
426 info_offset);
428 }
430
431 info_offset += 8;
432 src += info_offset;
433 }
434
435 data_start = src - avpkt->
data;
439
443 }
444
445 if (src[0] != 'H' || src[1] != 'Q') {
448 }
451 ctx->
dcb = (src[3] & 3) + 8;
454 for (i = 0; i < 17; i++)
456
460 }
462 if (ret < 0) {
466 }
467
473
478 break;
482 break;
486 break;
490 break;
491 default:
494 }
495
497 if (ret < 0)
498 return ret;
499
501
504
505 *got_picture_ptr = 1;
506
508 }
509
511 {
512 int i;
514
516 return 0;
517
519 for (i = 0; i < 3; i++) {
521 }
522
523 return 0;
524 }
525
527 {
529
531
533 }
534
548 };
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
const char const char void * val
#define AV_PIX_FMT_YUVA422P16
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
ptrdiff_t const GLvoid * data
int coded_width
Bitstream width / height, may be different from width/height e.g.
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
static void hqx_get_ac(GetBitContext *gb, const HQXAC *ac, int *run, int *lev)
static av_cold int init(AVCodecContext *avctx)
int ff_canopus_parse_info_tag(AVCodecContext *avctx, const uint8_t *src, size_t size)
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
mb_decode_func decode_func
int ff_hqx_init_vlcs(HQXContext *ctx)
void(* idct_put)(uint16_t *dst, ptrdiff_t stride, int16_t *block, const uint8_t *quant)
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
static av_cold int hqx_decode_init(AVCodecContext *avctx)
static int hqx_decode_frame(AVCodecContext *avctx, void *data, int *got_picture_ptr, AVPacket *avpkt)
const HQXAC ff_hqx_ac[NUM_HQX_AC]
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Multithreading support functions.
static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y)
static const uint8_t hqx_quant_luma[64]
static const int hqx_quants[16][4]
bitstream reader API header.
#define AV_PIX_FMT_YUV444P16
static const uint8_t hqx_quant_chroma[64]
static int hqx_decode_422(HQXContext *ctx, int slice_no, int x, int y)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static av_cold int hqx_decode_close(AVCodecContext *avctx)
int is_copy
Whether the parent AVCodecContext is a copy of the context which had init() called on it...
static int decode_slice(HQXContext *ctx, int slice_no)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
static int decode_block(GetBitContext *gb, VLC *vlc, const int *quants, int dcb, int16_t block[64], int *last_dc)
#define AV_PIX_FMT_YUVA444P16
const char * name
Name of the codec implementation.
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
enum AVPictureType pict_type
Picture type of the frame.
int width
picture width / height.
static unsigned int show_bits(GetBitContext *s, int n)
Show 1-25 bits.
static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE(*table)[2], int bits, int max_depth)
Parse a vlc code.
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y)
static int decode_slice_thread(AVCodecContext *avctx, void *arg, int slice_no, int threadnr)
Libavcodec external API header.
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
main external API structure.
static unsigned int get_bits1(GetBitContext *s)
static const int shuffle_16[16]
static void skip_bits(GetBitContext *s, int n)
const uint8_t ff_zigzag_direct[64]
static av_const int sign_extend(int val, unsigned bits)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
common internal api header.
static void put_blocks(HQXContext *ctx, int plane, int x, int y, int ilace, int16_t *block0, int16_t *block1, const uint8_t *quant)
av_cold void ff_hqxdsp_init(HQXDSPContext *c)
int(* execute2)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count)
The codec may call this to execute several independent things.
struct AVCodecInternal * internal
Private context used for internal data.
VLC_TYPE(* table)[2]
code, bits
int key_frame
1 -> keyframe, 0-> not
static int16_t block1[64]
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> dc
static int hqx_decode_444(HQXContext *ctx, int slice_no, int x, int y)
#define MKTAG(a, b, c, d)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
This structure stores compressed data.
void ff_free_vlc(VLC *vlc)
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
#define AV_PIX_FMT_YUV422P16