fix vips7 webp load

webp load using the vips7 interface was crashing, thanks barryspearce

see https://github.com/libvips/libvips/issues/1860
This commit is contained in:
John Cupitt 2020-10-19 14:34:02 +01:00
parent b1e636346a
commit 0131d4d3eb
3 changed files with 26 additions and 25 deletions

View File

@ -1,5 +1,6 @@
18/10/20 started 8.10.3
- relax heic is_a rules [hisham]
- fix vips7 webp load [barryspearce]
6/9/20 started 8.10.2
- update magicksave/load profile handling [kelilevi]

View File

@ -81,6 +81,7 @@
/* What we track during a read.
*/
typedef struct {
VipsImage *out;
VipsSource *source;
/* The data we load, as a webp object.
@ -340,14 +341,21 @@ read_free( Read *read )
return( 0 );
}
static void
read_close_cb( VipsImage *image, Read *read )
{
read_free( read );
}
static Read *
read_new( VipsSource *source, int page, int n, double scale )
read_new( VipsImage *out, VipsSource *source, int page, int n, double scale )
{
Read *read;
if( !(read = VIPS_NEW( NULL, Read )) )
return( NULL );
read->out = out;
read->source = source;
g_object_ref( source );
read->page = page;
@ -359,15 +367,19 @@ read_new( VipsSource *source, int page, int n, double scale )
read->dispose_method = WEBP_MUX_DISPOSE_NONE;
read->frame_no = 0;
/* Everything has to stay open until read has finished, unfortunately,
* since webp relies on us mapping the whole file.
*/
g_signal_connect( out, "close",
G_CALLBACK( read_close_cb ), read );
WebPInitDecoderConfig( &read->config );
read->config.options.use_threads = 1;
read->config.output.is_external_memory = 1;
if( !(read->data.bytes =
vips_source_map( source, &read->data.size )) ) {
read_free( read );
vips_source_map( source, &read->data.size )) )
return( NULL );
}
return( read );
}
@ -774,16 +786,10 @@ vips__webp_read_header_source( VipsSource *source, VipsImage *out,
{
Read *read;
if( !(read = read_new( source, page, n, scale )) )
if( !(read = read_new( out, source, page, n, scale )) ||
read_header( read, out ) )
return( -1 );
if( read_header( read, out ) ) {
read_free( read );
return( -1 );
}
read_free( read );
return( 0 );
}
@ -793,16 +799,10 @@ vips__webp_read_source( VipsSource *source, VipsImage *out,
{
Read *read;
if( !(read = read_new( source, page, n, scale )) )
if( !(read = read_new( out, source, page, n, scale )) ||
read_image( read, out ) )
return( -1 );
if( read_image( read, out ) ) {
read_free( read );
return( -1 );
}
read_free( read );
return( 0 );
}

View File

@ -260,6 +260,8 @@ vips_source_finalize( GObject *gobject )
{
VipsSource *source = VIPS_SOURCE( gobject );
VIPS_DEBUG_MSG( "vips_source_finalize: %p\n", source );
VIPS_FREEF( g_byte_array_unref, source->header_bytes );
VIPS_FREEF( g_byte_array_unref, source->sniff );
if( source->mmap_baseaddr ) {
@ -555,8 +557,6 @@ vips_source_minimise( VipsSource *source )
{
VipsConnection *connection = VIPS_CONNECTION( source );
VIPS_DEBUG_MSG( "vips_source_minimise:\n" );
SANITY( source );
(void) vips_source_test_features( source );
@ -565,7 +565,7 @@ vips_source_minimise( VipsSource *source )
connection->descriptor != -1 &&
connection->tracked_descriptor == connection->descriptor &&
!source->is_pipe ) {
VIPS_DEBUG_MSG( " tracked_close()\n" );
VIPS_DEBUG_MSG( "vips_source_minimise:\n" );
vips_tracked_close( connection->tracked_descriptor );
connection->tracked_descriptor = -1;
connection->descriptor = -1;
@ -590,13 +590,13 @@ vips_source_unminimise( VipsSource *source )
{
VipsConnection *connection = VIPS_CONNECTION( source );
VIPS_DEBUG_MSG( "vips_source_unminimise:\n" );
if( connection->descriptor == -1 &&
connection->tracked_descriptor == -1 &&
connection->filename ) {
int fd;
VIPS_DEBUG_MSG( "vips_source_unminimise: %p\n", source );
if( (fd = vips_tracked_open( connection->filename,
MODE_READ, 0 )) == -1 ) {
vips_error_system( errno,