This checklist maps the currently implemented codec behavior in src/codec.rs.
- Magic:
"CSL" - Versions supported:
0x20(VERSION),0x21(VERSION_V21),0x22(VERSION_V22),0x23(VERSION_V23) - Size fields:
u16little-endian width/height - V2.3 only: 1-byte flags + 4-byte IEEE CRC32
- Decoder performs strict version validation and rejects mismatches.
The stream is emitted/consumed at bit granularity (BitWriter/BitReader), including opcodes:
For V2.0 streams:
0=>0xED(Paeth residual)01 + 4 bits=>0xC0..0xCF011 + 5 bits=>0x80..0x9F0111 + 5 bits=>0xA0..0xBF1111 + 8 bits=> full opcode byte
For V2.1/V2.2 streams:
0=>0xED10 + 6 bits=>0x40..0x7F(cache)110 + 3 bits=>0xC0(literal single) or0xC1..0xCF(literal run)1110 + 5 bits=>0xA0..0xBF(short solid)11110 + 1 bit=>0xF1(repeat run)111110 + 1 bit=>0xF2(transparent pixel run)1111110 + 1 bit=>0xF5(transparent rectangle skip)1111111 + 8 bits=> full opcode byte
For V2.3 streams:
- Similar prefix table to V2.1/V2.2
- Supports both scanline and Morton traversal
Residual integers use Elias-gamma plus signed zigzag mapping.
0x40..=0x7F: cache draw (V2.1+, 64-slot cache)0x80..=0x9F: cache draw (V2.0, 32-slot cache)0xA0..=0xBF: short solid RGB run (len=1..32)0xC0..=0xCF: literal RGB run (len=1..16)0xD0..=0xDF: literal RGB run (V2.3,len=1..16)0xE4..=0xEB: literal RGBA run (len=1..8)0xED: Paeth residual pixel0xF0: extended solid RGB run0xF1: repeat last pixel run0xF2: transparent pixel run (V2.2+)0xF3: LZ back-reference0xF5: transparent rectangle skip (V2.2+)0xFF: alpha setter
- Operates in either Morton or Scanline traversal (V2.3 only) and keeps predictor context aligned to decoder-visible state.
- Uses short solid runs (
0xA0..0xBF) where profitable. - Uses RGB/RGBA literal runs for denser coding on photographic/noisy regions.
- Uses residual coding (
0xED) only when bit-cost is lower than literal fallback. - Uses LZ matching with rolling hash window and strict bounded distances/lengths.
- LZ candidate selection is bit-gain based (best gain candidate is chosen, not first match).
- RGB literal runs include a short lookahead chooser to reduce local greediness.
- Supports YCoCg color space transform (V2.3, optional, currently disabled by default)
- Supports grayscale mode (V2.3)
- Uses CRC32 checksum (V2.3)
- Use
scripts/benchmark_csl_vs_png.pyto compare encoded.cslsize against PNG inputs. - Use
scripts/benchmark_csl_png_qoi.pyto compare CSL, PNG, and QOI. - Example:
python scripts/benchmark_csl_png_qoi.py --bin ./target/release/chisel --inputs /abs/a.png /abs/b.png --out /tmp/full_bench.json
Benchmark results (from README):
| Image | PNG (bytes) | CSL (bytes) | QOI (bytes) | CSL vs PNG (%) | QOI vs PNG (%) | CSL vs QOI (%) |
|---|---|---|---|---|---|---|
| test.png | 115,988 | 267,747 | 252,139 | 230.84 | 217.38 | 106.19 |
| sample1.png | 331,125 | 989,318 | 604,299 | 298.77 | 182.50 | 163.71 |
| g.png | 207,459 | 413,275 | 446,090 | 199.21 | 215.03 | 92.64 |
| pngs/manga_page.png | 1,082,374 | 1,734,294 | 2,451,249 | 160.23 | 226.47 | 70.75 |
| pngs/photography.png | 40,673,701 | 49,328,083 | 48,494,880 | 121.28 | 119.23 | 101.72 |
| pngs/transparent_image.png | 6,518,746 | 7,457,298 | 7,801,000 | 114.40 | 119.67 | 95.59 |