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
58 const unsigned char *
buf;
99 const unsigned char *src,
int src_len)
101 unsigned char byte = *src++;
102 unsigned char ival = byte + 0x16;
103 const unsigned char * ptr = src + byte*2;
104 int ptr_len = src_len - 1 - byte*2;
105 unsigned char val = ival;
106 unsigned char *dest_end = dest + dest_len;
107 unsigned char *dest_start = dest;
115 while (val != 0x16) {
116 unsigned idx = val - 0x17 +
get_bits1(&gb) * byte;
122 if (dest >= dest_end)
129 return dest - dest_start;
138 const unsigned char *src,
int src_len)
140 unsigned char opcode;
142 unsigned char *dest_org = dest;
143 unsigned char *dest_end = dest + dest_len;
144 const unsigned char *src_end = src + src_len;
146 while (dest < dest_end && src < src_end) {
151 if ((opcode & 0x80) == 0) {
154 back = ((opcode & 0x60) << 3) + *src++ + 1;
155 size2 = ((opcode & 0x1c) >> 2) + 3;
156 }
else if ((opcode & 0x40) == 0) {
159 back = (bytestream_get_be16(&src) & 0x3fff) + 1;
160 size2 = (opcode & 0x3f) + 4;
164 back = ((opcode & 0x10) << 12) + bytestream_get_be16(&src) + 1;
165 size2 = ((opcode & 0x0c) << 6) + *src++ + 5;
168 if (dest_end - dest < size + size2 ||
169 dest + size - dest_org < back ||
170 src_end - src < size)
172 memcpy(dest, src, size); dest +=
size; src +=
size;
176 int finish = opcode >= 0xfc;
177 size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
179 if (dest_end - dest < size || src_end - src < size)
181 memcpy(dest, src, size); dest +=
size; src +=
size;
189 const unsigned char *pixel_buffer,
int x,
int y,
int pixel_count)
196 unsigned char *palette_plane;
200 line_inc = stride -
width;
201 index = y * stride + x;
203 while (pixel_count && index < s->
frame_size) {
204 int count =
FFMIN(pixel_count, width - current_x);
205 memcpy(palette_plane + index, pixel_buffer, count);
206 pixel_count -= count;
208 pixel_buffer += count;
211 if (current_x >= width) {
219 int pixel_count,
int motion_x,
224 int curframe_index, prevframe_index;
225 int curframe_x, prevframe_x;
227 unsigned char *palette_plane, *prev_palette_plane;
229 if (y + motion_y < 0 || y + motion_y >= s->
avctx->
height ||
230 x + motion_x < 0 || x + motion_x >= s->
avctx->
width)
235 if (!prev_palette_plane)
236 prev_palette_plane = palette_plane;
238 line_inc = stride -
width;
239 curframe_index = y * stride + x;
241 prevframe_index = (y + motion_y) * stride + x + motion_x;
242 prevframe_x = x + motion_x;
243 while (pixel_count &&
246 int count =
FFMIN3(pixel_count, width - curframe_x,
247 width - prevframe_x);
249 memcpy(palette_plane + curframe_index,
250 prev_palette_plane + prevframe_index, count);
251 pixel_count -= count;
252 curframe_index += count;
253 prevframe_index += count;
255 prevframe_x += count;
257 if (curframe_x >= width) {
258 curframe_index += line_inc;
262 if (prevframe_x >= width) {
263 prevframe_index += line_inc;
273 int total_pixels = width *
height;
274 unsigned char opcode;
275 unsigned char flag = 0;
277 int motion_x, motion_y;
280 unsigned char *opcode_buffer = s->
buffer1;
283 const unsigned char *imagedata_buffer = s->
buffer2;
286 const unsigned char *huffman_segment;
289 const unsigned char *imagedata_segment;
290 int huffman_offset, size_offset, vector_offset, imagedata_offset,
301 if (huffman_offset >= s->
size ||
302 size_offset >= s->
size ||
303 vector_offset >= s->
size ||
304 imagedata_offset >= s->
size)
307 huffman_segment = s->
buf + huffman_offset;
310 imagedata_segment = s->
buf + imagedata_offset;
313 huffman_segment, s->
size - huffman_offset)) < 0)
315 opcode_buffer_end = opcode_buffer + ret;
317 if (imagedata_segment[0] == 2) {
319 &imagedata_segment[1], s->
size - imagedata_offset - 1);
322 imagedata_size = s->
size - imagedata_offset - 1;
323 imagedata_buffer = &imagedata_segment[1];
328 while (total_pixels && opcode_buffer < opcode_buffer_end) {
330 opcode = *opcode_buffer++;
357 size += (opcode - 10);
362 size = bytestream2_get_byte(&size_segment);
367 size = bytestream2_get_be16(&size_segment);
372 size = bytestream2_get_be24(&size_segment);
376 if (size > total_pixels)
386 if (imagedata_size < size)
389 imagedata_buffer +=
size;
390 imagedata_size -=
size;
394 uint8_t vector = bytestream2_get_byte(&vector_segment);
405 total_pixels -=
size;
406 y += (x +
size) / width;
407 x = (x +
size) % width;
413 static inline unsigned mul(
unsigned a,
unsigned b)
415 return (a * b) >> 16;
418 static inline unsigned pow4(
unsigned a)
420 unsigned square = mul(a, a);
421 return mul(square, square);
424 static inline unsigned pow5(
unsigned a)
426 return mul(pow4(a), a);
430 unsigned lo, hi = 0xff40, target;
432 in = (in << 2) | (in >> 6);
438 lo = target = in << 8;
440 unsigned mid = (lo + hi) >> 1;
441 unsigned pow = pow5(mid);
442 if (pow > target) hi = mid;
445 return (pow4((lo + hi) >> 1) + 0x80) >> 8;
460 0x00, 0x09, 0x10, 0x16, 0x1C, 0x21, 0x27, 0x2C,
461 0x31, 0x35, 0x3A, 0x3F, 0x43, 0x48, 0x4C, 0x50,
462 0x54, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D, 0x71,
463 0x75, 0x79, 0x7D, 0x80, 0x84, 0x88, 0x8C, 0x8F,
464 0x93, 0x97, 0x9A, 0x9E, 0xA2, 0xA5, 0xA9, 0xAC,
465 0xB0, 0xB3, 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8,
466 0xCB, 0xCF, 0xD2, 0xD5, 0xD9, 0xDC, 0xDF, 0xE3,
467 0xE6, 0xE9, 0xED, 0xF0, 0xF3, 0xF6, 0xFA, 0xFD,
468 0x03, 0x0B, 0x12, 0x18, 0x1D, 0x23, 0x28, 0x2D,
469 0x32, 0x36, 0x3B, 0x40, 0x44, 0x49, 0x4D, 0x51,
470 0x56, 0x5A, 0x5E, 0x62, 0x66, 0x6A, 0x6E, 0x72,
471 0x76, 0x7A, 0x7D, 0x81, 0x85, 0x89, 0x8D, 0x90,
472 0x94, 0x98, 0x9B, 0x9F, 0xA2, 0xA6, 0xAA, 0xAD,
473 0xB1, 0xB4, 0xB8, 0xBB, 0xBF, 0xC2, 0xC5, 0xC9,
474 0xCC, 0xD0, 0xD3, 0xD6, 0xDA, 0xDD, 0xE0, 0xE4,
475 0xE7, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xFA, 0xFD,
476 0x05, 0x0D, 0x13, 0x19, 0x1F, 0x24, 0x29, 0x2E,
477 0x33, 0x38, 0x3C, 0x41, 0x45, 0x4A, 0x4E, 0x52,
478 0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73,
479 0x77, 0x7B, 0x7E, 0x82, 0x86, 0x8A, 0x8D, 0x91,
480 0x95, 0x99, 0x9C, 0xA0, 0xA3, 0xA7, 0xAA, 0xAE,
481 0xB2, 0xB5, 0xB9, 0xBC, 0xBF, 0xC3, 0xC6, 0xCA,
482 0xCD, 0xD0, 0xD4, 0xD7, 0xDA, 0xDE, 0xE1, 0xE4,
483 0xE8, 0xEB, 0xEE, 0xF1, 0xF5, 0xF8, 0xFB, 0xFD,
484 0x07, 0x0E, 0x15, 0x1A, 0x20, 0x25, 0x2A, 0x2F,
485 0x34, 0x39, 0x3D, 0x42, 0x46, 0x4B, 0x4F, 0x53,
486 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74,
487 0x78, 0x7C, 0x7F, 0x83, 0x87, 0x8B, 0x8E, 0x92,
488 0x96, 0x99, 0x9D, 0xA1, 0xA4, 0xA8, 0xAB, 0xAF,
489 0xB2, 0xB6, 0xB9, 0xBD, 0xC0, 0xC4, 0xC7, 0xCB,
490 0xCE, 0xD1, 0xD5, 0xD8, 0xDB, 0xDF, 0xE2, 0xE5,
491 0xE9, 0xEC, 0xEF, 0xF2, 0xF6, 0xF9, 0xFC, 0xFD
496 void *
data,
int *got_frame,
500 int ret, buf_size = avpkt->
size;
502 const uint8_t *buf_end = buf + buf_size;
505 while (buf_end - buf > 8 && tag !=
VGA__TAG) {
510 tag = bytestream_get_le32(&buf);
511 size = bytestream_get_be32(&buf);
512 size =
FFMIN(size, buf_end - buf);
527 int r = gamma_corr(*buf++);
528 int g = gamma_corr(*buf++);
529 int b = gamma_corr(*buf++);
531 int r = gamma_lookup[*buf++];
532 int g = gamma_lookup[*buf++];
533 int b = gamma_lookup[*buf++];
535 *tmpptr++ = (r << 16) | (g << 8) |
b;
542 new_pal = bytestream_get_le32(&buf);
543 if (new_pal < s->palettes_count) {
555 buf_size = buf_end - buf;
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
This structure describes decoded (raw) audio or video data.
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.
memory handling functions
static int xan_huffman_decode(unsigned char *dest, int dest_len, const unsigned char *src, int src_len)
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 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)
#define FFSWAP(type, a, b)
8 bit with PIX_FMT_RGB32 palette
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)
static const uint8_t frame_size[4]
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.
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame)
Get a buffer for a 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)
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)
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.
void * av_realloc(void *ptr, size_t size)
Allocate or reallocate a block of memory.
#define AVERROR_INVALIDDATA
static void xan_wc3_output_pixel_run(XanContext *s, const unsigned char *pixel_buffer, int x, int y, int pixel_count)
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
This structure stores compressed data.