- The vertical inverse 5/3 lifts whole rows at once (`inverse_lift` with samples `w` values wide)
instead of gathering each column through a strided iterator and scattering it back: the same
integer arithmetic, sequential memory. The horizontal pass is the same function with w = 1.
- `0^n 1` codes are counted with one `leading_zeros` over the next MAX_DPT + 1 bits instead of bit by
bit (same bits consumed, same errors); each line reserves its values up front.
- Colour reconstruction reads plane rows as slices and runs over rows in parallel (it was one
thread per tile: 4 threads on a full-frame file whatever the machine).
Best of 5 on 4 CPUs, previous and new decoder alternating: ILCE-7RM6 FF HQ 0.56 → 0.46 s,
FF Compressed 0.54 → 0.38 s, APS-C HQ 0.34 → 0.23 s, APS-C Compressed 0.35 → 0.24 s
(docs/arw6-compression.md → Timings). The decoded mosaic is identical (hash of every sample) on
the 8 ARW6 corpus files and 2 private full-frame photos (ISO 100, ISO 12800); the pinned corpus
sums still match.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Three changes, each leaving the output bit for bit as it was:
- Each step runs only where the tile's output depends on it (choice ±0, homogeneity ±1, Lab ±2,
greens ±3, mosaic ±5 inside the 6 px margin), with direct neighbour indices instead of an
index clamped on every read; the clamped values at the buffer edge never reached the output.
- A candidate pixel is built in registers before its Lab conversion: writing its channels
through an index and reading the pixel back stalled on store forwarding (the hottest
instructions of the profile).
- Tiles are written into the output one band at a time, instead of all 64 MP of tiles being
collected and then copied (797 MB held twice). Tiles inside the image copy their mosaic rows
instead of reflecting and taking a modulo per sample.
Sony ILCE-7RM6 9984 × 6656 Compressed HQ raw, demosaic only, best of 5 on 4 cores:
1.85 s → 1.05 s wall, 6.3 s → 4.0 s CPU. Verified identical (f32 bits) on 7 real raws
(ILCE-7RM6 FF/APS-C, ARW6 HQ/C and lossless, ILCE-7RM4A) and, against the previous code, on
random mosaics of all four Bayer layouts at 1 × 1 … 300 × 7, 257 × 130 (tile edges, reflection).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`load_bytes_now` ran every development through `resample::fit`, which returns a clone when the
image already fits. At full size (1:1 zoom, export) that cloned the whole picture: 797 MB and
~0.3 s for a 9984 × 6656 Sony ILCE-7RM6 raw. It now fits only when the image is larger, as the
other preview paths in files.rs already do. Output unchanged (same pixels, by construction).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>