adaptive-basis image codec

Different representation
for every tile.

Weft picks a different basis — primitive stack, bicubic patch, palette, gradient field, or DCT residual — for each tile of an image under a rate-distortion tournament, then writes only the winner.

10/14
iso-byte wins vs JPEG
+11.63 dB
avg PSNR delta vs JPEG
243 KB
total on 14-fixture corpus
5.2×
smaller than PNG lossless

Why another image codec?

JPEG, WebP, AVIF, and JPEG XL share one architectural choice: one basis representation, applied uniformly to every pixel of every image. JPEG transforms 8×8 blocks of every image with DCT. AVIF uses a stack of related linear transforms. It's mathematically clean and engineering- efficient, and it's why these codecs are deployed on every device.

But it means that on content far from natural-photo statistics, the codec is doing the wrong thing. A 256-color pixel-art icon compressed with JPEG produces ringing on every edge. A page of vector diagrams compressed with WebP-lossless rounds the strokes into noise patterns. A pure smooth gradient in PNG occupies thousands of bytes for what is essentially a single bicubic patch's worth of information.

The right answer for each of those is well-known: palette codecs for pixel art, vector formats for diagrams, smooth-function approximations for gradients. The problem is that real images aren't one of those things — they're a mix, often within the same image. A screenshot has UI chrome (palette), text (palette + edges), photographs (DCT), and gradient backgrounds (smooth). Using one codec for the whole thing leaves a lot on the table.

Weft is what happens if you say: what if the codec picked the right representation per tile?

The five bases

For every tile, the encoder fits each of these candidates and scores by PSNR − λ·BPP. The winner gets written to the bitstream; the decoder dispatches on the block type.

01

Primitive stack

Analytic shapes composited per tile: constant patches, linear gradients, lines, quadratic Bézier curves, triangles, bicubic Bernstein patches. Variable-length. The encoder runs a greedy primitive search to find the smallest set that reconstructs the tile to a target error.

best for: mixed content, analytic shapes
02

Per-tile bicubic

A single 4×4 Bernstein control grid replacing a primitive stack for tiles dominated by smooth content. 48 bytes per tile. Fit by one matrix solve — no iteration. Picked by the hybrid variant's per-tile R-D check when smoothness beats a primitive search.

best for: smooth gradients inside mixed images
03

Palette + labels

A K-color palette (K = 16 or 64) plus a per-pixel label grid. K-means clustered in linear RGB. Decoder is one palette[labels] lookup. Lossless when the source image only uses K distinct colors; scales via nearest-neighbor with zero interpolation blur.

best for: pixel art, icons, diagrams, screenshots
04

Gradient field

Stores ∂I/∂x and ∂I/∂y quantized to int8 per channel plus per-channel means. Decoder solves the Poisson equation via a closed-form DCT-II decomposition — O(N log N) per channel. Wins on content where the gradient field is locally simple even when the image isn't.

best for: diagrams, charts, region maps
05

DCT residual layer

A JPEG-style frequency-domain residual added on top of any of the other bases. YCbCr 4:2:0, per-tile presence bitmask, per-frequency quantization weighting. Closes the natural-photo PSNR gap when the primitive bases plateau.

best for: dense natural texture (stacked on a primitive basis)

Full benchmark

Every fixture in the committed corpus, quality 75 auto-select. JPEG and WebP are matched to Weft's byte count via binary search on their quality parameter (iso-bytes protocol).

Fixture Weft KB Weft dB JPEG dB Δ dB Variant
Loading…
AGGREGATE

What Weft is not

Reproduce it yourself

Everything on this page is reproducible from the repo with no external datasets. The synthetic corpus is deterministic; the encoder is deterministic; the benchmark protocol is a binary search over JPEG quality at iso-bytes.

# 1. Install
pip install -e .

# 2. (optional) regenerate the synthetic corpus
python samples/inputs/_generate.py

# 3. Run the benchmark (numbers + CSV + summary.json)
python scripts/whitepaper_bench.py

# 4. Rebuild the site assets (images + bench_data.json)
python scripts/generate_site_assets.py