Truepix is a lossless image codec for archives. On 24 photos it had never seen, JPEG XL at its top effort came out 3.62% larger, and Truepix won on all 24. Every pixel came back exact.
Four least-squares predictors and eleven simple ones guess the next value from pixels already decoded. An adaptive blend combines them.
Bias cancelling tracks the errors made in similar places and removes the part that keeps repeating.
21 contexts estimate each bit, including exact colour differences that can learn a colour grid with no formula. Seven logistic models add their own estimates.
50 inputs feed five small neural mixers. A final mixer weighs those, then two adaptive maps refine the probability.
A 32-bit binary arithmetic coder narrows an interval with every decision and writes out bytes. The decoder repeats all of this to get the pixel back exactly.
Bits per pixel across the whole set, so shorter wins. Every Truepix file decoded back exactly.
Truepix saved from 0.44% to 7.52% of the JPEG XL file. No image lost.
| Test set, 24 photos each | JPEG XL e10 larger by | Truepix wins |
|---|---|---|
| DIV2K 0801 to 0824 | 4.28% | 23 of 24 |
| DIV2K 0841 to 0864 | 4.29% | 24 of 24 |
| DIV2K 0865 to 0888, final build | 3.62% | 24 of 24 |
Only the last row used the final build. The first two ran on earlier versions.
A slow general compressor, paq8px, beat image codecs by a surprising margin on the famous Kodak test set. About 90% of that gap was colour.
Kodak's images came from Photo CD, so their RGB values sit on a stretched integer grid, recovered here from pixels alone.
Only 12.8% of all RGB colours can occur on that grid, and they hold 87.3% of Kodak's pixels. Exact-difference contexts turned the finding into a gain on ordinary photos too. Truepix was tuned on Kodak, so its 5.723 bits per pixel there isn't a fair score.
JPEG XL's highest effort took 42.0 seconds per photo. Truepix took 12.0, and its files were still smaller: JPEG XL's came out 3.71% larger on these five photos.
Shown at 6× speed. The timers count real seconds.
| Mean per image, 5 photos | Encode (s) | Total size |
|---|---|---|
| Truepix | 12.0 | smallest |
| JPEG XL, effort 10 | 42.0 | +3.71% |
| JPEG XL, effort 9 | 1.8 | +6.17% |
| FLIF | 14.3 | +10.62% |
| WebP lossless | 10.0 | +20.27% |
Ryzen 7 5800HS, 8 cores. Other work may have shared the machine during the rival timings, taken in an earlier run. Sizes are relative to Truepix on the same five photos.
Truepix reads a JPEG's own data, compresses it further, and rebuilds the original file exactly. There is no new quality loss, and it takes about a second. Bars show size saved, so longer wins.
| 24 photos each | Truepix saved | JPEG XL e9 saved | Truepix wins | Rebuilt exactly |
|---|---|---|---|---|
| Quality 85 | 21.84% | 16.40% | 24 of 24 | 24 of 24 |
| Quality 75 | 22.60% | 16.54% | 24 of 24 | 24 of 24 |
| Quality 95 | 22.54% | 18.51% | 24 of 24 | 24 of 24 |
| Quality 85, progressive | 17.06% | 11.31% | 24 of 24 | 24 of 24 |
JPEGs made by Pillow from DIV2K 0865 to 0888. The JPEG model was frozen, then scored once. Files from other encoders may behave differently.
This is the real codec, compiled to WebAssembly, and it writes the same files as the desktop build. Drop an image to compress it and check the result, or drop a Truepix file to rebuild the original.
Encoder and decoder must agree on every bit of floating-point maths. Each square is one build decoding another build's file. Files were byte-identical across all seven: GCC AVX2, GCC FMA, GCC SSE2, GCC -O0, Clang x64, Clang x86, WebAssembly.
Truepix is a C++ codec with a small Python command-line tool. The source is on GitHub.
g++ -std=c++17 -O3 -mavx2 -ffp-contract=off -static truepix-core.cpp -o truepix-core.exe
uv run truepix compress photo.png --verify # writes photo.tpix
uv run truepix decompress photo.tpix # writes photo.png
uv run truepix compress photo.jpg # the JPEG comes back byte for byte
Read the paper (PDF)