38 #define BITSTREAM_READER_LE
44 #define RUNTIME_GAMMA 0
46 #define VGA__TAG MKTAG('V', 'G', 'A', ' ')
47 #define PALT_TAG MKTAG('P', 'A', 'L', 'T')
48 #define SHOT_TAG MKTAG('S', 'H', 'O', 'T')
49 #define PALETTE_COUNT 256
50 #define PALETTE_SIZE (PALETTE_COUNT * 3)
51 #define PALETTES_MAX 256
122 const uint8_t * ptr = src + byte*2;
123 int ptr_len = src_len - 1 - byte*2;
125 uint8_t *dest_end = dest + dest_len;
133 while (val != 0x16) {
143 if (dest >= dest_end)
150 return dest - dest_start;
164 uint8_t *dest_end = dest + dest_len;
169 opcode = bytestream2_get_byte(&ctx);
173 if ((opcode & 0x80) == 0) {
176 back = ((opcode & 0x60) << 3) + bytestream2_get_byte(&ctx) + 1;
177 size2 = ((opcode & 0x1c) >> 2) + 3;
178 }
else if ((opcode & 0x40) == 0) {
179 size = bytestream2_peek_byte(&ctx) >> 6;
181 back = (bytestream2_get_be16(&ctx) & 0x3fff) + 1;
182 size2 = (opcode & 0x3f) + 4;
186 back = ((opcode & 0x10) << 12) + bytestream2_get_be16(&ctx) + 1;
187 size2 = ((opcode & 0x0c) << 6) + bytestream2_get_byte(&ctx) + 5;
190 if (dest_end - dest < size + size2 ||
191 dest + size - dest_org < back ||
199 int finish = opcode >= 0xfc;
200 size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
213 const uint8_t *pixel_buffer,
int x,
int y,
int pixel_count)
222 palette_plane = frame->
data[0];
224 line_inc = stride -
width;
225 index = y * stride + x;
227 while (pixel_count && index < s->
frame_size) {
228 int count =
FFMIN(pixel_count, width - current_x);
229 memcpy(palette_plane + index, pixel_buffer, count);
230 pixel_count -=
count;
232 pixel_buffer +=
count;
235 if (current_x >= width) {
244 int pixel_count,
int motion_x,
249 int curframe_index, prevframe_index;
250 int curframe_x, prevframe_x;
252 uint8_t *palette_plane, *prev_palette_plane;
254 if (y + motion_y < 0 || y + motion_y >= s->
avctx->
height ||
255 x + motion_x < 0 || x + motion_x >= s->
avctx->
width)
258 palette_plane = frame->
data[0];
260 if (!prev_palette_plane)
261 prev_palette_plane = palette_plane;
263 line_inc = stride -
width;
264 curframe_index = y * stride + x;
266 prevframe_index = (y + motion_y) * stride + x + motion_x;
267 prevframe_x = x + motion_x;
269 if (prev_palette_plane == palette_plane &&
FFABS(motion_x + width*motion_y) < pixel_count) {
274 while (pixel_count &&
277 int count =
FFMIN3(pixel_count, width - curframe_x,
278 width - prevframe_x);
280 memcpy(palette_plane + curframe_index,
281 prev_palette_plane + prevframe_index, count);
282 pixel_count -=
count;
283 curframe_index +=
count;
284 prevframe_index +=
count;
286 prevframe_x +=
count;
288 if (curframe_x >= width) {
289 curframe_index += line_inc;
293 if (prevframe_x >= width) {
294 prevframe_index += line_inc;
305 int total_pixels = width *
height;
309 int motion_x, motion_y;
318 const uint8_t *huffman_segment;
321 const uint8_t *imagedata_segment;
322 int huffman_offset, size_offset, vector_offset, imagedata_offset,
333 if (huffman_offset >= s->
size ||
334 size_offset >= s->
size ||
335 vector_offset >= s->
size ||
336 imagedata_offset >= s->
size)
339 huffman_segment = s->
buf + huffman_offset;
342 imagedata_segment = s->
buf + imagedata_offset;
345 huffman_segment, s->
size - huffman_offset)) < 0)
347 opcode_buffer_end = opcode_buffer + ret;
349 if (imagedata_segment[0] == 2) {
351 &imagedata_segment[1], s->
size - imagedata_offset - 1);
354 imagedata_size = s->
size - imagedata_offset - 1;
355 imagedata_buffer = &imagedata_segment[1];
360 while (total_pixels && opcode_buffer < opcode_buffer_end) {
362 opcode = *opcode_buffer++;
389 size += (opcode - 10);
398 size = bytestream2_get_byte(&size_segment);
407 size = bytestream2_get_be16(&size_segment);
416 size = bytestream2_get_be24(&size_segment);
420 if (size > total_pixels)
430 if (imagedata_size < size)
433 imagedata_buffer +=
size;
434 imagedata_size -=
size;
443 vector = bytestream2_get_byte(&vector_segment);
454 total_pixels -=
size;
455 y += (x +
size) / width;
456 x = (x +
size) % width;
462 static inline unsigned mul(
unsigned a,
unsigned b)
464 return (a * b) >> 16;
467 static inline unsigned pow4(
unsigned a)
469 unsigned square = mul(a, a);
470 return mul(square, square);
473 static inline unsigned pow5(
unsigned a)
475 return mul(pow4(a), a);
479 unsigned lo, hi = 0xff40, target;
481 in = (in << 2) | (in >> 6);
487 lo = target = in << 8;
489 unsigned mid = (lo + hi) >> 1;
490 unsigned pow = pow5(mid);
491 if (pow > target) hi = mid;
494 return (pow4((lo + hi) >> 1) + 0x80) >> 8;
509 0x00, 0x09, 0x10, 0x16, 0x1C, 0x21, 0x27, 0x2C,
510 0x31, 0x35, 0x3A, 0x3F, 0x43, 0x48, 0x4C, 0x50,
511 0x54, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D, 0x71,
512 0x75, 0x79, 0x7D, 0x80, 0x84, 0x88, 0x8C, 0x8F,
513 0x93, 0x97, 0x9A, 0x9E, 0xA2, 0xA5, 0xA9, 0xAC,
514 0xB0, 0xB3, 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8,
515 0xCB, 0xCF, 0xD2, 0xD5, 0xD9, 0xDC, 0xDF, 0xE3,
516 0xE6, 0xE9, 0xED, 0xF0, 0xF3, 0xF6, 0xFA, 0xFD,
517 0x03, 0x0B, 0x12, 0x18, 0x1D, 0x23, 0x28, 0x2D,
518 0x32, 0x36, 0x3B, 0x40, 0x44, 0x49, 0x4D, 0x51,
519 0x56, 0x5A, 0x5E, 0x62, 0x66, 0x6A, 0x6E, 0x72,
520 0x76, 0x7A, 0x7D, 0x81, 0x85, 0x89, 0x8D, 0x90,
521 0x94, 0x98, 0x9B, 0x9F, 0xA2, 0xA6, 0xAA, 0xAD,
522 0xB1, 0xB4, 0xB8, 0xBB, 0xBF, 0xC2, 0xC5, 0xC9,
523 0xCC, 0xD0, 0xD3, 0xD6, 0xDA, 0xDD, 0xE0, 0xE4,
524 0xE7, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xFA, 0xFD,
525 0x05, 0x0D, 0x13, 0x19, 0x1F, 0x24, 0x29, 0x2E,
526 0x33, 0x38, 0x3C, 0x41, 0x45, 0x4A, 0x4E, 0x52,
527 0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73,
528 0x77, 0x7B, 0x7E, 0x82, 0x86, 0x8A, 0x8D, 0x91,
529 0x95, 0x99, 0x9C, 0xA0, 0xA3, 0xA7, 0xAA, 0xAE,
530 0xB2, 0xB5, 0xB9, 0xBC, 0xBF, 0xC3, 0xC6, 0xCA,
531 0xCD, 0xD0, 0xD4, 0xD7, 0xDA, 0xDE, 0xE1, 0xE4,
532 0xE8, 0xEB, 0xEE, 0xF1, 0xF5, 0xF8, 0xFB, 0xFD,
533 0x07, 0x0E, 0x15, 0x1A, 0x20, 0x25, 0x2A, 0x2F,
534 0x34, 0x39, 0x3D, 0x42, 0x46, 0x4B, 0x4F, 0x53,
535 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74,
536 0x78, 0x7C, 0x7F, 0x83, 0x87, 0x8B, 0x8E, 0x92,
537 0x96, 0x99, 0x9D, 0xA1, 0xA4, 0xA8, 0xAB, 0xAF,
538 0xB2, 0xB6, 0xB9, 0xBD, 0xC0, 0xC4, 0xC7, 0xCB,
539 0xCE, 0xD1, 0xD5, 0xD8, 0xDB, 0xDF, 0xE2, 0xE5,
540 0xE9, 0xEC, 0xEF, 0xF2, 0xF6, 0xF9, 0xFC, 0xFD
545 void *
data,
int *got_frame,
550 int ret, buf_size = avpkt->
size;
561 tag = bytestream2_get_le32(&ctx);
562 size = bytestream2_get_be32(&ctx);
582 int r = gamma_corr(bytestream2_get_byteu(&ctx));
583 int g = gamma_corr(bytestream2_get_byteu(&ctx));
584 int b = gamma_corr(bytestream2_get_byteu(&ctx));
586 int r = gamma_lookup[bytestream2_get_byteu(&ctx)];
587 int g = gamma_lookup[bytestream2_get_byteu(&ctx)];
588 int b = gamma_lookup[bytestream2_get_byteu(&ctx)];
590 *tmpptr++ = (0xFF
U << 24) | (r << 16) | (g << 8) | b;
597 new_pal = bytestream2_get_le32(&ctx);
598 if (new_pal < s->palettes_count) {
623 memcpy(frame->
data[1],
static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame)
const char const char void * val
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
This structure describes decoded (raw) audio or video data.
ptrdiff_t const GLvoid * data
Memory handling functions.
static av_cold int init(AVCodecContext *avctx)
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.
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
8 bits with AV_PIX_FMT_RGB32 palette
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
AVCodec ff_xan_wc3_decoder
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
Overlapping memcpy() implementation.
bitstream reader API header.
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
static int get_bits_left(GetBitContext *gb)
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.
static av_cold int xan_decode_init(AVCodecContext *avctx)
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
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)
const char * name
Name of the codec implementation.
int width
picture width / height.
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
static void xan_wc3_output_pixel_run(XanContext *s, AVFrame *frame, const uint8_t *pixel_buffer, int x, int y, int pixel_count)
Libavcodec external API header.
static av_cold int xan_decode_end(AVCodecContext *avctx)
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_WB16 unsigned int_TMPL byte
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.
main external API structure.
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
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-> in
static unsigned int get_bits1(GetBitContext *s)
static av_const int sign_extend(int val, unsigned bits)
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
common internal api header.
static int xan_decode_frame(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)
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.
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.