@ -63,11 +63,10 @@ typedef struct FlashSVContext {
AVBufferRef * keyframedata_buf ;
uint8_t * keyframe ;
BlockInfo * blocks ;
uint8_t * deflate_block ;
int deflate_block_size ;
int color_depth ;
int zlibprime_curr , zlibprime_prev ;
int diff_start , diff_height ;
uint8_t tmp [ UINT16_MAX ] ;
} FlashSVContext ;
static int decode_hybrid ( const uint8_t * sptr , const uint8_t * sptr_end , uint8_t * dptr , int dx , int dy ,
@ -141,41 +140,59 @@ static av_cold int flashsv_decode_init(AVCodecContext *avctx)
static int flashsv2_prime ( FlashSVContext * s , const uint8_t * src , int size )
{
z_stream zs ;
int zret ; // Zlib return code
static const uint8_t zlib_header [ ] = { 0x78 , 0x01 } ;
uint8_t * data = s - > tmpblock ;
unsigned remaining ;
if ( ! src )
return AVERROR_INVALIDDATA ;
zs . zalloc = NULL ;
zs . zfree = NULL ;
zs . opaque = NULL ;
s - > zstream . next_in = src ;
s - > zstream . avail_in = size ;
s - > zstream . next_out = s - > tmpblock ;
s - > zstream . next_out = data ;
s - > zstream . avail_out = s - > block_size * 3 ;
inflate ( & s - > zstream , Z_SYNC_FLUSH ) ;
if ( deflateInit ( & zs , 0 ) ! = Z_OK )
return - 1 ;
zs . next_in = s - > tmpblock ;
zs . avail_in = s - > block_size * 3 - s - > zstream . avail_out ;
zs . next_out = s - > deflate_block ;
zs . avail_out = s - > deflate_block_size ;
deflate ( & zs , Z_SYNC_FLUSH ) ;
deflateEnd ( & zs ) ;
remaining = s - > block_size * 3 - s - > zstream . avail_out ;
if ( ( zret = inflateReset ( & s - > zstream ) ) ! = Z_OK ) {
av_log ( s - > avctx , AV_LOG_ERROR , " Inflate reset error: %d \n " , zret ) ;
return AVERROR_UNKNOWN ;
}
s - > zstream . next_in = s - > deflate_block ;
s - > zstream . avail_in = s - > deflate_block_size - zs . avail_out ;
s - > zstream . next_out = s - > tmpblock ;
s - > zstream . avail_out = s - > block_size * 3 ;
/* Create input for zlib that is equivalent to encoding the output
* from above and decoding it again ( the net result of this is that
* the dictionary of past decoded data is correctly primed and
* the adler32 checksum is correctly initialized ) .
* This is accomplished by synthetizing blocks of uncompressed data
* out of the output from above . See section 3.2 .4 of RFC 1951. */
s - > zstream . next_in = zlib_header ;
s - > zstream . avail_in = sizeof ( zlib_header ) ;
inflate ( & s - > zstream , Z_SYNC_FLUSH ) ;
while ( remaining > 0 ) {
unsigned block_size = FFMIN ( UINT16_MAX , remaining ) ;
uint8_t header [ 5 ] ;
/* Bit 0: Non-last-block, bits 1-2: BTYPE for uncompressed block */
header [ 0 ] = 0 ;
/* Block size */
AV_WL16 ( header + 1 , block_size ) ;
/* Block size (one's complement) */
AV_WL16 ( header + 3 , block_size ^ 0xFFFF ) ;
s - > zstream . next_in = header ;
s - > zstream . avail_in = sizeof ( header ) ;
s - > zstream . next_out = s - > tmp ;
s - > zstream . avail_out = sizeof ( s - > tmp ) ;
zret = inflate ( & s - > zstream , Z_SYNC_FLUSH ) ;
if ( zret ! = Z_OK )
return AVERROR_UNKNOWN ;
s - > zstream . next_in = data ;
s - > zstream . avail_in = block_size ;
zret = inflate ( & s - > zstream , Z_SYNC_FLUSH ) ;
if ( zret ! = Z_OK )
return AVERROR_UNKNOWN ;
data + = block_size ;
remaining - = block_size ;
}
return 0 ;
}
@ -248,22 +265,6 @@ static int flashsv_decode_block(AVCodecContext *avctx, const AVPacket *avpkt,
return 0 ;
}
static int calc_deflate_block_size ( int tmpblock_size )
{
z_stream zstream ;
int size ;
zstream . zalloc = Z_NULL ;
zstream . zfree = Z_NULL ;
zstream . opaque = Z_NULL ;
if ( deflateInit ( & zstream , 0 ) ! = Z_OK )
return - 1 ;
size = deflateBound ( & zstream , tmpblock_size ) ;
deflateEnd ( & zstream ) ;
return size ;
}
static int flashsv_decode_frame ( AVCodecContext * avctx , void * data ,
int * got_frame , AVPacket * avpkt )
{
@ -322,19 +323,6 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
" Cannot allocate decompression buffer. \n " ) ;
return err ;
}
if ( s - > ver = = 2 ) {
s - > deflate_block_size = calc_deflate_block_size ( tmpblock_size ) ;
if ( s - > deflate_block_size < = 0 ) {
av_log ( avctx , AV_LOG_ERROR ,
" Cannot determine deflate buffer size. \n " ) ;
return - 1 ;
}
if ( ( err = av_reallocp ( & s - > deflate_block , s - > deflate_block_size ) ) < 0 ) {
s - > block_size = 0 ;
av_log ( avctx , AV_LOG_ERROR , " Cannot allocate deflate buffer. \n " ) ;
return err ;
}
}
}
s - > block_size = s - > block_width * s - > block_height ;
@ -570,7 +558,6 @@ static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
av_buffer_unref ( & s - > keyframedata_buf ) ;
av_freep ( & s - > blocks ) ;
av_freep ( & s - > keyframe ) ;
av_freep ( & s - > deflate_block ) ;
flashsv_decode_end ( avctx ) ;
return 0 ;