35 #include "libavutil/intreadwrite.h"
36 #include "libavutil/mem.h"
39 #define BITSTREAM_READER_LE
43 #define RUNTIME_GAMMA 0
45 #define VGA__TAG MKTAG('V', 'G', 'A', ' ')
46 #define PALT_TAG MKTAG('P', 'A', 'L', 'T')
47 #define SHOT_TAG MKTAG('S', 'H', 'O', 'T')
48 #define PALETTE_COUNT 256
49 #define PALETTE_SIZE (PALETTE_COUNT * 3)
50 #define PALETTES_MAX 256
109 const uint8_t * ptr = src + byte*2;
110 int ptr_len = src_len - 1 - byte*2;
112 uint8_t *dest_end = dest + dest_len;
121 while (val != 0x16) {
122 unsigned idx = val - 0x17 +
get_bits1(&gb) * byte;
128 if (dest >= dest_end)
135 return dest - dest_start;
149 uint8_t *dest_end = dest + dest_len;
154 opcode = bytestream2_get_byte(&ctx);
158 if ((opcode & 0x80) == 0) {
161 back = ((opcode & 0x60) << 3) + bytestream2_get_byte(&ctx) + 1;
162 size2 = ((opcode & 0x1c) >> 2) + 3;
163 }
else if ((opcode & 0x40) == 0) {
164 size = bytestream2_peek_byte(&ctx) >> 6;
166 back = (bytestream2_get_be16(&ctx) & 0x3fff) + 1;
167 size2 = (opcode & 0x3f) + 4;
171 back = ((opcode & 0x10) << 12) + bytestream2_get_be16(&ctx) + 1;
172 size2 = ((opcode & 0x0c) << 6) + bytestream2_get_byte(&ctx) + 5;
175 if (dest_end - dest < size + size2 ||
176 dest + size - dest_org < back ||
184 int finish = opcode >= 0xfc;
185 size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
198 const uint8_t *pixel_buffer,
int x,
int y,
int pixel_count)
207 palette_plane = frame->
data[0];
209 line_inc = stride -
width;
210 index = y * stride + x;
212 while (pixel_count && index < s->
frame_size) {
213 int count =
FFMIN(pixel_count, width - current_x);
214 memcpy(palette_plane + index, pixel_buffer, count);
215 pixel_count -=
count;
217 pixel_buffer +=
count;
220 if (current_x >= width) {
229 int pixel_count,
int motion_x,
234 int curframe_index, prevframe_index;
235 int curframe_x, prevframe_x;
237 uint8_t *palette_plane, *prev_palette_plane;
239 if (y + motion_y < 0 || y + motion_y >= s->
avctx->
height ||
240 x + motion_x < 0 || x + motion_x >= s->
avctx->
width)
243 palette_plane = frame->
data[0];
245 if (!prev_palette_plane)
246 prev_palette_plane = palette_plane;
248 line_inc = stride -
width;
249 curframe_index = y * stride + x;
251 prevframe_index = (y + motion_y) * stride + x + motion_x;
252 prevframe_x = x + motion_x;
254 if (prev_palette_plane == palette_plane &&
FFABS(curframe_index - prevframe_index) < pixel_count) {
259 while (pixel_count &&
262 int count =
FFMIN3(pixel_count, width - curframe_x,
263 width - prevframe_x);
265 memcpy(palette_plane + curframe_index,
266 prev_palette_plane + prevframe_index, count);
267 pixel_count -=
count;
268 curframe_index +=
count;
269 prevframe_index +=
count;
271 prevframe_x +=
count;
273 if (curframe_x >= width) {
274 curframe_index += line_inc;
278 if (prevframe_x >= width) {
279 prevframe_index += line_inc;
290 int total_pixels = width *
height;
294 int motion_x, motion_y;
303 const uint8_t *huffman_segment;
306 const uint8_t *imagedata_segment;
307 int huffman_offset, size_offset, vector_offset, imagedata_offset,
318 if (huffman_offset >= s->
size ||
319 size_offset >= s->
size ||
320 vector_offset >= s->
size ||
321 imagedata_offset >= s->
size)
324 huffman_segment = s->
buf + huffman_offset;
327 imagedata_segment = s->
buf + imagedata_offset;
330 huffman_segment, s->
size - huffman_offset)) < 0)
332 opcode_buffer_end = opcode_buffer +
ret;
334 if (imagedata_segment[0] == 2) {
336 &imagedata_segment[1], s->
size - imagedata_offset - 1);
339 imagedata_size = s->
size - imagedata_offset - 1;
340 imagedata_buffer = &imagedata_segment[1];
345 while (total_pixels && opcode_buffer < opcode_buffer_end) {
347 opcode = *opcode_buffer++;
374 size += (opcode - 10);
383 size = bytestream2_get_byte(&size_segment);
392 size = bytestream2_get_be16(&size_segment);
401 size = bytestream2_get_be24(&size_segment);
405 if (size > total_pixels)
415 if (imagedata_size < size)
418 imagedata_buffer +=
size;
419 imagedata_size -=
size;
428 vector = bytestream2_get_byte(&vector_segment);
439 total_pixels -=
size;
440 y += (x +
size) / width;
441 x = (x +
size) % width;
447 static inline unsigned mul(
unsigned a,
unsigned b)
449 return (a * b) >> 16;
452 static inline unsigned pow4(
unsigned a)
454 unsigned square = mul(a, a);
455 return mul(square, square);
458 static inline unsigned pow5(
unsigned a)
460 return mul(pow4(a), a);
464 unsigned lo, hi = 0xff40, target;
466 in = (in << 2) | (in >> 6);
472 lo = target = in << 8;
474 unsigned mid = (lo + hi) >> 1;
475 unsigned pow = pow5(mid);
476 if (pow > target) hi = mid;
479 return (pow4((lo + hi) >> 1) + 0x80) >> 8;
494 0x00, 0x09, 0x10, 0x16, 0x1C, 0x21, 0x27, 0x2C,
495 0x31, 0x35, 0x3A, 0x3F, 0x43, 0x48, 0x4C, 0x50,
496 0x54, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D, 0x71,
497 0x75, 0x79, 0x7D, 0x80, 0x84, 0x88, 0x8C, 0x8F,
498 0x93, 0x97, 0x9A, 0x9E, 0xA2, 0xA5, 0xA9, 0xAC,
499 0xB0, 0xB3, 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8,
500 0xCB, 0xCF, 0xD2, 0xD5, 0xD9, 0xDC, 0xDF, 0xE3,
501 0xE6, 0xE9, 0xED, 0xF0, 0xF3, 0xF6, 0xFA, 0xFD,
502 0x03, 0x0B, 0x12, 0x18, 0x1D, 0x23, 0x28, 0x2D,
503 0x32, 0x36, 0x3B, 0x40, 0x44, 0x49, 0x4D, 0x51,
504 0x56, 0x5A, 0x5E, 0x62, 0x66, 0x6A, 0x6E, 0x72,
505 0x76, 0x7A, 0x7D, 0x81, 0x85, 0x89, 0x8D, 0x90,
506 0x94, 0x98, 0x9B, 0x9F, 0xA2, 0xA6, 0xAA, 0xAD,
507 0xB1, 0xB4, 0xB8, 0xBB, 0xBF, 0xC2, 0xC5, 0xC9,
508 0xCC, 0xD0, 0xD3, 0xD6, 0xDA, 0xDD, 0xE0, 0xE4,
509 0xE7, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xFA, 0xFD,
510 0x05, 0x0D, 0x13, 0x19, 0x1F, 0x24, 0x29, 0x2E,
511 0x33, 0x38, 0x3C, 0x41, 0x45, 0x4A, 0x4E, 0x52,
512 0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73,
513 0x77, 0x7B, 0x7E, 0x82, 0x86, 0x8A, 0x8D, 0x91,
514 0x95, 0x99, 0x9C, 0xA0, 0xA3, 0xA7, 0xAA, 0xAE,
515 0xB2, 0xB5, 0xB9, 0xBC, 0xBF, 0xC3, 0xC6, 0xCA,
516 0xCD, 0xD0, 0xD4, 0xD7, 0xDA, 0xDE, 0xE1, 0xE4,
517 0xE8, 0xEB, 0xEE, 0xF1, 0xF5, 0xF8, 0xFB, 0xFD,
518 0x07, 0x0E, 0x15, 0x1A, 0x20, 0x25, 0x2A, 0x2F,
519 0x34, 0x39, 0x3D, 0x42, 0x46, 0x4B, 0x4F, 0x53,
520 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74,
521 0x78, 0x7C, 0x7F, 0x83, 0x87, 0x8B, 0x8E, 0x92,
522 0x96, 0x99, 0x9D, 0xA1, 0xA4, 0xA8, 0xAB, 0xAF,
523 0xB2, 0xB6, 0xB9, 0xBD, 0xC0, 0xC4, 0xC7, 0xCB,
524 0xCE, 0xD1, 0xD5, 0xD8, 0xDB, 0xDF, 0xE2, 0xE5,
525 0xE9, 0xEC, 0xEF, 0xF2, 0xF6, 0xF9, 0xFC, 0xFD
530 void *
data,
int *got_frame,
535 int ret, buf_size = avpkt->
size;
546 tag = bytestream2_get_le32(&ctx);
547 size = bytestream2_get_be32(&ctx);
567 int r = gamma_corr(bytestream2_get_byteu(&ctx));
568 int g = gamma_corr(bytestream2_get_byteu(&ctx));
569 int b = gamma_corr(bytestream2_get_byteu(&ctx));
571 int r = gamma_lookup[bytestream2_get_byteu(&ctx)];
572 int g = gamma_lookup[bytestream2_get_byteu(&ctx)];
573 int b = gamma_lookup[bytestream2_get_byteu(&ctx)];
575 *tmpptr++ = (0xFF
U << 24) | (r << 16) | (g << 8) | b;
582 new_pal = bytestream2_get_le32(&ctx);
583 if (new_pal < s->palettes_count) {
608 memcpy(frame->
data[1],
static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame)
const char const char void * val
This structure describes decoded (raw) audio or video data.
static av_cold int init(AVCodecContext *avctx)
void av_log(void *avcl, int level, const char *fmt,...) av_printf_format(3
Send the specified message to the log if the level is less than or equal to the current av_log_level...
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
static void xan_unpack(uint8_t *dest, int dest_len, const uint8_t *src, int src_len)
unpack simple compression
static const uint8_t gamma_lookup[256]
This is a gamma correction that xan3 applies to all palette entries.
void av_freep(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
const char * name
Name of the codec implementation.
int av_frame_ref(AVFrame *dst, AVFrame *src)
Setup a new reference to the data described by a given frame.
AVCodec ff_xan_wc3_decoder
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
bitstream reader API header.
static const uint8_t frame_size[4]
static int xan_huffman_decode(uint8_t *dest, int dest_len, const uint8_t *src, int src_len)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
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){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));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=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);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);ff_audio_convert_init_arm(ac);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_dlog(ac->avr,"%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-> in
static av_cold int xan_decode_init(AVCodecContext *avctx)
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Libavcodec external API header.
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
void * av_realloc(void *ptr, size_t size) 1(2)
Allocate or reallocate a block of memory.
int width
picture width / height.
void * av_malloc(size_t size) av_malloc_attrib 1(1)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
static void xan_wc3_output_pixel_run(XanContext *s, AVFrame *frame, const uint8_t *pixel_buffer, int x, int y, int pixel_count)
static av_cold int xan_decode_end(AVCodecContext *avctx)
main external API structure.
static void close(AVCodecParserContext *s)
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
static unsigned int get_bits1(GetBitContext *s)
BYTE int const BYTE int int int height
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
static av_const int sign_extend(int val, unsigned bits)
common internal api header.
#define AVERROR_INVALIDDATA
static int xan_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
deliberately overlapping memcpy implementation
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
static void xan_wc3_copy_pixel_run(XanContext *s, AVFrame *frame, int x, int y, int pixel_count, int motion_x, int motion_y)
8 bit with PIX_FMT_RGB32 palette
This structure stores compressed data.
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.