From 155ab525d928343ccbaae233d974156936467c6e Mon Sep 17 00:00:00 2001 From: Fabio Marini Date: Tue, 28 Feb 2023 11:57:12 +0100 Subject: [PATCH 1/3] fix: Fixed calling NewDecoder and NewEncoder with nil Options --- decoder/decoder.go | 3 +++ encoder/encoder.go | 3 +++ 2 files changed, 6 insertions(+) diff --git a/decoder/decoder.go b/decoder/decoder.go index 4852052..6854560 100644 --- a/decoder/decoder.go +++ b/decoder/decoder.go @@ -59,6 +59,9 @@ func NewDecoder(r io.Reader, options *Options) (d *Decoder, err error) { return nil, errors.New("data is empty") } + if options == nil { + options = &Options{} + } d = &Decoder{data: data, options: options} if d.config, err = d.options.GetConfig(); err != nil { diff --git a/encoder/encoder.go b/encoder/encoder.go index 5f8c544..9bb96dd 100644 --- a/encoder/encoder.go +++ b/encoder/encoder.go @@ -75,6 +75,9 @@ type Encoder struct { func NewEncoder(src image.Image, options *Options) (e *Encoder, err error) { var config *C.WebPConfig + if options == nil { + options, _ = NewLossyEncoderOptions(PresetDefault, 75) + } if config, err = options.GetConfig(); err != nil { return nil, err } From 063943170bc920687280af210a9b20e464bd16be Mon Sep 17 00:00:00 2001 From: Fabio Marini Date: Tue, 28 Feb 2023 11:57:42 +0100 Subject: [PATCH 2/3] test: Added new tests to check calling NewDecoder and NewEncoder with nil Options --- decoder/decoder_test.go | 9 +++++++++ encoder/encoder_test.go | 24 +++++++++++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/decoder/decoder_test.go b/decoder/decoder_test.go index de07a5d..d1ba0ae 100644 --- a/decoder/decoder_test.go +++ b/decoder/decoder_test.go @@ -23,6 +23,7 @@ package decoder import ( "github.com/kolesa-team/go-webp/utils" + "github.com/stretchr/testify/require" "image" "os" "testing" @@ -104,3 +105,11 @@ func TestDecoder_GetFeatures(t *testing.T) { t.Fatal("file has_animation is invalid") } } + +func TestDecoder_NilOptions(t *testing.T) { + file, err := os.Open("../test_data/images/m4_q75.webp") + require.NoError(t, err) + + _, err = NewDecoder(file, nil) + require.NoError(t, err) +} diff --git a/encoder/encoder_test.go b/encoder/encoder_test.go index 1221fde..c3dd58d 100644 --- a/encoder/encoder_test.go +++ b/encoder/encoder_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "image" - "io/ioutil" + "os" "testing" ) @@ -28,7 +28,7 @@ func TestNewEncoder(t *testing.T) { err = e.Encode(expected) require.NoError(t, err) - actual, err := ioutil.ReadFile("../test_data/images/100x150_lossy.webp") + actual, err := os.ReadFile("../test_data/images/100x150_lossy.webp") require.NoError(t, err) assert.Equal(t, actual, expected.Bytes()) @@ -51,9 +51,27 @@ func TestNewEncoder(t *testing.T) { err = e.Encode(actuall) require.NoError(t, err) - expected, err := ioutil.ReadFile("../test_data/images/100x150_lossless.webp") + expected, err := os.ReadFile("../test_data/images/100x150_lossless.webp") require.NoError(t, err) assert.Equal(t, expected, actuall.Bytes()) }) } + +func TestNewEncoder_NilOptions(t *testing.T) { + t.Run("encode image without passing options should not panic", func(t *testing.T) { + expected := &bytes.Buffer{} + img := image.NewNRGBA(image.Rectangle{ + Max: image.Point{ + X: 100, + Y: 150, + }, + }) + + e, err := NewEncoder(img, nil) + require.NoError(t, err) + + err = e.Encode(expected) + require.NoError(t, err) + }) +} From b1b8eedadbed4b472364a41fe74f7dcab90c4619 Mon Sep 17 00:00:00 2001 From: Fabio Marini Date: Tue, 28 Feb 2023 11:58:20 +0100 Subject: [PATCH 3/3] feat: Implemented decode via standard image.Decode --- webp/webp.go | 27 ++++++++++++++++++++++++++- webp/webp_test.go | 43 +++++++++++++++++++++++++++++++------------ 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/webp/webp.go b/webp/webp.go index 0f9c87d..6bf5ebd 100644 --- a/webp/webp.go +++ b/webp/webp.go @@ -25,9 +25,22 @@ import ( "github.com/kolesa-team/go-webp/decoder" "github.com/kolesa-team/go-webp/encoder" "image" + "image/color" "io" ) +func init() { + image.RegisterFormat("webp", "RIFF????WEBPVP8", quickDecode, quickDecodeConfig) +} + +func quickDecode(r io.Reader) (image.Image, error) { + return Decode(r, &decoder.Options{}) +} + +func quickDecodeConfig(r io.Reader) (image.Config, error) { + return DecodeConfig(r, &decoder.Options{}) +} + // Decode picture from reader func Decode(r io.Reader, options *decoder.Options) (image.Image, error) { if dec, err := decoder.NewDecoder(r, options); err != nil { @@ -37,7 +50,19 @@ func Decode(r io.Reader, options *decoder.Options) (image.Image, error) { } } -// Encode encode picture and write to io.Writer +func DecodeConfig(r io.Reader, options *decoder.Options) (image.Config, error) { + if dec, err := decoder.NewDecoder(r, options); err != nil { + return image.Config{}, err + } else { + return image.Config{ + ColorModel: color.RGBAModel, + Width: dec.GetFeatures().Width, + Height: dec.GetFeatures().Height, + }, nil + } +} + +// Encode picture and write to io.Writer func Encode(w io.Writer, src image.Image, options *encoder.Options) error { if enc, err := encoder.NewEncoder(src, options); err != nil { return err diff --git a/webp/webp_test.go b/webp/webp_test.go index 9492296..d8ca75f 100644 --- a/webp/webp_test.go +++ b/webp/webp_test.go @@ -25,10 +25,11 @@ import ( "bytes" "github.com/kolesa-team/go-webp/decoder" "github.com/kolesa-team/go-webp/encoder" - "golang.org/x/image/webp" + "github.com/stretchr/testify/require" "image" + "image/color" "image/jpeg" - "io/ioutil" + "io" "os" "testing" ) @@ -50,7 +51,7 @@ func TestEncode(t *testing.T) { t.Fatal(err) } - if err = Encode(ioutil.Discard, img, options); err != nil { + if err = Encode(io.Discard, img, options); err != nil { t.Fatal(err) } }) @@ -70,7 +71,7 @@ func TestEncode(t *testing.T) { t.Fatal(err) } - if err = Encode(ioutil.Discard, img, options); err != nil { + if err = Encode(io.Discard, img, options); err != nil { t.Fatal(err) } }) @@ -84,7 +85,7 @@ func TestEncode(t *testing.T) { t.Fatal(err) } - if err = Encode(ioutil.Discard, img, options); err == nil { + if err = Encode(io.Discard, img, options); err == nil { t.Fatal("an error was expected") } }) @@ -143,10 +144,28 @@ func TestDecode(t *testing.T) { t.Fatal("an error was expected") } }) + t.Run("decode lossy image via standard image.Decode", func(t *testing.T) { + r, err := os.Open("../test_data/images/webp-logo-lossy.webp") + require.NoError(t, err) + img, format, err := image.Decode(r) + require.NoError(t, err) + + require.Equal(t, "webp", format) + require.Equal(t, color.NRGBAModel, img.ColorModel()) + }) + t.Run("decode lossless image via standard image.Decode", func(t *testing.T) { + r, err := os.Open("../test_data/images/webp-logo-lossless.webp") + require.NoError(t, err) + img, format, err := image.Decode(r) + require.NoError(t, err) + + require.Equal(t, "webp", format) + require.Equal(t, color.NRGBAModel, img.ColorModel()) + }) } func BenchmarkDecodeLossy(b *testing.B) { - data, err := ioutil.ReadFile("../test_data/images/webp-logo-lossy.webp") + data, err := os.ReadFile("../test_data/images/webp-logo-lossy.webp") if err != nil { b.Fatal(err) } @@ -164,13 +183,13 @@ func BenchmarkDecodeLossy(b *testing.B) { } func BenchmarkDecodeXImageLossy(b *testing.B) { - data, err := ioutil.ReadFile("../test_data/images/webp-logo-lossy.webp") + data, err := os.ReadFile("../test_data/images/webp-logo-lossy.webp") if err != nil { b.Fatal(err) } for i := 0; i < b.N; i++ { - _, err = webp.Decode(bytes.NewBuffer(data)) + _, err = Decode(bytes.NewBuffer(data), &decoder.Options{}) if err != nil { b.Fatal(err) } @@ -178,7 +197,7 @@ func BenchmarkDecodeXImageLossy(b *testing.B) { } func BenchmarkDecodeLossless(b *testing.B) { - data, err := ioutil.ReadFile("../test_data/images/webp-logo-lossless.webp") + data, err := os.ReadFile("../test_data/images/webp-logo-lossless.webp") if err != nil { b.Fatal(err) } @@ -196,13 +215,13 @@ func BenchmarkDecodeLossless(b *testing.B) { } func BenchmarkDecodeXImageLossless(b *testing.B) { - data, err := ioutil.ReadFile("../test_data/images/webp-logo-lossless.webp") + data, err := os.ReadFile("../test_data/images/webp-logo-lossless.webp") if err != nil { b.Fatal(err) } for i := 0; i < b.N; i++ { - _, err = webp.Decode(bytes.NewBuffer(data)) + _, err = Decode(bytes.NewBuffer(data), &decoder.Options{}) if err != nil { b.Fatal(err) } @@ -226,7 +245,7 @@ func BenchmarkEncode(b *testing.B) { b.Fatal(err) } - if err = Encode(ioutil.Discard, img, options); err != nil { + if err = Encode(io.Discard, img, options); err != nil { b.Fatal(err) } }