From 25bf910f217380ab27e6dc83e1061005c359e277 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 9 May 2015 16:33:38 +0100 Subject: [PATCH] vipsthumbnail uses vips_premultiply() --- ChangeLog | 1 + TODO | 1 + tools/vipsthumbnail.c | 56 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index e3a1d1a3..f114bb1a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ - add vips_premultiply(), vips_unpremultiply() - change the alpha range rules for vips_flatten() to match vips_premultiply() - vipsthumbnail uses vips_resize() rather than its own code +- vipsthumbnail uses vips_premultiply() for better alpha quality 4/5/15 started 8.0.2 - fix a refcount error in C++ wrapper, thanks huskier diff --git a/TODO b/TODO index 31b87df5..a6fbff9c 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,4 @@ +- get vipsthumbnail to use vips_premultiply() etc - are the mosaic functions calling vips_fastcor()? it must be very slow diff --git a/tools/vipsthumbnail.c b/tools/vipsthumbnail.c index 4bd17672..a29651c5 100644 --- a/tools/vipsthumbnail.c +++ b/tools/vipsthumbnail.c @@ -67,6 +67,7 @@ * - rename -o as -f, keep -o as a hidden flag * 9/5/15 * - use vips_resize() instead of our own code + * - premultiply alpha */ #ifdef HAVE_CONFIG_H @@ -346,12 +347,15 @@ thumbnail_shrink( VipsObject *process, VipsImage *in, */ gboolean have_imported; - int shrink; - double residual; - int tile_width; - int tile_height; - int nlines; - double sigma; + /* TRUE if we've premultiplied and need to unpremultiply. + */ + gboolean have_premultiplied; + + /* Sniff the incoming image and try to guess what the alpha max is. + */ + double max_alpha; + + double shrink; /* RAD needs special unpacking. */ @@ -365,6 +369,12 @@ thumbnail_shrink( VipsObject *process, VipsImage *in, in = t[0]; } + /* Try to guess what the maximum alpha might be. + */ + max_alpha = 255; + if( in->BandFmt == VIPS_FORMAT_USHORT ) + max_alpha = 65535; + /* In linear mode, we import right at the start. * * We also have to import the whole image if it's CMYK, since @@ -409,17 +419,42 @@ thumbnail_shrink( VipsObject *process, VipsImage *in, return( NULL ); in = t[2]; + /* If there's an alpha, we have to premultiply before shrinking. See + * https://github.com/jcupitt/libvips/issues/291 + */ + have_premultiplied = FALSE; + if( in->Bands == 2 || + (in->Bands == 4 && in->Type != VIPS_INTERPRETATION_CMYK) || + in->Bands == 5 ) { + vips_info( "vipsthumbnail", "premultiplying alpha" ); + if( vips_premultiply( in, &t[3], + "max_alpha", max_alpha, + NULL ) ) + return( NULL ); + in = t[3]; + have_premultiplied = TRUE; + } + shrink = calculate_shrink( in ); - vips_info( "vipsthumbnail", "resize by %d", shrink ); + vips_info( "vipsthumbnail", "shrink by %g", shrink ); vips_info( "vipsthumbnail", "%s interpolation", VIPS_OBJECT_GET_CLASS( interp )->nickname ); - if( vips_resize( in, &t[3], 1.0 / shrink, + if( vips_resize( in, &t[4], 1.0 / shrink, "interpolate", interp, NULL ) ) return( NULL ); - in = t[3]; + in = t[4]; + + if( have_premultiplied ) { + vips_info( "vipsthumbnail", "unpremultiplying alpha" ); + if( vips_unpremultiply( in, &t[5], + "max_alpha", max_alpha, + NULL ) ) + return( NULL ); + in = t[5]; + } /* Colour management. * @@ -500,8 +535,7 @@ thumbnail_shrink( VipsObject *process, VipsImage *in, /* If we are upsampling, don't sharpen, since nearest looks dumb * sharpened. */ - if( shrink >= 1 && - residual <= 1.0 && + if( shrink > 1.0 && sharpen ) { vips_info( "vipsthumbnail", "sharpening thumbnail" ); if( vips_conv( in, &t[8], sharpen, NULL ) )