Merge pull request #1385 from DarthSim/feature/optimize_gif
Add GIF optimization options to …
This commit is contained in:
commit
43d678c145
@ -692,7 +692,7 @@ if test x"$magick6" = x"yes"; then
|
||||
# IM
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$LIBS $MAGICK_LIBS"
|
||||
AC_CHECK_FUNCS([InheritException AcquireExceptionInfo SetImageProperty SetImageExtent AcquireImage GetVirtualPixels ResetImageProfileIterator ResetImageAttributeIterator ResetImagePropertyIterator MagickCoreGenesis SetImageOption BlobToStringInfo])
|
||||
AC_CHECK_FUNCS([InheritException AcquireExceptionInfo SetImageProperty SetImageExtent AcquireImage GetVirtualPixels ResetImageProfileIterator ResetImageAttributeIterator ResetImagePropertyIterator MagickCoreGenesis SetImageOption BlobToStringInfo OptimizePlusImageLayers OptimizeImageTransparency])
|
||||
LIBS="$save_LIBS"
|
||||
fi
|
||||
|
||||
|
@ -205,6 +205,31 @@ magick_set_number_scenes( ImageInfo *image_info, int scene, int number_scenes )
|
||||
image_info->scenes = strdup( page );
|
||||
}
|
||||
|
||||
int
|
||||
magick_optimize_image_layers( Image **images, ExceptionInfo *exception )
|
||||
{
|
||||
Image *tmp;
|
||||
|
||||
tmp = OptimizePlusImageLayers(*images, exception );
|
||||
|
||||
if ( exception->severity != UndefinedException )
|
||||
return MagickFalse;
|
||||
|
||||
VIPS_FREEF( DestroyImageList, *images );
|
||||
|
||||
*images = tmp;
|
||||
|
||||
return MagickTrue;
|
||||
}
|
||||
|
||||
int
|
||||
magick_optimize_image_transparency( const Image *images,
|
||||
ExceptionInfo *exception )
|
||||
{
|
||||
OptimizeImageTransparency(images, exception);
|
||||
return ( exception->severity == UndefinedException );
|
||||
}
|
||||
|
||||
/* Does a few bytes look like a file IM can handle?
|
||||
*/
|
||||
gboolean
|
||||
@ -445,6 +470,43 @@ magick_set_number_scenes( ImageInfo *image_info, int scene, int number_scenes )
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
magick_optimize_image_layers( Image **images, ExceptionInfo *exception )
|
||||
{
|
||||
#ifdef HAS_OPTIMIZEPLUSIMAGELAYERS
|
||||
Image *tmp;
|
||||
|
||||
tmp = OptimizePlusImageLayers(*images, exception );
|
||||
|
||||
if ( exception->severity != UndefinedException )
|
||||
return MagickFalse;
|
||||
|
||||
VIPS_FREEF( DestroyImageList, *images );
|
||||
|
||||
*images = tmp;
|
||||
|
||||
return MagickTrue;
|
||||
#else
|
||||
g_warning( "%s", _( "layers optimization is not supported by your version "
|
||||
"of libMagick" ) );
|
||||
return MagickTrue;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
magick_optimize_image_transparency( const Image *images,
|
||||
ExceptionInfo *exception )
|
||||
{
|
||||
#ifdef HAS_OPTIMIZEIMAGETRANSPARENCY
|
||||
OptimizeImageTransparency(images, exception);
|
||||
return ( exception->severity == UndefinedException );
|
||||
#else
|
||||
g_warning( "%s", _( "transparency optimization is not supported by your "
|
||||
"version of libMagick" ) );
|
||||
return MagickTrue;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Does a few bytes look like a file IM can handle?
|
||||
*/
|
||||
gboolean
|
||||
|
@ -84,6 +84,10 @@ int magick_set_vips_profile( VipsImage *im, Image *image );
|
||||
int magick_set_magick_profile( Image *image,
|
||||
VipsImage *im, ExceptionInfo *exception );
|
||||
|
||||
int magick_optimize_image_layers( Image **images, ExceptionInfo *exception );
|
||||
int magick_optimize_image_transparency( const Image *images,
|
||||
ExceptionInfo *exception );
|
||||
|
||||
gboolean magick_ismagick( const unsigned char *bytes, size_t length );
|
||||
|
||||
#endif /*HAVE_MAGICK6*/
|
||||
|
@ -10,6 +10,8 @@
|
||||
* - support "strip" option
|
||||
* 6/7/19 [deftomat]
|
||||
* - support array of delays
|
||||
* 5/8/19 DarthSim
|
||||
* - support GIF optimization
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -63,6 +65,8 @@ typedef struct _VipsForeignSaveMagick {
|
||||
char *filename; /* NULL during buffer output */
|
||||
char *format;
|
||||
int quality;
|
||||
gboolean optimize_gif_frames;
|
||||
gboolean optimize_gif_transparency;
|
||||
|
||||
ImageInfo *image_info;
|
||||
ExceptionInfo *exception;
|
||||
@ -365,6 +369,24 @@ vips_foreign_save_magick_build( VipsObject *object )
|
||||
vips_foreign_save_magick_write_block, magick ) )
|
||||
return( -1 );
|
||||
|
||||
if( magick->optimize_gif_frames ) {
|
||||
if( !magick_optimize_image_layers(&magick->images, magick->exception ) ) {
|
||||
magick_inherit_exception( magick->exception, magick->images );
|
||||
magick_vips_error( class->nickname, magick->exception );
|
||||
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( magick->optimize_gif_transparency ) {
|
||||
if( !magick_optimize_image_transparency(magick->images, magick->exception) ) {
|
||||
magick_inherit_exception( magick->exception, magick->images );
|
||||
magick_vips_error( class->nickname, magick->exception );
|
||||
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@ -428,6 +450,20 @@ vips_foreign_save_magick_class_init( VipsForeignSaveMagickClass *class )
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignSaveMagick, quality ),
|
||||
0, 100, 0 );
|
||||
|
||||
VIPS_ARG_BOOL( class, "optimize_gif_frames", 4,
|
||||
_( "Optimize_gif_frames" ),
|
||||
_( "Apply GIF frames optimization" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignSaveMagick, optimize_gif_frames ),
|
||||
FALSE );
|
||||
|
||||
VIPS_ARG_BOOL( class, "optimize_gif_transparency", 5,
|
||||
_( "Optimize_gif_transparency" ),
|
||||
_( "Apply GIF transparency optimization" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignSaveMagick, optimize_gif_transparency ),
|
||||
FALSE );
|
||||
}
|
||||
|
||||
static void
|
||||
@ -586,6 +622,8 @@ vips_foreign_save_magick_buffer_init( VipsForeignSaveMagickBuffer *buffer )
|
||||
*
|
||||
* * @quality: %gint, quality factor
|
||||
* * @format: %gchararray, format to save as
|
||||
* * @optimize_gif_frames: %gboolean, apply GIF frames optimization
|
||||
* * @optimize_gif_transparency: %gboolean, apply GIF transparency optimization
|
||||
*
|
||||
* Write an image using libMagick.
|
||||
*
|
||||
@ -594,6 +632,15 @@ vips_foreign_save_magick_buffer_init( VipsForeignSaveMagickBuffer *buffer )
|
||||
* Use @format to explicitly set the save format, for example, "BMP". Otherwise
|
||||
* the format is guessed from the filename suffix.
|
||||
*
|
||||
* If @optimize_gif_frames is set, GIF frames are cropped to the smallest size
|
||||
* while preserving the results of the GIF animation. This takes some time for
|
||||
* computation but saves some time on encoding and produces smaller files in
|
||||
* some cases.
|
||||
*
|
||||
* If @optimize_gif_transparency is set, pixels that don't change the image
|
||||
* through animation are made transparent. This takes some time for computation
|
||||
* but saves some time on encoding and produces smaller files in some cases.
|
||||
*
|
||||
* See also: vips_magicksave_buffer(), vips_magickload().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
@ -622,6 +669,8 @@ vips_magicksave( VipsImage *in, const char *filename, ... )
|
||||
*
|
||||
* * @quality: %gint, quality factor
|
||||
* * @format: %gchararray, format to save as
|
||||
* * @optimize_gif_frames: %gboolean, apply GIF frames optimization
|
||||
* * @optimize_gif_transparency: %gboolean, apply GIF transparency optimization
|
||||
*
|
||||
* As vips_magicksave(), but save to a memory buffer.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user