From 01a82646a1263423228cbc3b0a2ad4dff74b10c0 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 27 Jul 2019 13:40:18 +0100 Subject: [PATCH] experiment with minimise in insert try minimising sub after we've passed it --- cplusplus/examples/test_overloads.cpp | 3 ++- libvips/conversion/insert.c | 20 +++++++++++++++++++- libvips/include/vips/image.h | 2 ++ libvips/iofuncs/image.c | 16 ++++++++++++++++ libvips/resample/shrinkv.c | 2 +- 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/cplusplus/examples/test_overloads.cpp b/cplusplus/examples/test_overloads.cpp index 8a183ca6..ed3a25cc 100644 --- a/cplusplus/examples/test_overloads.cpp +++ b/cplusplus/examples/test_overloads.cpp @@ -34,7 +34,8 @@ equal_vector( std::vector a, std::vector b ) printf( "%g", a[i] ); } printf( "], is [" ); - for( unsigned int i = 0; i < a.size(); i++ ) { if( i > 0 ) + for( unsigned int i = 0; i < a.size(); i++ ) { + if( i > 0 ) printf( ", " ); printf( "%g", a[i] ); } diff --git a/libvips/conversion/insert.c b/libvips/conversion/insert.c index ce45ccdf..66d1d65c 100644 --- a/libvips/conversion/insert.c +++ b/libvips/conversion/insert.c @@ -28,6 +28,8 @@ * 29/9/11 * - rewrite as a class * - add expand, bg options + * 27/7/19 + * - minimise sub when we're done with it */ /* @@ -103,6 +105,10 @@ typedef struct _VipsInsert { VipsRect rout; /* Output space */ VipsRect rmain; /* Position of main in output */ VipsRect rsub; /* Position of sub in output */ + + /* TRUE if we've minimise sub. + */ + gboolean sub_minimised; } VipsInsert; typedef VipsConversionClass VipsInsertClass; @@ -187,9 +193,21 @@ vips_insert_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop ) */ vips_rect_intersectrect( &or->valid, &insert->rsub, &ovl ); if( vips_rect_includesrect( &insert->rmain, &or->valid ) && - vips_rect_isempty( &ovl ) ) + vips_rect_isempty( &ovl ) ) { + /* If we're now below the sub-image, and we're in sequential + * mode, and we've not minimised it before, we can shut down + * that input. + */ + if( vips_image_is_sequential( insert->sub ) && + r->top > VIPS_RECT_BOTTOM( &insert->rsub ) && + !insert->sub_minimised ) { + insert->sub_minimised = TRUE; + vips_image_minimise_all( insert->sub ); + } + return( vips__insert_just_one( or, ir[0], insert->rmain.left, insert->rmain.top ) ); + } /* Output requires both (or neither) input. If it is not entirely * inside both the main and the sub, then there is going to be some diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index 7353aa89..be5dc94a 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -426,6 +426,8 @@ void vips_image_invalidate_all( VipsImage *image ); void vips_image_minimise_all( VipsImage *image ); +gboolean vips_image_is_sequential( VipsImage *image ); + void vips_image_set_progress( VipsImage *image, gboolean progress ); gboolean vips_image_iskilled( VipsImage *image ); void vips_image_set_kill( VipsImage *image, gboolean kill ); diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 3037b1c4..15274c68 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -1454,6 +1454,22 @@ vips_image_minimise_all( VipsImage *image ) (VipsSListMap2Fn) vips_image_minimise_all_cb, NULL, NULL ); } +/** + * vips_image_is_sequential: (method) + * @image: #VipsImage to minimise + * + * TRUE if any of the images upstream from @image were opened in sequential + * mode. Some operations change behaviour slightly in sequential mode to + * optimise memory behaviour. + * + * Returns: %TRUE if @image is in sequential mode. + */ +gboolean +vips_image_is_sequential( VipsImage *image ) +{ + return( vips_image_get_typeof( image, VIPS_META_SEQUENTIAL ) ); +} + /* Attach a new time struct, if necessary, and reset it. */ static int diff --git a/libvips/resample/shrinkv.c b/libvips/resample/shrinkv.c index caf67832..eaacbf98 100644 --- a/libvips/resample/shrinkv.c +++ b/libvips/resample/shrinkv.c @@ -413,7 +413,7 @@ vips_shrinkv_build( VipsObject *object ) * always have the previous XX lines of the shrunk image, and we won't * fetch out of order. */ - if( vips_image_get_typeof( in, VIPS_META_SEQUENTIAL ) ) { + if( vips_image_is_sequential( in ) ) { g_info( "shrinkv sequential line cache" ); shrink->sequential = TRUE;