diff --git a/ChangeLog b/ChangeLog index 859045b4..e3d5dd3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 1/5/16 started 8.4 - many more wepsave options [Felix Bünemann] +- kick load operations from cache on read error 15/4/16 started 8.3.1 - rename vips wrapper script, it was still vips-8.2, thanks Benjamin diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index ead692d0..ebf23d66 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -791,6 +791,13 @@ vips_foreign_load_start( VipsImage *out, void *a, void *b ) */ load->real->progress_signal = load->out; + /* Note the load object on the image. Loaders can use + * this to signal invalidate if they hit a load error. See + * vips_foreign_load_invalidate() below. + */ + g_object_set_qdata( G_OBJECT( load->real ), + vips__foreign_load_operation, load ); + if( class->load( load ) || vips_image_pio_input( load->real ) ) return( NULL ); @@ -886,13 +893,6 @@ vips_foreign_load_build( VipsObject *object ) g_object_set( object, "out", vips_image_new(), NULL ); - /* Note the load object on the output image. Loaders can use this to - * signal invalidate if they hit a load error. See - * vips_foreign_load_invalidate() below. - */ - g_object_set_qdata( G_OBJECT( load->out ), - vips__foreign_load_operation, object ); - vips_image_set_string( load->out, VIPS_META_LOADER, class->nickname ); @@ -1036,6 +1036,10 @@ vips_foreign_load_invalidate( VipsImage *image ) { VipsOperation *operation; +#ifdef DEBUG + printf( "vips_foreign_load_invalidate: %p\n", image ); +#endif /*DEBUG*/ + if( (operation = g_object_get_qdata( G_OBJECT( image ), vips__foreign_load_operation )) ) { vips_operation_invalidate( operation ); diff --git a/libvips/foreign/jpeg2vips.c b/libvips/foreign/jpeg2vips.c index aad4cd6e..da134fbc 100644 --- a/libvips/foreign/jpeg2vips.c +++ b/libvips/foreign/jpeg2vips.c @@ -243,6 +243,11 @@ readjpeg_new( VipsImage *out, jpeg->y_pos = 0; jpeg->autorotate = autorotate; + /* This is used by the error handlers to signal invalidate on the + * output image. + */ + jpeg->cinfo.client_data = out; + /* jpeg_create_decompress() can fail on some sanity checks. Don't * readjpeg_free() since we don't want to jpeg_destroy_decompress(). */ @@ -959,14 +964,8 @@ read_jpeg_generate( VipsRegion *or, /* Here for longjmp() from vips__new_error_exit(). */ - if( setjmp( jpeg->eman.jmp ) ) { - /* Signal invalidate on our load operation to force it from - * cache. - */ - vips_foreign_load_invalidate( or->im ); - + if( setjmp( jpeg->eman.jmp ) ) return( -1 ); - } for( y = 0; y < r->height; y++ ) { JSAMPROW row_pointer[1]; diff --git a/libvips/foreign/vips2jpeg.c b/libvips/foreign/vips2jpeg.c index d714cfc9..dce1d3d7 100644 --- a/libvips/foreign/vips2jpeg.c +++ b/libvips/foreign/vips2jpeg.c @@ -104,8 +104,8 @@ */ /* -#define DEBUG #define VIPS_DEBUG +#define DEBUG */ #ifdef HAVE_CONFIG_H @@ -122,9 +122,6 @@ #include #include -#include -#include - #ifdef HAVE_EXIF #ifdef UNTAGGED_EXIF #include @@ -139,6 +136,10 @@ #endif /*UNTAGGED_EXIF*/ #endif /*HAVE_EXIF*/ +#include +#include +#include + #include "jpeg.h" #include "vipsjpeg.h" @@ -155,6 +156,12 @@ vips__new_output_message( j_common_ptr cinfo ) #ifdef DEBUG printf( "vips__new_output_message: \"%s\"\n", buffer ); #endif /*DEBUG*/ + + /* This is run for things like file truncated. Signal invalidate to + * force this op out of cache. + */ + if( cinfo->client_data ) + vips_foreign_load_invalidate( VIPS_IMAGE( cinfo->client_data ) ); } /* New error_exit handler. diff --git a/libvips/iofuncs/cache.c b/libvips/iofuncs/cache.c index 26f6b7b4..d6fed388 100644 --- a/libvips/iofuncs/cache.c +++ b/libvips/iofuncs/cache.c @@ -46,6 +46,7 @@ /* #define VIPS_DEBUG +#define DEBUG */ #ifdef HAVE_CONFIG_H @@ -549,6 +550,10 @@ vips_cache_remove( VipsOperation *operation ) VipsOperationCacheEntry *entry = (VipsOperationCacheEntry *) g_hash_table_lookup( vips_cache_table, operation ); +#ifdef DEBUG + printf( "vips_cache_remove: trimming %p\n", operation ); +#endif /*DEBUG*/ + g_assert( entry ); if( entry->invalidate_id ) { diff --git a/libvips/iofuncs/operation.c b/libvips/iofuncs/operation.c index 2e4c01ca..a8436f27 100644 --- a/libvips/iofuncs/operation.c +++ b/libvips/iofuncs/operation.c @@ -628,10 +628,10 @@ vips_operation_class_print_usage( VipsOperationClass *operation_class ) void vips_operation_invalidate( VipsOperation *operation ) { - /* +#ifdef VIPS_DEBUG printf( "vips_operation_invalidate: %p\n", operation ); vips_object_print_summary( VIPS_OBJECT( operation ) ); - */ +#endif /*VIPS_DEBUG*/ g_signal_emit( operation, vips_operation_signals[SIG_INVALIDATE], 0 ); }