diff --git a/ChangeLog b/ChangeLog index af3189b9..6b3907e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,8 @@ - better handling of unaligned reads in multipage tiffs [petoor] - mark old --delete option to vipsthumbnail as deprecated [UweOhse] - png save with a bad ICC profile just gives a warning +- add "premultipled" option to vips_affine(), clarified vips_resize() + behaviour with alpha channels 24/4/20 started 8.9.3 - better iiif tile naming [IllyaMoskvin] diff --git a/libvips/resample/affine.c b/libvips/resample/affine.c index cbf6903a..b75cd73d 100644 --- a/libvips/resample/affine.c +++ b/libvips/resample/affine.c @@ -88,6 +88,8 @@ * - add "background" parameter * - better clipping means we have no jaggies on edges * - premultiply alpha + * 18/5/20 + * - add "premultiplied" flag */ /* @@ -166,6 +168,10 @@ typedef struct _VipsAffine { */ VipsPel *ink; + /* True if the input is already premultiplied (and we don't need to). + */ + gboolean premultiplied; + } VipsAffine; typedef VipsResampleClass VipsAffineClass; @@ -524,11 +530,13 @@ vips_affine_build( VipsObject *object ) affine->trn.idx -= 1; affine->trn.idy -= 1; - /* If there's an alpha, we have to premultiply before resampling. See + /* If there's an alpha and we've not premultiplied, we have to + * premultiply before resampling. See * https://github.com/libvips/libvips/issues/291 */ have_premultiplied = FALSE; - if( vips_image_hasalpha( in ) ) { + if( vips_image_hasalpha( in ) && + !affine->premultiplied ) { if( vips_premultiply( in, &t[3], NULL ) ) return( -1 ); have_premultiplied = TRUE; @@ -680,6 +688,13 @@ vips_affine_class_init( VipsAffineClass *class ) G_STRUCT_OFFSET( VipsAffine, background ), VIPS_TYPE_ARRAY_DOUBLE ); + VIPS_ARG_BOOL( class, "premultiplied", 117, + _( "Premultiplied" ), + _( "Images have premultiplied alpha" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsAffine, premultiplied ), + FALSE ); + } static void @@ -709,6 +724,7 @@ vips_affine_init( VipsAffine *affine ) * * @ody: %gdouble, output vertical offset * * @extend: #VipsExtend how to generate new pixels * * @background: #VipsArrayDouble colour for new pixels + * * @premultiplied: %gboolean, images are already premultiplied * * This operator performs an affine transform on an image using @interpolate. * @@ -737,6 +753,10 @@ vips_affine_init( VipsAffine *affine ) * * @idx, @idy, @odx, @ody default to zero. * + * Image are normally treated as unpremultiplied, so this operation can be used + * directly on PNG images. If your images have been through vips_premultiply(), + * set @premultiplied. + * * This operation does not change xres or yres. The image resolution needs to * be updated by the application. * diff --git a/libvips/resample/resize.c b/libvips/resample/resize.c index d56e4e13..28235351 100644 --- a/libvips/resample/resize.c +++ b/libvips/resample/resize.c @@ -289,6 +289,7 @@ vips_resize_build( VipsObject *object ) "idx", id, "idy", id, "extend", VIPS_EXTEND_COPY, + "premultiplied", TRUE, NULL ) ) return( -1 ); in = t[4]; @@ -300,6 +301,7 @@ vips_resize_build( VipsObject *object ) "idx", id, "idy", id, "extend", VIPS_EXTEND_COPY, + "premultiplied", TRUE, NULL ) ) return( -1 ); in = t[4]; @@ -311,6 +313,7 @@ vips_resize_build( VipsObject *object ) "idx", id, "idy", id, "extend", VIPS_EXTEND_COPY, + "premultiplied", TRUE, NULL ) ) return( -1 ); in = t[4]; @@ -444,7 +447,10 @@ vips_resize_init( VipsResize *resize ) * This operation does not change xres or yres. The image resolution needs to * be updated by the application. * - * See also: vips_shrink(), vips_reduce(). + * This operation does not premultiply alpha. If your image has an alpha + * channel, you should use vips_premultiply() on it first. + * + * See also: vips_premultiply(), vips_shrink(), vips_reduce(). * * Returns: 0 on success, -1 on error */