RGBV3D container format
Strictly lossless image container with two encoder profiles in this repository—documented for engineers who need round-trip proof, not marketing compression claims.
Why another lossless format?
PNG already solves everyday lossless RGB interchange. RGBV3D exists as a research and teaching container: a small, auditable bitstream we can evolve (block triage, entropy stages, optional multi-frame packaging) without pretending to replace PNG overnight. The PracticalKit site ships a browser encoder and long-form notes so reviewers and collaborators can inspect behavior without installing a private toolchain first.
What we guarantee today: for profiles labeled lossless, decode(encode(pixels)) equals the RGB24 raster we fed the encoder. What we do not guarantee: smaller files than PNG/WebP on every image, mobile-friendly encode of multi-megapixel photos, or studio color-management beyond the browser canvas path.
Profile 0 — classic (lossless-rgb)
Classic uses spatial prediction across the raster, then Deflate on residual streams. Philosophically it sits near PNG: exploit local correlation, store the unpredictable remainder. The magic header, chunk layout, and profile id are distinct so files cannot be confused with PNG. Unit tests in @rgbv3d/core assert pixel-exact round trips on solid fills, gradients, and synthetic noise patterns.
When classic loses to PNG it is usually because PNG’s mature predictors and filters have decades of edge-case hardening. Treat classic as the conservative RGBV3D path—especially for noise-heavy inputs—rather than a size contest.
Profile 1 — vector-v2
Vector-v2 decomposes each pixel C=(R,G,B) into a magnitude L and a direction d on a first-octant codebook. The encoder stores a direction index and a quantized norm proxy ΔLq, then writes per-channel residuals so reconstruction is exact. Without residuals, low-bit direction alone cannot be lossless—two different RGB triples could share a direction bucket.
Smooth UI panels and synthetic gradients often benefit: neighbors share direction, residuals stay small. High ISO grain and dithered scans do the opposite: residuals approach full channel entropy and the file grows. That failure mode is documented on the benchmark page rather than hidden.
File layout
A file begins with magic bytes, version, width, height, and profile id, followed by compressed streams (direction where applicable, optional sign placeholders, ΔLq, residuals). Readers must reject unknown critical versions. The experimental multi-frame container .rgbv3dvi stacks per-frame payloads with timing metadata; inter-frame predictors remain roadmap work and must not be assumed present in today’s CLI flags.
How we prove lossless
CI hashes RGB buffers before and after encode/decode. Browser users can export PNG after decode and diff with ImageMagick or a short Python script. Prefer asserting zero differing pixels over “looks the same.” Color-profile stripping and canvas premultiplication are common false alarms—keep width, height, and alpha policy fixed across the pipeline.
Continue reading
Benchmark tables → · CLI & packages → · Open encoder tool → · Classic vs vector-v2 essay →