From 5e2d66d14bea989321cd706ae80d1e54d26d7097 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 9 Jul 2019 16:58:30 +0100 Subject: [PATCH] better early shutdown behaviour in shrinkv read the tail of the input to force early shutdown in seq readers does reducev need something similar? see https://github.com/kleisauke/net-vips/issues/12 --- ChangeLog | 3 +++ configure.ac | 6 ++--- libvips/conversion/sequential.c | 3 ++- libvips/resample/shrinkv.c | 42 ++++++++++++++++++++++++++++++--- 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index f79c8303..c26954e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +9/7/19 started 8.8.2 +- better early shutdown in readers + 24/5/19 started 8.8.1 - improve realpath() use on older libc - better magickload error messages diff --git a/configure.ac b/configure.ac index e802b7d4..e9f8d2f1 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # also update the version number in the m4 macros below -AC_INIT([vips], [8.8.1], [vipsip@jiscmail.ac.uk]) +AC_INIT([vips], [8.8.2], [vipsip@jiscmail.ac.uk]) # required for gobject-introspection AC_PREREQ(2.62) @@ -18,7 +18,7 @@ AC_CONFIG_MACRO_DIR([m4]) # user-visible library versioning m4_define([vips_major_version], [8]) m4_define([vips_minor_version], [8]) -m4_define([vips_micro_version], [1]) +m4_define([vips_micro_version], [2]) m4_define([vips_version], [vips_major_version.vips_minor_version.vips_micro_version]) @@ -38,7 +38,7 @@ VIPS_VERSION_STRING=$VIPS_VERSION-`date -u -r ChangeLog` # binary interface changes not backwards compatible?: reset age to 0 LIBRARY_CURRENT=53 -LIBRARY_REVISION=0 +LIBRARY_REVISION=1 LIBRARY_AGE=11 # patched into include/vips/version.h diff --git a/libvips/conversion/sequential.c b/libvips/conversion/sequential.c index a35d388c..9da91786 100644 --- a/libvips/conversion/sequential.c +++ b/libvips/conversion/sequential.c @@ -171,7 +171,8 @@ vips_sequential_generate( VipsRegion *or, return( -1 ); } - sequential->y_pos = VIPS_MAX( sequential->y_pos, VIPS_RECT_BOTTOM( r ) ); + sequential->y_pos = + VIPS_MAX( sequential->y_pos, VIPS_RECT_BOTTOM( r ) ); g_mutex_unlock( sequential->lock ); diff --git a/libvips/resample/shrinkv.c b/libvips/resample/shrinkv.c index 13da3218..3808d1e0 100644 --- a/libvips/resample/shrinkv.c +++ b/libvips/resample/shrinkv.c @@ -45,6 +45,8 @@ * - rename yshrink -> vshrink for greater consistency * 7/3/17 * - add a seq line cache + * 9/7/19 + * - read the tail of the input to force early shutdown in seq readers */ /* @@ -99,6 +101,7 @@ typedef struct _VipsShrinkv { int vshrink; size_t sizeof_line_buffer; + gboolean sequential; } VipsShrinkv; @@ -315,6 +318,37 @@ vips_shrinkv_gen( VipsRegion *or, void *vseq, VIPS_COUNT_PIXELS( or, "vips_shrinkv_gen" ); + /* If we are in seq mode and we've just generated the last line of + * the output, make sure we read all of the input. + * + * This will trigger the early shutdown logic in things like the + * tiff loader. + */ + if( shrink->sequential && + r->top + r->height >= or->im->Ysize ) { + /* First unused scanline. + */ + int first = or->im->Ysize * shrink->vshrink; + int unused = ir->im->Ysize - first; + + g_assert( unused >= 0 ); + + for( y = 0; y < unused; y++ ) { + VipsRect s; + + s.left = r->left; + s.top = first + y; + s.width = r->width; + s.height = 1; +#ifdef DEBUG + printf( "shrink_gen: requesting tail %d\n", s.top ); +#endif /*DEBUG*/ + + if( vips_region_prepare( ir, &s ) ) + return( -1 ); + } + } + return( 0 ); } @@ -349,12 +383,12 @@ vips_shrinkv_build( VipsObject *object ) return( -1 ); in = t[0]; - /* We need new pixels along the bottom so that we don't have small chunks - * to average along the bottom edge. + /* Make the height a multiple of the shrink factor so we don't need to + * average half pixels. */ if( vips_embed( in, &t[1], 0, 0, - in->Xsize, in->Ysize + shrink->vshrink, + in->Xsize, VIPS_ROUND_UP( in->Ysize, shrink->vshrink ), "extend", VIPS_EXTEND_COPY, NULL ) ) return( -1 ); @@ -415,6 +449,8 @@ vips_shrinkv_build( VipsObject *object ) if( vips_image_get_typeof( in, VIPS_META_SEQUENTIAL ) ) { g_info( "shrinkv sequential line cache" ); + shrink->sequential = TRUE; + if( vips_sequential( in, &t[3], "tile_height", 10, NULL ) )