Skip to content

Commit

Permalink
Refactoring IsTypeSupport to deal with save.
Browse files Browse the repository at this point in the history
Signed-off-by: Yoan Blanc <yoan@dosimple.ch>
  • Loading branch information
greut committed Dec 14, 2016
1 parent dcd91c8 commit a2ba03d
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 24 deletions.
53 changes: 39 additions & 14 deletions type.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,28 @@ var ImageTypes = map[ImageType]string{
// for SupportedImageTypes map.
var imageMutex = &sync.RWMutex{}

// SupportedImageType represents whether a type can be loaded and/or saved by
// the current libvips compilation.
type SupportedImageType struct {
Load bool
Save bool
}

// SupportedImageTypes stores the optional image type supported
// by the current libvips compilation.
// Note: lazy evaluation as demand is required due
// to bootstrap runtime limitation with C/libvips world.
var SupportedImageTypes = map[ImageType]bool{}
var SupportedImageTypes = map[ImageType]SupportedImageType{}

// discoverSupportedImageTypes is used to fill SupportedImageTypes map.
func discoverSupportedImageTypes() {
imageMutex.Lock()
SupportedImageTypes[JPEG] = VipsIsTypeSupported(JPEG)
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)
for imageType := range ImageTypes {
SupportedImageTypes[imageType] = SupportedImageType{
Load: VipsIsTypeSupported(imageType),
Save: VipsIsTypeSupportedSave(imageType),
}
}
imageMutex.Unlock()
}

Expand Down Expand Up @@ -102,7 +107,7 @@ func DetermineImageTypeName(buf []byte) string {

// IsImageTypeSupportedByVips returns true if the given image type
// is supported by current libvips compilation.
func IsImageTypeSupportedByVips(t ImageType) bool {
func IsImageTypeSupportedByVips(t ImageType) SupportedImageType {
imageMutex.RLock()

// Discover supported image types and cache the result
Expand All @@ -113,25 +118,45 @@ func IsImageTypeSupportedByVips(t ImageType) bool {
}

// Check if image type is actually supported
isSupported, ok := SupportedImageTypes[t]
supported, ok := SupportedImageTypes[t]
if !itShouldDiscover {
imageMutex.RUnlock()
}

return ok && isSupported
if ok {
return supported
}
return SupportedImageType{Load: false, Save: false}
}

// IsTypeSupported checks if a given image type is supported
func IsTypeSupported(t ImageType) bool {
_, ok := ImageTypes[t]
return ok && IsImageTypeSupportedByVips(t)
return ok && IsImageTypeSupportedByVips(t).Load
}

// IsTypeNameSupported checks if a given image type name is supported
func IsTypeNameSupported(t string) bool {
for imageType, name := range ImageTypes {
if name == t {
return IsImageTypeSupportedByVips(imageType)
return IsImageTypeSupportedByVips(imageType).Load
}
}
return false
}

// IsTypeSupportedSave checks if a given image type is support for saving
func IsTypeSupportedSave(t ImageType) bool {
_, ok := ImageTypes[t]
return ok && IsImageTypeSupportedByVips(t).Save
}

// IsTypeNameSupportedSave checks if a given image type name is supported for
// saving
func IsTypeNameSupportedSave(t string) bool {
for imageType, name := range ImageTypes {
if name == t {
return IsImageTypeSupportedByVips(imageType).Save
}
}
return false
Expand Down
41 changes: 39 additions & 2 deletions type_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestIsTypeSupported(t *testing.T) {

for _, n := range types {
if IsTypeSupported(n.name) == false {
t.Fatal("Image type is not valid")
t.Fatalf("Image type %#v is not valid", ImageTypes[n.name])
}
}
}
Expand All @@ -85,7 +85,44 @@ func TestIsTypeNameSupported(t *testing.T) {

for _, n := range types {
if IsTypeNameSupported(n.name) != n.expected {
t.Fatal("Image type is not valid")
t.Fatalf("Image type %#v is not valid", n.name)
}
}
}

func TestIsTypeSupportedSave(t *testing.T) {
types := []struct {
name ImageType
}{
{JPEG}, {PNG}, {WEBP},
}
if VipsVersion >= "8.5.0" {
types = append(types, struct{ name ImageType }{TIFF})
}

for _, n := range types {
if IsTypeSupportedSave(n.name) == false {
t.Fatalf("Image type %#v is not valid", ImageTypes[n.name])
}
}
}

func TestIsTypeNameSupportedSave(t *testing.T) {
types := []struct {
name string
expected bool
}{
{"jpeg", true},
{"png", true},
{"webp", true},
{"gif", false},
{"pdf", false},
{"tiff", VipsVersion >= "8.5.0"},
}

for _, n := range types {
if IsTypeNameSupportedSave(n.name) != n.expected {
t.Fatalf("Image type %#v is not valid", n.name)
}
}
}
14 changes: 7 additions & 7 deletions vips.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ 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) {
if o.Type != 0 && !IsTypeSupportedSave(o.Type) {
return nil, fmt.Errorf("VIPS cannot save to %#v", ImageTypes[o.Type])
}
var ptr unsafe.Pointer
Expand Down Expand Up @@ -520,24 +520,24 @@ func vipsImageType(buf []byte) ImageType {
if buf[0] == 0xFF && buf[1] == 0xD8 && buf[2] == 0xFF {
return JPEG
}
if IsImageTypeSupportedByVips(WEBP) && buf[8] == 0x57 && buf[9] == 0x45 && buf[10] == 0x42 && buf[11] == 0x50 {
if IsTypeSupported(WEBP) && buf[8] == 0x57 && buf[9] == 0x45 && buf[10] == 0x42 && buf[11] == 0x50 {
return WEBP
}
if IsImageTypeSupportedByVips(TIFF) &&
if IsTypeSupported(TIFF) &&
((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
}
if IsImageTypeSupportedByVips(GIF) && buf[0] == 0x47 && buf[1] == 0x49 && buf[2] == 0x46 {
if IsTypeSupported(GIF) && buf[0] == 0x47 && buf[1] == 0x49 && buf[2] == 0x46 {
return GIF
}
if IsImageTypeSupportedByVips(PDF) && buf[0] == 0x25 && buf[1] == 0x50 && buf[2] == 0x44 && buf[3] == 0x46 {
if IsTypeSupported(PDF) && buf[0] == 0x25 && buf[1] == 0x50 && buf[2] == 0x44 && buf[3] == 0x46 {
return PDF
}
if IsImageTypeSupportedByVips(SVG) && IsSVGImage(buf) {
if IsTypeSupported(SVG) && IsSVGImage(buf) {
return SVG
}
if IsImageTypeSupportedByVips(MAGICK) && strings.HasSuffix(readImageType(buf), "MagickBuffer") {
if IsTypeSupported(MAGICK) && strings.HasSuffix(readImageType(buf), "MagickBuffer") {
return MAGICK
}
return UNKNOWN
Expand Down
2 changes: 1 addition & 1 deletion vips_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func TestVipsSave(t *testing.T) {
}

func TestVipsSaveTiff(t *testing.T) {
if !VipsIsTypeSupportedSave(TIFF) {
if !IsTypeSupportedSave(TIFF) {
t.Skipf("Format %#v is not supported", ImageTypes[TIFF])
}
image, _, _ := vipsRead(readImage("test.jpg"))
Expand Down

0 comments on commit a2ba03d

Please sign in to comment.