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) {
140 if (dest >= dest_end)
147 return dest - dest_start;
161 uint8_t *dest_end = dest + dest_len;
166 opcode = bytestream2_get_byte(&ctx);
170 if ((opcode & 0x80) == 0) {
173 back = ((opcode & 0x60) << 3) + bytestream2_get_byte(&ctx) + 1;
174 size2 = ((opcode & 0x1c) >> 2) + 3;
175 }
else if ((opcode & 0x40) == 0) {
176 size = bytestream2_peek_byte(&ctx) >> 6;
178 back = (bytestream2_get_be16(&ctx) & 0x3fff) + 1;
179 size2 = (opcode & 0x3f) + 4;
183 back = ((opcode & 0x10) << 12) + bytestream2_get_be16(&ctx) + 1;
184 size2 = ((opcode & 0x0c) << 6) + bytestream2_get_byte(&ctx) + 5;
187 if (dest_end - dest < size + size2 ||
188 dest + size - dest_org < back ||
196 int finish = opcode >= 0xfc;
197 size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
210 const uint8_t *pixel_buffer,
int x,
int y,
int pixel_count)
219 palette_plane = frame->
data[0];
221 line_inc = stride -
width;
222 index = y * stride + x;
224 while (pixel_count && index < s->
frame_size) {
225 int count =
FFMIN(pixel_count, width - current_x);
226 memcpy(palette_plane + index, pixel_buffer, count);
227 pixel_count -=
count;
229 pixel_buffer +=
count;
232 if (current_x >= width) {
241 int pixel_count,
int motion_x,
246 int curframe_index, prevframe_index;
247 int curframe_x, prevframe_x;
249 uint8_t *palette_plane, *prev_palette_plane;
251 if (y + motion_y < 0 || y + motion_y >= s->
avctx->
height ||
252 x + motion_x < 0 || x + motion_x >= s->
avctx->
width)
255 palette_plane = frame->
data[0];
257 if (!prev_palette_plane)
258 prev_palette_plane = palette_plane;
260 line_inc = stride -
width;
261 curframe_index = y * stride + x;
263 prevframe_index = (y + motion_y) * stride + x + motion_x;
264 prevframe_x = x + motion_x;
266 if (prev_palette_plane == palette_plane &&
FFABS(curframe_index - prevframe_index) < pixel_count) {
271 while (pixel_count &&
274 int count =
FFMIN3(pixel_count, width - curframe_x,
275 width - prevframe_x);
277 memcpy(palette_plane + curframe_index,
278 prev_palette_plane + prevframe_index, count);
279 pixel_count -=
count;
280 curframe_index +=
count;
281 prevframe_index +=
count;
283 prevframe_x +=
count;
285 if (curframe_x >= width) {
286 curframe_index += line_inc;
290 if (prevframe_x >= width) {
291 prevframe_index += line_inc;
302 int total_pixels = width *
height;
306 int motion_x, motion_y;
315 const uint8_t *huffman_segment;
318 const uint8_t *imagedata_segment;
319 int huffman_offset, size_offset, vector_offset, imagedata_offset,
330 if (huffman_offset >= s->
size ||
331 size_offset >= s->
size ||
332 vector_offset >= s->
size ||
333 imagedata_offset >= s->
size)
336 huffman_segment = s->
buf + huffman_offset;
339 imagedata_segment = s->
buf + imagedata_offset;
342 huffman_segment, s->
size - huffman_offset)) < 0)
344 opcode_buffer_end = opcode_buffer + ret;
346 if (imagedata_segment[0] == 2) {
348 &imagedata_segment[1], s->
size - imagedata_offset - 1);
351 imagedata_size = s->
size - imagedata_offset - 1;
352 imagedata_buffer = &imagedata_segment[1];
357 while (total_pixels && opcode_buffer < opcode_buffer_end) {
359 opcode = *opcode_buffer++;
386 size += (opcode - 10);
395 size = bytestream2_get_byte(&size_segment);
404 size = bytestream2_get_be16(&size_segment);
413 size = bytestream2_get_be24(&size_segment);
417 if (size > total_pixels)
427 if (imagedata_size < size)
430 imagedata_buffer +=
size;
431 imagedata_size -=
size;
440 vector = bytestream2_get_byte(&vector_segment);
451 total_pixels -=
size;
452 y += (x +
size) / width;
453 x = (x +
size) % width;
459 static inline unsigned mul(
unsigned a,
unsigned b)
461 return (a * b) >> 16;
464 static inline unsigned pow4(
unsigned a)
466 unsigned square = mul(a, a);
467 return mul(square, square);
470 static inline unsigned pow5(
unsigned a)
472 return mul(pow4(a), a);
476 unsigned lo, hi = 0xff40, target;
478 in = (in << 2) | (in >> 6);
484 lo = target = in << 8;
486 unsigned mid = (lo + hi) >> 1;
487 unsigned pow = pow5(mid);
488 if (pow > target) hi = mid;
491 return (pow4((lo + hi) >> 1) + 0x80) >> 8;
506 0x00, 0x09, 0x10, 0x16, 0x1C, 0x21, 0x27, 0x2C,
507 0x31, 0x35, 0x3A, 0x3F, 0x43, 0x48, 0x4C, 0x50,
508 0x54, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D, 0x71,
509 0x75, 0x79, 0x7D, 0x80, 0x84, 0x88, 0x8C, 0x8F,
510 0x93, 0x97, 0x9A, 0x9E, 0xA2, 0xA5, 0xA9, 0xAC,
511 0xB0, 0xB3, 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8,
512 0xCB, 0xCF, 0xD2, 0xD5, 0xD9, 0xDC, 0xDF, 0xE3,
513 0xE6, 0xE9, 0xED, 0xF0, 0xF3, 0xF6, 0xFA, 0xFD,
514 0x03, 0x0B, 0x12, 0x18, 0x1D, 0x23, 0x28, 0x2D,
515 0x32, 0x36, 0x3B, 0x40, 0x44, 0x49, 0x4D, 0x51,
516 0x56, 0x5A, 0x5E, 0x62, 0x66, 0x6A, 0x6E, 0x72,
517 0x76, 0x7A, 0x7D, 0x81, 0x85, 0x89, 0x8D, 0x90,
518 0x94, 0x98, 0x9B, 0x9F, 0xA2, 0xA6, 0xAA, 0xAD,
519 0xB1, 0xB4, 0xB8, 0xBB, 0xBF, 0xC2, 0xC5, 0xC9,
520 0xCC, 0xD0, 0xD3, 0xD6, 0xDA, 0xDD, 0xE0, 0xE4,
521 0xE7, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xFA, 0xFD,
522 0x05, 0x0D, 0x13, 0x19, 0x1F, 0x24, 0x29, 0x2E,
523 0x33, 0x38, 0x3C, 0x41, 0x45, 0x4A, 0x4E, 0x52,
524 0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73,
525 0x77, 0x7B, 0x7E, 0x82, 0x86, 0x8A, 0x8D, 0x91,
526 0x95, 0x99, 0x9C, 0xA0, 0xA3, 0xA7, 0xAA, 0xAE,
527 0xB2, 0xB5, 0xB9, 0xBC, 0xBF, 0xC3, 0xC6, 0xCA,
528 0xCD, 0xD0, 0xD4, 0xD7, 0xDA, 0xDE, 0xE1, 0xE4,
529 0xE8, 0xEB, 0xEE, 0xF1, 0xF5, 0xF8, 0xFB, 0xFD,
530 0x07, 0x0E, 0x15, 0x1A, 0x20, 0x25, 0x2A, 0x2F,
531 0x34, 0x39, 0x3D, 0x42, 0x46, 0x4B, 0x4F, 0x53,
532 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74,
533 0x78, 0x7C, 0x7F, 0x83, 0x87, 0x8B, 0x8E, 0x92,
534 0x96, 0x99, 0x9D, 0xA1, 0xA4, 0xA8, 0xAB, 0xAF,
535 0xB2, 0xB6, 0xB9, 0xBD, 0xC0, 0xC4, 0xC7, 0xCB,
536 0xCE, 0xD1, 0xD5, 0xD8, 0xDB, 0xDF, 0xE2, 0xE5,
537 0xE9, 0xEC, 0xEF, 0xF2, 0xF6, 0xF9, 0xFC, 0xFD
542 void *
data,
int *got_frame,
547 int ret, buf_size = avpkt->
size;
558 tag = bytestream2_get_le32(&ctx);
559 size = bytestream2_get_be32(&ctx);
579 int r = gamma_corr(bytestream2_get_byteu(&ctx));
580 int g = gamma_corr(bytestream2_get_byteu(&ctx));
581 int b = gamma_corr(bytestream2_get_byteu(&ctx));
583 int r = gamma_lookup[bytestream2_get_byteu(&ctx)];
584 int g = gamma_lookup[bytestream2_get_byteu(&ctx)];
585 int b = gamma_lookup[bytestream2_get_byteu(&ctx)];
587 *tmpptr++ = (0xFF
U << 24) | (r << 16) | (g << 8) | b;
594 new_pal = bytestream2_get_le32(&ctx);
595 if (new_pal < s->palettes_count) {
620 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
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 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 int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
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.