Add the dependency
In your project’s ziran.toml; pin ref to a commit for reproducible builds.
[dependencies.webp]
git = "https://github.com/ziranlang/webp.git"
ref = "master"Overview
WebpDecode(input: BorrowedBytes, options: DecodeOptions) -> DecodeResult
owns straight RGBA8 pixels. WebpDecodeInto borrows a validated OutputBuffer
and returns metadata/error without transferring its storage. Animation returns
only the first complete composed frame and reports the source frame count.
WebpDefaultOptions preserves the existing native WebP input cap of
2147483647 bytes; ordinary DefaultOptions can impose a smaller cap.
webp/authored exposes the authored VP8L/VP8(+ALPH) still-image provider,
including bounded scratch backing and portable execution with no native codec
link. webp/authored_lossless retains the VP8L entry points and optional format
trace. The API contract records ownership and capability limits.
webp/riff is an allocation-free authored RIFF parser with explicit length,
padding, image header, animation frame rectangle/count and metadata limits.
It is independently executed from source and saved IR in C, Go and the direct
portable VM. Header validation and pixel decoding have separate tests.
LibwebpCapabilities truthfully reports caller-owned output, one execution lane
and first-frame compatibility. Synchronous native calls cannot enforce an
internal scratch-memory allocation ceiling or stop mid-call; those capabilities
are false. Input/output/container limits and cooperative checks before/after
native work remain enforced. Native opaque objects and borrowed frames are
released before returning; native internal threads are disabled. No color
management/HDR or encoding capability is exposed. The bridge rejects FastColor.
build-queue -- sh tests/engine_contract.sh
build-queue -- sh tests/riff.sh
build-queue -- sh tests/legacy_compare.sh
build-queue -- sh tests/dynamic_contract.sh
build-queue -- sh tests/package_import.sh
build-queue -- sh tests/all.sh
Tests reuse the independently pinned mandatory image-codec corpus. Only the
optional legacy comparison reads the hash-pinned original Kryon decoder from
its frozen baseline (or an unchanged original checkout), without changing it.
The native tests use the existing pinned source package offline. Configure
local ziran and image_codec overrides before locking during development;
no bootstrap commit is needed. WEBP_SOURCE can select an existing source
package with the exact declared revision. No native source is fetched during
a build. All builds run through build-queue; no display is used.
The validated native artifact platform is currently Linux x86-64 GNU. Consumers
request ziran pkg artifact webp:libwebp --platform linux-x86_64-gnu, add the
returned descriptor's lib directory to link search paths, and link
imagewebp and m. The same artifact includes self-contained
libimagewebp.so; shared-link consumers must also provide its runtime search
path or package it beside their application. Consumers importing webp/dynamic can call
OpenDynamicWebp(path), DynamicWebpDecode/DynamicWebpDecodeInto and
CloseDynamicWebp with no static codec linkage (only dl and m). The engine
owns its library handle; keep it alive through every decode and do not copy
or close it during a call. Returned pixels remain owned after closing it.
Missing libraries/symbols produce an unavailable engine and explicit capability
error. Other platforms fail explicitly until their recipes and
actual execution are validated. The authored implementation status
records completed pixel work and remaining acceptance gates. The stable bridge
is not represented as a fully authored WebP decoder.
build-queue -- sh tests/benchmark.sh builds the stable build/bin/webp-bench.
It verifies exact golden pixels before timing real warm file reads and decode
calls. It records actual samples and active workers; unavailable CPU, RSS,
allocation and energy instruments remain null. authored-vp8l selects lossless
decoding; authored-still selects the authored VP8L/VP8/ALPH provider. The local
test measures actual warm samples for both lossless and lossy input. Cold-cache
timing, CPU time, RSS, allocations and energy remain unmeasured.
A small successful case is not a general codec performance result.
webp/src/facade.zi
facade
Import with #import "webp/facade".
WebpDecode :: (input: BorrowedBytes, options: DecodeOptions) -> DecodeResultThe bridge is explicit until the independently authored engine has parity.
WebpDecodeInto :: (input: BorrowedBytes, output: OutputBuffer, options: DecodeOptions) -> WebpOutputResultwebp/src/engine.zi
engine
Import with #import "webp/engine".
LibwebpEngine :: 1AuthoredStillEngine :: 2WebpEngineCapabilities :: struct { still_images: bool; first_animation_frame: bool; caller_owned_output: bool; interrupt_native_decode: bool; enforces_native_scratch_limit: bool; max_active_workers: s32; }WebpOutputResult :: struct { is_ok: bool; metadata: ImageMetadata; error: DecodeError; }Compatibility budget for existing native WebP paths. Generic callers can
WebpDefaultOptions :: () -> DecodeOptionsCompatibility budget for existing native WebP paths. Generic callers can instead pass DefaultOptions() or lower explicit limits.
webp/src/riff.zi
riff
Import with #import "webp/riff".
WebpLossy :: 1WebpLossless :: 2WebpAnimation :: 3MaxWebpChunks :: 65536WebpProbeResult :: struct { is_ok: bool; metadata: ImageMetadata; kind: s32; payload: BorrowedBytes; payload_offset: s64; alpha: BorrowedBytes; alpha_offset: s64; error: DecodeError; }WebpHasSignature :: (input: BorrowedBytes) -> boolPrefix dispatch only. Structural validation remains WebpProbe's job; this predicate accepts a RIFF/WEBP prefix even if its declared body is incomplete.
WebpProbe :: (input: BorrowedBytes, limits: DecodeLimits) -> WebpProbeResultwebp/src/libwebp.zi
libwebp
Import with #import "webp/libwebp".
LibwebpCapabilities :: () -> WebpEngineCapabilitiesLibwebpVersion :: () -> s32LibwebpDecode :: (input: BorrowedBytes, options: DecodeOptions) -> DecodeResultLibwebpDecodeInto :: (input: BorrowedBytes, output: OutputBuffer, options: DecodeOptions) -> WebpOutputResultwebp/src/dynamic.zi
dynamic
Import with #import "webp/dynamic".
DynamicWebpEngine :: struct { library: *void; api: WebpNativeApi; available: bool; }OpenDynamicWebp :: (path: string) -> DynamicWebpEngineCaller owns this library handle: do not copy it or close while decoding. A missing/incompatible library is an explicit unavailable engine.
CloseDynamicWebp :: (engine: *DynamicWebpEngine)DynamicWebpVersion :: (engine: *DynamicWebpEngine) -> s32DynamicWebpDecode :: (engine: *DynamicWebpEngine, input: BorrowedBytes, options: DecodeOptions) -> DecodeResultDynamicWebpDecodeInto :: (engine: *DynamicWebpEngine, input: BorrowedBytes, output: OutputBuffer, options: DecodeOptions) -> WebpOutputResult