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
121 const uint8_t * ptr = src + byte*2;
122 int ptr_len = src_len - 1 - byte*2;
124 uint8_t *dest_end = dest + dest_len;
132 while (val != 0x16) {
136 idx = val - 0x17 +
get_bits1(&gb) * byte;
142 if (dest >= dest_end)
149 return dest - dest_start;
163 uint8_t *dest_end = dest + dest_len;
168 opcode = bytestream2_get_byte(&ctx);
172 if ((opcode & 0x80) == 0) {
175 back = ((opcode & 0x60) << 3) + bytestream2_get_byte(&ctx) + 1;
176 size2 = ((opcode & 0x1c) >> 2) + 3;
177 }
else if ((opcode & 0x40) == 0) {
178 size = bytestream2_peek_byte(&ctx) >> 6;
180 back = (bytestream2_get_be16(&ctx) & 0x3fff) + 1;
181 size2 = (opcode & 0x3f) + 4;
185 back = ((opcode & 0x10) << 12) + bytestream2_get_be16(&ctx) + 1;
186 size2 = ((opcode & 0x0c) << 6) + bytestream2_get_byte(&ctx) + 5;
189 if (dest_end - dest < size + size2 ||
190 dest + size - dest_org < back ||
198 int finish = opcode >= 0xfc;
199 size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
212 const uint8_t *pixel_buffer,
int x,
int y,
int pixel_count)
221 palette_plane = frame->
data[0];
223 line_inc = stride -
width;
224 index = y * stride + x;
226 while (pixel_count && index < s->
frame_size) {
227 int count =
FFMIN(pixel_count, width - current_x);
228 memcpy(palette_plane + index, pixel_buffer, count);
229 pixel_count -=
count;
231 pixel_buffer +=
count;
234 if (current_x >= width) {
243 int pixel_count,
int motion_x,
248 int curframe_index, prevframe_index;
249 int curframe_x, prevframe_x;
251 uint8_t *palette_plane, *prev_palette_plane;
253 if (y + motion_y < 0 || y + motion_y >= s->
avctx->
height ||
254 x + motion_x < 0 || x + motion_x >= s->
avctx->
width)
257 palette_plane = frame->
data[0];
259 if (!prev_palette_plane)
260 prev_palette_plane = palette_plane;
262 line_inc = stride -
width;
263 curframe_index = y * stride + x;
265 prevframe_index = (y + motion_y) * stride + x + motion_x;
266 prevframe_x = x + motion_x;
268 if (prev_palette_plane == palette_plane &&
FFABS(motion_x + width*motion_y) < pixel_count) {
273 while (pixel_count &&
276 int count =
FFMIN3(pixel_count, width - curframe_x,
277 width - prevframe_x);
279 memcpy(palette_plane + curframe_index,
280 prev_palette_plane + prevframe_index, count);
281 pixel_count -=
count;
282 curframe_index +=
count;
283 prevframe_index +=
count;
285 prevframe_x +=
count;
287 if (curframe_x >= width) {
288 curframe_index += line_inc;
292 if (prevframe_x >= width) {
293 prevframe_index += line_inc;
304 int total_pixels = width *
height;
308 int motion_x, motion_y;
317 const uint8_t *huffman_segment;
320 const uint8_t *imagedata_segment;
321 int huffman_offset, size_offset, vector_offset, imagedata_offset,
332 if (huffman_offset >= s->
size ||
333 size_offset >= s->
size ||
334 vector_offset >= s->
size ||
335 imagedata_offset >= s->
size)
338 huffman_segment = s->
buf + huffman_offset;
341 imagedata_segment = s->
buf + imagedata_offset;
344 huffman_segment, s->
size - huffman_offset)) < 0)
346 opcode_buffer_end = opcode_buffer + ret;
348 if (imagedata_segment[0] == 2) {
350 &imagedata_segment[1], s->
size - imagedata_offset - 1);
353 imagedata_size = s->
size - imagedata_offset - 1;
354 imagedata_buffer = &imagedata_segment[1];
359 while (total_pixels && opcode_buffer < opcode_buffer_end) {
361 opcode = *opcode_buffer++;
388 size += (opcode - 10);
397 size = bytestream2_get_byte(&size_segment);
406 size = bytestream2_get_be16(&size_segment);
415 size = bytestream2_get_be24(&size_segment);
419 if (size > total_pixels)
429 if (imagedata_size < size)
432 imagedata_buffer +=
size;
433 imagedata_size -=
size;
442 vector = bytestream2_get_byte(&vector_segment);
453 total_pixels -=
size;
454 y += (x +
size) / width;
455 x = (x +
size) % width;
461 static inline unsigned mul(
unsigned a,
unsigned b)
463 return (a * b) >> 16;
466 static inline unsigned pow4(
unsigned a)
468 unsigned square = mul(a, a);
469 return mul(square, square);
472 static inline unsigned pow5(
unsigned a)
474 return mul(pow4(a), a);
478 unsigned lo, hi = 0xff40, target;
480 in = (in << 2) | (in >> 6);
486 lo = target = in << 8;
488 unsigned mid = (lo + hi) >> 1;
489 unsigned pow = pow5(mid);
490 if (pow > target) hi = mid;
493 return (pow4((lo + hi) >> 1) + 0x80) >> 8;
508 0x00, 0x09, 0x10, 0x16, 0x1C, 0x21, 0x27, 0x2C,
509 0x31, 0x35, 0x3A, 0x3F, 0x43, 0x48, 0x4C, 0x50,
510 0x54, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D, 0x71,
511 0x75, 0x79, 0x7D, 0x80, 0x84, 0x88, 0x8C, 0x8F,
512 0x93, 0x97, 0x9A, 0x9E, 0xA2, 0xA5, 0xA9, 0xAC,
513 0xB0, 0xB3, 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8,
514 0xCB, 0xCF, 0xD2, 0xD5, 0xD9, 0xDC, 0xDF, 0xE3,
515 0xE6, 0xE9, 0xED, 0xF0, 0xF3, 0xF6, 0xFA, 0xFD,
516 0x03, 0x0B, 0x12, 0x18, 0x1D, 0x23, 0x28, 0x2D,
517 0x32, 0x36, 0x3B, 0x40, 0x44, 0x49, 0x4D, 0x51,
518 0x56, 0x5A, 0x5E, 0x62, 0x66, 0x6A, 0x6E, 0x72,
519 0x76, 0x7A, 0x7D, 0x81, 0x85, 0x89, 0x8D, 0x90,
520 0x94, 0x98, 0x9B, 0x9F, 0xA2, 0xA6, 0xAA, 0xAD,
521 0xB1, 0xB4, 0xB8, 0xBB, 0xBF, 0xC2, 0xC5, 0xC9,
522 0xCC, 0xD0, 0xD3, 0xD6, 0xDA, 0xDD, 0xE0, 0xE4,
523 0xE7, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xFA, 0xFD,
524 0x05, 0x0D, 0x13, 0x19, 0x1F, 0x24, 0x29, 0x2E,
525 0x33, 0x38, 0x3C, 0x41, 0x45, 0x4A, 0x4E, 0x52,
526 0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73,
527 0x77, 0x7B, 0x7E, 0x82, 0x86, 0x8A, 0x8D, 0x91,
528 0x95, 0x99, 0x9C, 0xA0, 0xA3, 0xA7, 0xAA, 0xAE,
529 0xB2, 0xB5, 0xB9, 0xBC, 0xBF, 0xC3, 0xC6, 0xCA,
530 0xCD, 0xD0, 0xD4, 0xD7, 0xDA, 0xDE, 0xE1, 0xE4,
531 0xE8, 0xEB, 0xEE, 0xF1, 0xF5, 0xF8, 0xFB, 0xFD,
532 0x07, 0x0E, 0x15, 0x1A, 0x20, 0x25, 0x2A, 0x2F,
533 0x34, 0x39, 0x3D, 0x42, 0x46, 0x4B, 0x4F, 0x53,
534 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74,
535 0x78, 0x7C, 0x7F, 0x83, 0x87, 0x8B, 0x8E, 0x92,
536 0x96, 0x99, 0x9D, 0xA1, 0xA4, 0xA8, 0xAB, 0xAF,
537 0xB2, 0xB6, 0xB9, 0xBD, 0xC0, 0xC4, 0xC7, 0xCB,
538 0xCE, 0xD1, 0xD5, 0xD8, 0xDB, 0xDF, 0xE2, 0xE5,
539 0xE9, 0xEC, 0xEF, 0xF2, 0xF6, 0xF9, 0xFC, 0xFD
544 void *
data,
int *got_frame,
549 int ret, buf_size = avpkt->
size;
560 tag = bytestream2_get_le32(&ctx);
561 size = bytestream2_get_be32(&ctx);
581 int r = gamma_corr(bytestream2_get_byteu(&ctx));
582 int g = gamma_corr(bytestream2_get_byteu(&ctx));
583 int b = gamma_corr(bytestream2_get_byteu(&ctx));
585 int r = gamma_lookup[bytestream2_get_byteu(&ctx)];
586 int g = gamma_lookup[bytestream2_get_byteu(&ctx)];
587 int b = gamma_lookup[bytestream2_get_byteu(&ctx)];
589 *tmpptr++ = (0xFF
U << 24) | (r << 16) | (g << 8) | b;
596 new_pal = bytestream2_get_le32(&ctx);
597 if (new_pal < s->palettes_count) {
622 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.
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 bit 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
bitstream reader API header.
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.
Libavcodec external API header.
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)
static av_cold int xan_decode_end(AVCodecContext *avctx)
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)
BYTE int const BYTE int int int height
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.
static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avpkt)
common internal api header.
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
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 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.