39 #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
59 const unsigned char *
buf;
100 const unsigned char *src,
int src_len)
102 unsigned char byte = *src++;
103 unsigned char ival = byte + 0x16;
104 const unsigned char * ptr = src + byte*2;
105 int ptr_len = src_len - 1 - byte*2;
106 unsigned char val = ival;
107 unsigned char *dest_end = dest + dest_len;
108 unsigned char *dest_start = dest;
116 while (val != 0x16) {
117 unsigned idx = val - 0x17 +
get_bits1(&gb) * byte;
123 if (dest >= dest_end)
130 return dest - dest_start;
139 const unsigned char *src,
int src_len)
141 unsigned char opcode;
143 unsigned char *dest_org = dest;
144 unsigned char *dest_end = dest + dest_len;
145 const unsigned char *src_end = src + src_len;
147 while (dest < dest_end && src < src_end) {
152 if ((opcode & 0x80) == 0) {
155 back = ((opcode & 0x60) << 3) + *src++ + 1;
156 size2 = ((opcode & 0x1c) >> 2) + 3;
157 }
else if ((opcode & 0x40) == 0) {
160 back = (bytestream_get_be16(&src) & 0x3fff) + 1;
161 size2 = (opcode & 0x3f) + 4;
165 back = ((opcode & 0x10) << 12) + bytestream_get_be16(&src) + 1;
166 size2 = ((opcode & 0x0c) << 6) + *src++ + 5;
169 if (dest_end - dest < size + size2 ||
170 dest + size - dest_org < back ||
171 src_end - src < size)
173 memcpy(dest, src, size); dest +=
size; src +=
size;
177 int finish = opcode >= 0xfc;
178 size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
180 if (dest_end - dest < size || src_end - src < size)
182 memcpy(dest, src, size); dest +=
size; src +=
size;
190 const unsigned char *pixel_buffer,
int x,
int y,
int pixel_count)
197 unsigned char *palette_plane;
201 line_inc = stride -
width;
202 index = y * stride + x;
204 while (pixel_count && index < s->frame_size) {
205 int count =
FFMIN(pixel_count, width - current_x);
206 memcpy(palette_plane + index, pixel_buffer, count);
207 pixel_count -= count;
209 pixel_buffer += count;
212 if (current_x >= width) {
220 int pixel_count,
int motion_x,
225 int curframe_index, prevframe_index;
226 int curframe_x, prevframe_x;
228 unsigned char *palette_plane, *prev_palette_plane;
230 if (y + motion_y < 0 || y + motion_y >= s->
avctx->
height ||
231 x + motion_x < 0 || x + motion_x >= s->
avctx->
width)
236 if (!prev_palette_plane)
237 prev_palette_plane = palette_plane;
239 line_inc = stride -
width;
240 curframe_index = y * stride + x;
242 prevframe_index = (y + motion_y) * stride + x + motion_x;
243 prevframe_x = x + motion_x;
244 while (pixel_count &&
245 curframe_index < s->frame_size &&
246 prevframe_index < s->frame_size) {
247 int count =
FFMIN3(pixel_count, width - curframe_x,
248 width - prevframe_x);
250 memcpy(palette_plane + curframe_index,
251 prev_palette_plane + prevframe_index, count);
252 pixel_count -= count;
253 curframe_index += count;
254 prevframe_index += count;
256 prevframe_x += count;
258 if (curframe_x >= width) {
259 curframe_index += line_inc;
263 if (prevframe_x >= width) {
264 prevframe_index += line_inc;
274 int total_pixels = width *
height;
275 unsigned char opcode;
276 unsigned char flag = 0;
278 int motion_x, motion_y;
281 unsigned char *opcode_buffer = s->
buffer1;
284 const unsigned char *imagedata_buffer = s->
buffer2;
287 const unsigned char *huffman_segment;
290 const unsigned char *imagedata_segment;
291 int huffman_offset, size_offset, vector_offset, imagedata_offset,
302 if (huffman_offset >= s->
size ||
303 size_offset >= s->
size ||
304 vector_offset >= s->
size ||
305 imagedata_offset >= s->
size)
308 huffman_segment = s->
buf + huffman_offset;
311 imagedata_segment = s->
buf + imagedata_offset;
314 huffman_segment, s->
size - huffman_offset)) < 0)
316 opcode_buffer_end = opcode_buffer + ret;
318 if (imagedata_segment[0] == 2) {
320 &imagedata_segment[1], s->
size - imagedata_offset - 1);
323 imagedata_size = s->
size - imagedata_offset - 1;
324 imagedata_buffer = &imagedata_segment[1];
329 while (total_pixels && opcode_buffer < opcode_buffer_end) {
331 opcode = *opcode_buffer++;
358 size += (opcode - 10);
363 size = bytestream2_get_byte(&size_segment);
368 size = bytestream2_get_be16(&size_segment);
373 size = bytestream2_get_be24(&size_segment);
377 if (size > total_pixels)
387 if (imagedata_size < size)
390 imagedata_buffer +=
size;
391 imagedata_size -=
size;
395 uint8_t vector = bytestream2_get_byte(&vector_segment);
406 total_pixels -=
size;
407 y += (x +
size) / width;
408 x = (x +
size) % width;
414 static inline unsigned mul(
unsigned a,
unsigned b)
416 return (a * b) >> 16;
419 static inline unsigned pow4(
unsigned a)
421 unsigned square = mul(a, a);
422 return mul(square, square);
425 static inline unsigned pow5(
unsigned a)
427 return mul(pow4(a), a);
430 static uint8_t gamma_corr(uint8_t in) {
431 unsigned lo, hi = 0xff40, target;
433 in = (in << 2) | (in >> 6);
439 lo = target = in << 8;
441 unsigned mid = (lo + hi) >> 1;
442 unsigned pow = pow5(mid);
443 if (pow > target) hi = mid;
446 return (pow4((lo + hi) >> 1) + 0x80) >> 8;
461 0x00, 0x09, 0x10, 0x16, 0x1C, 0x21, 0x27, 0x2C,
462 0x31, 0x35, 0x3A, 0x3F, 0x43, 0x48, 0x4C, 0x50,
463 0x54, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D, 0x71,
464 0x75, 0x79, 0x7D, 0x80, 0x84, 0x88, 0x8C, 0x8F,
465 0x93, 0x97, 0x9A, 0x9E, 0xA2, 0xA5, 0xA9, 0xAC,
466 0xB0, 0xB3, 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8,
467 0xCB, 0xCF, 0xD2, 0xD5, 0xD9, 0xDC, 0xDF, 0xE3,
468 0xE6, 0xE9, 0xED, 0xF0, 0xF3, 0xF6, 0xFA, 0xFD,
469 0x03, 0x0B, 0x12, 0x18, 0x1D, 0x23, 0x28, 0x2D,
470 0x32, 0x36, 0x3B, 0x40, 0x44, 0x49, 0x4D, 0x51,
471 0x56, 0x5A, 0x5E, 0x62, 0x66, 0x6A, 0x6E, 0x72,
472 0x76, 0x7A, 0x7D, 0x81, 0x85, 0x89, 0x8D, 0x90,
473 0x94, 0x98, 0x9B, 0x9F, 0xA2, 0xA6, 0xAA, 0xAD,
474 0xB1, 0xB4, 0xB8, 0xBB, 0xBF, 0xC2, 0xC5, 0xC9,
475 0xCC, 0xD0, 0xD3, 0xD6, 0xDA, 0xDD, 0xE0, 0xE4,
476 0xE7, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xFA, 0xFD,
477 0x05, 0x0D, 0x13, 0x19, 0x1F, 0x24, 0x29, 0x2E,
478 0x33, 0x38, 0x3C, 0x41, 0x45, 0x4A, 0x4E, 0x52,
479 0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73,
480 0x77, 0x7B, 0x7E, 0x82, 0x86, 0x8A, 0x8D, 0x91,
481 0x95, 0x99, 0x9C, 0xA0, 0xA3, 0xA7, 0xAA, 0xAE,
482 0xB2, 0xB5, 0xB9, 0xBC, 0xBF, 0xC3, 0xC6, 0xCA,
483 0xCD, 0xD0, 0xD4, 0xD7, 0xDA, 0xDE, 0xE1, 0xE4,
484 0xE8, 0xEB, 0xEE, 0xF1, 0xF5, 0xF8, 0xFB, 0xFD,
485 0x07, 0x0E, 0x15, 0x1A, 0x20, 0x25, 0x2A, 0x2F,
486 0x34, 0x39, 0x3D, 0x42, 0x46, 0x4B, 0x4F, 0x53,
487 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74,
488 0x78, 0x7C, 0x7F, 0x83, 0x87, 0x8B, 0x8E, 0x92,
489 0x96, 0x99, 0x9D, 0xA1, 0xA4, 0xA8, 0xAB, 0xAF,
490 0xB2, 0xB6, 0xB9, 0xBD, 0xC0, 0xC4, 0xC7, 0xCB,
491 0xCE, 0xD1, 0xD5, 0xD8, 0xDB, 0xDF, 0xE2, 0xE5,
492 0xE9, 0xEC, 0xEF, 0xF2, 0xF6, 0xF9, 0xFC, 0xFD
497 void *
data,
int *data_size,
500 const uint8_t *buf = avpkt->
data;
501 int ret, buf_size = avpkt->
size;
505 const uint8_t *buf_end = buf + buf_size;
507 while (buf_end - buf > 8 && tag !=
VGA__TAG) {
512 tag = bytestream_get_le32(&buf);
513 size = bytestream_get_be32(&buf);
514 size =
FFMIN(size, buf_end - buf);
529 int r = gamma_corr(*buf++);
530 int g = gamma_corr(*buf++);
531 int b = gamma_corr(*buf++);
533 int r = gamma_lookup[*buf++];
534 int g = gamma_lookup[*buf++];
535 int b = gamma_lookup[*buf++];
537 *tmpptr++ = (r << 16) | (g << 8) |
b;
544 new_pal = bytestream_get_le32(&buf);
545 if (new_pal < s->palettes_count) {
557 buf_size = buf_end - buf;
enum PixelFormat pix_fmt
Pixel format, see PIX_FMT_xxx.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
static int xan_wc3_decode_frame(XanContext *s)
void(* release_buffer)(struct AVCodecContext *c, AVFrame *pic)
Called to release buffers which were allocated with get_buffer.
static int xan_huffman_decode(unsigned char *dest, int dest_len, const unsigned char *src, int src_len)
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
void * av_realloc(void *ptr, size_t size)
Allocate or reallocate a block of memory.
static const uint8_t gamma_lookup[256]
This is a gamma correction that xan3 applies to all palette entries.
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
static int decode(MimicContext *ctx, int quality, int num_coeffs, int is_iframe)
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
deliberately overlapping memcpy implementation
AVCodec ff_xan_wc3_decoder
static void xan_wc3_copy_pixel_run(XanContext *s, int x, int y, int pixel_count, int motion_x, int motion_y)
bitstream reader API header.
static int init(AVCodecParserContext *s)
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
static av_cold int xan_decode_init(AVCodecContext *avctx)
int reference
is this picture used as reference The values for this are the same as the MpegEncContext.picture_structure variable, that is 1->top field, 2->bottom field, 3->frame/both fields.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void av_log(void *avcl, int level, const char *fmt,...)
const char * name
Name of the codec implementation.
struct XanContext XanContext
const unsigned char * buf
int width
picture width / height.
struct AVFrame AVFrame
Audio Video Frame.
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame)
static av_cold int xan_decode_end(AVCodecContext *avctx)
int linesize[AV_NUM_DATA_POINTERS]
Size, in bytes, of the data for each picture/channel plane.
main external API structure.
static void close(AVCodecParserContext *s)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static void xan_unpack(unsigned char *dest, int dest_len, const unsigned char *src, int src_len)
unpack simple compression
static unsigned int get_bits1(GetBitContext *s)
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
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.
8 bit with PIX_FMT_RGB32 palette
static void xan_wc3_output_pixel_run(XanContext *s, const unsigned char *pixel_buffer, int x, int y, int pixel_count)
#define FFSWAP(type, a, b)
static int xan_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)