mirror of
https://github.com/talgo-cloud/bimg.git
synced 2026-03-14 09:55:56 -07:00
feat(types): infer types in runtime
This commit is contained in:
parent
de76daee9c
commit
bffc7652bb
3 changed files with 102 additions and 100 deletions
50
type.go
50
type.go
|
|
@ -2,6 +2,7 @@ package bimg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sync"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -46,17 +47,28 @@ var ImageTypes = map[ImageType]string{
|
||||||
MAGICK: "magick",
|
MAGICK: "magick",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// imageMutex is used to provide thread-safe synchronization
|
||||||
|
// for SupportedImageTypes map.
|
||||||
|
var imageMutex = &sync.RWMutex{}
|
||||||
|
|
||||||
// SupportedImageTypes stores the optional image type supported
|
// SupportedImageTypes stores the optional image type supported
|
||||||
// by the current libvips compilation.
|
// by the current libvips compilation.
|
||||||
var SupportedImageTypes = map[ImageType]bool{
|
// Note: lazy evaluation as demand is required due
|
||||||
JPEG: HasJPEGSupport,
|
// to bootstrap runtime limitation with C/libvips world.
|
||||||
PNG: HasPNGSupport,
|
var SupportedImageTypes = map[ImageType]bool{}
|
||||||
WEBP: HasWEBPSupport,
|
|
||||||
TIFF: HasTIFFSupport,
|
// discoverSupportedImageTypes is used to fill SupportedImageTypes map.
|
||||||
GIF: HasGIFSupport,
|
func discoverSupportedImageTypes() {
|
||||||
SVG: HasSVGSupport,
|
imageMutex.Lock()
|
||||||
PDF: HasPDFSupport,
|
SupportedImageTypes[JPEG] = VipsIsTypeSupported(JPEG)
|
||||||
MAGICK: HasMagickSupport,
|
SupportedImageTypes[PNG] = VipsIsTypeSupported(PNG)
|
||||||
|
SupportedImageTypes[GIF] = VipsIsTypeSupported(GIF)
|
||||||
|
SupportedImageTypes[WEBP] = VipsIsTypeSupported(WEBP)
|
||||||
|
SupportedImageTypes[SVG] = VipsIsTypeSupported(SVG)
|
||||||
|
SupportedImageTypes[TIFF] = VipsIsTypeSupported(TIFF)
|
||||||
|
SupportedImageTypes[PDF] = VipsIsTypeSupported(PDF)
|
||||||
|
SupportedImageTypes[MAGICK] = VipsIsTypeSupported(MAGICK)
|
||||||
|
imageMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// isBinary checks if the given buffer is a binary file.
|
// isBinary checks if the given buffer is a binary file.
|
||||||
|
|
@ -91,21 +103,35 @@ func DetermineImageTypeName(buf []byte) string {
|
||||||
// IsImageTypeSupportedByVips returns true if the given image type
|
// IsImageTypeSupportedByVips returns true if the given image type
|
||||||
// is supported by current libvips compilation.
|
// is supported by current libvips compilation.
|
||||||
func IsImageTypeSupportedByVips(t ImageType) bool {
|
func IsImageTypeSupportedByVips(t ImageType) bool {
|
||||||
|
imageMutex.RLock()
|
||||||
|
|
||||||
|
// Discover supported image types and cache the result
|
||||||
|
itShouldDiscovery := len(SupportedImageTypes) == 0
|
||||||
|
if itShouldDiscovery {
|
||||||
|
imageMutex.RUnlock()
|
||||||
|
discoverSupportedImageTypes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if image type is actually supported
|
||||||
isSupported, ok := SupportedImageTypes[t]
|
isSupported, ok := SupportedImageTypes[t]
|
||||||
|
if !itShouldDiscovery {
|
||||||
|
imageMutex.RUnlock()
|
||||||
|
}
|
||||||
|
|
||||||
return ok && isSupported
|
return ok && isSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsTypeSupported checks if a given image type is supported
|
// IsTypeSupported checks if a given image type is supported
|
||||||
func IsTypeSupported(t ImageType) bool {
|
func IsTypeSupported(t ImageType) bool {
|
||||||
_, ok := ImageTypes[t]
|
_, ok := ImageTypes[t]
|
||||||
return ok
|
return ok && IsImageTypeSupportedByVips(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsTypeNameSupported checks if a given image type name is supported
|
// IsTypeNameSupported checks if a given image type name is supported
|
||||||
func IsTypeNameSupported(t string) bool {
|
func IsTypeNameSupported(t string) bool {
|
||||||
for _, name := range ImageTypes {
|
for imageType, name := range ImageTypes {
|
||||||
if name == t {
|
if name == t {
|
||||||
return true
|
return IsImageTypeSupportedByVips(imageType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
|
||||||
75
vips.go
75
vips.go
|
|
@ -30,38 +30,6 @@ const VipsMajorVersion = int(C.VIPS_MAJOR_VERSION)
|
||||||
// VipsMinorVersion exposes the current libvips minor version number
|
// VipsMinorVersion exposes the current libvips minor version number
|
||||||
const VipsMinorVersion = int(C.VIPS_MINOR_VERSION)
|
const VipsMinorVersion = int(C.VIPS_MINOR_VERSION)
|
||||||
|
|
||||||
// HasJPEGSupport exposes if the current libvips compilation
|
|
||||||
// supports JPEG images.
|
|
||||||
const HasJPEGSupport = int(C.VIPS_JPEG_SUPPORT) == 1
|
|
||||||
|
|
||||||
// HasWEBPSupport exposes if the current libvips compilation
|
|
||||||
// supports WEBP images.
|
|
||||||
const HasWEBPSupport = int(C.VIPS_WEBP_SUPPORT) == 1
|
|
||||||
|
|
||||||
// HasPNGSupport exposes if the current libvips compilation
|
|
||||||
// supports PNG images.
|
|
||||||
const HasPNGSupport = int(C.VIPS_PNG_SUPPORT) == 1
|
|
||||||
|
|
||||||
// HasMagickSupport exposes if the current libvips compilation
|
|
||||||
// supports libmagick bindings.
|
|
||||||
const HasMagickSupport = int(C.VIPS_MAGICK_SUPPORT) == 1
|
|
||||||
|
|
||||||
// HasGIFSupport exposes if the current libvips compilation
|
|
||||||
// supports GIF images.
|
|
||||||
const HasGIFSupport = int(C.VIPS_GIF_SUPPORT) == 1
|
|
||||||
|
|
||||||
// HasSVGSupport exposes if the current libvips compilation
|
|
||||||
// supports SVG images.
|
|
||||||
const HasSVGSupport = int(C.VIPS_SVG_SUPPORT) == 1
|
|
||||||
|
|
||||||
// HasPDFSupport exposes if the current libvips compilation
|
|
||||||
// supports PDF images.
|
|
||||||
const HasPDFSupport = int(C.VIPS_PDF_SUPPORT) == 1
|
|
||||||
|
|
||||||
// HasTIFFSupport exposes if the current libvips compilation
|
|
||||||
// supports TIFF images.
|
|
||||||
const HasTIFFSupport = int(C.VIPS_TIFF_SUPPORT) == 1
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
maxCacheMem = 100 * 1024 * 1024
|
maxCacheMem = 100 * 1024 * 1024
|
||||||
maxCacheSize = 500
|
maxCacheSize = 500
|
||||||
|
|
@ -169,6 +137,33 @@ func VipsMemory() VipsMemoryInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VipsIsTypeSupported returns true if the given image type
|
||||||
|
// is supported by the current libvips compilation.
|
||||||
|
func VipsIsTypeSupported(t ImageType) bool {
|
||||||
|
if t == JPEG {
|
||||||
|
return int(C.vips_type_find_bridge(C.JPEG)) != 0
|
||||||
|
}
|
||||||
|
if t == WEBP {
|
||||||
|
return int(C.vips_type_find_bridge(C.WEBP)) != 0
|
||||||
|
}
|
||||||
|
if t == PNG {
|
||||||
|
return int(C.vips_type_find_bridge(C.PNG)) != 0
|
||||||
|
}
|
||||||
|
if t == GIF {
|
||||||
|
return int(C.vips_type_find_bridge(C.GIF)) != 0
|
||||||
|
}
|
||||||
|
if t == PDF {
|
||||||
|
return int(C.vips_type_find_bridge(C.PDF)) != 0
|
||||||
|
}
|
||||||
|
if t == SVG {
|
||||||
|
return int(C.vips_type_find_bridge(C.SVG)) != 0
|
||||||
|
}
|
||||||
|
if t == TIFF {
|
||||||
|
return int(C.vips_type_find_bridge(C.TIFF)) != 0
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func vipsExifOrientation(image *C.VipsImage) int {
|
func vipsExifOrientation(image *C.VipsImage) int {
|
||||||
return int(C.vips_exif_orientation(image))
|
return int(C.vips_exif_orientation(image))
|
||||||
}
|
}
|
||||||
|
|
@ -493,30 +488,30 @@ func vipsImageType(buf []byte) ImageType {
|
||||||
if len(buf) == 0 {
|
if len(buf) == 0 {
|
||||||
return UNKNOWN
|
return UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
if buf[0] == 0x89 && buf[1] == 0x50 && buf[2] == 0x4E && buf[3] == 0x47 {
|
if buf[0] == 0x89 && buf[1] == 0x50 && buf[2] == 0x4E && buf[3] == 0x47 {
|
||||||
return PNG
|
return PNG
|
||||||
}
|
}
|
||||||
if buf[0] == 0xFF && buf[1] == 0xD8 && buf[2] == 0xFF {
|
if buf[0] == 0xFF && buf[1] == 0xD8 && buf[2] == 0xFF {
|
||||||
return JPEG
|
return JPEG
|
||||||
}
|
}
|
||||||
if buf[8] == 0x57 && buf[9] == 0x45 && buf[10] == 0x42 && buf[11] == 0x50 {
|
if IsImageTypeSupportedByVips(WEBP) && buf[8] == 0x57 && buf[9] == 0x45 && buf[10] == 0x42 && buf[11] == 0x50 {
|
||||||
return WEBP
|
return WEBP
|
||||||
}
|
}
|
||||||
if (buf[0] == 0x49 && buf[1] == 0x49 && buf[2] == 0x2A && buf[3] == 0x0) ||
|
if IsImageTypeSupportedByVips(TIFF) &&
|
||||||
(buf[0] == 0x4D && buf[1] == 0x4D && buf[2] == 0x0 && buf[3] == 0x2A) {
|
((buf[0] == 0x49 && buf[1] == 0x49 && buf[2] == 0x2A && buf[3] == 0x0) ||
|
||||||
|
(buf[0] == 0x4D && buf[1] == 0x4D && buf[2] == 0x0 && buf[3] == 0x2A)) {
|
||||||
return TIFF
|
return TIFF
|
||||||
}
|
}
|
||||||
if buf[0] == 0x47 && buf[1] == 0x49 && buf[2] == 0x46 {
|
if IsImageTypeSupportedByVips(GIF) && buf[0] == 0x47 && buf[1] == 0x49 && buf[2] == 0x46 {
|
||||||
return GIF
|
return GIF
|
||||||
}
|
}
|
||||||
if buf[0] == 0x25 && buf[1] == 0x50 && buf[2] == 0x44 && buf[3] == 0x46 {
|
if IsImageTypeSupportedByVips(PDF) && buf[0] == 0x25 && buf[1] == 0x50 && buf[2] == 0x44 && buf[3] == 0x46 {
|
||||||
return PDF
|
return PDF
|
||||||
}
|
}
|
||||||
if IsSVGImage(buf) {
|
if IsImageTypeSupportedByVips(SVG) && IsSVGImage(buf) {
|
||||||
return SVG
|
return SVG
|
||||||
}
|
}
|
||||||
if HasMagickSupport && strings.HasSuffix(readImageType(buf), "MagickBuffer") {
|
if strings.HasSuffix(readImageType(buf), "MagickBuffer") {
|
||||||
return MAGICK
|
return MAGICK
|
||||||
}
|
}
|
||||||
return UNKNOWN
|
return UNKNOWN
|
||||||
|
|
|
||||||
77
vips.h
77
vips.h
|
|
@ -3,54 +3,6 @@
|
||||||
#include <vips/foreign.h>
|
#include <vips/foreign.h>
|
||||||
#include <vips/vips7compat.h>
|
#include <vips/vips7compat.h>
|
||||||
|
|
||||||
#ifdef VIPS_MAGICK_H
|
|
||||||
#define VIPS_MAGICK_SUPPORT 1
|
|
||||||
#else
|
|
||||||
#define VIPS_MAGICK_SUPPORT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_JPEG
|
|
||||||
#define VIPS_JPEG_SUPPORT 1
|
|
||||||
#else
|
|
||||||
#define VIPS_JPEG_SUPPORT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_PNG
|
|
||||||
#define VIPS_PNG_SUPPORT 1
|
|
||||||
#else
|
|
||||||
#define VIPS_PNG_SUPPORT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBWEBP
|
|
||||||
#define VIPS_WEBP_SUPPORT 1
|
|
||||||
#else
|
|
||||||
#define VIPS_WEBP_SUPPORT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_GIFLIB
|
|
||||||
#define VIPS_GIF_SUPPORT 1
|
|
||||||
#else
|
|
||||||
#define VIPS_GIF_SUPPORT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_RSVG
|
|
||||||
#define VIPS_SVG_SUPPORT 1
|
|
||||||
#else
|
|
||||||
#define VIPS_SVG_SUPPORT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_POPPLER
|
|
||||||
#define VIPS_PDF_SUPPORT 1
|
|
||||||
#else
|
|
||||||
#define VIPS_PDF_SUPPORT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_TIFF
|
|
||||||
#define VIPS_TIFF_SUPPORT 1
|
|
||||||
#else
|
|
||||||
#define VIPS_TIFF_SUPPORT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starting libvips 7.41, VIPS_ANGLE_x has been renamed to VIPS_ANGLE_Dx
|
* Starting libvips 7.41, VIPS_ANGLE_x has been renamed to VIPS_ANGLE_Dx
|
||||||
* "to help python". So we provide the macro to correctly build for versions
|
* "to help python". So we provide the macro to correctly build for versions
|
||||||
|
|
@ -163,6 +115,35 @@ vips_shrink_bridge(VipsImage *in, VipsImage **out, double xshrink, double yshrin
|
||||||
return vips_shrink(in, out, xshrink, yshrink, NULL);
|
return vips_shrink(in, out, xshrink, yshrink, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
vips_type_find_bridge(int t) {
|
||||||
|
if (t == GIF) {
|
||||||
|
return vips_type_find("VipsOperation", "gifload");
|
||||||
|
}
|
||||||
|
if (t == PDF) {
|
||||||
|
return vips_type_find("VipsOperation", "pdfload");
|
||||||
|
}
|
||||||
|
if (t == TIFF) {
|
||||||
|
return vips_type_find("VipsOperation", "tiffload");
|
||||||
|
}
|
||||||
|
if (t == SVG) {
|
||||||
|
return vips_type_find("VipsOperation", "svgload");
|
||||||
|
}
|
||||||
|
if (t == WEBP) {
|
||||||
|
return vips_type_find("VipsOperation", "webpload");
|
||||||
|
}
|
||||||
|
if (t == PNG) {
|
||||||
|
return vips_type_find("VipsOperation", "pngload");
|
||||||
|
}
|
||||||
|
if (t == JPEG) {
|
||||||
|
return vips_type_find("VipsOperation", "jpegload");
|
||||||
|
}
|
||||||
|
if (t == MAGICK) {
|
||||||
|
return vips_type_find("VipsOperation", "magickload");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
vips_rotate(VipsImage *in, VipsImage **out, int angle) {
|
vips_rotate(VipsImage *in, VipsImage **out, int angle) {
|
||||||
int rotate = VIPS_ANGLE_D0;
|
int rotate = VIPS_ANGLE_D0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue