magicksave: Add bitdepth option (#2819)

* flag to save bmp with bitdepth 1

* magicksave: add bitdepth option

* update comments

* update documentation

* revised based on review comments

Co-authored-by: Thomas Barton <thomasryanbarton@gmail.com>
This commit is contained in:
Daniel Löbl 2022-05-27 12:41:01 +02:00 committed by GitHub
parent 2af2ca5ca2
commit ed79cfba7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 56 additions and 0 deletions

View File

@ -28,6 +28,7 @@
- add vips_target_end(), deprecate vips_target_finish()
- add "mixed" to webpsave [dloebl]
- add "reoptimise" to gifsave [dloebl]
- add "bitdepth" to magicksave [dloebl]
26/11/21 started 8.12.3
- better arg checking for vips_hist_find_ndim() [travisbell]

View File

@ -286,6 +286,19 @@ magick_ismagick( const unsigned char *bytes, size_t length )
GetImageMagick( bytes, length, format ) );
}
int
magick_quantize_images( Image *images,
const size_t depth, ExceptionInfo *exception )
{
QuantizeInfo info;
GetQuantizeInfo( &info );
info.number_colors = 1 << depth;
QuantizeImages( &info, images, exception );
return( exception->severity == UndefinedException );
}
#endif /*HAVE_MAGICK7*/
#ifdef HAVE_MAGICK6
@ -616,6 +629,17 @@ magick_ismagick( const unsigned char *bytes, size_t length )
#endif
}
int
magick_quantize_images( Image *images,
const size_t depth, ExceptionInfo *exception )
{
QuantizeInfo info;
GetQuantizeInfo( &info );
info.number_colors = (1 << depth);
return QuantizeImages( &info, images );
}
#endif /*HAVE_MAGICK6*/
#if defined(HAVE_MAGICK6) || defined(HAVE_MAGICK7)

View File

@ -88,6 +88,8 @@ int magick_optimize_image_layers( Image **images, ExceptionInfo *exception );
int magick_optimize_image_transparency( const Image *images,
ExceptionInfo *exception );
int magick_quantize_images( Image *images, const size_t depth, ExceptionInfo *exception );
gboolean magick_ismagick( const unsigned char *bytes, size_t length );
#endif /*HAVE_MAGICK6*/

View File

@ -66,6 +66,7 @@
* * @format: %gchararray, format to save as
* * @optimize_gif_frames: %gboolean, apply GIF frames optimization
* * @optimize_gif_transparency: %gboolean, apply GIF transparency optimization
* * @bitdepth: %gint, number of bits per pixel
*
* Write an image using libMagick.
*
@ -83,6 +84,9 @@
* through animation are made transparent. This takes some time for computation
* but saves some time on encoding and produces smaller files in some cases.
*
* @bitdepth specifies the number of bits per pixel. The image will be quantized
* and dithered if the value is within the valid range (1 to 8).
*
* See also: vips_magicksave_buffer(), vips_magickload().
*
* Returns: 0 on success, -1 on error.
@ -113,6 +117,7 @@ vips_magicksave( VipsImage *in, const char *filename, ... )
* * @format: %gchararray, format to save as
* * @optimize_gif_frames: %gboolean, apply GIF frames optimization
* * @optimize_gif_transparency: %gboolean, apply GIF transparency optimization
* * @bitdepth: %gint, number of bits per pixel
*
* As vips_magicksave(), but save to a memory buffer.
*

View File

@ -69,6 +69,7 @@ typedef struct _VipsForeignSaveMagick {
char *filename; /* NULL during buffer output */
char *format;
int quality;
int bitdepth;
gboolean optimize_gif_frames;
gboolean optimize_gif_transparency;
@ -406,6 +407,21 @@ vips_foreign_save_magick_build( VipsObject *object )
return( -1 );
}
}
/* Bitdepth <= 8 requested? Quantize/Dither images.
* ImageMagick then selects the appropriate bit depth when writing
* the actual image (e.g. BMP or GIF).
*/
if( magick->bitdepth ) {
if ( !magick_quantize_images( magick->images,
magick->bitdepth, magick->exception ) ) {
magick_inherit_exception( magick->exception,
magick->images );
magick_vips_error( class->nickname, magick->exception );
return( -1 );
}
}
return( 0 );
}
@ -493,6 +509,13 @@ vips_foreign_save_magick_class_init( VipsForeignSaveMagickClass *class )
G_STRUCT_OFFSET( VipsForeignSaveMagick,
optimize_gif_transparency ),
FALSE );
VIPS_ARG_INT( class, "bitdepth", 6,
_( "Image bitdepth" ),
_( "Image bitdepth. Default is auto bitdepth." ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignSaveMagick, bitdepth ),
0, 8, 0);
}
static void
@ -502,6 +525,7 @@ vips_foreign_save_magick_init( VipsForeignSaveMagick *magick )
* int array later.
*/
g_value_init( &magick->delay_gvalue, G_TYPE_INT );
magick->bitdepth = 0;
}
typedef struct _VipsForeignSaveMagickFile {