@ -300,10 +300,9 @@ static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame)
/* pointers to segments inside the compressed chunk */
const uint8_t * huffman_segment ;
const uint8_t * size_segment ;
const uint8_t * vector_segment ;
GetByteContext size_segment ;
GetByteContext vector_segment ;
const uint8_t * imagedata_segment ;
const uint8_t * buf_end = s - > buf + s - > size ;
int huffman_offset , size_offset , vector_offset , imagedata_offset ,
imagedata_size ;
@ -322,8 +321,8 @@ static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame)
return AVERROR_INVALIDDATA ;
huffman_segment = s - > buf + huffman_offset ;
size_segment = s - > buf + size_offset ;
vector_segment = s - > buf + vector_offset ;
bytestream2_init ( & size_segment , s - > buf + size_offset , s - > size - size_offset ) ;
bytestream2_init ( & vector_segment , s - > buf + vector_offset , s - > size - vector_offset ) ;
imagedata_segment = s - > buf + imagedata_offset ;
if ( xan_huffman_decode ( opcode_buffer , opcode_buffer_size ,
@ -375,31 +374,29 @@ static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame)
case 9 :
case 19 :
if ( buf_end - size_segment < 1 ) {
if ( bytestream2_get_bytes_left ( & size_segment ) < 1 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " size_segment overread \n " ) ;
return AVERROR_INVALIDDATA ;
}
size = * size_segment + + ;
size = bytestream2_get_byte ( & size_segment ) ;
break ;
case 10 :
case 20 :
if ( buf_end - size_segment < 2 ) {
if ( bytestream2_get_bytes_left ( & size_segment ) < 2 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " size_segment overread \n " ) ;
return AVERROR_INVALIDDATA ;
}
size = AV_RB16 ( & size_segment [ 0 ] ) ;
size_segment + = 2 ;
size = bytestream2_get_be16 ( & size_segment ) ;
break ;
case 11 :
case 21 :
if ( buf_end - size_segment < 3 ) {
if ( bytestream2_get_bytes_left ( & size_segment ) < 3 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " size_segment overread \n " ) ;
return AVERROR_INVALIDDATA ;
}
size = AV_RB24 ( size_segment ) ;
size_segment + = 3 ;
size = bytestream2_get_be24 ( & size_segment ) ;
break ;
}
@ -420,14 +417,15 @@ static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame)
imagedata_size - = size ;
}
} else {
if ( vector_segment > = buf_end ) {
uint8_t vector ;
if ( bytestream2_get_bytes_left ( & vector_segment ) < = 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " vector_segment overread \n " ) ;
return AVERROR_INVALIDDATA ;
}
/* run-based motion compensation from last frame */
motion_x = sign_extend ( * vector_segment > > 4 , 4 ) ;
motion_y = sign_extend ( * vector_segment & 0xF , 4 ) ;
vector_segment + + ;
vector = bytestream2_get_byte ( & vector_segment ) ;
motion_x = sign_extend ( vector > > 4 , 4 ) ;
motion_y = sign_extend ( vector & 0xF , 4 ) ;
/* copy a run of pixels from the previous frame */
xan_wc3_copy_pixel_run ( s , frame , x , y , size , motion_x , motion_y ) ;