The pith suite contract
pith-jpeg is part of the pith suite (pith-hash). Every suite repository follows the same rules; CI enforces them mechanically:
- Naming: a library is always
pith-<domain>(pith-image,pith-audio,pith-zip, ...). The curator/repository of repositories is the barepith-hash. Never invent a second naming scheme inside the suite. - Version pinning: cross-library dependencies pin
~0.1(e.g.pith-image = { version = "~0.1", path = "../pith-image" }). The whole suite moves together inside 0.1.x; breaking changes require a suite-wide version bump, never a silent minor drift. - Zero third-party dependencies: every crate depends only on other
pith-*crates plusstd.scripts/check-zero-deps.py(run in CI) fails the build on any other crate, for normal, build and dev dependencies alike. - No unsafe: every crate root carries
#![forbid(unsafe_code)]. - Hex-exact vectors:
reference.jsonat the repo root is the cross-language source of truth. Thegen-referencebinary regenerates it; CI verifies the committed copy is current (gen-reference verify), and CD ships the regenerated file with every SDK artifact. Python, Node and Go SDKs MUST test against the same bytes.
Repository layout
crates/ one published crate per suite lib (pith-<domain>)
tools/gen-reference the vector generator binary (bin name: gen-reference)
sdk/python ctypes wheel; build backend reads PITH_CDYLIB_DIR
sdk/node koffi-based package; prebuilds/<os-arch>/ carry the cdylib
sdk/go cgo binding; go.mod carries the module's cgo flags
fuzz/corpus fuzz inputs, replayed by tests/fuzz_corpus.rs (parser crates)
reference.json hex-exact cross-SDK test vectors
Overview
JPEG decoding per ITU T.81: baseline (SOF0), extended sequential (SOF1)
and progressive (SOF2) Huffman-coded frames — spectral selection,
successive approximation and EOBRUN included — with restart markers,
4:4:4/4:2:2/4:4:0/4:2:0 and other integral sampling factors, and 1- or
3-component output as pith_image::raster::Image (Gray/Rgb, 8-bit).
The pixel pipeline is a byte-exact transcription of libjpeg-turbo's
islow integer IDCT, fancy triangle chroma upsampling and
fixed-point YCbCr→RGB, validated against Pillow 12.3.0 fixtures byte
for byte (see tests/fixtures/PROVENANCE.md). Arithmetic-coded,
lossless, differential, hierarchical, 12-bit and CMYK/YCCK streams are
refused with Error::Unsupported naming the coding process.
Install
Rust (the core library):
Python / Node / Go SDKs are published from the same cdylib on every release; see the release assets or the package registries for the matching version.
Quick start
Rust (the core library):
let img = decode?;
match img
decode never panics on untrusted input: malformed structure surfaces
as Error::Truncated / Error::BadValue, refusals as
Error::Unsupported. Hex-exact cross-SDK vectors — decode digests for
every committed fixture plus the DCT/dequant numerics — live in
reference.json (regenerate with cargo run --bin gen-reference,
verify with cargo run --bin gen-reference -- verify).
Contributing
See CONTRIBUTING.md.
Security
See SECURITY.md.
License
MIT © pith-hash