From d4815e8b7e63411bf585afd63afe40102eaf2530 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 21 Nov 2018 14:26:52 +0000 Subject: [PATCH 1/5] more info output for tmpfile open to help diagnose problems --- ChangeLog | 3 +++ configure.ac | 6 +++--- libvips/iofuncs/vips.c | 18 ++++++++++++++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index bedc0fa8..077ab5d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +21/11/18 started 8.7.2 +- more info output for temp files to help diagnose problems + 23/9/18 started 8.7.1 - update function list in docs [janko-m] - test for g_str_to_ascii() [jcupitt] diff --git a/configure.ac b/configure.ac index c82fe564..15b0e243 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.7.1], [vipsip@jiscmail.ac.uk]) +AC_INIT([vips], [8.7.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], [7]) -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=51 -LIBRARY_REVISION=1 +LIBRARY_REVISION=2 LIBRARY_AGE=9 # patched into include/vips/version.h diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index c224bdba..1e0ddc9b 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -189,6 +189,11 @@ vips__open_image_write( const char *filename, gboolean temp ) fd = -1; +#ifndef O_TMPFILE + if( temp ) + g_info( "vips__open_image_write: O_TMPFILE not available" ); +#endif /*!O_TMPFILE*/ + #ifdef O_TMPFILE /* Linux-only extension creates an unlinked file. CREAT and TRUNC must * be clear. The filename arg to open() must name a directory. @@ -200,9 +205,13 @@ vips__open_image_write( const char *filename, gboolean temp ) if( temp ) { char *dirname; + g_info( "vips__open_image_write: opening with O_TMPFILE" ); dirname = g_path_get_dirname( filename ); fd = vips_tracked_open( dirname, O_TMPFILE | O_RDWR , 0666 ); g_free( dirname ); + + if( fd < 0 ) + g_info( "vips__open_image_write: O_TMPFILE failed!" ); } #endif /*O_TMPFILE*/ @@ -212,14 +221,19 @@ vips__open_image_write( const char *filename, gboolean temp ) /* On Windows, setting _O_TEMPORARY will delete the file automatically * on process exit, even if the processes crashes. */ - if( temp ) + if( temp ) { + g_info( "vips__open_image_write: setting _O_TEMPORARY" ); flags |= _O_TEMPORARY; + } #endif /*_O_TEMPORARY*/ - if( fd < 0 ) + if( fd < 0 ) { + g_info( "vips__open_image_write: simple open" ); fd = vips_tracked_open( filename, flags, 0666 ); + } if( fd < 0 ) { + g_info( "vips__open_image_write: failed!" ); vips_error_system( errno, "VipsImage", _( "unable to write to \"%s\"" ), filename ); return( -1 ); From e7cf88cf993bfb98cea764a349d10225923506ad Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 28 Nov 2018 07:17:02 +0000 Subject: [PATCH 2/5] note delay and loop in webpsave docs --- libvips/foreign/webpsave.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libvips/foreign/webpsave.c b/libvips/foreign/webpsave.c index 70e011fe..3e24f55b 100644 --- a/libvips/foreign/webpsave.c +++ b/libvips/foreign/webpsave.c @@ -444,6 +444,9 @@ vips_foreign_save_webp_mime_init( VipsForeignSaveWebpMime *mime ) * frames between frames. Setting 0 means no keyframes. By default, keyframes * are disabled. * + * Use the metadata items `gif-loop` and `gif-delay` to set the number of + * loops for the animation and the frame delay. + * * The writer will attach ICC, EXIF and XMP metadata, unless @strip is set to * %TRUE. * From ee4d1d7c221033d0d0d6e2377b3f9e3ec7e4adc4 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 29 Nov 2018 13:32:15 +0000 Subject: [PATCH 3/5] try to fix pdfium linking still not quite there --- m4/pdfium.m4 | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/m4/pdfium.m4 b/m4/pdfium.m4 index 393745dd..8294107b 100644 --- a/m4/pdfium.m4 +++ b/m4/pdfium.m4 @@ -20,21 +20,16 @@ ZLIB_LIBS="" # order. pdfium_objects="\ libpdfium.a \ - libfpdfapi.a \ - libfxge.a \ - libfpdfdoc.a \ - libfxcrt.a \ - libfx_agg.a \ - libfxcodec.a \ - libfx_lpng.a \ - libfx_libopenjpeg.a \ - libfx_lcms2.a \ - libfx_freetype.a \ + libchrome_zlib.a \ + libgmock_main.a \ + libicui18n.a \ + libicuuc.a \ libjpeg.a \ - libfdrm.a \ - libpwl.a \ - libbigint.a \ - libformfiller.a" + libminizip.a \ + libzlib_x86_simd.a \ + libsimd.a \ + libsimd_asm.a \ + libyasm_utils.a" AC_ARG_WITH(pdfium, AS_HELP_STRING([--without-pdfium], [build without pdfium (default: test)])) @@ -74,6 +69,7 @@ if test "$PDFIUM_INCLUDES" = ""; then fi # Now for the libraries ... if there's nothing set, try $PREFIX/lib +# we must link with g++ for pdfium if test "$PDFIUM_LIBS" = ""; then pdfium_save_LIBS="$LIBS" pdfium_save_CPPFLAGS="$CPPFLAGS" @@ -83,15 +79,14 @@ if test "$PDFIUM_LIBS" = ""; then LIBS="$LIBS $prefix/lib/pdfium-obj/$i" done LIBS="$LIBS -L$prefix/lib -lm -lpthread" - CPPFLAGS="$PDFIUM_INCLUDES $CPPFLAGS" + CPPFLAGS="$PDFIUM_INCLUDES $CPPFLAGS -std=c++11" - AC_TRY_LINK([#include ], - [FPDF_DOCUMENT doc; doc = FPDF_LoadDocument("", "")], [ - PDFIUM_LIBS="${prefix}/lib" - ], [ - PDFIUM_LIBS=no - ] - ) + AC_LANG(C++) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([#include ], + [FPDF_DOCUMENT doc; doc = FPDF_LoadDocument("", "")])], + [PDFIUM_LIBS="${prefix}/lib"], + [PDFIUM_LIBS=no]) LIBS="$pdfium_save_LIBS" CPPFLAGS="$pdfium_save_CPPFLAGS" From f5d76b42fc889d6db74f256a53a54d56b73a22a3 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 3 Dec 2018 17:13:57 +0000 Subject: [PATCH 4/5] fix centre sampling for non-int nearest upscale we were not disabling the input offset for NEAREST, whcih is always centre thanks edwjusti see https://github.com/lovell/sharp/issues/1479 --- libvips/resample/resize.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libvips/resample/resize.c b/libvips/resample/resize.c index fd5f4c37..c22135ed 100644 --- a/libvips/resample/resize.c +++ b/libvips/resample/resize.c @@ -28,6 +28,9 @@ * - make LINEAR and CUBIC adaptive * 25/11/17 * - deprecate --centre ... it's now always on, thanks tback + * 3/12/18 [edwjusti] + * - disable the centre sampling offset for nearest upscale, since the + * affine nearest interpolator is always centre */ /* @@ -241,9 +244,12 @@ vips_resize_build( VipsObject *object ) vips_resize_interpolate( resize->kernel ); /* Input displacement. For centre sampling, shift by 0.5 down - * and right. + * and right. Except if this is nearest, which is always + * centre. */ - const double id = 0.5; + const double id = + resize->kernel == VIPS_KERNEL_NEAREST ? + 0.0 : 0.5; VipsInterpolate *interpolate; From ac4897abee983300c5b496f00b70fbd2a545f67c Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 5 Dec 2018 14:24:26 +0000 Subject: [PATCH 5/5] Fix up vips_text() Fixes two issues: 1. vips_text() in autofit mode could set the wrong DPI, since it set the DPI in its own copy of the variable, but did not do a final update on the DPI setting that FT uses for rendering. 2. vips_text() in autofit mode allocated a new context each time, rather than reusing the context for that call. This caused a small memory leak. See https://github.com/libvips/libvips/issues/1174 --- ChangeLog | 2 ++ libvips/create/text.c | 73 ++++++++++++++++++++++--------------------- 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 077ab5d1..262018d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 21/11/18 started 8.7.2 - more info output for temp files to help diagnose problems +- vips_text() could set the wrong DPI +- vips_text() leaked in autofit mode 23/9/18 started 8.7.1 - update function list in docs [janko-m] diff --git a/libvips/create/text.c b/libvips/create/text.c index c0b14694..a6a4810a 100644 --- a/libvips/create/text.c +++ b/libvips/create/text.c @@ -22,6 +22,9 @@ * - better fitting of fonts with overhanging edges, thanks AdriĆ  * 26/4/18 fangqiao * - add fontfile option + * 5/12/18 + * - fitting mode could set wrong dpi + * - fitting mode leaked */ /* @@ -170,8 +173,6 @@ vips_text_get_extents( VipsText *text, VipsRect *extents ) pango_ft2_font_map_set_resolution( PANGO_FT2_FONT_MAP( vips_text_fontmap ), text->dpi, text->dpi ); - text->context = pango_font_map_create_context( - PANGO_FONT_MAP( vips_text_fontmap ) ); if( !(text->layout = text_layout_new( text->context, text->text, text->font, @@ -180,17 +181,18 @@ vips_text_get_extents( VipsText *text, VipsRect *extents ) pango_layout_get_pixel_extents( text->layout, &ink_rect, &logical_rect ); - extents->left = ink_rect.x; extents->top = ink_rect.y; extents->width = ink_rect.width; extents->height = ink_rect.height; #ifdef DEBUG - printf( "vips_text_get_extents: dpi = %d, " - "left = %d, top = %d, width = %d, height = %d\n", - text->dpi, - extents->left, extents->top, extents->width, extents->height ); + printf( "vips_text_get_extents: dpi = %d\n", text->dpi ); + printf( " ink left = %d, top = %d, width = %d, height = %d\n", + ink_rect.x, ink_rect.y, ink_rect.width, ink_rect.height ); + printf( " logical left = %d, top = %d, width = %d, height = %d\n", + logical_rect.x, logical_rect.y, + logical_rect.width, logical_rect.height ); #endif /*DEBUG*/ return( 0 ); @@ -215,27 +217,32 @@ vips_text_rect_difference( VipsRect *target, VipsRect *extents ) /* Adjust text->dpi to try to fit to the bounding box. */ static int -vips_text_autofit( VipsText *text, VipsRect *out_extents ) +vips_text_autofit( VipsText *text ) { VipsRect target; VipsRect extents; - VipsRect previous_extents; int difference; int previous_difference; int previous_dpi; int lower_dpi; int upper_dpi; - VipsRect lower_extents; - VipsRect upper_extents; /* First, repeatedly double or halve dpi until we pass the correct * value. This will give us a lower and upper bound. */ + target.left = 0; + target.top = 0; target.width = text->width; target.height = text->height; previous_dpi = -1; +#ifdef DEBUG + printf( "vips_text_autofit: " + "target left = %d, top = %d, width = %d, height = %d\n", + target.left, target.top, target.width, target.height ); +#endif /*DEBUG*/ + for(;;) { if( vips_text_get_extents( text, &extents ) ) return( -1 ); @@ -246,7 +253,6 @@ vips_text_autofit( VipsText *text, VipsRect *out_extents ) if( previous_dpi == -1 ) { previous_dpi = text->dpi; previous_difference = difference; - previous_extents = extents; } /* Hit the size, or we straddle the target. @@ -256,7 +262,6 @@ vips_text_autofit( VipsText *text, VipsRect *out_extents ) break; previous_difference = difference; - previous_extents = extents; previous_dpi = text->dpi; text->dpi = difference < 0 ? text->dpi * 2 : text->dpi / 2; @@ -266,17 +271,18 @@ vips_text_autofit( VipsText *text, VipsRect *out_extents ) /* We've been coming down. */ lower_dpi = text->dpi; - lower_extents = extents; upper_dpi = previous_dpi; - upper_extents = previous_extents; } else { lower_dpi = previous_dpi; - lower_extents = previous_extents; upper_dpi = text->dpi; - upper_extents = extents; } +#ifdef DEBUG + printf( "vips_text_autofit: lower dpi = %d, upper dpi = %d\n", + lower_dpi, upper_dpi ); +#endif /*DEBUG*/ + /* Refine lower and upper until they are almost touching. */ while( upper_dpi - lower_dpi > 1 && @@ -288,31 +294,26 @@ vips_text_autofit( VipsText *text, VipsRect *out_extents ) target.top = extents.top; difference = vips_text_rect_difference( &target, &extents ); - if( difference < 0 ) { + if( difference < 0 ) lower_dpi = text->dpi; - lower_extents = extents; - } - else { + else upper_dpi = text->dpi; - upper_extents = extents; - } } /* If we've hit the target exactly and quit the loop, diff will be 0 * and we can use upper. Otherwise we are straddling the target and we * must take lower. */ - if( difference == 0 ) { + if( difference == 0 ) text->dpi = upper_dpi; - *out_extents = upper_extents; - } - else { + else text->dpi = lower_dpi; - *out_extents = lower_extents; - } - g_object_set( text, "autofit_dpi", text->dpi, NULL ); +#ifdef DEBUG + printf( "vips_text_autofit: final dpi = %d\n", text->dpi ); +#endif /*DEBUG*/ + return( 0 ); } @@ -340,6 +341,9 @@ vips_text_build( VipsObject *object ) if( !vips_text_fontmap ) vips_text_fontmap = pango_ft2_font_map_new(); + text->context = pango_font_map_create_context( + PANGO_FONT_MAP( vips_text_fontmap ) ); + if( text->fontfile && !FcConfigAppFontAddFile( NULL, (const FcChar8 *) text->fontfile ) ) { @@ -354,15 +358,14 @@ vips_text_build( VipsObject *object ) */ if( vips_object_argument_isset( object, "height" ) && !vips_object_argument_isset( object, "dpi" ) ) { - if( vips_text_autofit( text, &extents ) ) + if( vips_text_autofit( text ) ) return( -1 ); } - else - if( vips_text_get_extents( text, &extents ) ) - return( -1 ); - /* Can happen for "", for example. + /* Layout. Can fail for "", for example. */ + if( vips_text_get_extents( text, &extents ) ) + return( -1 ); if( extents.width == 0 || extents.height == 0 ) { vips_error( class->nickname, "%s", _( "no text to render" ) );