mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-26 02:59:17 -06:00
# Conflicts: # README.md # ROADMAP.md # crates/catalog/src/model.rs # crates/engine/src/camera_preview.rs # crates/raw/src/lib.rs # crates/raw/tests/corpus.rs # docs/camera-preview-colour.md # docs/parity.md # docs/whats-new.md
75 lines
4.6 KiB
Markdown
75 lines
4.6 KiB
Markdown
# Canon CR3 decoding
|
||
|
||
The CR3 adapter reads the CRX Bayer track, `CMP1` compression descriptor,
|
||
`CDI1`/`IAD1` sensor geometry and timed `CTMD` maker notes. White balance,
|
||
black/white levels and the default crop come from the file. A Dual Pixel delta
|
||
track is never substituted for the primary Bayer track.
|
||
|
||
The decoder is independent Rust code shared by desktop, CLI and WebAssembly;
|
||
it has no operating-system imaging dependency or external decoder. Its sources
|
||
are the public prose descriptions and patents cited in
|
||
`crates/raw/src/vendor/crx.rs`. Unsupported coding variants retain the existing
|
||
embedded-JPEG fallback and its visible warning when a JPEG is present. So does
|
||
any other CR3 decode error (a corrupt file, or a body whose CRX stream the
|
||
decoder misreads): every CR3 opened from its embedded JPEG before this decoder,
|
||
and only three bodies are verified, so a CR3 never fails to import or load
|
||
where a preview exists. HEVC-only preview tracks are recognized but are not
|
||
decoded.
|
||
|
||
## Verified sensor decoding
|
||
|
||
CRX version `0x100`, four Bayer planes and `ff01`/`ff02`/`ff03` marker headers
|
||
support lossless RAW and three-level C-RAW with horizontal tiles. Uniform
|
||
quantization values 4–43 are independently verified. Version `0x200` C-RAW
|
||
supports the `ff11`/`ff12`/`ff13` marker family, a single 14-bit Bayer tile and
|
||
its adaptive quantization map. Other unverified coding variants return explicit
|
||
unsupported errors. Header probing validates the same coding variants and
|
||
tile/plane layout as full decoding.
|
||
|
||
`crates/raw/tests/cr3_corpus.rs` checks every full-sensor sample against a
|
||
black-box reference, before cropping or colour processing. Public CC0 files
|
||
are downloaded by `cargo xtask corpus --download` and kept outside version
|
||
control. The exact inputs and reference hashes are:
|
||
|
||
| File | Input SHA-256 | Sensor FNV-1a (u16 little-endian) |
|
||
|---|---|---|
|
||
| Canon M50 RAW, raw.pixls.us 4657 | `1ba9ad6b51b315b88820eb0fe5fd7f52bc136ba37b1a5ca76825ebfe25b18058` | `62261f0ba81cfcd2` |
|
||
| Canon M50 C-RAW, raw.pixls.us 2663 | `15384b775867ec4c42b11882837f1e368cedc0561832ffab271221e6bb80be4c` | `9aacbfe66f505e1b` |
|
||
| Canon R100 RAW, raw.pixls.us 7896 | `6d83217d58a5e6d2dabcf470430e91a16676b60531c025b81fa7453fc74b0521` | `cbe5299ab9c52630` |
|
||
| Canon R100 C-RAW, raw.pixls.us 7897 | `0b66842b2fe00329ebc05fe8ab9357ddbbe1a0a2d2e69a2893102de7fdf5c942` | `341c706b37c38bbf` |
|
||
| Canon R8 RAW, raw.pixls.us 6585 | `7d5c6dbb11ff7e6ee58715d90a20f5d801e8b103f4711ff6ea329ceafcef254c` | `63c1c6d8d1eb2312` |
|
||
| Canon R8 C-RAW, raw.pixls.us 6587 | `df33cf394573645ce03dea1b2e9f0b5cc2b7734e9e3391ee7114151414cf2812` | `f836a663a795a375` |
|
||
|
||
Reference pixels were observed from the DNGLab 0.8.0 macOS arm64 release
|
||
binary; no decoder source was read or copied, and it is not shipped or linked.
|
||
The release ZIP SHA-256 was
|
||
`ee70805cb60f18d5ed62548c4e595f6cee0a33407e15358eb1766a46afc1c16e`.
|
||
All six sensor comparisons pass. R8 HEVC preview tracks are distinguished from
|
||
the primary Bayer RAW; the HEVC preview itself is not decoded. Missing corpus
|
||
files are reported as skipped by the tests.
|
||
|
||
The version `0x200` QP predictor and entropy framing were checked independently.
|
||
Controlled input mutations establish floor averaging of paired QP rows before
|
||
the nonlinear integer table, then multiplication, division by eight, addition
|
||
of the subband base and a minimum step of one. QP values 131–167 are verified;
|
||
unmeasured values and an odd QP-map height are rejected. Partial-subband and
|
||
rounded-plane coding, vertical C-RAW tiling and adaptive low-frequency gains
|
||
remain unsupported. The decoder bounds image dimensions, sample count,
|
||
tile count, marker headers and temporary allocations. The full sensor buffer is
|
||
allocated only after the first plane decodes, and plane buffers grow row by row,
|
||
so a small crafted file fails before reserving memory for the image it claims.
|
||
|
||
## Colour limits
|
||
|
||
CR3 carries as-shot white balance but no measured camera matrix is imported
|
||
here. The existing guarded embedded-JPEG fitting path now includes CR3, with
|
||
both proxies oriented identically before gathering training pairs. A bounded
|
||
crop/translation registration of the JPEG is confirmed on held-out edge
|
||
directions before fitting colour; the existing held-out colour acceptance gates
|
||
are unchanged. No lens distortion correction is applied (LightCraft has no lens
|
||
profiles of its own yet), so lenses whose camera JPEG is strongly
|
||
distortion-corrected may fail the gates and keep the neutral matrix. Render
|
||
cache version 13 invalidates earlier thumbnails. All developed pixels still come
|
||
from the RAW sensor; a rejected colour fit retains the documented neutral
|
||
matrix fallback. See `camera-preview-colour.md` for the limits of this estimate.
|