From 34fcd1fe69e3ea48e8e10cfa5bae8b388a49ffb4 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 12 Jan 2020 14:24:23 +0000 Subject: [PATCH] fix autorot in thumbnail `vips_thumbnail()` was not taking a private copy of the image before modifying metadata during auto-rotate. Thanks janko. See https://github.com/libvips/libvips/issues/1523 --- ChangeLog | 1 + libvips/resample/thumbnail.c | 23 +++++++++++++---------- test/test-suite/test_resample.py | 14 +++++++++++++- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index cf3cacc2..a9016b2d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 20/6/19 started 8.9.1 - don't use the new source loaders for new_from_file or new_from_buffer, it will break the loader priority system +- fix thumbnail autorot [janko] 20/6/19 started 8.9.0 - add vips_image_get/set_array_int() diff --git a/libvips/resample/thumbnail.c b/libvips/resample/thumbnail.c index 215bc61d..dd282bc6 100644 --- a/libvips/resample/thumbnail.c +++ b/libvips/resample/thumbnail.c @@ -520,13 +520,12 @@ static int vips_thumbnail_build( VipsObject *object ) { VipsThumbnail *thumbnail = VIPS_THUMBNAIL( object ); - VipsImage **t = (VipsImage **) vips_object_local_array( object, 14 ); + VipsImage **t = (VipsImage **) vips_object_local_array( object, 15 ); VipsInterpretation interpretation = thumbnail->linear ? VIPS_INTERPRETATION_scRGB : VIPS_INTERPRETATION_sRGB; VipsImage *in; int preshrunk_page_height; - int output_page_height; double hshrink; double vshrink; @@ -673,17 +672,20 @@ vips_thumbnail_build( VipsObject *object ) return( -1 ); in = t[4]; - if( vips_copy( in, &t[13], NULL ) ) - return( -1 ); - in = t[13]; - output_page_height = VIPS_RINT( preshrunk_page_height / vshrink ); - /* Only set page-height if we have more than one page, or this could * accidentally turn into an animated image later. */ - if( thumbnail->n_loaded_pages > 1 ) + if( thumbnail->n_loaded_pages > 1 ) { + int output_page_height = + VIPS_RINT( preshrunk_page_height / vshrink ); + + if( vips_copy( in, &t[13], NULL ) ) + return( -1 ); + in = t[13]; + vips_image_set_int( in, VIPS_META_PAGE_HEIGHT, output_page_height ); + } if( have_premultiplied ) { g_info( "unpremultiplying alpha" ); @@ -746,9 +748,10 @@ vips_thumbnail_build( VipsObject *object ) /* Need to copy to memory, we have to stay seq. */ if( !(t[9] = vips_image_copy_memory( in )) || - vips_rot( t[9], &t[10], angle, NULL ) ) + vips_rot( t[9], &t[10], angle, NULL ) || + vips_copy( t[10], &t[14], NULL ) ) return( -1 ); - in = t[10]; + in = t[14]; vips_autorot_remove_angle( in ); } diff --git a/test/test-suite/test_resample.py b/test/test-suite/test_resample.py index abd4a61d..04c81580 100644 --- a/test/test-suite/test_resample.py +++ b/test/test-suite/test_resample.py @@ -2,7 +2,7 @@ import pytest import pyvips -from helpers import JPEG_FILE, all_formats, have +from helpers import JPEG_FILE, HEIC_FILE, all_formats, have # Run a function expecting a complex image on a two-band image @@ -166,6 +166,18 @@ class TestResample: im2 = pyvips.Image.thumbnail_buffer(buf, 100) assert abs(im1.avg() - im2.avg()) < 1 + if have("heifload"): + # this image is orientation 6 ... thumbnail should flip it + im = pyvips.Image.new_from_file(HEIC_FILE) + thumb = pyvips.Image.thumbnail(HEIC_FILE, 100) + + # original is landscape + assert im.width > im.height + + # thumb should be portrait + assert thumb.width < thumb.height + assert thumb.height == 100 + def test_similarity(self): im = pyvips.Image.new_from_file(JPEG_FILE) im2 = im.similarity(angle=90)