mirror of
https://github.com/talgo-cloud/bimg.git
synced 2026-03-07 21:48:13 -08:00
Adding support for heif (i.e. heic files).
This commit is contained in:
parent
5a9d7f21d9
commit
f9eadf55bb
6 changed files with 58 additions and 3 deletions
BIN
testdata/test.heic
vendored
Normal file
BIN
testdata/test.heic
vendored
Normal file
Binary file not shown.
3
type.go
3
type.go
|
|
@ -25,6 +25,8 @@ const (
|
||||||
SVG
|
SVG
|
||||||
// MAGICK represents the libmagick compatible genetic image type.
|
// MAGICK represents the libmagick compatible genetic image type.
|
||||||
MAGICK
|
MAGICK
|
||||||
|
// HEIF represents the HEIC/HEIF/HVEC image type
|
||||||
|
HEIF
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImageType represents an image type value.
|
// ImageType represents an image type value.
|
||||||
|
|
@ -45,6 +47,7 @@ var ImageTypes = map[ImageType]string{
|
||||||
PDF: "pdf",
|
PDF: "pdf",
|
||||||
SVG: "svg",
|
SVG: "svg",
|
||||||
MAGICK: "magick",
|
MAGICK: "magick",
|
||||||
|
HEIF: "heif",
|
||||||
}
|
}
|
||||||
|
|
||||||
// imageMutex is used to provide thread-safe synchronization
|
// imageMutex is used to provide thread-safe synchronization
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ func TestDeterminateImageType(t *testing.T) {
|
||||||
{"test.pdf", PDF},
|
{"test.pdf", PDF},
|
||||||
{"test.svg", SVG},
|
{"test.svg", SVG},
|
||||||
{"test.jp2", MAGICK},
|
{"test.jp2", MAGICK},
|
||||||
|
{"test.heic", HEIF},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
|
|
@ -46,6 +47,7 @@ func TestDeterminateImageTypeName(t *testing.T) {
|
||||||
{"test.pdf", "pdf"},
|
{"test.pdf", "pdf"},
|
||||||
{"test.svg", "svg"},
|
{"test.svg", "svg"},
|
||||||
{"test.jp2", "magick"},
|
{"test.jp2", "magick"},
|
||||||
|
{"test.heic", "heif"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
|
|
@ -63,7 +65,7 @@ func TestIsTypeSupported(t *testing.T) {
|
||||||
types := []struct {
|
types := []struct {
|
||||||
name ImageType
|
name ImageType
|
||||||
}{
|
}{
|
||||||
{JPEG}, {PNG}, {WEBP}, {GIF}, {PDF},
|
{JPEG}, {PNG}, {WEBP}, {GIF}, {PDF}, {HEIF},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, n := range types {
|
for _, n := range types {
|
||||||
|
|
@ -83,6 +85,7 @@ func TestIsTypeNameSupported(t *testing.T) {
|
||||||
{"webp", true},
|
{"webp", true},
|
||||||
{"gif", true},
|
{"gif", true},
|
||||||
{"pdf", true},
|
{"pdf", true},
|
||||||
|
{"heif", true},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, n := range types {
|
for _, n := range types {
|
||||||
|
|
@ -101,6 +104,9 @@ func TestIsTypeSupportedSave(t *testing.T) {
|
||||||
if VipsVersion >= "8.5.0" {
|
if VipsVersion >= "8.5.0" {
|
||||||
types = append(types, struct{ name ImageType }{TIFF})
|
types = append(types, struct{ name ImageType }{TIFF})
|
||||||
}
|
}
|
||||||
|
if VipsVersion >= "8.8.0" {
|
||||||
|
types = append(types, struct{ name ImageType }{HEIF})
|
||||||
|
}
|
||||||
|
|
||||||
for _, n := range types {
|
for _, n := range types {
|
||||||
if IsTypeSupportedSave(n.name) == false {
|
if IsTypeSupportedSave(n.name) == false {
|
||||||
|
|
@ -120,6 +126,7 @@ func TestIsTypeNameSupportedSave(t *testing.T) {
|
||||||
{"gif", false},
|
{"gif", false},
|
||||||
{"pdf", false},
|
{"pdf", false},
|
||||||
{"tiff", VipsVersion >= "8.5.0"},
|
{"tiff", VipsVersion >= "8.5.0"},
|
||||||
|
{"heif", VipsVersion >= "8.8.0"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, n := range types {
|
for _, n := range types {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package bimg
|
package bimg
|
||||||
|
|
||||||
// Version represents the current package semantic version.
|
// Version represents the current package semantic version.
|
||||||
const Version = "1.0.18"
|
const Version = "1.0.19"
|
||||||
|
|
|
||||||
14
vips.go
14
vips.go
|
|
@ -185,6 +185,9 @@ func VipsIsTypeSupported(t ImageType) bool {
|
||||||
if t == MAGICK {
|
if t == MAGICK {
|
||||||
return int(C.vips_type_find_bridge(C.MAGICK)) != 0
|
return int(C.vips_type_find_bridge(C.MAGICK)) != 0
|
||||||
}
|
}
|
||||||
|
if t == HEIF {
|
||||||
|
return int(C.vips_type_find_bridge(C.HEIF)) != 0
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,6 +207,9 @@ func VipsIsTypeSupportedSave(t ImageType) bool {
|
||||||
if t == TIFF {
|
if t == TIFF {
|
||||||
return int(C.vips_type_find_save_bridge(C.TIFF)) != 0
|
return int(C.vips_type_find_save_bridge(C.TIFF)) != 0
|
||||||
}
|
}
|
||||||
|
if t == HEIF {
|
||||||
|
return int(C.vips_type_find_save_bridge(C.HEIF)) != 0
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -431,6 +437,8 @@ func vipsSave(image *C.VipsImage, o vipsSaveOptions) ([]byte, error) {
|
||||||
saveErr = C.vips_pngsave_bridge(tmpImage, &ptr, &length, strip, C.int(o.Compression), quality, interlace)
|
saveErr = C.vips_pngsave_bridge(tmpImage, &ptr, &length, strip, C.int(o.Compression), quality, interlace)
|
||||||
case TIFF:
|
case TIFF:
|
||||||
saveErr = C.vips_tiffsave_bridge(tmpImage, &ptr, &length)
|
saveErr = C.vips_tiffsave_bridge(tmpImage, &ptr, &length)
|
||||||
|
case HEIF:
|
||||||
|
saveErr = C.vips_heifsave_bridge(tmpImage, &ptr, &length, strip, quality, lossless)
|
||||||
default:
|
default:
|
||||||
saveErr = C.vips_jpegsave_bridge(tmpImage, &ptr, &length, strip, quality, interlace)
|
saveErr = C.vips_jpegsave_bridge(tmpImage, &ptr, &length, strip, quality, interlace)
|
||||||
}
|
}
|
||||||
|
|
@ -634,6 +642,12 @@ func vipsImageType(buf []byte) ImageType {
|
||||||
if IsTypeSupported(MAGICK) && strings.HasSuffix(readImageType(buf), "MagickBuffer") {
|
if IsTypeSupported(MAGICK) && strings.HasSuffix(readImageType(buf), "MagickBuffer") {
|
||||||
return MAGICK
|
return MAGICK
|
||||||
}
|
}
|
||||||
|
// NOTE: libheif current;y only supports heic sub types; see:
|
||||||
|
// https://github.com/strukturag/libheif/issues/83#issuecomment-421427091
|
||||||
|
if IsTypeSupported(HEIF) && buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70 &&
|
||||||
|
buf[8] == 0x68 && buf[9] == 0x65 && buf[10] == 0x69 && buf[11] == 0x63 {
|
||||||
|
return HEIF
|
||||||
|
}
|
||||||
|
|
||||||
return UNKNOWN
|
return UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
|
||||||
33
vips.h
33
vips.h
|
|
@ -32,7 +32,10 @@ enum types {
|
||||||
GIF,
|
GIF,
|
||||||
PDF,
|
PDF,
|
||||||
SVG,
|
SVG,
|
||||||
MAGICK
|
MAGICK,
|
||||||
|
#if (VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 8))
|
||||||
|
HEIF,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -156,6 +159,11 @@ vips_type_find_bridge(int t) {
|
||||||
if (t == MAGICK) {
|
if (t == MAGICK) {
|
||||||
return vips_type_find("VipsOperation", "magickload");
|
return vips_type_find("VipsOperation", "magickload");
|
||||||
}
|
}
|
||||||
|
#if (VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 8))
|
||||||
|
if (t == HEIF) {
|
||||||
|
return vips_type_find("VipsOperation", "heifload");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -173,6 +181,11 @@ vips_type_find_save_bridge(int t) {
|
||||||
if (t == JPEG) {
|
if (t == JPEG) {
|
||||||
return vips_type_find("VipsOperation", "jpegsave_buffer");
|
return vips_type_find("VipsOperation", "jpegsave_buffer");
|
||||||
}
|
}
|
||||||
|
#if (VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 8))
|
||||||
|
if (t == HEIF) {
|
||||||
|
return vips_type_find("VipsOperation", "heifsave_buffer");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -324,6 +337,20 @@ vips_tiffsave_bridge(VipsImage *in, void **buf, size_t *len) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
vips_heifsave_bridge(VipsImage *in, void **buf, size_t *len, int strip, int quality, int lossless) {
|
||||||
|
#if (VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 8))
|
||||||
|
return vips_heifsave_buffer(in, buf, len,
|
||||||
|
"strip", INT_TO_GBOOLEAN(strip),
|
||||||
|
"Q", quality,
|
||||||
|
"lossless", INT_TO_GBOOLEAN(lossless),
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
vips_is_16bit (VipsInterpretation interpretation) {
|
vips_is_16bit (VipsInterpretation interpretation) {
|
||||||
return interpretation == VIPS_INTERPRETATION_RGB16 || interpretation == VIPS_INTERPRETATION_GREY16;
|
return interpretation == VIPS_INTERPRETATION_RGB16 || interpretation == VIPS_INTERPRETATION_GREY16;
|
||||||
|
|
@ -370,6 +397,10 @@ vips_init_image (void *buf, size_t len, int imageType, VipsImage **out) {
|
||||||
#endif
|
#endif
|
||||||
} else if (imageType == MAGICK) {
|
} else if (imageType == MAGICK) {
|
||||||
code = vips_magickload_buffer(buf, len, out, "access", VIPS_ACCESS_RANDOM, NULL);
|
code = vips_magickload_buffer(buf, len, out, "access", VIPS_ACCESS_RANDOM, NULL);
|
||||||
|
#endif
|
||||||
|
#if (VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 8))
|
||||||
|
} else if (imageType == HEIF) {
|
||||||
|
code = vips_heifload_buffer(buf, len, out, "access", VIPS_ACCESS_RANDOM, NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue