# webpdec.h — single-file WebP decoder A standalone, dependency-free **WebP decoder** in one C header, in the spirit of the [stb](https://github.com/nothings/stb) libraries. It is libwebp's decode + demux path — *not* a reimplementation — amalgamated into a single file and built as portable C99 with **all SIMD, threads and host file I/O disabled**. So it is as correct as upstream libwebp (it *is* libwebp) while staying trivial to drop into any project. Handles everything real WebP files use: - **Lossy** (VP8) and **lossless** (VP8L) - The **VP8X** extended container - The **ALPH** alpha chunk (transparency on lossy images) - **Animation** + metadata via the demux API (`WebPDemux`, `WebPAnimDecoder`) ## Usage In exactly **one** translation unit: ```c #define WEBPDEC_IMPLEMENTATION #include "webpdec.h" ``` Everywhere else, just `#include "webpdec.h"`. The public API is the standard libwebp decode + demux API. Still image: ```c int w, h; uint8_t *rgba = WebPDecodeRGBA(data, len, &w, &h); /* R,G,B,A, top-to-bottom */ if (rgba) { /* ... w*h*4 bytes ... */ WebPFree(rgba); } ``` Animation (all frames, with blending/disposal handled for you): ```c WebPData wd = { data, len }; WebPAnimDecoderOptions opt; WebPAnimDecoderOptionsInit(&opt); opt.color_mode = MODE_RGBA; WebPAnimDecoder *dec = WebPAnimDecoderNew(&wd, &opt); WebPAnimInfo info; WebPAnimDecoderGetInfo(dec, &info); /* canvas, frame_count */ while (WebPAnimDecoderHasMoreFrames(dec)) { uint8_t *rgba; int timestamp_ms; WebPAnimDecoderGetNext(dec, &rgba, ×tamp_ms); /* rgba owned by dec */ } WebPAnimDecoderDelete(dec); ``` `WebPGetInfo`, `WebPDecodeRGB/BGRA/ARGB`, the advanced `WebPDecode` + `WebPDecoderConfig` path (including decode-time downscaling via `config.options.use_scaling`), and the full `WebPDemux*` chunk/metadata iterator are all available — see the declarations near the top of `webpdec.h`. Link with `-lm` (libwebp uses `pow()` for gamma tables). That's the only dependency. ## What's not included Encoding and the mux (assembly/write) API — this is decode-only, by design. ## Portability `webpdec.h` defines `HAVE_CONFIG_H` and bakes in an empty `config.h`, which is libwebp's own switch for "no detected SIMD": every architecture dispatcher falls back to the reference C path. This works even on SIMD-capable targets — e.g. on ARMv8 where the toolchain defines `__ARM_NEON`, NEON still stays off. No pthreads, no `` file calls. Tested decoding bit-exactly against upstream libwebp on x86-64 and aarch64. ## Repo layout ``` webpdec.h the single-file library (committed; this is all you need) amalgamate.py regenerates webpdec.h from libwebp UPSTREAM_COMMIT the exact pinned libwebp revision LICENSE, PATENTS upstream BSD-style license + patent grant tests/ test_decode.c, test_demux.c, run.sh libwebp/ upstream checkout (git-ignored; fetched on demand) ``` ## Regenerating ```sh python3 amalgamate.py # writes webpdec.h (+ refreshes UPSTREAM_COMMIT) ``` With no `libwebp/` present it shallow-clones libwebp at the pinned commit, so a fresh checkout just works — no submodules, no manual steps. The amalgamation is `LIBWEBPDECODER_OBJS` + `DEMUX_OBJS` minus every `*_sse2/_neon/_msa/...` SIMD translation unit; the few single-TU symbol clashes are namespaced by the script (the upstream tree is left pristine, so regeneration is byte-for-byte reproducible). ## Tests ```sh sh tests/run.sh ``` With [Pillow](https://python-pillow.org/) installed it generates lossy / lossless / alpha / animated samples and checks decode output **bit-exactly** against reference libwebp; otherwise pass it `.webp` paths to decode. ## License BSD-style, identical to libwebp. See `LICENSE` and `PATENTS`. Copyright Google LLC and the WebM project authors; this file only mechanically concatenates their sources.