From 0c7b65e1569f28ceee74c9b5e348edb3a18aff68 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 21 Sep 2020 09:29:25 +0100 Subject: [PATCH 1/3] allow both dpi and scale to be set for pdfload pdfload didn't allow both dpi and scale to be set. This patch makes the two settings combine if both are given. thanks le0daniel see https://github.com/libvips/libvips/issues/1824 --- ChangeLog | 1 + libvips/foreign/pdfload.c | 26 +++++++++++++++----------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2c00b499..1eb7cf4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,7 @@ - in jpegsave, don't set JFIF resolution if we set EXIF resolution - bump minimum libheif version to 1.3 [lovell] - dzsave in iiif mode could set info.json dimensions off by one [Linden6] +- pdfload allows dpi and scale to both be set [le0daniel] 9/8/20 started 8.10.1 - fix markdown -> xml conversion in doc generation diff --git a/libvips/foreign/pdfload.c b/libvips/foreign/pdfload.c index 04caef60..b9a66c10 100644 --- a/libvips/foreign/pdfload.c +++ b/libvips/foreign/pdfload.c @@ -16,6 +16,8 @@ * - reopen the input if we minimised too early * 11/3/20 * - move on top of VipsSource + * 21/9/20 + * - allow dpi and scale to both be set [le0daniel] */ /* @@ -109,10 +111,14 @@ typedef struct _VipsForeignLoadPdf { */ double dpi; - /* Calculate this from DPI. At 72 DPI, we render 1:1 with cairo. + /* Scale by this factor. */ double scale; + /* The total scale factor we render with. + */ + double total_scale; + /* Background colour. */ VipsArrayDouble *background; @@ -170,8 +176,7 @@ vips_foreign_load_pdf_build( VipsObject *object ) GError *error = NULL; - if( !vips_object_argument_isset( object, "scale" ) ) - pdf->scale = pdf->dpi / 72.0; + pdf->total_scale = pdf->scale * pdf->dpi / 72.0; pdf->stream = vips_g_input_stream_new_from_source( pdf->source ); if( !(pdf->doc = poppler_document_new_from_stream( pdf->stream, @@ -338,8 +343,8 @@ vips_foreign_load_pdf_header( VipsForeignLoad *load ) * does round to nearest. Without this, things like * shrink-on-load will break. */ - pdf->pages[i].width = VIPS_RINT( width * pdf->scale ); - pdf->pages[i].height = VIPS_RINT( height * pdf->scale ); + pdf->pages[i].width = VIPS_RINT( width * pdf->total_scale ); + pdf->pages[i].height = VIPS_RINT( height * pdf->total_scale ); if( pdf->pages[i].width > pdf->image.width ) pdf->image.width = pdf->pages[i].width; @@ -421,10 +426,10 @@ vips_foreign_load_pdf_generate( VipsRegion *or, cr = cairo_create( surface ); cairo_surface_destroy( surface ); - cairo_scale( cr, pdf->scale, pdf->scale ); + cairo_scale( cr, pdf->total_scale, pdf->total_scale ); cairo_translate( cr, - (pdf->pages[i].left - rect.left) / pdf->scale, - (pdf->pages[i].top - rect.top) / pdf->scale ); + (pdf->pages[i].left - rect.left) / pdf->total_scale, + (pdf->pages[i].top - rect.top) / pdf->total_scale ); /* poppler is single-threaded, but we don't need to lock since * we're running inside a non-threaded tilecache. @@ -862,9 +867,8 @@ vips_foreign_load_pdf_is_a( const char *filename ) * left. Set to -1 to mean "until the end of the document". Use vips_grid() * to change page layout. * - * Use @dpi to set the rendering resolution. The default is 72. Alternatively, - * you can scale the rendering from the default 1 point == 1 pixel by - * setting @scale. + * Use @dpi to set the rendering resolution. The default is 72. Additionally, + * you can scale by setting @scale. If you set both, they combine. * * Use @background to set the background RGBA colour. The default is 255 * (solid white), use eg. 0 for a transparent background. From 10bada0161abf0cc8b33c8284b8173ba3dea3852 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 21 Sep 2020 09:38:11 +0100 Subject: [PATCH 2/3] tiny thumbnail speedup thumbnail can skip premultiply/unpre if there's no residual resize --- libvips/resample/thumbnail.c | 38 +++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/libvips/resample/thumbnail.c b/libvips/resample/thumbnail.c index b6ffe672..88b18d8a 100644 --- a/libvips/resample/thumbnail.c +++ b/libvips/resample/thumbnail.c @@ -736,24 +736,6 @@ vips_thumbnail_build( VipsObject *object ) return( -1 ); in = t[2]; - /* If there's an alpha, we have to premultiply before shrinking. See - * https://github.com/libvips/libvips/issues/291 - */ - have_premultiplied = FALSE; - if( vips_image_hasalpha( in ) ) { - g_info( "premultiplying alpha" ); - if( vips_premultiply( in, &t[3], NULL ) ) - return( -1 ); - have_premultiplied = TRUE; - - /* vips_premultiply() makes a float image. When we - * vips_unpremultiply() below, we need to cast back to the - * pre-premultiply format. - */ - unpremultiplied_format = in->BandFmt; - in = t[3]; - } - /* Shrink to preshrunk_page_height, so we work for multi-page images. */ vips_thumbnail_calculate_shrink( thumbnail, @@ -771,6 +753,26 @@ vips_thumbnail_build( VipsObject *object ) vshrink = (double) in->Ysize / target_image_height; } + /* If there's an alpha, we have to premultiply before shrinking. See + * https://github.com/libvips/libvips/issues/291 + */ + have_premultiplied = FALSE; + if( vips_image_hasalpha( in ) && + hshrink != 1.0 && + vshrink != 1.0 ) { + g_info( "premultiplying alpha" ); + if( vips_premultiply( in, &t[3], NULL ) ) + return( -1 ); + have_premultiplied = TRUE; + + /* vips_premultiply() makes a float image. When we + * vips_unpremultiply() below, we need to cast back to the + * pre-premultiply format. + */ + unpremultiplied_format = in->BandFmt; + in = t[3]; + } + if( vips_resize( in, &t[4], 1.0 / hshrink, "vscale", 1.0 / vshrink, NULL ) ) From 54144a8bc5a90f6f7885680ff9414d89f5cd667c Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 21 Sep 2020 09:45:08 +0100 Subject: [PATCH 3/3] allow gaussblur sigma 0 meaning no blur (obviosuly) --- ChangeLog | 1 + libvips/convolution/gaussblur.c | 39 ++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1eb7cf4c..34a9525b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ - bump minimum libheif version to 1.3 [lovell] - dzsave in iiif mode could set info.json dimensions off by one [Linden6] - pdfload allows dpi and scale to both be set [le0daniel] +- allow gaussblur sigma zero, meaning no blur 9/8/20 started 8.10.1 - fix markdown -> xml conversion in doc generation diff --git a/libvips/convolution/gaussblur.c b/libvips/convolution/gaussblur.c index 215eefd9..e5228542 100644 --- a/libvips/convolution/gaussblur.c +++ b/libvips/convolution/gaussblur.c @@ -4,6 +4,9 @@ * - from vips_sharpen() * 19/11/14 * - change parameters to be more imagemagick-like + * 21/9/20 + * - allow sigma zero, meaning no blur + * - sigma < 0.2 is just copy */ /* @@ -73,23 +76,33 @@ vips_gaussblur_build( VipsObject *object ) if( VIPS_OBJECT_CLASS( vips_gaussblur_parent_class )->build( object ) ) return( -1 ); - if( vips_gaussmat( &t[0], gaussblur->sigma, gaussblur->min_ampl, - "separable", TRUE, - "precision", gaussblur->precision, - NULL ) ) - return( -1 ); + /* vips_gaussmat() will make a 1x1 pixel mask for anything smaller than + * this. + */ + if( sigma < 0.2 ) { + if( vips_copy( gaussblur->in, &t[1], NULL ) ) + return( -1 ); + } + else { + if( vips_gaussmat( &t[0], + gaussblur->sigma, gaussblur->min_ampl, + "separable", TRUE, + "precision", gaussblur->precision, + NULL ) ) + return( -1 ); #ifdef DEBUG - printf( "gaussblur: blurring with:\n" ); - vips_matrixprint( t[0], NULL ); + printf( "gaussblur: blurring with:\n" ); + vips_matrixprint( t[0], NULL ); #endif /*DEBUG*/ - g_info( "gaussblur mask width %d", t[0]->Xsize ); + g_info( "gaussblur mask width %d", t[0]->Xsize ); - if( vips_convsep( gaussblur->in, &t[1], t[0], - "precision", gaussblur->precision, - NULL ) ) - return( -1 ); + if( vips_convsep( gaussblur->in, &t[1], t[0], + "precision", gaussblur->precision, + NULL ) ) + return( -1 ); + } g_object_set( object, "out", vips_image_new(), NULL ); @@ -132,7 +145,7 @@ vips_gaussblur_class_init( VipsGaussblurClass *class ) _( "Sigma of Gaussian" ), VIPS_ARGUMENT_REQUIRED_INPUT, G_STRUCT_OFFSET( VipsGaussblur, sigma ), - 0.01, 1000, 1.5 ); + 0.0, 1000, 1.5 ); VIPS_ARG_DOUBLE( class, "min_ampl", 3, _( "Minimum amplitude" ),