diff --git a/vips/color.go b/vips/color.go index a0fbc608..def51aca 100644 --- a/vips/color.go +++ b/vips/color.go @@ -2,9 +2,6 @@ package vips // #include "color.h" import "C" -import ( - "unsafe" -) // Color represents an RGB type Color struct { @@ -80,11 +77,11 @@ func vipsICCTransform(in *C.VipsImage, outputProfile string, inputProfile string var cEmbedded C.gboolean cOutputProfile := C.CString(outputProfile) - defer C.free(unsafe.Pointer(cOutputProfile)) + defer freeCString(cOutputProfile) if inputProfile != "" { cInputProfile = C.CString(inputProfile) - defer C.free(unsafe.Pointer(cInputProfile)) + defer freeCString(cInputProfile) } if embedded { diff --git a/vips/foreign.go b/vips/foreign.go index 5e515523..a85edae5 100644 --- a/vips/foreign.go +++ b/vips/foreign.go @@ -252,36 +252,37 @@ func isJP2K(buf []byte) bool { return bytes.HasPrefix(buf, jp2kHeader) } -func vipsLoadFromBuffer(buf []byte, params *ImportParams) (*C.VipsImage, ImageType, error) { +func vipsLoadFromBuffer(buf []byte, params *ImportParams) (*C.VipsImage, ImageType, ImageType, error) { src := buf // Reference src here so it's not garbage collected during image initialization. defer runtime.KeepAlive(src) var err error - imageType := DetermineImageType(src) + originalType := DetermineImageType(src) + currentType := originalType - if imageType == ImageTypeBMP { + if originalType == ImageTypeBMP { src, err = bmpToPNG(src) if err != nil { - return nil, ImageTypeUnknown, err + return nil, currentType, originalType, err } - imageType = ImageTypePNG + currentType = ImageTypePNG } - if !IsTypeSupported(imageType) { + if !IsTypeSupported(currentType) { govipsLog("govips", LogLevelInfo, fmt.Sprintf("failed to understand image format size=%d", len(src))) - return nil, ImageTypeUnknown, ErrUnsupportedImageFormat + return nil, currentType, originalType, ErrUnsupportedImageFormat } - importParams := createImportParams(imageType, params) + importParams := createImportParams(currentType, params) if err := C.load_from_buffer(&importParams, unsafe.Pointer(&src[0]), C.size_t(len(src))); err != 0 { - return nil, ImageTypeUnknown, handleImageError(importParams.outputImage) + return nil, currentType, originalType, handleImageError(importParams.outputImage) } - return importParams.outputImage, imageType, nil + return importParams.outputImage, currentType, originalType, nil } func bmpToPNG(src []byte) ([]byte, error) { diff --git a/vips/header.go b/vips/header.go index 2d164015..f99b995d 100644 --- a/vips/header.go +++ b/vips/header.go @@ -100,7 +100,7 @@ func vipsSetPageHeight(in *C.VipsImage, height int) { func vipsImageGetMetaLoader(in *C.VipsImage) (string, bool) { var out *C.char - defer gFreePointer(unsafe.Pointer(out)) + defer freeCString(out) code := int(C.get_meta_loader(in, &out)) return C.GoString(out), code == 0 } diff --git a/vips/image.go b/vips/image.go index 9ef2807f..5e3fe728 100644 --- a/vips/image.go +++ b/vips/image.go @@ -30,6 +30,7 @@ type ImageRef struct { buf []byte image *C.VipsImage format ImageType + originalFormat ImageType lock sync.Mutex preMultiplication *PreMultiplicationState optimizedIccProfile string @@ -412,12 +413,12 @@ func LoadImageFromBuffer(buf []byte, params *ImportParams) (*ImageRef, error) { params = NewImportParams() } - vipsImage, format, err := vipsLoadFromBuffer(buf, params) + vipsImage, currentFormat, originalFormat, err := vipsLoadFromBuffer(buf, params) if err != nil { return nil, err } - ref := newImageRef(vipsImage, format, buf) + ref := newImageRef(vipsImage, currentFormat, originalFormat, buf) govipsLog("govips", LogLevelDebug, fmt.Sprintf("created imageRef %p", ref)) return ref, nil @@ -447,7 +448,7 @@ func LoadThumbnailFromFile(file string, width, height int, crop Interesting, siz return nil, err } - ref := newImageRef(vipsImage, format, nil) + ref := newImageRef(vipsImage, format, format, nil) govipsLog("govips", LogLevelDebug, fmt.Sprintf("created imageref %p", ref)) return ref, nil @@ -467,7 +468,7 @@ func LoadThumbnailFromBuffer(buf []byte, width, height int, crop Interesting, si return nil, err } - ref := newImageRef(vipsImage, format, buf) + ref := newImageRef(vipsImage, format, format, buf) govipsLog("govips", LogLevelDebug, fmt.Sprintf("created imageref %p", ref)) return ref, nil @@ -492,7 +493,7 @@ func (r *ImageRef) Copy() (*ImageRef, error) { return nil, err } - return newImageRef(out, r.format, r.buf), nil + return newImageRef(out, r.format, r.originalFormat, r.buf), nil } // XYZ creates a two-band uint32 image where the elements in the first band have the value of their x coordinate @@ -515,13 +516,15 @@ func Black(width, height int) (*ImageRef, error) { return &ImageRef{image: vipsImage}, err } -func newImageRef(vipsImage *C.VipsImage, format ImageType, buf []byte) *ImageRef { +func newImageRef(vipsImage *C.VipsImage, currentFormat ImageType, originalFormat ImageType, buf []byte) *ImageRef { imageRef := &ImageRef{ - image: vipsImage, - format: format, - buf: buf, + image: vipsImage, + format: currentFormat, + originalFormat: originalFormat, + buf: buf, } runtime.SetFinalizer(imageRef, finalizeImage) + return imageRef } @@ -546,11 +549,19 @@ func (r *ImageRef) Close() { r.lock.Unlock() } -// Format returns the initial format of the vips image when loaded. +// Format returns the current format of the vips image. func (r *ImageRef) Format() ImageType { return r.format } +// OriginalFormat returns the original format of the image when loaded. +// In some cases the loaded image is converted on load, for example, a BMP is automatically converted to PNG +// This method returns the format of the original buffer, as opposed to Format() with will return the format of the +// currently held buffer content. +func (r *ImageRef) OriginalFormat() ImageType { + return r.originalFormat +} + // Width returns the width of this image. func (r *ImageRef) Width() int { return int(r.image.Xsize) @@ -1798,6 +1809,7 @@ func clearImage(ref *C.VipsImage) { type Coding int // Coding enum +//goland:noinspection GoUnusedConst const ( CodingError Coding = C.VIPS_CODING_ERROR CodingNone Coding = C.VIPS_CODING_NONE diff --git a/vips/image_test.go b/vips/image_test.go index 621597bc..7308b44f 100644 --- a/vips/image_test.go +++ b/vips/image_test.go @@ -145,6 +145,7 @@ func TestImageRef_BMP__ImplicitConversionToPNG(t *testing.T) { exported, metadata, err := img.ExportNative() assert.NoError(t, err) assert.Equal(t, ImageTypePNG, metadata.Format) + assert.Equal(t, ImageTypeBMP, img.OriginalFormat()) assert.NotNil(t, exported) }