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
This commit is contained in:
John Cupitt 2019-06-27 18:44:38 +01:00
parent 72c103f95a
commit 8a354c5aec
2 changed files with 34 additions and 14 deletions

View File

@ -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

View File

@ -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 );