From c5e3ce44081a5059375d0211c07e0e3579544a94 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 21 Jan 2010 17:04:00 +0000 Subject: [PATCH] stuff --- ChangeLog | 2 ++ TODO | 7 ++++- libvips/iofuncs/buffer.c | 56 ++++++++++++++++++++++++++++++++++--- libvips/iofuncs/im_close.c | 7 +++-- libvips/iofuncs/im_open.c | 6 ++-- libvips/iofuncs/im_render.c | 6 ++-- 6 files changed, 71 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 209f1163..a0ee3a7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,6 +19,8 @@ - better TIFF YCbCr reading (thanks Ole) - isanalyze generates fewer silly error messages - added "written" callbacks, used to implement write to non-vips formats +- "invalidate" is careful to keep images alive, so invalidate callbacks can do + im_close() 26/11/09 started 7.20.3 - updated en_GB.po translation diff --git a/TODO b/TODO index 277cb807..97843671 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,9 @@ -- test new floodfill in paintbox +- close callbacks could use invalidate's trick and give close callbacks more + safety + + could get rid of a couple of image flags too + +- flood blob with ink == initial click loops - we sill have the old flood-fill code there, move to deprecated diff --git a/libvips/iofuncs/buffer.c b/libvips/iofuncs/buffer.c index d41451a9..c67b738f 100644 --- a/libvips/iofuncs/buffer.c +++ b/libvips/iofuncs/buffer.c @@ -559,16 +559,50 @@ im_invalidate_region( REGION *reg ) } static void * -im_invalidate_image( IMAGE *im ) +im_invalidate_image( IMAGE *im, GSList **to_be_invalidated ) { (void) im_slist_map2( im->regions, (VSListMap2Fn) im_invalidate_region, NULL, NULL ); - if( im__trigger_callbacks( im->invalidatefns ) ) - return( im ); + + *to_be_invalidated = g_slist_prepend( *to_be_invalidated, im ); return( NULL ); } +/* Trigger a callbacks on a list of images, where the callbacks might create + * or destroy the images. + * + * We make a set of temp regions to hold the images open, but when we switch + * to VipsObject we should incr/decr ref count. + */ +static void +im_invalidate_trigger( GSList *images ) +{ + GSList *regions; + GSList *p; + + regions = NULL; + for( p = images; p; p = p->next ) { + IMAGE *im = (IMAGE *) p->data; + + regions = g_slist_prepend( regions, im_region_create( im ) ); + } + + for( p = images; p; p = p->next ) { + IMAGE *im = (IMAGE *) p->data; + + (void) im__trigger_callbacks( im->invalidatefns ); + } + + for( p = regions; p; p = p->next ) { + REGION *r = (REGION *) p->data; + + im_region_free( r ); + } + + g_slist_free( regions ); +} + /** * im_invalidate: * @im: #IMAGE to invalidate @@ -581,8 +615,22 @@ im_invalidate_image( IMAGE *im ) void im_invalidate( IMAGE *im ) { + GSList *to_be_invalidated; + + /* Invalidate callbacks might do anything, including removing images + * or invalidating other images, so we can't trigger them from within + * the image loop. Instead we collect a list of image to invalidate + * and trigger them all in one go, checking that they are not + * invalidated. + */ + to_be_invalidated = NULL; (void) im__link_map( im, - (VSListMap2Fn) im_invalidate_image, NULL, NULL ); + (VSListMap2Fn) im_invalidate_image, &to_be_invalidated, NULL ); + + im_invalidate_trigger( to_be_invalidated ); + + g_slist_free( to_be_invalidated ); + } /* Init the buffer cache system. diff --git a/libvips/iofuncs/im_close.c b/libvips/iofuncs/im_close.c index e428771a..3ab462bf 100644 --- a/libvips/iofuncs/im_close.c +++ b/libvips/iofuncs/im_close.c @@ -276,9 +276,10 @@ im_close( IMAGE *im ) * be closed when the last region is freed * (see im_region_free()). */ -#ifdef DEBUG_IO - printf( "im_close: pending close for \"%s\"\n", im->filename ); -#endif /*DEBUG_IO*/ +#ifdef DEBUG_NEW + printf( "im_close: pending close for 0x%p, \"%s\"\n", + im, im->filename ); +#endif /*DEBUG_NEW*/ im->close_pending = 1; } diff --git a/libvips/iofuncs/im_open.c b/libvips/iofuncs/im_open.c index 2c0cfdf5..2ed70d6e 100644 --- a/libvips/iofuncs/im_open.c +++ b/libvips/iofuncs/im_open.c @@ -125,7 +125,7 @@ Modified: */ /* -#define DEBUG_IO +#define DEBUG */ #ifdef HAVE_CONFIG_H @@ -501,9 +501,9 @@ im_open( const char *filename, const char *mode ) (im_callback_fn) evalend_cb, progress, NULL ); } -#ifdef DEBUG_IO +#ifdef DEBUG printf( "im_open: success for %s (%p)\n", im->filename, im ); -#endif /*DEBUG_IO*/ +#endif /*DEBUG*/ return( im ); } diff --git a/libvips/iofuncs/im_render.c b/libvips/iofuncs/im_render.c index c3a6a322..14036a06 100644 --- a/libvips/iofuncs/im_render.c +++ b/libvips/iofuncs/im_render.c @@ -1079,11 +1079,13 @@ im_render_priority( IMAGE *in, IMAGE *out, IMAGE *mask, if( render_thread_create() ) return( -1 ); - if( width <= 0 || height <= 0 || max < -1 ) { + if( width <= 0 || + height <= 0 || + max < -1 ) { im_error( "im_render", "%s", _( "bad parameters" ) ); return( -1 ); } - if( im_pincheck( in ) || im_poutcheck( out ) ) + if( im_piocheck( in, out ) ) return( -1 ); if( mask ) { if( im_poutcheck( mask ) ||