@ -452,15 +452,16 @@ static int qtrle_decode_frame(AVCodecContext *avctx,
int header , start_line ;
int height , row_ptr ;
int has_palette = 0 ;
int duplicate = 0 ;
int ret , size ;
bytestream2_init ( & s - > g , avpkt - > data , avpkt - > size ) ;
if ( ( ret = ff_reget_buffer ( avctx , s - > frame ) ) < 0 )
return ret ;
/* check if this frame is even supposed to change */
if ( avpkt - > size < 8 )
if ( avpkt - > size < 8 ) {
duplicate = 1 ;
goto done ;
}
/* start after the chunk size */
size = bytestream2_get_be32 ( & s - > g ) & 0x3FFFFFFF ;
@ -473,18 +474,25 @@ static int qtrle_decode_frame(AVCodecContext *avctx,
/* if a header is present, fetch additional decoding parameters */
if ( header & 0x0008 ) {
if ( avpkt - > size < 14 )
if ( avpkt - > size < 14 ) {
duplicate = 1 ;
goto done ;
}
start_line = bytestream2_get_be16 ( & s - > g ) ;
bytestream2_skip ( & s - > g , 2 ) ;
height = bytestream2_get_be16 ( & s - > g ) ;
bytestream2_skip ( & s - > g , 2 ) ;
if ( height > s - > avctx - > height - start_line )
if ( height > s - > avctx - > height - start_line ) {
duplicate = 1 ;
goto done ;
}
} else {
start_line = 0 ;
height = s - > avctx - > height ;
}
if ( ( ret = ff_reget_buffer ( avctx , s - > frame ) ) < 0 )
return ret ;
row_ptr = s - > frame - > linesize [ 0 ] * start_line ;
switch ( avctx - > bits_per_coded_sample ) {
@ -546,6 +554,16 @@ static int qtrle_decode_frame(AVCodecContext *avctx,
}
done :
if ( ! s - > frame - > data [ 0 ] )
return AVERROR_INVALIDDATA ;
if ( duplicate ) {
// ff_reget_buffer() isn't needed when frames don't change, so just update
// frame props.
ret = ff_decode_frame_props ( avctx , s - > frame ) ;
if ( ret < 0 )
return ret ;
}
if ( ( ret = av_frame_ref ( data , s - > frame ) ) < 0 )
return ret ;
* got_frame = 1 ;