webpdec.h: single-file WebP decoder
libwebp 1.6.0's decode + demux path (lossy VP8, lossless VP8L, VP8X container, ALPH alpha, and the WebPDemux/WebPAnimDecoder animation API) amalgamated into one stb-style header, built as portable C99 with all SIMD, threads and host file I/O disabled. amalgamate.py regenerates webpdec.h from a pinned, auto-cloned libwebp checkout; tests/run.sh checks decode output bit-exactly against reference libwebp. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#!/bin/sh
|
||||
# Build and run the webpdec.h tests. If Pillow is available, samples are
|
||||
# generated and decode output is checked bit-exactly against reference libwebp;
|
||||
# otherwise the tests just decode whatever .webp files are passed/present.
|
||||
#
|
||||
# sh tests/run.sh
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")/.." # repo root
|
||||
CC=${CC:-cc}
|
||||
CFLAGS="-O2 -std=c99 -Wall -I."
|
||||
TMP=$(mktemp -d)
|
||||
trap 'rm -rf "$TMP"' EXIT
|
||||
|
||||
# Generate samples with Pillow if present (covers lossy, lossless, alpha,
|
||||
# odd dimensions, and a multi-frame animation).
|
||||
HAVE_PIL=0
|
||||
if python3 - "$TMP" >/dev/null 2>&1 <<'PY'
|
||||
import sys
|
||||
from PIL import Image
|
||||
d = sys.argv[1]
|
||||
w, h = 137, 83
|
||||
img = Image.new("RGBA", (w, h))
|
||||
px = img.load()
|
||||
for y in range(h):
|
||||
for x in range(w):
|
||||
px[x, y] = ((x*255)//w, (y*255)//h, (x*y) % 256, (x+y) % 256)
|
||||
img.save(d+"/lossless.webp", lossless=True)
|
||||
img.save(d+"/lossy.webp", quality=90)
|
||||
frames = [Image.new("RGBA", (48, 32), (i*50 % 256, 80, 200, 255)) for i in range(5)]
|
||||
frames[0].save(d+"/anim.webp", save_all=True, append_images=frames[1:],
|
||||
duration=[100, 120, 140, 160, 180], loop=0, lossless=True)
|
||||
PY
|
||||
then HAVE_PIL=1; fi
|
||||
|
||||
echo "== build =="
|
||||
$CC $CFLAGS -o "$TMP/test_decode" tests/test_decode.c -lm
|
||||
$CC $CFLAGS -o "$TMP/test_demux" tests/test_demux.c -lm
|
||||
|
||||
if [ "$HAVE_PIL" = 1 ]; then
|
||||
echo "== decode (still) =="
|
||||
for k in lossless lossy; do
|
||||
"$TMP/test_decode" "$TMP/$k.webp" "$TMP/$k.raw"
|
||||
python3 - "$TMP/$k.webp" "$TMP/$k.raw" <<'PY'
|
||||
import sys
|
||||
from PIL import Image
|
||||
ref = Image.open(sys.argv[1]).convert("RGBA").tobytes()
|
||||
mine = open(sys.argv[2], "rb").read()
|
||||
assert ref == mine, "%s: pixels differ from reference libwebp!" % sys.argv[1]
|
||||
print(" %s: bit-exact vs reference libwebp" % sys.argv[1].split('/')[-1])
|
||||
PY
|
||||
done
|
||||
echo "== demux + animation =="
|
||||
"$TMP/test_demux" "$TMP/anim.webp"
|
||||
else
|
||||
echo "(Pillow not found -- decoding any .webp passed as args)"
|
||||
for f in "$@"; do "$TMP/test_decode" "$f"; done
|
||||
fi
|
||||
echo "ALL TESTS PASSED"
|
||||
Reference in New Issue
Block a user