pngsave: expose quantisation effort setting (#2367)
This commit is contained in:
parent
9221fae973
commit
aabb1555d2
@ -187,7 +187,7 @@ int vips__png_write_target( VipsImage *in, VipsTarget *target,
|
||||
int compress, int interlace, const char *profile,
|
||||
VipsForeignPngFilter filter, gboolean strip,
|
||||
gboolean palette, int Q, double dither,
|
||||
int bitdepth );
|
||||
int bitdepth, int effort );
|
||||
|
||||
/* Map WEBP metadata names to vips names.
|
||||
*/
|
||||
@ -217,7 +217,7 @@ int vips__webp_write_target( VipsImage *image, VipsTarget *target,
|
||||
|
||||
int vips__quantise_image( VipsImage *in,
|
||||
VipsImage **index_out, VipsImage **palette_out,
|
||||
int colours, int Q, double dither );
|
||||
int colours, int Q, double dither, int effort );
|
||||
|
||||
extern const char *vips_foreign_nifti_suffs[];
|
||||
|
||||
|
@ -68,6 +68,7 @@ typedef struct _VipsForeignSavePng {
|
||||
int Q;
|
||||
double dither;
|
||||
int bitdepth;
|
||||
int effort;
|
||||
|
||||
/* Set by subclasses.
|
||||
*/
|
||||
@ -153,7 +154,7 @@ vips_foreign_save_png_build( VipsObject *object )
|
||||
if( vips__png_write_target( in, png->target,
|
||||
png->compression, png->interlace, png->profile, png->filter,
|
||||
save->strip, png->palette, png->Q, png->dither,
|
||||
png->bitdepth ) ) {
|
||||
png->bitdepth, png->effort ) ) {
|
||||
g_object_unref( in );
|
||||
return( -1 );
|
||||
}
|
||||
@ -262,6 +263,13 @@ vips_foreign_save_png_class_init( VipsForeignSavePngClass *class )
|
||||
G_STRUCT_OFFSET( VipsForeignSavePng, bitdepth ),
|
||||
0, 8, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "effort", 18,
|
||||
_( "Effort" ),
|
||||
_( "Quantisation CPU effort" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignSavePng, effort ),
|
||||
1, 10, 7 );
|
||||
|
||||
VIPS_ARG_INT( class, "colours", 14,
|
||||
_( "Colours" ),
|
||||
_( "Max number of palette colours" ),
|
||||
@ -278,6 +286,7 @@ vips_foreign_save_png_init( VipsForeignSavePng *png )
|
||||
png->filter = VIPS_FOREIGN_PNG_FILTER_ALL;
|
||||
png->Q = 100;
|
||||
png->dither = 1.0;
|
||||
png->effort = 7;
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignSavePngTarget {
|
||||
@ -464,6 +473,7 @@ vips_foreign_save_png_buffer_init( VipsForeignSavePngBuffer *buffer )
|
||||
* * @Q: %gint, quality for 8bpp quantisation
|
||||
* * @dither: %gdouble, amount of dithering for 8bpp quantization
|
||||
* * @bitdepth: %int, set write bit depth to 1, 2, 4 or 8
|
||||
* * @effort: %int, quantisation CPU effort
|
||||
*
|
||||
* Write a VIPS image to a file as PNG.
|
||||
*
|
||||
@ -492,8 +502,9 @@ vips_foreign_save_png_buffer_init( VipsForeignSavePngBuffer *buffer )
|
||||
*
|
||||
* Set @palette to %TRUE to enable palette mode for RGB or RGBA images. A
|
||||
* palette will be computed with enough space for @bitdepth (1, 2, 4 or 8)
|
||||
* bits. Use @Q to set the optimisation effort, and @dither to set the degree of
|
||||
* Floyd-Steinberg dithering.
|
||||
* bits. Use @Q to set the optimisation effort, @dither to set the degree of
|
||||
* Floyd-Steinberg dithering and @effort to control the CPU effort
|
||||
* (1 is the fastest, 10 is the slowest, 7 is the default).
|
||||
* This feature requires libvips to be compiled with libimagequant.
|
||||
*
|
||||
* You can also set @bitdepth for mono and mono + alpha images, and the image
|
||||
@ -536,6 +547,7 @@ vips_pngsave( VipsImage *in, const char *filename, ... )
|
||||
* * @Q: %gint, quality for 8bpp quantisation
|
||||
* * @dither: %gdouble, amount of dithering for 8bpp quantization
|
||||
* * @bitdepth: %int, set write bit depth to 1, 2, 4 or 8
|
||||
* * @effort: %int, quantisation CPU effort
|
||||
*
|
||||
* As vips_pngsave(), but save to a memory buffer.
|
||||
*
|
||||
@ -591,6 +603,7 @@ vips_pngsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
|
||||
* * @Q: quality for 8bpp quantisation
|
||||
* * @dither: amount of dithering for 8bpp quantization
|
||||
* * @bitdepth: %int, set write bit depth to 1, 2, 4 or 8
|
||||
* * @effort: %int, quantisation CPU effort
|
||||
*
|
||||
* As vips_pngsave(), but save to a target.
|
||||
*
|
||||
|
@ -53,11 +53,12 @@
|
||||
*/
|
||||
typedef struct _Quantise {
|
||||
VipsImage *in;
|
||||
VipsImage **index_out;
|
||||
VipsImage **palette_out;
|
||||
int colours;
|
||||
int Q;
|
||||
double dither;
|
||||
VipsImage **index_out;
|
||||
VipsImage **palette_out;
|
||||
int colours;
|
||||
int Q;
|
||||
double dither;
|
||||
int effort;
|
||||
|
||||
liq_attr *attr;
|
||||
liq_image *input_image;
|
||||
@ -83,7 +84,7 @@ vips__quantise_free( Quantise *quantise )
|
||||
static Quantise *
|
||||
vips__quantise_new( VipsImage *in,
|
||||
VipsImage **index_out, VipsImage **palette_out,
|
||||
int colours, int Q, double dither )
|
||||
int colours, int Q, double dither, int effort )
|
||||
{
|
||||
Quantise *quantise;
|
||||
int i;
|
||||
@ -95,6 +96,7 @@ vips__quantise_new( VipsImage *in,
|
||||
quantise->colours = colours;
|
||||
quantise->Q = Q;
|
||||
quantise->dither = dither;
|
||||
quantise->effort = effort;
|
||||
for( i = 0; i < VIPS_NUMBER( quantise->t ); i++ )
|
||||
quantise->t[i] = NULL;
|
||||
|
||||
@ -104,7 +106,7 @@ vips__quantise_new( VipsImage *in,
|
||||
int
|
||||
vips__quantise_image( VipsImage *in,
|
||||
VipsImage **index_out, VipsImage **palette_out,
|
||||
int colours, int Q, double dither )
|
||||
int colours, int Q, double dither, int effort )
|
||||
{
|
||||
Quantise *quantise;
|
||||
VipsImage *index;
|
||||
@ -113,7 +115,7 @@ vips__quantise_image( VipsImage *in,
|
||||
int i;
|
||||
|
||||
quantise = vips__quantise_new( in, index_out, palette_out,
|
||||
colours, Q, dither );
|
||||
colours, Q, dither, effort );
|
||||
|
||||
/* Ensure input is sRGB.
|
||||
*/
|
||||
@ -145,13 +147,14 @@ vips__quantise_image( VipsImage *in,
|
||||
quantise->attr = liq_attr_create();
|
||||
liq_set_max_colors( quantise->attr, colours );
|
||||
liq_set_quality( quantise->attr, 0, Q );
|
||||
liq_set_speed( quantise->attr, 11 - effort );
|
||||
|
||||
quantise->input_image = liq_image_create_rgba( quantise->attr,
|
||||
VIPS_IMAGE_ADDR( in, 0, 0 ), in->Xsize, in->Ysize, 0 );
|
||||
|
||||
if( liq_image_quantize( quantise->input_image, quantise->attr,
|
||||
&quantise->quantisation_result ) ) {
|
||||
vips_error( "vips2png", "%s", _( "quantisation failed" ) );
|
||||
vips_error( "quantise", "%s", _( "quantisation failed" ) );
|
||||
vips__quantise_free( quantise );
|
||||
return( -1 );
|
||||
}
|
||||
@ -171,7 +174,7 @@ vips__quantise_image( VipsImage *in,
|
||||
if( liq_write_remapped_image( quantise->quantisation_result,
|
||||
quantise->input_image,
|
||||
VIPS_IMAGE_ADDR( index, 0, 0 ), VIPS_IMAGE_N_PELS( index ) ) ) {
|
||||
vips_error( "vips2png", "%s", _( "quantisation failed" ) );
|
||||
vips_error( "quantise", "%s", _( "quantisation failed" ) );
|
||||
vips__quantise_free( quantise );
|
||||
return( -1 );
|
||||
}
|
||||
|
@ -986,7 +986,7 @@ write_vips( Write *write,
|
||||
int compress, int interlace, const char *profile,
|
||||
VipsForeignPngFilter filter, gboolean strip,
|
||||
gboolean palette, int Q, double dither,
|
||||
int bitdepth )
|
||||
int bitdepth, int effort )
|
||||
{
|
||||
VipsImage *in = write->in;
|
||||
|
||||
@ -1162,7 +1162,7 @@ write_vips( Write *write,
|
||||
int trans_count;
|
||||
|
||||
if( vips__quantise_image( in, &im_index, &im_palette,
|
||||
1 << bitdepth, Q, dither ) )
|
||||
1 << bitdepth, Q, dither, effort ) )
|
||||
return( -1 );
|
||||
|
||||
palette_count = im_palette->Xsize;
|
||||
@ -1256,7 +1256,7 @@ vips__png_write_target( VipsImage *in, VipsTarget *target,
|
||||
int compression, int interlace,
|
||||
const char *profile, VipsForeignPngFilter filter, gboolean strip,
|
||||
gboolean palette, int Q, double dither,
|
||||
int bitdepth )
|
||||
int bitdepth, int effort )
|
||||
{
|
||||
Write *write;
|
||||
|
||||
@ -1265,7 +1265,7 @@ vips__png_write_target( VipsImage *in, VipsTarget *target,
|
||||
|
||||
if( write_vips( write,
|
||||
compression, interlace, profile, filter, strip, palette,
|
||||
Q, dither, bitdepth ) ) {
|
||||
Q, dither, bitdepth, effort ) ) {
|
||||
write_destroy( write );
|
||||
vips_error( "vips2png", _( "unable to write to target %s" ),
|
||||
vips_connection_nick( VIPS_CONNECTION( target ) ) );
|
||||
|
Loading…
Reference in New Issue
Block a user