From aedafaf0a71a87663b13565ea2773becb992ad07 Mon Sep 17 00:00:00 2001 From: Paul van Santen Date: Tue, 15 Feb 2022 17:15:33 +0100 Subject: [PATCH 1/2] Use gifsave instead of magicksave for saving GIF files --- vips/foreign.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/vips/foreign.c b/vips/foreign.c index 2f471165..32479523 100644 --- a/vips/foreign.c +++ b/vips/foreign.c @@ -327,6 +327,14 @@ int set_magicksave_options(VipsOperation *operation, SaveParams *params) { return ret; } +// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-gifsave-buffer +int set_gifsave_options(VipsOperation *operation, SaveParams *params) { + // TODO: Set optional arguments? + // int ret = vips_object_set(VIPS_OBJECT(operation), "quality", params->quality, NULL); + int ret = 0; + return ret; +} + int set_avifsave_options(VipsOperation *operation, SaveParams *params) { int ret = vips_object_set( VIPS_OBJECT(operation), "compression", VIPS_FOREIGN_HEIF_COMPRESSION_AV1, @@ -406,7 +414,7 @@ int save_to_buffer(SaveParams *params) { case TIFF: return save_buffer("tiffsave_buffer", params, set_tiffsave_options); case GIF: - return save_buffer("magicksave_buffer", params, set_magicksave_options); + return save_buffer("gifsave_buffer", params, set_gifsave_options); case AVIF: return save_buffer("heifsave_buffer", params, set_avifsave_options); case JP2K: From 14f35e5faa3152b8d412d24573b88e35fac449be Mon Sep 17 00:00:00 2001 From: Paul van Santen Date: Wed, 16 Feb 2022 09:11:53 +0100 Subject: [PATCH 2/2] Add optional CGIF arguments and add version detection around gifsave call --- vips/foreign.c | 20 ++++++++++++++++++-- vips/foreign.go | 3 +++ vips/foreign.h | 5 +++++ vips/image.go | 7 ++++++- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/vips/foreign.c b/vips/foreign.c index 32479523..a9a89846 100644 --- a/vips/foreign.c +++ b/vips/foreign.c @@ -329,9 +329,17 @@ int set_magicksave_options(VipsOperation *operation, SaveParams *params) { // https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-gifsave-buffer int set_gifsave_options(VipsOperation *operation, SaveParams *params) { - // TODO: Set optional arguments? - // int ret = vips_object_set(VIPS_OBJECT(operation), "quality", params->quality, NULL); int ret = 0; + // See for argument values: https://www.libvips.org/API/current/VipsForeignSave.html#vips-gifsave + if (params->gifDither > 0.0 && params->gifDither <= 1.0) { + ret = vips_object_set(VIPS_OBJECT(operation), "dither", params->gifDither, NULL); + } + if (params->gifEffort >= 1 && params->gifEffort <= 10) { + ret = vips_object_set(VIPS_OBJECT(operation), "effort", params->gifEffort, NULL); + } + if (params->gifBitdepth >= 1 && params->gifBitdepth <= 8) { + ret = vips_object_set(VIPS_OBJECT(operation), "bitdepth", params->gifBitdepth, NULL); + } return ret; } @@ -414,7 +422,11 @@ int save_to_buffer(SaveParams *params) { case TIFF: return save_buffer("tiffsave_buffer", params, set_tiffsave_options); case GIF: +#if (VIPS_MAJOR_VERSION >= 8) && (VIPS_MINOR_VERSION >= 12) return save_buffer("gifsave_buffer", params, set_gifsave_options); +#else + return save_buffer("magicksave_buffer", params, set_magicksave_options); +#endif case AVIF: return save_buffer("heifsave_buffer", params, set_avifsave_options); case JP2K: @@ -468,6 +480,10 @@ static SaveParams defaultSaveParams = { .pngDither = 0, .pngFilter = VIPS_FOREIGN_PNG_FILTER_NONE, + .gifDither = 0.0, + .gifEffort = 0, + .gifBitdepth = 0, + .webpLossless = FALSE, .webpNearLossless = FALSE, .webpReductionEffort = 4, diff --git a/vips/foreign.go b/vips/foreign.go index 78809e7f..206dee0b 100644 --- a/vips/foreign.go +++ b/vips/foreign.go @@ -428,6 +428,9 @@ func vipsSaveGIFToBuffer(in *C.VipsImage, params GifExportParams) ([]byte, error p := C.create_save_params(C.GIF) p.inputImage = in p.quality = C.int(params.Quality) + p.gifDither = C.double(params.Dither) + p.gifEffort = C.int(params.Effort) + p.gifBitdepth = C.int(params.Bitdepth) return vipsSaveToBuffer(p) } diff --git a/vips/foreign.h b/vips/foreign.h index 60f06467..0b770768 100644 --- a/vips/foreign.h +++ b/vips/foreign.h @@ -96,6 +96,11 @@ typedef struct SaveParams { double pngDither; int pngBitdepth; + // GIF (with CGIF) + double gifDither; + int gifEffort; + int gifBitdepth; + // WEBP BOOL webpLossless; BOOL webpNearLossless; diff --git a/vips/image.go b/vips/image.go index 1faf875b..68502fba 100644 --- a/vips/image.go +++ b/vips/image.go @@ -321,12 +321,17 @@ func NewTiffExportParams() *TiffExportParams { type GifExportParams struct { StripMetadata bool Quality int + Dither float64 + Effort int + Bitdepth int } // NewGifExportParams creates default values for an export of a GIF image. func NewGifExportParams() *GifExportParams { return &GifExportParams{ - Quality: 75, + Quality: 75, + Effort: 7, + Bitdepth: 8, } }