halidecx/wpd

WebP Decoder

Rust

2

436 commits

updated Oct 3, 2026

See the code

See what people are saying

SourceMessageScoreDate

code: https://github.com/halidecx/wpd

on Memory-Safe WebP Decoding

0

Oct 3, 2026

README

wpd

A safe, fast Rust and assembly WebP decoder with a C ABI.

ImageOutputimage-webp (ms)libwebp (ms)wpd (ms)libwebp / wpd
lossy.webpYUV420P—180.40173.561.04x
simplelf-lossy.webpYUV420P—174.43162.071.08x
anim_yuv.webpRGBA359.85190.90169.181.13x
lossless.webpRGBA231.50195.75111.271.76x
anim_rgb.webpRGBA206.09104.4762.561.67x
a_lossy.webpYUVA420P—50.7036.381.39x
anim_yuva.webpRGBA776.54494.37374.461.32x

Build

Dependencies:

  • Rust
  • 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.

Library

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.

C

See wpd.h for C API usage.

Rust

[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 handling
  • open_stream, append, end_of_stream, and partial_frame provide streaming
  • update and UpdateBuffer reuse an allocation

Test

meson 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.

Credits

This project would not be possible without:

  • libwebp, the reference WebP implementation
  • dav1d, the fastest open-source AV1 decoder
  • rav1d, a Rust rewrite of dav1d

Significant stargazers

Kristóf Poduszló

319 followers · starred Sep 2026

halidecx/wpd

WebP Decoder

Rust

2

436 commits

updated Oct 3, 2026

See the code

See what people are saying

SourceMessageScoreDate

code: https://github.com/halidecx/wpd

on Memory-Safe WebP Decoding

0

Oct 3, 2026

README

wpd

A safe, fast Rust and assembly WebP decoder with a C ABI.

ImageOutputimage-webp (ms)libwebp (ms)wpd (ms)libwebp / wpd
lossy.webpYUV420P—180.40173.561.04x
simplelf-lossy.webpYUV420P—174.43162.071.08x
anim_yuv.webpRGBA359.85190.90169.181.13x
lossless.webpRGBA231.50195.75111.271.76x
anim_rgb.webpRGBA206.09104.4762.561.67x
a_lossy.webpYUVA420P—50.7036.381.39x
anim_yuva.webpRGBA776.54494.37374.461.32x

Build

Dependencies:

  • Rust
  • 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.

Library

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.

C

See wpd.h for C API usage.

Rust

[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 handling
  • open_stream, append, end_of_stream, and partial_frame provide streaming
  • update and UpdateBuffer reuse an allocation

Test

meson 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.

Credits

This project would not be possible without:

  • libwebp, the reference WebP implementation
  • dav1d, the fastest open-source AV1 decoder
  • rav1d, a Rust rewrite of dav1d

Significant stargazers

Kristóf Poduszló

319 followers · starred Sep 2026

Languages

Rust

53.6%

Assembly

24.7%

C

19.0%

Shell

1.5%

Meson

1.3%