From 120ba3289c026778f2db036292d1f9a669dbb372 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 7 Oct 2019 12:11:45 +0100 Subject: [PATCH] fix up png restart hopefully ... we needed a png_init_io() as well --- libvips/foreign/vipspng.c | 5 ++- libvips/foreign/webp2vips.c | 83 ++++++++++++++++++++++--------------- test/test_descriptors.sh | 4 ++ 3 files changed, 57 insertions(+), 35 deletions(-) diff --git a/libvips/foreign/vipspng.c b/libvips/foreign/vipspng.c index 0d63b71f..6d5cca88 100644 --- a/libvips/foreign/vipspng.c +++ b/libvips/foreign/vipspng.c @@ -208,6 +208,10 @@ read_open_input( Read *read ) return( -1 ); if( read->seek_position != -1 ) fseek( read->fp, read->seek_position, SEEK_SET ); + + /* Just takes a copy of the fp. + */ + png_init_io( read->pPng, read->fp ); } return( 0 ); @@ -324,7 +328,6 @@ read_new_filename( VipsImage *out, const char *name, gboolean fail ) return( NULL ); } - png_init_io( read->pPng, read->fp ); read_info( read ); return( read ); diff --git a/libvips/foreign/webp2vips.c b/libvips/foreign/webp2vips.c index 90bf3a04..f9d60aa5 100644 --- a/libvips/foreign/webp2vips.c +++ b/libvips/foreign/webp2vips.c @@ -343,29 +343,52 @@ vips__iswebp( const char *filename ) return( 0 ); } -static void -read_minimise( Read *read ) +static int +read_mmap( Read *read ) { - WebPDemuxReleaseIterator( &read->iter ); - VIPS_UNREF( read->frame ); - VIPS_FREEF( WebPDemuxDelete, read->demux ); - WebPFreeDecBuffer( &read->config.output ); - - if( read->fd > 0 && - read->data && - read->length > 0 ) { - vips__munmap( read->data, read->length ); - read->data = NULL; - read->length = 0; + if( read->filename && + read->fd < 0 ) { + if( (read->fd = vips__open_image_read( read->filename )) < 0 ) + return( -1 ); + if( read->length < 0 && + (read->length = vips_file_length( read->fd )) < 0 ) + return( -1 ); + if( !(read->data = + vips__mmap( read->fd, FALSE, read->length, 0 )) ) { + return( -1 ); + } } - VIPS_FREEF( vips_tracked_close, read->fd ); + return( 0 ); +} + +static void +read_munmap( Read *read ) +{ + if( read->fd >= 0 ) { + if( read->data && + read->length > 0 ) { + vips__munmap( read->data, read->length ); + read->data = NULL; + read->length = 0; + } + + if( read->fd >= 0 ) { + vips_tracked_close( read->fd ); + read->fd = -1; + } + } } static int read_free( Read *read ) { - read_minimise( read ); + read_munmap( read ); + + WebPDemuxReleaseIterator( &read->iter ); + VIPS_UNREF( read->frame ); + VIPS_FREEF( WebPDemuxDelete, read->demux ); + WebPFreeDecBuffer( &read->config.output ); VIPS_FREE( read->filename ); VIPS_FREE( read->delays ); @@ -383,33 +406,22 @@ read_new( const char *filename, const void *data, size_t length, if( !(read = VIPS_NEW( NULL, Read )) ) return( NULL ); - read->filename = g_strdup( filename ); + if( filename ) + read->filename = g_strdup( filename ); read->data = data; read->length = length; read->page = page; read->n = n; read->scale = scale; read->delays = NULL; - read->fd = 0; + read->fd = -1; read->demux = NULL; read->frame = NULL; read->dispose_method = WEBP_MUX_DISPOSE_NONE; read->frame_no = 0; - if( read->filename ) { - /* libwebp makes streaming from a file source very hard. We - * have to read to a full memory buffer, then copy to out. - * - * mmap the input file, it's slightly quicker. - */ - if( (read->fd = vips__open_image_read( read->filename )) < 0 || - (read->length = vips_file_length( read->fd )) < 0 || - !(read->data = vips__mmap( read->fd, - FALSE, read->length, 0 )) ) { - read_free( read ); - return( NULL ); - } - } + if( read_mmap( read ) ) + return( NULL ); WebPInitDecoderConfig( &read->config ); read->config.options.use_threads = 1; @@ -605,7 +617,7 @@ vips__webp_read_file_header( const char *filename, VipsImage *out, { Read *read; - if( !(read = read_new( filename, NULL, 0, page, n, scale )) ) { + if( !(read = read_new( filename, NULL, -1, page, n, scale )) ) { vips_error( "webp2vips", _( "unable to open \"%s\"" ), filename ); return( -1 ); @@ -769,6 +781,9 @@ read_webp_generate( VipsRegion *or, g_assert( r->height == 1 ); + if( read_mmap( read ) ) + return( -1 ); + while( read->frame_no < frame ) { if( read_next_frame( read ) ) return( -1 ); @@ -806,7 +821,7 @@ read_webp_generate( VipsRegion *or, static void read_minimise_cb( VipsObject *object, Read *read ) { - read_minimise( read ); + read_munmap( read ); } static int @@ -837,7 +852,7 @@ vips__webp_read_file( const char *filename, VipsImage *out, { Read *read; - if( !(read = read_new( filename, NULL, 0, page, n, scale )) ) { + if( !(read = read_new( filename, NULL, -1, page, n, scale )) ) { vips_error( "webp2vips", _( "unable to open \"%s\"" ), filename ); return( -1 ); diff --git a/test/test_descriptors.sh b/test/test_descriptors.sh index 4ce21404..0d644949 100755 --- a/test/test_descriptors.sh +++ b/test/test_descriptors.sh @@ -26,3 +26,7 @@ fi if test_supported pngload; then ./test_descriptors $test_images/sample.png fi + +if test_supported webpload; then + ./test_descriptors $test_images/1.webp +fi