From d134e05395f105e1493f0fd605ee811aebe84258 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Mon, 14 Jan 2019 19:55:52 +0000 Subject: [PATCH] Expose libwebp reduction_effort parameter --- libvips/foreign/pforeign.h | 4 ++-- libvips/foreign/vips2webp.c | 13 ++++++++----- libvips/foreign/webpsave.c | 23 ++++++++++++++++++++--- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/libvips/foreign/pforeign.h b/libvips/foreign/pforeign.h index 28c5650a..611300b2 100644 --- a/libvips/foreign/pforeign.h +++ b/libvips/foreign/pforeign.h @@ -238,13 +238,13 @@ int vips__webp_read_buffer( const void *buf, size_t len, VipsImage *out, int vips__webp_write_file( VipsImage *out, const char *filename, int Q, gboolean lossless, VipsForeignWebpPreset preset, gboolean smart_subsample, gboolean near_lossless, - int alpha_q, + int alpha_q, int reduction_effort, gboolean min_size, int kmin, int kmax, gboolean strip ); int vips__webp_write_buffer( VipsImage *out, void **buf, size_t *len, int Q, gboolean lossless, VipsForeignWebpPreset preset, gboolean smart_subsample, gboolean near_lossless, - int alpha_q, + int alpha_q, int reduction_effort, gboolean min_size, int kmin, int kmax, gboolean strip ); diff --git a/libvips/foreign/vips2webp.c b/libvips/foreign/vips2webp.c index 92ae96cf..e0d40115 100644 --- a/libvips/foreign/vips2webp.c +++ b/libvips/foreign/vips2webp.c @@ -77,6 +77,7 @@ typedef struct { gboolean smart_subsample; gboolean near_lossless; int alpha_q; + int reduction_effort; gboolean min_size; int kmin; int kmax; @@ -136,7 +137,7 @@ static int vips_webp_write_init( VipsWebPWrite *write, VipsImage *image, int Q, gboolean lossless, VipsForeignWebpPreset preset, gboolean smart_subsample, gboolean near_lossless, - int alpha_q, + int alpha_q, int reduction_effort, gboolean min_size, int kmin, int kmax, gboolean strip ) { @@ -147,6 +148,7 @@ vips_webp_write_init( VipsWebPWrite *write, VipsImage *image, write->smart_subsample = smart_subsample; write->near_lossless = near_lossless; write->alpha_q = alpha_q; + write->reduction_effort = reduction_effort; write->min_size = min_size; write->kmin = kmin; write->kmax = kmax; @@ -175,6 +177,7 @@ vips_webp_write_init( VipsWebPWrite *write, VipsImage *image, write->config.lossless = lossless || near_lossless; write->config.alpha_quality = alpha_q; + write->config.method = reduction_effort; if( near_lossless ) write->config.near_lossless = Q; @@ -497,7 +500,7 @@ int vips__webp_write_file( VipsImage *image, const char *filename, int Q, gboolean lossless, VipsForeignWebpPreset preset, gboolean smart_subsample, gboolean near_lossless, - int alpha_q, + int alpha_q, int reduction_effort, gboolean min_size, int kmin, int kmax, gboolean strip ) { @@ -506,7 +509,7 @@ vips__webp_write_file( VipsImage *image, const char *filename, if( vips_webp_write_init( &write, image, Q, lossless, preset, smart_subsample, near_lossless, - alpha_q, min_size, kmin, kmax, strip ) ) + alpha_q, reduction_effort, min_size, kmin, kmax, strip ) ) return( -1 ); if( write_webp( &write, image ) ) { @@ -543,7 +546,7 @@ int vips__webp_write_buffer( VipsImage *image, void **obuf, size_t *olen, int Q, gboolean lossless, VipsForeignWebpPreset preset, gboolean smart_subsample, gboolean near_lossless, - int alpha_q, + int alpha_q, int reduction_effort, gboolean min_size, int kmin, int kmax, gboolean strip ) { @@ -551,7 +554,7 @@ vips__webp_write_buffer( VipsImage *image, void **obuf, size_t *olen, if( vips_webp_write_init( &write, image, Q, lossless, preset, smart_subsample, near_lossless, - alpha_q, min_size, kmin, kmax, strip ) ) + alpha_q, reduction_effort, min_size, kmin, kmax, strip ) ) return( -1 ); if( write_webp( &write, image ) ) { diff --git a/libvips/foreign/webpsave.c b/libvips/foreign/webpsave.c index 3e24f55b..8d75db14 100644 --- a/libvips/foreign/webpsave.c +++ b/libvips/foreign/webpsave.c @@ -76,6 +76,10 @@ typedef struct _VipsForeignSaveWebp { */ int alpha_q; + /* Level of CPU effort to reduce file size. + */ + int reduction_effort; + /* Animated webp options. */ @@ -190,6 +194,12 @@ vips_foreign_save_webp_class_init( VipsForeignSaveWebpClass *class ) G_STRUCT_OFFSET( VipsForeignSaveWebp, kmax ), 0, INT_MAX, INT_MAX ); + VIPS_ARG_INT( class, "reduction_effort", 19, + _( "Reduction effort" ), + _( "Level of CPU effort to reduce file size" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsForeignSaveWebp, reduction_effort ), + 0, 6, 4 ); } static void @@ -197,6 +207,7 @@ vips_foreign_save_webp_init( VipsForeignSaveWebp *webp ) { webp->Q = 75; webp->alpha_q = 100; + webp->reduction_effort = 4; /* ie. keyframes disabled by default. */ @@ -232,7 +243,7 @@ vips_foreign_save_webp_file_build( VipsObject *object ) if( vips__webp_write_file( save->ready, file->filename, webp->Q, webp->lossless, webp->preset, webp->smart_subsample, webp->near_lossless, - webp->alpha_q, + webp->alpha_q, webp->reduction_effort, webp->min_size, webp->kmin, webp->kmax, save->strip ) ) return( -1 ); @@ -298,7 +309,7 @@ vips_foreign_save_webp_buffer_build( VipsObject *object ) if( vips__webp_write_buffer( save->ready, &obuf, &olen, webp->Q, webp->lossless, webp->preset, webp->smart_subsample, webp->near_lossless, - webp->alpha_q, + webp->alpha_q, webp->reduction_effort, webp->min_size, webp->kmin, webp->kmax, save->strip ) ) return( -1 ); @@ -365,7 +376,7 @@ vips_foreign_save_webp_mime_build( VipsObject *object ) if( vips__webp_write_buffer( save->ready, &obuf, &olen, webp->Q, webp->lossless, webp->preset, webp->smart_subsample, webp->near_lossless, - webp->alpha_q, + webp->alpha_q, webp->reduction_effort, webp->min_size, webp->kmin, webp->kmax, save->strip ) ) return( -1 ); @@ -416,6 +427,7 @@ vips_foreign_save_webp_mime_init( VipsForeignSaveWebpMime *mime ) * * @smart_subsample: %gboolean, enables high quality chroma subsampling * * @near_lossless: %gboolean, preprocess in lossless mode (controlled by Q) * * @alpha_q: %gint, set alpha quality in lossless mode + * * @reduction_effort: %gint, level of CPU effort to reduce file size * * @min_size: %gboolean, minimise size * * @kmin: %gint, minimum number of frames between keyframes * * @kmax: %gint, maximum number of frames between keyframes @@ -432,6 +444,9 @@ vips_foreign_save_webp_mime_init( VipsForeignSaveWebpMime *mime ) * Set @smart_subsample to enable high quality chroma subsampling. * Use @alpha_q to set the quality for the alpha channel in lossy mode. It has * the range 1 - 100, with the default 100. + * Use @reduction_effort to control how much CPU time to spend attempting to + * reduce file size. A higher value means more effort and therefore CPU time + * should be spent. It has the range 0-6 and a default value of 4. * * Set @lossless to use lossless compression, or combine @near_lossless * with @Q 80, 60, 40 or 20 to apply increasing amounts of preprocessing @@ -482,6 +497,7 @@ vips_webpsave( VipsImage *in, const char *filename, ... ) * * @smart_subsample: %gboolean, enables high quality chroma subsampling * * @near_lossless: %gboolean, preprocess in lossless mode (controlled by Q) * * @alpha_q: %gint, set alpha quality in lossless mode + * * @reduction_effort: %gint, level of CPU effort to reduce file size * * @min_size: %gboolean, minimise size * * @kmin: %gint, minimum number of frames between keyframes * * @kmax: %gint, maximum number of frames between keyframes @@ -538,6 +554,7 @@ vips_webpsave_buffer( VipsImage *in, void **buf, size_t *len, ... ) * * @smart_subsample: %gboolean, enables high quality chroma subsampling * * @near_lossless: %gboolean, preprocess in lossless mode (controlled by Q) * * @alpha_q: %gint, set alpha quality in lossless mode + * * @reduction_effort: %gint, level of CPU effort to reduce file size * * @min_size: %gboolean, minimise size * * @kmin: %gint, minimum number of frames between keyframes * * @kmax: %gint, maximum number of frames between keyframes