diff --git a/goheif.go b/goheif.go index 214c19c..7a5d78d 100644 --- a/goheif.go +++ b/goheif.go @@ -1,12 +1,15 @@ package goheif import ( + "bytes" "fmt" - "github.com/jdeng/goheif/heif" - "github.com/jdeng/goheif/libde265" "image" "image/color" "io" + "io/ioutil" + + "github.com/jdeng/goheif/heif" + "github.com/jdeng/goheif/libde265" ) type gridBox struct { @@ -75,7 +78,12 @@ func ExtractExif(ra io.ReaderAt) ([]byte, error) { return hf.EXIF() } -func DecodeImage(ra io.ReaderAt) (image.Image, error) { +func Decode(r io.Reader) (image.Image, error) { + ra, err := asReaderAt(r) + if err != nil { + return nil, err + } + hf := heif.Open(ra) it, err := hf.PrimaryItem() @@ -170,9 +178,14 @@ func DecodeImage(ra io.ReaderAt) (image.Image, error) { return out, nil } -func DecodeConfig(ra io.ReaderAt) (image.Config, error) { +func DecodeConfig(r io.Reader) (image.Config, error) { var config image.Config + ra, err := asReaderAt(r) + if err != nil { + return config, err + } + hf := heif.Open(ra) it, err := hf.PrimaryItem() @@ -193,7 +206,22 @@ func DecodeConfig(ra io.ReaderAt) (image.Config, error) { return config, nil } +func asReaderAt(r io.Reader) (io.ReaderAt, error) { + if ra, ok := r.(io.ReaderAt); ok { + return ra, nil + } + + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + return bytes.NewReader(b), nil +} + func init() { libde265.Init() - //image.RegisterFormat("heif", "????ftypheic", decodeImage, decodeConfig) + // they check for "ftyp" at the 5th bytes, let's do the same... + // https://github.com/strukturag/libheif/blob/master/libheif/heif.cc#L94 + image.RegisterFormat("heic", "????ftyp", Decode, DecodeConfig) } diff --git a/goheif_test.go b/goheif_test.go new file mode 100644 index 0000000..660fcc7 --- /dev/null +++ b/goheif_test.go @@ -0,0 +1,28 @@ +package goheif + +import ( + "bytes" + "image" + "io/ioutil" + "testing" +) + +func TestFormatRegistered(t *testing.T) { + b, err := ioutil.ReadFile("testdata/camel.heic") + if err != nil { + t.Fatal(err) + } + + img, dec, err := image.Decode(bytes.NewReader(b)) + if err != nil { + t.Fatalf("unable to decode heic image: %s", err) + } + + if got, want := dec, "heic"; got != want { + t.Errorf("unexpected decoder: got %s, want %s", got, want) + } + + if w, h := img.Bounds().Dx(), img.Bounds().Dy(); w != 1596 || h != 1064 { + t.Errorf("unexpected decoded image size: got %dx%d, want 1596x1064", w, h) + } +} diff --git a/testdata/camel.heic b/testdata/camel.heic new file mode 100644 index 0000000..ecb8453 Binary files /dev/null and b/testdata/camel.heic differ