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 20/6/19 started 8.9.0
- add vips_image_get/set_array_int() - 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 24/5/19 started 8.8.1
- improve realpath() use on older libc - improve realpath() use on older libc

View File

@ -97,17 +97,22 @@ typedef struct {
*/ */
double scale; 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. /* Size of final output image.
*/ */
int width; int width;
int height; int height;
/* Size of each frame. /* TRUE if we will save the final image as RGBA.
*/
int frame_width;
int frame_height;
/* TRUE for RGBA.
*/ */
int alpha; int alpha;
@ -418,8 +423,6 @@ static int
read_header( Read *read, VipsImage *out ) read_header( Read *read, VipsImage *out )
{ {
WebPData data; WebPData data;
int canvas_width;
int canvas_height;
int flags; int flags;
int i; int i;
@ -430,16 +433,19 @@ read_header( Read *read, VipsImage *out )
return( -1 ); return( -1 );
} }
canvas_width = WebPDemuxGetI( read->demux, WEBP_FF_CANVAS_WIDTH ); read->canvas_width =
canvas_height = WebPDemuxGetI( read->demux, WEBP_FF_CANVAS_HEIGHT ); WebPDemuxGetI( read->demux, WEBP_FF_CANVAS_WIDTH );
read->canvas_height =
WebPDemuxGetI( read->demux, WEBP_FF_CANVAS_HEIGHT );
/* We round-to-nearest cf. pdfload etc. /* We round-to-nearest cf. pdfload etc.
*/ */
read->frame_width = VIPS_RINT( canvas_width * read->scale ); read->frame_width = VIPS_RINT( read->canvas_width * read->scale );
read->frame_height = VIPS_RINT( canvas_height * read->scale ); read->frame_height = VIPS_RINT( read->canvas_height * read->scale );
#ifdef DEBUG #ifdef DEBUG
printf( "webp2vips: canvas_width = %d\n", canvas_width ); printf( "webp2vips: canvas_width = %d\n", read->canvas_width );
printf( "webp2vips: canvas_height = %d\n", canvas_height ); printf( "webp2vips: canvas_height = %d\n", read->canvas_height );
printf( "webp2vips: frame_width = %d\n", read->frame_width ); printf( "webp2vips: frame_width = %d\n", read->frame_width );
printf( "webp2vips: frame_height = %d\n", read->frame_height ); printf( "webp2vips: frame_height = %d\n", read->frame_height );
#endif /*DEBUG*/ #endif /*DEBUG*/
@ -484,6 +490,19 @@ read_header( Read *read, VipsImage *out )
*/ */
vips_image_set_int( out, "gif-delay", vips_image_set_int( out, "gif-delay",
VIPS_RINT( read->delay / 10.0 ) ); 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 ); WebPDemuxReleaseIterator( &iter );