From 8a98bea063d2373e7e2180a20c8298c05466d9af Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 19 Jun 2019 17:56:09 +0100 Subject: [PATCH] fix vipsthumbnail for pyr tiff files thumbnail was not testing pyramidal tiff images for pyramidness correctly. see https://github.com/libvips/libvips/issues/1297 --- ChangeLog | 1 + configure.ac | 6 +++--- libvips/include/vips/header.h | 1 + libvips/iofuncs/header.c | 37 +++++++++++++++++++++++++++++------ libvips/resample/thumbnail.c | 18 ++++++++--------- 5 files changed, 44 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7d2a6a34..581d82e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ magic number [przemyslawpluta] - better behaviour for vips_region_fetch() if request lies partly ouside image - remove 256 band limit in arithmetic.c [erdmann] - disable Orc if building with CET [lovell] +- fix vipsthumbnail with pyr tiff [kleisauke] 21/9/18 started 8.8.0 - much faster smartcrop [lovell] diff --git a/configure.ac b/configure.ac index 826b3b34..e802b7d4 100644 --- a/configure.ac +++ b/configure.ac @@ -37,9 +37,9 @@ VIPS_VERSION_STRING=$VIPS_VERSION-`date -u -r ChangeLog` # binary interface changes backwards compatible?: increment age # binary interface changes not backwards compatible?: reset age to 0 -LIBRARY_CURRENT=52 -LIBRARY_REVISION=1 -LIBRARY_AGE=10 +LIBRARY_CURRENT=53 +LIBRARY_REVISION=0 +LIBRARY_AGE=11 # patched into include/vips/version.h AC_SUBST(VIPS_VERSION) diff --git a/libvips/include/vips/header.h b/libvips/include/vips/header.h index c3544d32..64e61708 100644 --- a/libvips/include/vips/header.h +++ b/libvips/include/vips/header.h @@ -170,6 +170,7 @@ const char *vips_image_get_mode( const VipsImage *image ); double vips_image_get_scale( const VipsImage *image ); double vips_image_get_offset( const VipsImage *image ); int vips_image_get_page_height( VipsImage *image ); +int vips_image_get_n_pages( VipsImage *image ); const void *vips_image_get_data( VipsImage *image ); void vips_image_init_fields( VipsImage *image, diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index c5cb2814..2af3752d 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -32,6 +32,8 @@ * - hide deprecated header fields from _map * 17/2/19 * - add vips_image_get_page_height() + * 19/6/19 + * - add vips_image_get_n_pages() */ /* @@ -792,13 +794,10 @@ vips_image_get_page_height( VipsImage *image ) { int page_height; - page_height = image->Ysize; - if( vips_image_get_typeof( image, VIPS_META_PAGE_HEIGHT ) && + if( !vips_image_get_typeof( image, VIPS_META_PAGE_HEIGHT ) || vips_image_get_int( image, VIPS_META_PAGE_HEIGHT, - &page_height ) ) - ; - - if( page_height <= 0 || + &page_height ) || + page_height <= 0 || page_height > image->Ysize || image->Ysize % page_height != 0 ) page_height = image->Ysize; @@ -806,6 +805,32 @@ vips_image_get_page_height( VipsImage *image ) return( page_height ); } +/** + * vips_image_get_n_pages: (method) + * @image: image to get from + * + * Fetch and sanity-check VIPS_META_N_PAGES. Default to 1 if not present or + * crazy. + * + * This is the number of pages in the image file, not the number of pages that + * have been loaded into @image. + * + * Returns: the number of pages in the image file + */ +int +vips_image_get_n_pages( VipsImage *image ) +{ + int n_pages; + + if( !vips_image_get_typeof( image, VIPS_META_N_PAGES ) || + vips_image_get_int( image, VIPS_META_N_PAGES, &n_pages ) || + n_pages < 2 || + n_pages > 1000 ) + n_pages = 1; + + return( n_pages ); +} + /** * vips_image_get_data: (method) * @image: image to get data for diff --git a/libvips/resample/thumbnail.c b/libvips/resample/thumbnail.c index e9de9ddd..89fbf48a 100644 --- a/libvips/resample/thumbnail.c +++ b/libvips/resample/thumbnail.c @@ -109,7 +109,8 @@ typedef struct _VipsThumbnail { int input_height; int page_height; VipsAngle angle; /* From vips_autorot_get_angle() */ - int n_pages; /* Pages in this image, not original */ + int n_pages; /* Pages in file */ + int n_loaded_pages; /* Pages we've loaded from file */ /* For openslide, we need to read out the size of each level too. * @@ -191,15 +192,17 @@ vips_thumbnail_read_header( VipsThumbnail *thumbnail, VipsImage *image ) thumbnail->input_height = image->Ysize; thumbnail->angle = vips_autorot_get_angle( image ); thumbnail->page_height = vips_image_get_page_height( image ); + thumbnail->n_pages = vips_image_get_n_pages( image ); - /* The "n-pages" metadata item is the number of pages in the document, + /* VIPS_META_N_PAGES is the number of pages in the document, * not the number we've read out into this image. We calculate * ourselves from page_height. * - * vips_image_get_page_height() verifies that Ysize is a simple + * vips_image_get_page_height() has verified that Ysize is a simple * multiple of page_height. */ - thumbnail->n_pages = thumbnail->input_height / thumbnail->page_height; + thumbnail->n_loaded_pages = + thumbnail->input_height / thumbnail->page_height; /* For openslide, read out the level structure too. */ @@ -235,11 +238,6 @@ vips_thumbnail_get_tiff_pyramid( VipsThumbnail *thumbnail ) VipsThumbnailClass *class = VIPS_THUMBNAIL_GET_CLASS( thumbnail ); int i; - /* Only one page? Can't be. - */ - if( thumbnail->n_pages < 2 ) - return; - for( i = 0; i < thumbnail->n_pages; i++ ) { VipsImage *page; int level_width; @@ -672,7 +670,7 @@ vips_thumbnail_build( VipsObject *object ) int target_page_height = VIPS_RINT( preshrunk_page_height / vshrink ); int target_image_height = target_page_height * - thumbnail->n_pages; + thumbnail->n_loaded_pages; vshrink = (double) in->Ysize / target_image_height; }