|
|
|
@@ -76,7 +76,7 @@ typedef struct VmdVideoContext { |
|
|
|
#define QUEUE_SIZE 0x1000 |
|
|
|
#define QUEUE_MASK 0x0FFF |
|
|
|
|
|
|
|
static void lz_unpack(const unsigned char *src, int src_len, |
|
|
|
static int lz_unpack(const unsigned char *src, int src_len, |
|
|
|
unsigned char *dest, int dest_len) |
|
|
|
{ |
|
|
|
unsigned char *d; |
|
|
|
@@ -97,7 +97,7 @@ static void lz_unpack(const unsigned char *src, int src_len, |
|
|
|
dataleft = bytestream2_get_le32(&gb); |
|
|
|
memset(queue, 0x20, QUEUE_SIZE); |
|
|
|
if (bytestream2_get_bytes_left(&gb) < 4) |
|
|
|
return; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
if (bytestream2_peek_le32(&gb) == 0x56781234) { |
|
|
|
bytestream2_skipu(&gb, 4); |
|
|
|
qpos = 0x111; |
|
|
|
@@ -111,7 +111,7 @@ static void lz_unpack(const unsigned char *src, int src_len, |
|
|
|
tag = bytestream2_get_byteu(&gb); |
|
|
|
if ((tag == 0xFF) && (dataleft > 8)) { |
|
|
|
if (d_end - d < 8 || bytestream2_get_bytes_left(&gb) < 8) |
|
|
|
return; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
for (i = 0; i < 8; i++) { |
|
|
|
queue[qpos++] = *d++ = bytestream2_get_byteu(&gb); |
|
|
|
qpos &= QUEUE_MASK; |
|
|
|
@@ -123,7 +123,7 @@ static void lz_unpack(const unsigned char *src, int src_len, |
|
|
|
break; |
|
|
|
if (tag & 0x01) { |
|
|
|
if (d_end - d < 1 || bytestream2_get_bytes_left(&gb) < 1) |
|
|
|
return; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
queue[qpos++] = *d++ = bytestream2_get_byteu(&gb); |
|
|
|
qpos &= QUEUE_MASK; |
|
|
|
dataleft--; |
|
|
|
@@ -135,7 +135,7 @@ static void lz_unpack(const unsigned char *src, int src_len, |
|
|
|
chainlen = bytestream2_get_byte(&gb) + 0xF + 3; |
|
|
|
} |
|
|
|
if (d_end - d < chainlen) |
|
|
|
return; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
for (j = 0; j < chainlen; j++) { |
|
|
|
*d = queue[chainofs++ & QUEUE_MASK]; |
|
|
|
queue[qpos++] = *d++; |
|
|
|
@@ -147,6 +147,7 @@ static void lz_unpack(const unsigned char *src, int src_len, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return d - dest; |
|
|
|
} |
|
|
|
static int rle_unpack(const unsigned char *src, unsigned char *dest, |
|
|
|
int src_count, int src_size, int dest_len) |
|
|
|
@@ -279,15 +280,18 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
meth = bytestream2_get_byteu(&gb); |
|
|
|
if (meth & 0x80) { |
|
|
|
int size; |
|
|
|
if (!s->unpack_buffer_size) { |
|
|
|
av_log(s->avctx, AV_LOG_ERROR, |
|
|
|
"Trying to unpack LZ-compressed frame with no LZ buffer\n"); |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
} |
|
|
|
lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb), |
|
|
|
s->unpack_buffer, s->unpack_buffer_size); |
|
|
|
size = lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb), |
|
|
|
s->unpack_buffer, s->unpack_buffer_size); |
|
|
|
if (size < 0) |
|
|
|
return size; |
|
|
|
meth &= 0x7F; |
|
|
|
bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size); |
|
|
|
bytestream2_init(&gb, s->unpack_buffer, size); |
|
|
|
} |
|
|
|
|
|
|
|
dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x]; |
|
|
|
|