A safe, fast Rust and assembly WebP decoder with a C ABI.
| Image | Output | image-webp (ms) | libwebp (ms) | wpd (ms) | libwebp / wpd |
|---|---|---|---|---|---|
| lossy.webp | YUV420P | — | 180.40 | 173.56 | 1.04x |
| simplelf-lossy.webp | YUV420P | — | 174.43 | 162.07 | 1.08x |
| anim_yuv.webp | RGBA | 359.85 | 190.90 | 169.18 | 1.13x |
| lossless.webp | RGBA | 231.50 | 195.75 | 111.27 | 1.76x |
| anim_rgb.webp | RGBA | 206.09 | 104.47 | 62.56 | 1.67x |
| a_lossy.webp | YUVA420P | — | 50.70 | 36.38 | 1.39x |
| anim_yuva.webp | RGBA | 776.54 | 494.37 | 374.46 | 1.32x |
Dependencies:
nasm (on x86)meson setup build
meson compile -C build
build/wpd [options] input.webp output.raw
The build enables assembly by default. Compile with -Denable_asm=false for
memory safety guarantees at the cost of speed.
For minimal binary and library sizes:
meson setup build-minsize --buildtype=minsize
meson compile -C build-minsize
-Dnightly_size=true also needs nightly Rust and rust-src. The build then
produces libwpd-sealed.a alongside libwpd.a. The sealed static lib aborts
instead of unwinding on an internal panic. The build merges every object into
one monolithic object for downstream consumers.
meson install -C build installs the static/shared libraries, wpd.h, and
wpd.pc. The library exports only the wpd_* symbols declared in the header.
See wpd.h for C API usage.
[dependencies]
wpd = { git = "https://github.com/halidecx/wpd" }
use wpd::{api::Decoder, image::Format, options::Options};
let mut decoder = Decoder::new();
decoder.set_format(Format::Rgba)?;
decoder.set_options(Options { scale: Some((320, 0)), ..Default::default() })?;
decoder.open(&data)?;
while let Some(frame) = decoder.next_frame()? {
for row in frame.rows_of(0) {
present(row);
}
}
rows_of() yields output-order rows, so flips don't need special stride
handlingopen_stream, append, end_of_stream, and partial_frame provide
streamingupdate and UpdateBuffer reuse an allocationmeson test -C build
meson configure build -Dtestdata_tests=true
meson test -C build --suite testdata
./scripts/stylecheck.sh
Test data is maintained at
wpd-test-data, which you can clone
into the wpd/ root. ./scripts/testdata.sh runs end-to-end assembly and
fallback checks.
For libwebp parity testing and benchmarking against alternative WebP decoders, build the optional third-party test binaries:
meson configure build -Dbuildtype=release -Dtrim_dsp=false
meson compile -C build
meson compile -C build libwebpdec imagewebpdec
./scripts/bench.sh
On Linux, use taskset -c 0 ./scripts/bench.sh to reproduce the CPU affinity
above. The harness exports raw Hyperfine timings to build/bench/; set
BENCH_DIR to select another directory. Output is discarded, but requested
format conversion still runs on every decode.
The default libwebp is the pinned Meson subproject. -Dlibwebp=system or
-Dlibwebpdecoder=/path/to/libwebpdecoder.a overrides it. imagewebpdec is the
same harness over the pure-Rust image-webp crate, which bench.sh includes
whenever it has been built.
This project would not be possible without:
319 followers · starred Sep 2026
Rust
53.6%
Assembly
24.7%
C
19.0%
Shell
1.5%
Meson
1.3%
A safe, fast Rust and assembly WebP decoder with a C ABI.
| Image | Output | image-webp (ms) | libwebp (ms) | wpd (ms) | libwebp / wpd |
|---|---|---|---|---|---|
| lossy.webp | YUV420P | — | 180.40 | 173.56 | 1.04x |
| simplelf-lossy.webp | YUV420P | — | 174.43 | 162.07 | 1.08x |
| anim_yuv.webp | RGBA | 359.85 | 190.90 | 169.18 | 1.13x |
| lossless.webp | RGBA | 231.50 | 195.75 | 111.27 | 1.76x |
| anim_rgb.webp | RGBA | 206.09 | 104.47 | 62.56 | 1.67x |
| a_lossy.webp | YUVA420P | — | 50.70 | 36.38 | 1.39x |
| anim_yuva.webp | RGBA | 776.54 | 494.37 | 374.46 | 1.32x |
Dependencies:
nasm (on x86)meson setup build
meson compile -C build
build/wpd [options] input.webp output.raw
The build enables assembly by default. Compile with -Denable_asm=false for
memory safety guarantees at the cost of speed.
For minimal binary and library sizes:
meson setup build-minsize --buildtype=minsize
meson compile -C build-minsize
-Dnightly_size=true also needs nightly Rust and rust-src. The build then
produces libwpd-sealed.a alongside libwpd.a. The sealed static lib aborts
instead of unwinding on an internal panic. The build merges every object into
one monolithic object for downstream consumers.
meson install -C build installs the static/shared libraries, wpd.h, and
wpd.pc. The library exports only the wpd_* symbols declared in the header.
See wpd.h for C API usage.
[dependencies]
wpd = { git = "https://github.com/halidecx/wpd" }
use wpd::{api::Decoder, image::Format, options::Options};
let mut decoder = Decoder::new();
decoder.set_format(Format::Rgba)?;
decoder.set_options(Options { scale: Some((320, 0)), ..Default::default() })?;
decoder.open(&data)?;
while let Some(frame) = decoder.next_frame()? {
for row in frame.rows_of(0) {
present(row);
}
}
rows_of() yields output-order rows, so flips don't need special stride
handlingopen_stream, append, end_of_stream, and partial_frame provide
streamingupdate and UpdateBuffer reuse an allocationmeson test -C build
meson configure build -Dtestdata_tests=true
meson test -C build --suite testdata
./scripts/stylecheck.sh
Test data is maintained at
wpd-test-data, which you can clone
into the wpd/ root. ./scripts/testdata.sh runs end-to-end assembly and
fallback checks.
For libwebp parity testing and benchmarking against alternative WebP decoders, build the optional third-party test binaries:
meson configure build -Dbuildtype=release -Dtrim_dsp=false
meson compile -C build
meson compile -C build libwebpdec imagewebpdec
./scripts/bench.sh
On Linux, use taskset -c 0 ./scripts/bench.sh to reproduce the CPU affinity
above. The harness exports raw Hyperfine timings to build/bench/; set
BENCH_DIR to select another directory. Output is discarded, but requested
format conversion still runs on every decode.
The default libwebp is the pinned Meson subproject. -Dlibwebp=system or
-Dlibwebpdecoder=/path/to/libwebpdecoder.a overrides it. imagewebpdec is the
same harness over the pure-Rust image-webp crate, which bench.sh includes
whenever it has been built.
This project would not be possible without:
319 followers · starred Sep 2026
Rust
53.6%
Assembly
24.7%
C
19.0%
Shell
1.5%
Meson
1.3%