go-libwebp

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

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

README: update for libwebp 1.6.0 and the ccgo v4 toolchain

The toolchain section still described the v3 pipeline and its osxcross
requirement, which no longer exists.

Diffstat:
MREADME.md | 52++++++++++++++++++++++++++++++++--------------------
1 file changed, 32 insertions(+), 20 deletions(-)

diff --git a/README.md b/README.md @@ -53,26 +53,26 @@ Lower is better. | operation | dynamic | wasm | transpiled | | --------------------- | ------- | ---- | ---------- | -| encode lossless | 1.0x | 2.6x | 2.5x | -| encode lossy (q=0.75) | 1.0x | 2.7x | 4.2x | -| decode | 1.0x | 2.3x | 4.5x | +| encode lossless | 1.0x | 2.6x | 2.8x | +| encode lossy (q=0.75) | 1.0x | 2.6x | 4.3x | +| decode | 1.0x | 2.2x | 4.5x | Megapixels per second, 1280x720 photographic: | operation | dynamic | wasm | transpiled | | --------------------- | ------- | ---- | ---------- | -| encode lossless | 4.0 | 1.9 | 2.1 | -| encode lossy (q=0.75) | 26.2 | 9.9 | 5.8 | -| decode | 328 | 139 | 68 | +| encode lossless | 4.0 | 1.7 | 1.7 | +| encode lossy (q=0.75) | 25.7 | 10.0 | 5.1 | +| decode | 309 | 133 | 56 | Same source, six builds. SIMD accounts for the whole wasm/transpiled difference, and lossless barely uses it: | operation | native SIMD | native scalar | wasm zig | wasm em | wasm em+SIMD | transpiled | | --------------- | ----------- | ------------- | -------- | ------- | ------------ | ---------- | -| encode lossless | 1.0x | 1.2x | 3.2x | 3.2x | 2.6x | 2.5x | -| encode lossy | 1.0x | 2.3x | 4.9x | 4.7x | 2.7x | 4.2x | -| decode | 1.0x | 2.3x | 5.3x | 5.2x | 2.3x | 4.5x | +| encode lossless | 1.0x | 1.2x | 3.2x | 3.2x | 2.6x | 2.8x | +| encode lossy | 1.0x | 2.3x | 4.8x | 4.7x | 2.6x | 4.3x | +| decode | 1.0x | 2.1x | 4.8x | 4.7x | 2.2x | 4.5x | All backends encode byte-identically; the harness checks that before measuring. @@ -122,17 +122,29 @@ Run `tools/test-matrix.sh` to build and test every supported tag combination. ## Toolchain -The transpilation process relies on a cross compile toolchain. - -This is not strictly required at the moment, since the transpiled code is -identical between operating systems and architectures (amd64, arm64). - -`tools/transpile.sh` expects these compilers on an amd64 Linux box: - -- gcc (gcc native) -- aarch64-linux-gnu (gcc) -- x86_64-w64-mingw32 (mingw) -- x86_64-apple-darwin15 (osxcross) +`tools/transpile.sh` regenerates `lib/transpiled` with +[`ccgo`](https://pkg.go.dev/modernc.org/ccgo/v4) v4, one file per GOOS/GOARCH, on an +amd64 Linux box. It needs: + +| tool | for | +| ------------------------ | ------------------------------------------- | +| `ccgo` v4 | the transpiler | +| `zig` | darwin headers | +| `x86_64-w64-mingw32-gcc` | windows headers | +| `aarch64-linux-gnu-gcc` | linux/arm64 headers | + +ccgo v4 supplies target predefines through `--goos`/`--goarch` but not target libc +headers, so each cross target needs a header source. zig covers darwin from its bundled +`any-macos-any` headers, which is why no macOS SDK or osxcross install is required. It +does not cover linux: ccgo cannot parse zig's `generic-glibc` `bits/types.h`, so +linux/arm64 uses a real cross compiler and linux/amd64 uses the host. + +Two patches are applied during transpilation. libwebp declares `GetCoeffs` as a +`volatile` function pointer, which ccgo cannot emit a call through; threading is +disabled here so dropping `volatile` is safe. And `tools/sharpyuv_stub.c` replaces the +sharpyuv library, whose `sharpyuv_gamma.c` is libwebp's only caller of `expf`/`logf` — +`modernc.org/libc` provides those for linux only. Nothing reaches sharpyuv unless +`WebPConfig.use_sharp_yuv` is set, which this package never does. ## Dynamic