38 #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 &&
244 curframe_index < s->frame_size &&
245 prevframe_index < s->frame_size) {
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);
429 static uint8_t gamma_corr(uint8_t in) {
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 *data_size,
499 const uint8_t *buf = avpkt->
data;
500 int ret, buf_size = avpkt->
size;
504 const uint8_t *buf_end = buf + buf_size;
506 while (buf_end - buf > 8 && tag !=
VGA__TAG) {
511 tag = bytestream_get_le32(&buf);
512 size = bytestream_get_be32(&buf);
513 size =
FFMIN(size, buf_end - buf);
528 int r = gamma_corr(*buf++);
529 int g = gamma_corr(*buf++);
530 int b = gamma_corr(*buf++);
532 int r = gamma_lookup[*buf++];
533 int g = gamma_lookup[*buf++];
534 int b = gamma_lookup[*buf++];
536 *tmpptr++ = (r << 16) | (g << 8) |
b;
543 new_pal = bytestream_get_le32(&buf);
544 if (new_pal < s->palettes_count) {
556 buf_size = buf_end - buf;