|
|
|
@ -152,9 +152,10 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest, |
|
|
|
|
int src_count, int src_size, int dest_len) |
|
|
|
|
{ |
|
|
|
|
unsigned char *pd; |
|
|
|
|
int i, l; |
|
|
|
|
int i, l, used = 0; |
|
|
|
|
unsigned char *dest_end = dest + dest_len; |
|
|
|
|
GetByteContext gb; |
|
|
|
|
uint16_t run_val; |
|
|
|
|
|
|
|
|
|
bytestream2_init(&gb, src, src_size); |
|
|
|
|
pd = dest; |
|
|
|
@ -162,10 +163,9 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest, |
|
|
|
|
if (bytestream2_get_bytes_left(&gb) < 1) |
|
|
|
|
return 0; |
|
|
|
|
*pd++ = bytestream2_get_byteu(&gb); |
|
|
|
|
used++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
src_count >>= 1; |
|
|
|
|
i = 0; |
|
|
|
|
do { |
|
|
|
|
if (bytestream2_get_bytes_left(&gb) < 1) |
|
|
|
|
break; |
|
|
|
@ -177,16 +177,17 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest, |
|
|
|
|
bytestream2_get_buffer(&gb, pd, l); |
|
|
|
|
pd += l; |
|
|
|
|
} else { |
|
|
|
|
if (pd + i > dest_end || bytestream2_get_bytes_left(&gb) < 2) |
|
|
|
|
if (pd + l > dest_end || bytestream2_get_bytes_left(&gb) < 2) |
|
|
|
|
return bytestream2_tell(&gb); |
|
|
|
|
run_val = bytestream2_get_ne16(&gb); |
|
|
|
|
for (i = 0; i < l; i++) { |
|
|
|
|
*pd++ = bytestream2_get_byteu(&gb); |
|
|
|
|
*pd++ = bytestream2_get_byteu(&gb); |
|
|
|
|
AV_WN16(pd, run_val); |
|
|
|
|
pd += 2; |
|
|
|
|
} |
|
|
|
|
bytestream2_skip(&gb, 2); |
|
|
|
|
l *= 2; |
|
|
|
|
} |
|
|
|
|
i += l; |
|
|
|
|
} while (i < src_count); |
|
|
|
|
used += l; |
|
|
|
|
} while (used < src_count); |
|
|
|
|
|
|
|
|
|
return bytestream2_tell(&gb); |
|
|
|
|
} |
|
|
|
@ -332,13 +333,18 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) |
|
|
|
|
len = bytestream2_get_byte(&gb); |
|
|
|
|
if (len & 0x80) { |
|
|
|
|
len = (len & 0x7F) + 1; |
|
|
|
|
if (bytestream2_get_byte(&gb) == 0xFF) |
|
|
|
|
if (bytestream2_peek_byte(&gb) == 0xFF) { |
|
|
|
|
int slen = len; |
|
|
|
|
bytestream2_get_byte(&gb); |
|
|
|
|
len = rle_unpack(gb.buffer, &dp[ofs], |
|
|
|
|
len, bytestream2_get_bytes_left(&gb), |
|
|
|
|
frame_width - ofs); |
|
|
|
|
else |
|
|
|
|
ofs += slen; |
|
|
|
|
bytestream2_skip(&gb, len); |
|
|
|
|
} else { |
|
|
|
|
bytestream2_get_buffer(&gb, &dp[ofs], len); |
|
|
|
|
bytestream2_skip(&gb, len); |
|
|
|
|
ofs += len; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
/* interframe pixel copy */ |
|
|
|
|
if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) |
|
|
|
|