go-libwebp

Experimental translation from libwebp to Go source.
Log | Files | Refs | README | LICENSE

commit c39ff56bebedaa274ffee3e7237a470701a77a91
parent 2b3a104db86fd2d93cbf1e09d0ea819d479398e2
Author: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Date:   Sun, 20 Sep 2026 15:31:26 -0300

webp: cover lossy decode in the backend tests

Every existing test went through VP8L: the golden is lossless and the fuzz
targets only decode when lossless is set. Nothing decoded a lossy image
through a pure-Go backend, so a transpiled build whose VP8 bit reader aborted
on the first call passed the whole suite.

Diffstat:
Mwebp/backend_transpiled_test.go | 4++++
Mwebp/backend_wazero_test.go | 4++++
Mwebp/webp_test.go | 25+++++++++++++++++++++++++
3 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/webp/backend_transpiled_test.go b/webp/backend_transpiled_test.go @@ -41,6 +41,10 @@ func TestTranspiledDecodesCurrentGolden(t *testing.T) { } } +func TestTranspiledDecodesLossy(t *testing.T) { + assertLossyDecode(t, transpiled.EncodeImpl, transpiled.DecodeImpl) +} + func FuzzEncodeTranspiled(f *testing.F) { addEncodeSeeds(f) f.Fuzz(func(t *testing.T, x1, y1 uint16, seed int64, quality float32, lossless bool) { diff --git a/webp/backend_wazero_test.go b/webp/backend_wazero_test.go @@ -38,6 +38,10 @@ func TestWasmRoundTrip(t *testing.T) { assertOutput(t, m, &buf, decodeReaderWith(wasm.DecodeImpl)) } +func TestWasmDecodesLossy(t *testing.T) { + assertLossyDecode(t, wasm.EncodeImpl, wasm.DecodeImpl) +} + func FuzzEncodeWasm(f *testing.F) { addEncodeSeeds(f) f.Fuzz(func(t *testing.T, x1, y1 uint16, seed int64, quality float32, lossless bool) { diff --git a/webp/webp_test.go b/webp/webp_test.go @@ -122,6 +122,31 @@ func decodeReaderWith(fn func([]byte) (image.Image, error)) func(io.Reader) (ima } } +// assertLossyDecode encodes lossily and decodes the result through the same +// backend, checking dimensions rather than pixels. +// +// This is the VP8 decode path, which is entirely separate from the VP8L path +// the golden and the fuzz seeds exercise. A transpiled build that fell back +// to inline-asm byte swapping passed every other test and aborted here. +func assertLossyDecode(t *testing.T, + encode func(io.Writer, *image.NRGBA, float32) error, + decode func([]byte) (image.Image, error), +) { + t.Helper() + m := goldenNRGBA(t) + var buf bytes.Buffer + if err := encode(&buf, m, 0.75); err != nil { + t.Fatalf("lossy encode: %v", err) + } + got, err := decode(buf.Bytes()) + if err != nil { + t.Fatalf("lossy decode: %v", err) + } + if got.Bounds() != m.Bounds() { + t.Fatalf("bounds: got %v want %v", got.Bounds(), m.Bounds()) + } +} + func save(t *testing.T, name string, m image.Image) { t.Helper()