35 #include "libavutil/intreadwrite.h"
36 #include "libavutil/mem.h"
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;
101 const unsigned char *src,
int src_len)
103 unsigned char byte = *src++;
104 unsigned char ival = byte + 0x16;
105 const unsigned char * ptr = src + byte*2;
106 int ptr_len = src_len - 1 - byte*2;
107 unsigned char val = ival;
108 unsigned char *dest_end = dest + dest_len;
116 while (val != 0x16) {
117 unsigned idx = val - 0x17 +
get_bits1(&gb) * byte;
123 if (dest >= dest_end)
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;
149 opcode = bytestream2_get_byte(&ctx);
153 if ((opcode & 0x80) == 0) {
156 back = ((opcode & 0x60) << 3) + bytestream2_get_byte(&ctx) + 1;
157 size2 = ((opcode & 0x1c) >> 2) + 3;
158 }
else if ((opcode & 0x40) == 0) {
159 size = bytestream2_peek_byte(&ctx) >> 6;
161 back = (bytestream2_get_be16(&ctx) & 0x3fff) + 1;
162 size2 = (opcode & 0x3f) + 4;
166 back = ((opcode & 0x10) << 12) + bytestream2_get_be16(&ctx) + 1;
167 size2 = ((opcode & 0x0c) << 6) + bytestream2_get_byte(&ctx) + 5;
170 if (dest_end - dest < size + size2 ||
171 dest + size - dest_org < back ||
179 int finish = opcode >= 0xfc;
180 size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
193 const unsigned char *pixel_buffer,
int x,
int y,
int pixel_count)
200 unsigned char *palette_plane;
204 line_inc = stride -
width;
205 index = y * stride + x;
207 while (pixel_count && index < s->
frame_size) {
208 int count =
FFMIN(pixel_count, width - current_x);
209 memcpy(palette_plane + index, pixel_buffer, count);
210 pixel_count -= count;
212 pixel_buffer += count;
215 if (current_x >= width) {
223 int pixel_count,
int motion_x,
228 int curframe_index, prevframe_index;
229 int curframe_x, prevframe_x;
231 unsigned char *palette_plane, *prev_palette_plane;
233 if (y + motion_y < 0 || y + motion_y >= s->
avctx->
height ||
234 x + motion_x < 0 || x + motion_x >= s->
avctx->
width)
239 if (!prev_palette_plane)
240 prev_palette_plane = palette_plane;
242 line_inc = stride -
width;
243 curframe_index = y * stride + x;
245 prevframe_index = (y + motion_y) * stride + x + motion_x;
246 prevframe_x = x + motion_x;
248 if (prev_palette_plane == palette_plane &&
FFABS(curframe_index - prevframe_index) < pixel_count) {
252 while (pixel_count &&
255 int count =
FFMIN3(pixel_count, width - curframe_x,
256 width - prevframe_x);
258 memcpy(palette_plane + curframe_index,
259 prev_palette_plane + prevframe_index, count);
260 pixel_count -= count;
261 curframe_index += count;
262 prevframe_index += count;
264 prevframe_x += count;
266 if (curframe_x >= width) {
267 curframe_index += line_inc;
271 if (prevframe_x >= width) {
272 prevframe_index += line_inc;
282 int total_pixels = width *
height;
283 unsigned char opcode;
284 unsigned char flag = 0;
286 int motion_x, motion_y;
289 unsigned char *opcode_buffer = s->
buffer1;
292 const unsigned char *imagedata_buffer = s->
buffer2;
295 const unsigned char *huffman_segment;
296 const unsigned char *size_segment;
297 const unsigned char *vector_segment;
298 const unsigned char *imagedata_segment;
299 const unsigned char *buf_end = s->
buf + s->
size;
300 int huffman_offset, size_offset, vector_offset, imagedata_offset,
311 if (huffman_offset >= s->
size ||
312 size_offset >= s->
size ||
313 vector_offset >= s->
size ||
314 imagedata_offset >= s->
size)
317 huffman_segment = s->
buf + huffman_offset;
318 size_segment = s->
buf + size_offset;
319 vector_segment = s->
buf + vector_offset;
320 imagedata_segment = s->
buf + imagedata_offset;
323 huffman_segment, s->
size - huffman_offset) < 0)
326 if (imagedata_segment[0] == 2) {
328 &imagedata_segment[1], s->
size - imagedata_offset - 1);
331 imagedata_size = s->
size - imagedata_offset - 1;
332 imagedata_buffer = &imagedata_segment[1];
337 while (total_pixels && opcode_buffer < opcode_buffer_end) {
339 opcode = *opcode_buffer++;
366 size += (opcode - 10);
371 if (buf_end - size_segment < 1) {
375 size = *size_segment++;
380 if (buf_end - size_segment < 2) {
384 size =
AV_RB16(&size_segment[0]);
390 if (buf_end - size_segment < 3) {
399 if (size > total_pixels)
409 if (imagedata_size < size)
412 imagedata_buffer +=
size;
413 imagedata_size -=
size;
416 if (vector_segment >= buf_end) {
432 total_pixels -=
size;
433 y += (x +
size) / width;
434 x = (x +
size) % width;
440 static inline unsigned mul(
unsigned a,
unsigned b)
442 return (a * b) >> 16;
445 static inline unsigned pow4(
unsigned a)
447 unsigned square = mul(a, a);
448 return mul(square, square);
451 static inline unsigned pow5(
unsigned a)
453 return mul(pow4(a), a);
457 unsigned lo, hi = 0xff40, target;
459 in = (in << 2) | (in >> 6);
465 lo = target = in << 8;
467 unsigned mid = (lo + hi) >> 1;
468 unsigned pow = pow5(mid);
469 if (pow > target) hi = mid;
472 return (pow4((lo + hi) >> 1) + 0x80) >> 8;
487 0x00, 0x09, 0x10, 0x16, 0x1C, 0x21, 0x27, 0x2C,
488 0x31, 0x35, 0x3A, 0x3F, 0x43, 0x48, 0x4C, 0x50,
489 0x54, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D, 0x71,
490 0x75, 0x79, 0x7D, 0x80, 0x84, 0x88, 0x8C, 0x8F,
491 0x93, 0x97, 0x9A, 0x9E, 0xA2, 0xA5, 0xA9, 0xAC,
492 0xB0, 0xB3, 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8,
493 0xCB, 0xCF, 0xD2, 0xD5, 0xD9, 0xDC, 0xDF, 0xE3,
494 0xE6, 0xE9, 0xED, 0xF0, 0xF3, 0xF6, 0xFA, 0xFD,
495 0x03, 0x0B, 0x12, 0x18, 0x1D, 0x23, 0x28, 0x2D,
496 0x32, 0x36, 0x3B, 0x40, 0x44, 0x49, 0x4D, 0x51,
497 0x56, 0x5A, 0x5E, 0x62, 0x66, 0x6A, 0x6E, 0x72,
498 0x76, 0x7A, 0x7D, 0x81, 0x85, 0x89, 0x8D, 0x90,
499 0x94, 0x98, 0x9B, 0x9F, 0xA2, 0xA6, 0xAA, 0xAD,
500 0xB1, 0xB4, 0xB8, 0xBB, 0xBF, 0xC2, 0xC5, 0xC9,
501 0xCC, 0xD0, 0xD3, 0xD6, 0xDA, 0xDD, 0xE0, 0xE4,
502 0xE7, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xFA, 0xFD,
503 0x05, 0x0D, 0x13, 0x19, 0x1F, 0x24, 0x29, 0x2E,
504 0x33, 0x38, 0x3C, 0x41, 0x45, 0x4A, 0x4E, 0x52,
505 0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73,
506 0x77, 0x7B, 0x7E, 0x82, 0x86, 0x8A, 0x8D, 0x91,
507 0x95, 0x99, 0x9C, 0xA0, 0xA3, 0xA7, 0xAA, 0xAE,
508 0xB2, 0xB5, 0xB9, 0xBC, 0xBF, 0xC3, 0xC6, 0xCA,
509 0xCD, 0xD0, 0xD4, 0xD7, 0xDA, 0xDE, 0xE1, 0xE4,
510 0xE8, 0xEB, 0xEE, 0xF1, 0xF5, 0xF8, 0xFB, 0xFD,
511 0x07, 0x0E, 0x15, 0x1A, 0x20, 0x25, 0x2A, 0x2F,
512 0x34, 0x39, 0x3D, 0x42, 0x46, 0x4B, 0x4F, 0x53,
513 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74,
514 0x78, 0x7C, 0x7F, 0x83, 0x87, 0x8B, 0x8E, 0x92,
515 0x96, 0x99, 0x9D, 0xA1, 0xA4, 0xA8, 0xAB, 0xAF,
516 0xB2, 0xB6, 0xB9, 0xBD, 0xC0, 0xC4, 0xC7, 0xCB,
517 0xCE, 0xD1, 0xD5, 0xD8, 0xDB, 0xDF, 0xE2, 0xE5,
518 0xE9, 0xEC, 0xEF, 0xF2, 0xF6, 0xF9, 0xFC, 0xFD
523 void *
data,
int *got_frame,
527 int ret, buf_size = avpkt->
size;
538 tag = bytestream2_get_le32(&ctx);
539 size = bytestream2_get_be32(&ctx);
559 int r = gamma_corr(bytestream2_get_byteu(&ctx));
560 int g = gamma_corr(bytestream2_get_byteu(&ctx));
561 int b = gamma_corr(bytestream2_get_byteu(&ctx));
563 int r = gamma_lookup[bytestream2_get_byteu(&ctx)];
564 int g = gamma_lookup[bytestream2_get_byteu(&ctx)];
565 int b = gamma_lookup[bytestream2_get_byteu(&ctx)];
567 *tmpptr++ = (0xFF
U << 24) | (r << 16) | (g << 8) | b;
574 new_pal = bytestream2_get_le32(&ctx);
575 if (new_pal < s->palettes_count) {