From 89527b80ebc1f58240b03a5cd86f6c48f462a728 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 8 Jul 2012 10:37:35 +0100 Subject: [PATCH] fix odd tile height + no overlap dzsave with zero overlap and odd height was broken also, fix cache init --- ChangeLog | 2 ++ TODO | 8 ++++++++ libvips/foreign/dzsave.c | 19 ++++++++++++++----- libvips/include/vips/internal.h | 2 ++ libvips/iofuncs/cache.c | 6 ++---- libvips/iofuncs/init.c | 4 ++++ 6 files changed, 32 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 73eb7c2d..0174a868 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,8 @@ - much more gentle sharpening in thumbnails - added "minimise" signal, used by tilecache to drop - add :seq support to im_tiff2vips(), im_jpeg2vips() ... helps ruby-vips +- better thread safety for vips8 operation dispatch +- better thread safety for upstream / downstream image linking 18/6/12 started 7.28.9 - slightly more memory debugging output diff --git a/TODO b/TODO index 80599d85..2bdba7cf 100644 --- a/TODO +++ b/TODO @@ -4,6 +4,14 @@ have "rs" mode? ie. open for sequential read? +- need a flag on operations for "is sequential" + + should be on the object, not the class, since it can change with params + +- we probably have more threading issues :-( + + look through image and operation init and unref and see what gets called + blocking bugs ============= diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index bb04e6dd..5ff88742 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -168,13 +168,16 @@ pyramid_build( VipsForeignSaveDz *dz, Layer *above, int w, int h ) /* Build a line of tiles here. Normally strips are height + 2 * * overlap, but the first row is missing the top edge. + * + * We add one so that we will have the extra scan line for the shrink + * in case tile_height is odd and there's no overlap. */ layer->y = 0; layer->write_y = 0; strip.left = 0; strip.top = 0; strip.width = w; - strip.height = dz->tile_height + dz->overlap; + strip.height = dz->tile_height + dz->overlap + 1; if( vips_region_buffer( layer->strip, &strip ) ) { layer_free( layer ); return( NULL ); @@ -506,6 +509,9 @@ strip_shrink( Layer *layer ) source.top = target.top * 2; source.width = target.width * 2; source.height = target.height * 2; + + /* Of which we have these available. + */ vips_rect_intersectrect( &source, &from->valid, &source ); /* So these are the pixels in the layer below we can provide. @@ -515,7 +521,7 @@ strip_shrink( Layer *layer ) target.width = source.width / 2; target.height = source.height / 2; - /* Are we empty? All done. + /* None? All done. */ if( source.height < 2 ) break; @@ -558,13 +564,15 @@ strip_arrived( Layer *layer ) strip_shrink( layer ) ) return( -1 ); - /* Position our strip down the image. + /* Position our strip down the image. We add one to the strip height + * to make sure we will have enough pixels for any shrinking even if + * tile_height is odd and there's no overlap. */ layer->y += dz->tile_height; new_strip.left = 0; new_strip.top = layer->y - dz->overlap; new_strip.width = layer->image->Xsize; - new_strip.height = dz->tile_height + 2 * dz->overlap; + new_strip.height = dz->tile_height + 2 * dz->overlap + 1; /* What pixels that we will need do we already have? Save them in * overlap. @@ -622,7 +630,8 @@ pyramid_strip( VipsRegion *region, VipsRect *area, void *a ) /* And copy those pixels in. * * FIXME: If the strip fits inside the region we've just - * received, we could skip the copy. + * received, we could skip the copy. Will this happen very + * often? Unclear. */ vips_region_copy( region, layer->strip, &target, target.left, target.top ); diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 118b88b9..937a60fa 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -83,6 +83,8 @@ extern char *vips__cache_max_files; extern gboolean vips__cache_dump; extern gboolean vips__cache_trace; +void vips__cache_init( void ); + typedef int (*im__fftproc_fn)( VipsImage *, VipsImage *, VipsImage * ); /* iofuncs diff --git a/libvips/iofuncs/cache.c b/libvips/iofuncs/cache.c index a4af6e61..bab52246 100644 --- a/libvips/iofuncs/cache.c +++ b/libvips/iofuncs/cache.c @@ -409,8 +409,8 @@ vips_operation_equal( VipsOperation *a, VipsOperation *b ) return( FALSE ); } -static void -vips_cache_init( void ) +void +vips__cache_init( void ) { if( !vips_cache_table ) { vips_cache_lock = g_mutex_new(); @@ -670,8 +670,6 @@ vips_cache_operation_buildp( VipsOperation **operation ) vips_object_print_dump( VIPS_OBJECT( *operation ) ); #endif /*VIPS_DEBUG*/ - vips_cache_init(); - vips_cache_trim(); g_mutex_lock( vips_cache_lock ); diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index c4e5d5af..e4961237 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -227,6 +227,10 @@ vips_init( const char *argv0 ) vips__interpolate_init(); im__format_init(); + /* Start up operator cache. + */ + vips__cache_init(); + /* Start up packages. */ vips_arithmetic_operation_init();