From 767bfdac74485911b2795edf9ce2948f890083d1 Mon Sep 17 00:00:00 2001 From: Janis Meybohm Date: Fri, 7 Jul 2017 14:02:03 +0200 Subject: [PATCH] Add option to convert embedded ICC profiles Set an bimg.Options OutputICC to an absolute path to the desired output ICC profile. If an embedded ICC profile is found in VipsImage, it is converted to the output ICC profile. Fixes #50 --- options.go | 1 + resize.go | 1 + vips.go | 15 ++++++++++++++- vips.h | 6 ++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/options.go b/options.go index f6ebec2..d7ee592 100644 --- a/options.go +++ b/options.go @@ -215,4 +215,5 @@ type Options struct { Interpretation Interpretation GaussianBlur GaussianBlur Sharpen Sharpen + OutputICC string } diff --git a/resize.go b/resize.go index 93d6248..dbf1e87 100644 --- a/resize.go +++ b/resize.go @@ -161,6 +161,7 @@ func saveImage(image *C.VipsImage, o Options) ([]byte, error) { Interlace: o.Interlace, NoProfile: o.NoProfile, Interpretation: o.Interpretation, + OutputICC: o.OutputICC, } // Finally get the resultant buffer return vipsSave(image, saveOptions) diff --git a/vips.go b/vips.go index 221233f..ba3e2f8 100644 --- a/vips.go +++ b/vips.go @@ -55,6 +55,7 @@ type vipsSaveOptions struct { Type ImageType Interlace bool NoProfile bool + OutputICC string // Absolute path to the output ICC profile Interpretation Interpretation } @@ -362,6 +363,7 @@ func vipsFlattenBackground(image *C.VipsImage, background Color) (*C.VipsImage, } func vipsPreSave(image *C.VipsImage, o *vipsSaveOptions) (*C.VipsImage, error) { + var outImage *C.VipsImage // Remove ICC profile metadata if o.NoProfile { C.remove_profile(image) @@ -374,7 +376,6 @@ func vipsPreSave(image *C.VipsImage, o *vipsSaveOptions) (*C.VipsImage, error) { interpretation := C.VipsInterpretation(o.Interpretation) // Apply the proper colour space - var outImage *C.VipsImage if vipsColourspaceIsSupported(image) { err := C.vips_colourspace_bridge(image, &outImage, interpretation) if int(err) != 0 { @@ -383,6 +384,18 @@ func vipsPreSave(image *C.VipsImage, o *vipsSaveOptions) (*C.VipsImage, error) { image = outImage } + if o.OutputICC != "" && vipsHasProfile(image) { + debug("Embedded ICC profile found, trying to convert to %s", o.OutputICC) + outputIccPath := C.CString(o.OutputICC) + defer C.free(unsafe.Pointer(outputIccPath)) + + err := C.vips_icc_transform_bridge(image, &outImage, outputIccPath) + if int(err) != 0 { + return nil, catchVipsError() + } + image = outImage + } + return image, nil } diff --git a/vips.h b/vips.h index 6d76550..067466e 100644 --- a/vips.h +++ b/vips.h @@ -260,6 +260,12 @@ vips_colourspace_bridge(VipsImage *in, VipsImage **out, VipsInterpretation space return vips_colourspace(in, out, space, NULL); } +int +vips_icc_transform_bridge (VipsImage *in, VipsImage **out, const char *output_icc_profile) { + // `output_icc_profile` represents the absolute path to the output ICC profile file + return vips_icc_transform(in, out, output_icc_profile, "embedded", TRUE, NULL); +} + int vips_jpegsave_bridge(VipsImage *in, void **buf, size_t *len, int strip, int quality, int interlace) { return vips_jpegsave_buffer(in, buf, len,