From dcd91c85e0b4d40e5a88fb729c62d3b5ca756b99 Mon Sep 17 00:00:00 2001 From: Yoan Blanc Date: Sun, 13 Nov 2016 17:57:58 +0100 Subject: [PATCH] Adding support for TIFF save. Signed-off-by: Yoan Blanc --- vips.go | 30 +++++++++++++++++++++++++----- vips.h | 28 ++++++++++++++++++++++++++++ vips_test.go | 22 +++++++++------------- 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/vips.go b/vips.go index e2e9e68..83ff2b0 100644 --- a/vips.go +++ b/vips.go @@ -168,6 +168,25 @@ func VipsIsTypeSupported(t ImageType) bool { return false } +// VipsIsTypeSupportedSave returns true if the given image type +// is supported by the current libvips compilation for the +// save operation. +func VipsIsTypeSupportedSave(t ImageType) bool { + if t == JPEG { + return int(C.vips_type_find_save_bridge(C.JPEG)) != 0 + } + if t == WEBP { + return int(C.vips_type_find_save_bridge(C.WEBP)) != 0 + } + if t == PNG { + return int(C.vips_type_find_save_bridge(C.PNG)) != 0 + } + if t == TIFF { + return int(C.vips_type_find_save_bridge(C.TIFF)) != 0 + } + return false +} + func vipsExifOrientation(image *C.VipsImage) int { return int(C.vips_exif_orientation(image)) } @@ -367,18 +386,19 @@ func vipsSave(image *C.VipsImage, o vipsSaveOptions) ([]byte, error) { interlace := C.int(boolToInt(o.Interlace)) quality := C.int(o.Quality) + if o.Type != 0 && !VipsIsTypeSupportedSave(o.Type) { + return nil, fmt.Errorf("VIPS cannot save to %#v", ImageTypes[o.Type]) + } var ptr unsafe.Pointer switch o.Type { case WEBP: saveErr = C.vips_webpsave_bridge(tmpImage, &ptr, &length, 1, quality) case PNG: saveErr = C.vips_pngsave_bridge(tmpImage, &ptr, &length, 1, C.int(o.Compression), quality, interlace) - case 0: - saveErr = C.vips_jpegsave_bridge(tmpImage, &ptr, &length, 1, quality, interlace) - case JPEG: - saveErr = C.vips_jpegsave_bridge(tmpImage, &ptr, &length, 1, quality, interlace) + case TIFF: + saveErr = C.vips_tiffsave_bridge(tmpImage, &ptr, &length) default: - return nil, fmt.Errorf("VIPS cannot save to %v.", ImageTypes[o.Type]) + saveErr = C.vips_jpegsave_bridge(tmpImage, &ptr, &length, 1, quality, interlace) } if int(saveErr) != 0 { diff --git a/vips.h b/vips.h index c3f7d9e..e9129b5 100644 --- a/vips.h +++ b/vips.h @@ -144,6 +144,23 @@ vips_type_find_bridge(int t) { return 0; } +int +vips_type_find_save_bridge(int t) { + if (t == TIFF) { + return vips_type_find("VipsOperation", "tiffsave_buffer"); + } + if (t == WEBP) { + return vips_type_find("VipsOperation", "webpsave_buffer"); + } + if (t == PNG) { + return vips_type_find("VipsOperation", "pngsave_buffer"); + } + if (t == JPEG) { + return vips_type_find("VipsOperation", "jpegsave_buffer"); + } + return 0; +} + int vips_rotate(VipsImage *in, VipsImage **out, int angle) { int rotate = VIPS_ANGLE_D0; @@ -276,6 +293,17 @@ vips_webpsave_bridge(VipsImage *in, void **buf, size_t *len, int strip, int qual ); } +int +vips_tiffsave_bridge(VipsImage *in, void **buf, size_t *len) { +#if (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 5) + return vips_tiffsave_buffer(in, buf, len, + NULL + ); +#else + return 0; +#endif +} + int vips_is_16bit (VipsInterpretation interpretation) { return interpretation == VIPS_INTERPRETATION_RGB16 || interpretation == VIPS_INTERPRETATION_GREY16; diff --git a/vips_test.go b/vips_test.go index 157400d..bbbee9e 100644 --- a/vips_test.go +++ b/vips_test.go @@ -45,20 +45,16 @@ func TestVipsSave(t *testing.T) { } } -func TestVipsCannotSave(t *testing.T) { - types := [...]ImageType{GIF, MAGICK, PDF, SVG, TIFF} - - for _, typ := range types { - image, _, _ := vipsRead(readImage("test.jpg")) - options := vipsSaveOptions{Quality: 95, Type: typ} +func TestVipsSaveTiff(t *testing.T) { + if !VipsIsTypeSupportedSave(TIFF) { + t.Skipf("Format %#v is not supported", ImageTypes[TIFF]) + } + image, _, _ := vipsRead(readImage("test.jpg")) + options := vipsSaveOptions{Quality: 95, Type: TIFF} + buf, _ := vipsSave(image, options) - buf, err := vipsSave(image, options) - if err == nil { - t.Fatalf("Format '%v' shouldn't be supported", ImageTypes[typ]) - } - if len(buf) != 0 { - t.Fatalf("'%v' image is not empty", ImageTypes[typ]) - } + if len(buf) == 0 { + t.Fatalf("Empty saved '%v' image", ImageTypes[TIFF]) } }