From 8a354c5aecff341f509af2ad24e24066161e144f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 27 Jun 2019 18:44:38 +0100 Subject: [PATCH] improve webp rgba handling disable webp alpha output if all frame fill the canvas and are solid see https://github.com/libvips/libvips/issues/1351 --- ChangeLog | 1 + libvips/foreign/webp2vips.c | 47 ++++++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index bf0e16f0..ad086f4e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 20/6/19 started 8.9.0 - add vips_image_get/set_array_int() +- disable webp alpha output if all frame fill the canvas and are solid 24/5/19 started 8.8.1 - improve realpath() use on older libc diff --git a/libvips/foreign/webp2vips.c b/libvips/foreign/webp2vips.c index 695e87c1..28d0a0dd 100644 --- a/libvips/foreign/webp2vips.c +++ b/libvips/foreign/webp2vips.c @@ -97,17 +97,22 @@ typedef struct { */ double scale; + /* Size of each frame in input image coordinates. + */ + int canvas_width; + int canvas_height; + + /* Size of each frame, in scaled output image coordinates, + */ + int frame_width; + int frame_height; + /* Size of final output image. */ int width; int height; - /* Size of each frame. - */ - int frame_width; - int frame_height; - - /* TRUE for RGBA. + /* TRUE if we will save the final image as RGBA. */ int alpha; @@ -418,8 +423,6 @@ static int read_header( Read *read, VipsImage *out ) { WebPData data; - int canvas_width; - int canvas_height; int flags; int i; @@ -430,16 +433,19 @@ read_header( Read *read, VipsImage *out ) return( -1 ); } - canvas_width = WebPDemuxGetI( read->demux, WEBP_FF_CANVAS_WIDTH ); - canvas_height = WebPDemuxGetI( read->demux, WEBP_FF_CANVAS_HEIGHT ); + read->canvas_width = + WebPDemuxGetI( read->demux, WEBP_FF_CANVAS_WIDTH ); + read->canvas_height = + WebPDemuxGetI( read->demux, WEBP_FF_CANVAS_HEIGHT ); + /* We round-to-nearest cf. pdfload etc. */ - read->frame_width = VIPS_RINT( canvas_width * read->scale ); - read->frame_height = VIPS_RINT( canvas_height * read->scale ); + read->frame_width = VIPS_RINT( read->canvas_width * read->scale ); + read->frame_height = VIPS_RINT( read->canvas_height * read->scale ); #ifdef DEBUG - printf( "webp2vips: canvas_width = %d\n", canvas_width ); - printf( "webp2vips: canvas_height = %d\n", canvas_height ); + printf( "webp2vips: canvas_width = %d\n", read->canvas_width ); + printf( "webp2vips: canvas_height = %d\n", read->canvas_height ); printf( "webp2vips: frame_width = %d\n", read->frame_width ); printf( "webp2vips: frame_height = %d\n", read->frame_height ); #endif /*DEBUG*/ @@ -484,6 +490,19 @@ read_header( Read *read, VipsImage *out ) */ vips_image_set_int( out, "gif-delay", VIPS_RINT( read->delay / 10.0 ) ); + + /* If we find a frame which doesn't fill the canvas, + * we'll need to save as RGBA. + */ + do { + if( iter.x_offset != 0 || + iter.y_offset != 0 || + iter.width != read->canvas_width || + iter.height != read->canvas_height ) { + read->alpha = TRUE; + break; + } + } while( WebPDemuxNextFrame( &iter ) ); } WebPDemuxReleaseIterator( &iter );