set dispose in magicksave

since we always give complete new frames

revise gifload slightly too
This commit is contained in:
John Cupitt 2019-02-16 17:37:23 +00:00
parent ca60cc30aa
commit 30b5c49d0b
2 changed files with 20 additions and 26 deletions

View File

@ -88,10 +88,6 @@
#endif #endif
/* Added in giflib5. /* Added in giflib5.
*
* DO_NOT - no dispose action after frame load
* BACKGROUND - after frame load, reset to 0 (transparent)
* PREVIOUS - after frame load, reset previous
*/ */
#ifndef HAVE_GIFLIB_5 #ifndef HAVE_GIFLIB_5
#define DISPOSAL_UNSPECIFIED 0 #define DISPOSAL_UNSPECIFIED 0
@ -734,33 +730,26 @@ vips_foreign_load_gif_render( VipsForeignLoadGif *gif )
*/ */
vips_foreign_load_gif_build_cmap( gif ); vips_foreign_load_gif_build_cmap( gif );
/* DISPOSE_BACKGROUND means transparent pixels in this frame will show /* BACKGROUND means we reset the frame to 0 (transparent) before we
* the background of the web page, ie. be transparent. * render the next set of pixels.
*
* PREVIOUS means we init with the last non-previous frame.
*
* Otherwise, we must update previous.
*/ */
if( gif->dispose == DISPOSE_BACKGROUND ) { if( gif->dispose == DISPOSE_BACKGROUND )
VIPS_DEBUG_MSG( "vips_foreign_load_gif_render: "
"dispose clear to zero\n" );
memset( VIPS_IMAGE_ADDR( gif->frame, 0, 0 ), 0, memset( VIPS_IMAGE_ADDR( gif->frame, 0, 0 ), 0,
VIPS_IMAGE_SIZEOF_IMAGE( gif->frame ) ); VIPS_IMAGE_SIZEOF_IMAGE( gif->frame ) );
}
else if( gif->dispose == DISPOSE_PREVIOUS ) { /* PREVIOUS means we init the frame with the frame before last, ie. we
VIPS_DEBUG_MSG( "vips_foreign_load_gif_render: " * undo the last render.
"dispose restore from previous\n" ); *
* Anything other than PREVIOUS, we must update the previous buffer,
*/
if( gif->dispose == DISPOSE_PREVIOUS )
memcpy( VIPS_IMAGE_ADDR( gif->frame, 0, 0 ), memcpy( VIPS_IMAGE_ADDR( gif->frame, 0, 0 ),
VIPS_IMAGE_ADDR( gif->previous, 0, 0 ), VIPS_IMAGE_ADDR( gif->previous, 0, 0 ),
VIPS_IMAGE_SIZEOF_IMAGE( gif->frame ) ); VIPS_IMAGE_SIZEOF_IMAGE( gif->frame ) );
} else
else {
VIPS_DEBUG_MSG( "vips_foreign_load_gif_render: "
"dispose copy to previous\n" );
memcpy( VIPS_IMAGE_ADDR( gif->previous, 0, 0 ), memcpy( VIPS_IMAGE_ADDR( gif->previous, 0, 0 ),
VIPS_IMAGE_ADDR( gif->frame, 0, 0 ), VIPS_IMAGE_ADDR( gif->frame, 0, 0 ),
VIPS_IMAGE_SIZEOF_IMAGE( gif->frame ) ); VIPS_IMAGE_SIZEOF_IMAGE( gif->frame ) );
}
if( file->Image.Interlace ) { if( file->Image.Interlace ) {
int i; int i;

View File

@ -93,7 +93,7 @@ static int
vips_foreign_save_magick_set_properties( VipsForeignSaveMagick *magick, vips_foreign_save_magick_set_properties( VipsForeignSaveMagick *magick,
Image *image, VipsImage *im ) Image *image, VipsImage *im )
{ {
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( magick ); VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( magick );
int number; int number;
const char *str; const char *str;
@ -110,10 +110,15 @@ vips_foreign_save_magick_set_properties( VipsForeignSaveMagick *magick,
!vips_image_get_string( im, "gif-comment", &str ) ) !vips_image_get_string( im, "gif-comment", &str ) )
magick_set_property( image, "comment", str, magick->exception ); magick_set_property( image, "comment", str, magick->exception );
if( magick_set_magick_profile( image, im, magick->exception ) ) { /* libvips keeps animations as a set of independent frames, so we want
* to clear to the background between each one.
*/
image->dispose = BackgroundDispose;
if( magick_set_magick_profile( image, im, magick->exception ) ) {
magick_vips_error( class->nickname, magick->exception ); magick_vips_error( class->nickname, magick->exception );
return( -1 ); return( -1 );
} }
return( 0 ); return( 0 );
} }