From 2f73f4d9e0472ef4089cb9b8518cbedb94916292 Mon Sep 17 00:00:00 2001 From: lucor Date: Tue, 11 Jan 2022 14:51:12 +0100 Subject: [PATCH] Add GIF save support from libvips 8.12 --- image_test.go | 15 ++++++++++++--- type_test.go | 7 +++++-- vips.go | 5 +++++ vips.h | 17 +++++++++++++++++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/image_test.go b/image_test.go index 76e819d..8b3f927 100644 --- a/image_test.go +++ b/image_test.go @@ -21,9 +21,18 @@ func TestImageResize(t *testing.T) { } func TestImageGifResize(t *testing.T) { - _, err := initImage("test.gif").Resize(300, 240) - if err == nil { - t.Errorf("GIF shouldn't be saved within VIPS") + if VipsMajorVersion >= 8 && VipsMinorVersion >= 12 { + buf, err := initImage("test.gif").Resize(300, 240) + if err != nil { + t.Errorf("Cannot process the image: %#v", err) + } + + err = assertSize(buf, 300, 240) + if err != nil { + t.Error(err) + } + + Write("testdata/test_resize_out.gif", buf) } } diff --git a/type_test.go b/type_test.go index 7154da2..40ae09a 100644 --- a/type_test.go +++ b/type_test.go @@ -125,7 +125,7 @@ func TestIsTypeSupportedSave(t *testing.T) { types := []struct { name ImageType }{ - {JPEG}, {PNG}, {WEBP}, + {JPEG}, {PNG}, {WEBP}, {GIF}, } if VipsVersion >= "8.5.0" { types = append(types, struct{ name ImageType }{TIFF}) @@ -136,6 +136,9 @@ func TestIsTypeSupportedSave(t *testing.T) { if VipsVersion >= "8.9.0" { types = append(types, struct{ name ImageType }{AVIF}) } + if VipsVersion >= "8.12.0" { + types = append(types, struct{ name ImageType }{GIF}) + } for _, n := range types { if IsTypeSupportedSave(n.name) == false { @@ -152,11 +155,11 @@ func TestIsTypeNameSupportedSave(t *testing.T) { {"jpeg", true}, {"png", true}, {"webp", true}, - {"gif", false}, {"pdf", false}, {"tiff", VipsVersion >= "8.5.0"}, {"heif", VipsVersion >= "8.8.0"}, {"avif", VipsVersion >= "8.9.0"}, + {"gif", VipsVersion >= "8.12.0"}, } for _, n := range types { diff --git a/vips.go b/vips.go index 906a935..1c73641 100644 --- a/vips.go +++ b/vips.go @@ -230,6 +230,9 @@ func VipsIsTypeSupportedSave(t ImageType) bool { if t == AVIF { return int(C.vips_type_find_save_bridge(C.HEIF)) != 0 } + if t == GIF { + return int(C.vips_type_find_save_bridge(C.GIF)) != 0 + } return false } @@ -524,6 +527,8 @@ func vipsSave(image *C.VipsImage, o vipsSaveOptions) ([]byte, error) { saveErr = C.vips_heifsave_bridge(tmpImage, &ptr, &length, strip, quality, lossless) case AVIF: saveErr = C.vips_avifsave_bridge(tmpImage, &ptr, &length, strip, quality, lossless, speed) + case GIF: + saveErr = C.vips_gifsave_bridge(tmpImage, &ptr, &length, strip) default: saveErr = C.vips_jpegsave_bridge(tmpImage, &ptr, &length, strip, quality, interlace) } diff --git a/vips.h b/vips.h index ab2c82e..334814f 100644 --- a/vips.h +++ b/vips.h @@ -185,6 +185,11 @@ vips_type_find_save_bridge(int t) { if (t == HEIF) { return vips_type_find("VipsOperation", "heifsave_buffer"); } +#endif +#if (VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 12)) + if (t == GIF) { + return vips_type_find("VipsOperation", "gifsave_buffer"); + } #endif return 0; } @@ -407,6 +412,18 @@ vips_heifsave_bridge(VipsImage *in, void **buf, size_t *len, int strip, int qual #endif } +int +vips_gifsave_bridge(VipsImage *in, void **buf, size_t *len, int strip) { +#if (VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 12)) + return vips_gifsave_buffer(in, buf, len, + "strip", INT_TO_GBOOLEAN(strip), + NULL + ); +#else + return 0; +#endif +} + int vips_is_16bit (VipsInterpretation interpretation) { return interpretation == VIPS_INTERPRETATION_RGB16 || interpretation == VIPS_INTERPRETATION_GREY16;