@ -44,6 +44,7 @@
# include "bytestream.h"
# include "get_bits.h"
# include "internal.h"
# include "zlib_wrapper.h"
typedef struct BlockInfo {
const uint8_t * pos ;
@ -57,7 +58,6 @@ typedef struct FlashSVContext {
int block_width , block_height ;
uint8_t * tmpblock ;
int block_size ;
z_stream zstream ;
int ver ;
const uint32_t * pal ;
int is_keyframe ;
@ -68,6 +68,7 @@ typedef struct FlashSVContext {
int color_depth ;
int zlibprime_curr , zlibprime_prev ;
int diff_start , diff_height ;
FFZStream zstream ;
uint8_t tmp [ UINT16_MAX ] ;
} FlashSVContext ;
@ -106,7 +107,8 @@ static int decode_hybrid(const uint8_t *sptr, const uint8_t *sptr_end, uint8_t *
static av_cold int flashsv_decode_end ( AVCodecContext * avctx )
{
FlashSVContext * s = avctx - > priv_data ;
inflateEnd ( & s - > zstream ) ;
ff_inflate_end ( & s - > zstream ) ;
/* release the frame if needed */
av_frame_free ( & s - > frame ) ;
@ -119,17 +121,8 @@ static av_cold int flashsv_decode_end(AVCodecContext *avctx)
static av_cold int flashsv_decode_init ( AVCodecContext * avctx )
{
FlashSVContext * s = avctx - > priv_data ;
int zret ; // Zlib return code
s - > avctx = avctx ;
s - > zstream . zalloc = Z_NULL ;
s - > zstream . zfree = Z_NULL ;
s - > zstream . opaque = Z_NULL ;
zret = inflateInit ( & s - > zstream ) ;
if ( zret ! = Z_OK ) {
av_log ( avctx , AV_LOG_ERROR , " Inflate init error: %d \n " , zret ) ;
return AVERROR_EXTERNAL ;
}
avctx - > pix_fmt = AV_PIX_FMT_BGR24 ;
s - > frame = av_frame_alloc ( ) ;
@ -137,27 +130,28 @@ static av_cold int flashsv_decode_init(AVCodecContext *avctx)
return AVERROR ( ENOMEM ) ;
}
return 0 ;
return ff_inflate_init ( & s - > zstream , avctx ) ;
}
static int flashsv2_prime ( FlashSVContext * s , const uint8_t * src , int size )
{
int zret ; // Zlib return code
static const uint8_t zlib_header [ ] = { 0x78 , 0x01 } ;
z_stream * const zstream = & s - > zstream . zstream ;
uint8_t * data = s - > tmpblock ;
unsigned remaining ;
if ( ! src )
return AVERROR_INVALIDDATA ;
s - > zstream . next_in = src ;
s - > zstream . avail_in = size ;
s - > zstream . next_out = data ;
s - > zstream . avail_out = s - > block_size * 3 ;
inflate ( & s - > zstream , Z_SYNC_FLUSH ) ;
remaining = s - > block_size * 3 - s - > zstream . avail_out ;
z stream - > next_in = src ;
z stream - > avail_in = size ;
z stream - > next_out = data ;
z stream - > avail_out = s - > block_size * 3 ;
inflate ( zstream , Z_SYNC_FLUSH ) ;
remaining = s - > block_size * 3 - z stream - > avail_out ;
if ( ( zret = inflateReset ( & s - > zstream ) ) ! = Z_OK ) {
if ( ( zret = inflateReset ( zstream ) ) ! = Z_OK ) {
av_log ( s - > avctx , AV_LOG_ERROR , " Inflate reset error: %d \n " , zret ) ;
return AVERROR_UNKNOWN ;
}
@ -168,9 +162,9 @@ static int flashsv2_prime(FlashSVContext *s, const uint8_t *src, int size)
* 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 ) ;
z stream - > next_in = zlib_header ;
z stream - > avail_in = sizeof ( zlib_header ) ;
inflate ( zstream , Z_SYNC_FLUSH ) ;
while ( remaining > 0 ) {
unsigned block_size = FFMIN ( UINT16_MAX , remaining ) ;
uint8_t header [ 5 ] ;
@ -180,16 +174,16 @@ static int flashsv2_prime(FlashSVContext *s, const uint8_t *src, int 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 ) ;
z stream - > next_in = header ;
z stream - > avail_in = sizeof ( header ) ;
z stream - > next_out = s - > tmp ;
z stream - > avail_out = sizeof ( s - > tmp ) ;
zret = inflate ( 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 ) ;
z stream - > next_in = data ;
z stream - > avail_in = block_size ;
zret = inflate ( zstream , Z_SYNC_FLUSH ) ;
if ( zret ! = Z_OK )
return AVERROR_UNKNOWN ;
data + = block_size ;
@ -205,9 +199,10 @@ static int flashsv_decode_block(AVCodecContext *avctx, const AVPacket *avpkt,
int blk_idx )
{
struct FlashSVContext * s = avctx - > priv_data ;
z_stream * const zstream = & s - > zstream . zstream ;
uint8_t * line = s - > tmpblock ;
int k ;
int ret = inflateReset ( & s - > zstream ) ;
int ret = inflateReset ( zstream ) ;
if ( ret ! = Z_OK ) {
av_log ( avctx , AV_LOG_ERROR , " Inflate reset error: %d \n " , ret ) ;
return AVERROR_UNKNOWN ;
@ -219,15 +214,15 @@ static int flashsv_decode_block(AVCodecContext *avctx, const AVPacket *avpkt,
if ( ret < 0 )
return ret ;
}
s - > zstream . next_in = avpkt - > data + get_bits_count ( gb ) / 8 ;
s - > zstream . avail_in = block_size ;
s - > zstream . next_out = s - > tmpblock ;
s - > zstream . avail_out = s - > block_size * 3 ;
ret = inflate ( & s - > zstream , Z_FINISH ) ;
z stream - > next_in = avpkt - > data + get_bits_count ( gb ) / 8 ;
z stream - > avail_in = block_size ;
z stream - > next_out = s - > tmpblock ;
z stream - > avail_out = s - > block_size * 3 ;
ret = inflate ( zstream , Z_FINISH ) ;
if ( ret = = Z_DATA_ERROR ) {
av_log ( avctx , AV_LOG_ERROR , " Zlib resync occurred \n " ) ;
inflateSync ( & s - > zstream ) ;
ret = inflate ( & s - > zstream , Z_FINISH ) ;
inflateSync ( zstream ) ;
ret = inflate ( zstream , Z_FINISH ) ;
}
if ( ret ! = Z_OK & & ret ! = Z_STREAM_END ) {
@ -253,7 +248,7 @@ static int flashsv_decode_block(AVCodecContext *avctx, const AVPacket *avpkt,
}
} else {
/* hybrid 15-bit/palette mode */
ret = decode_hybrid ( s - > tmpblock , s - > zstream . next_out ,
ret = decode_hybrid ( s - > tmpblock , z stream - > next_out ,
s - > frame - > data [ 0 ] ,
s - > image_height - ( y_pos + 1 + s - > diff_height ) ,
x_pos , s - > diff_height , width ,