# Conflicts:
#	crates/engine/src/media.rs
#	crates/raw/src/vendor/crx.rs
#	crates/ui-egui/locales/de.json
#	docs/gaps.md
#	docs/parity-checklist.md
#	docs/raw-parity.md
#	docs/whats-new.md
This commit is contained in:
Claude 2026-10-11 11:58:15 +00:00
commit 7ecb0b0191
No known key found for this signature in database
14 changed files with 189 additions and 51 deletions

View File

@ -2,7 +2,7 @@
**Stage: alpha** · next: beta, ~14 points and ~340–600 h away
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-10 · **Change:** major (full re-measure against Lightroom Classic 15.5 and the installed Lightroom 9.6; restructured to the progress-docs standard) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (EOS R5 Mark II CR3 verified; RAW decoding 77%) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6
One-page summary of how close LightCraft is to Adobe Lightroom. Agents: read this, then pick work
from [docs/gaps.md](docs/gaps.md). The full assessment, method and evidence are in
@ -29,11 +29,11 @@ Each audience with its own hours (Opus 5.5 agent wall-clock hours to ~95%):
| Essentials user | **~64%** | **160–300 h** (~50% parallelizes) | default raw look for popular cameras; launch stability; basic-slider feel; opening CR3 / HEIC files people send |
The gap between breadth and readiness is quality and coverage, not missing buttons: camera colour is
estimated rather than measured, CR3 decodes on three verified Canon bodies, compressed ORF and HE NEF
estimated rather than measured, CR3 decodes on four verified Canon bodies, compressed ORF and HE NEF
open as previews, rendering is tuned by eye, AI masks are heuristics, there is no lens database, and
tests run in CI on FreeBSD only. **Why alpha:** core workflows run end to end, but readiness is below
the ~75% beta bar (it is above the ~40% alpha bar) and Lightroom's main inputs, raw files, still have blocking gaps (Canon, ~30% of
raw users, decodes CR3 on three verified bodies). It passes the alpha gate: all six core workflows
raw users, decodes CR3 on four verified bodies). It passes the alpha gate: all six core workflows
(import, cull, develop, save and reopen, batch looks, export) work end to end on macOS
([docs/roadmap.md](docs/roadmap.md#alpha-gate)). The three readiness numbers and their weights and discounts are in
[target-app-parity.md](docs/target-app-parity.md#ready-for-real-work-mainstream-practitioner-and-essentials-user).
@ -61,7 +61,7 @@ Hours are calibrated on this repo's PR history; see
| Area | Ready | Breadth | Remaining |
|---|---:|---:|---:|
| Import and library | 80% | 90% | 25–45 h |
| RAW decoding and camera coverage | 76% | 81% | 120–220 h |
| RAW decoding and camera coverage | 77% | 81% | 120–220 h |
| Colour, camera profiles, render fidelity | 35% | 65% | 80–150 h |
| Global develop adjustments | 70% | 93% | 30–60 h |
| Optics, lens profiles, crop and geometry | 50% | 80% | 40–80 h |
@ -114,6 +114,10 @@ Ranked toward beta; detail in [docs/roadmap.md](docs/roadmap.md), gaps in [docs/
## Progress log
- 2026-10-11: Canon EOS R5 Mark II C-RAW decodes from sensor data (57% of its files opened as a
preview): the CRX QP map's first-symbol literal and limited-length escape; four CC0 R5 Mark II files
pinned, the QP maps of 33,665 private C-RAW files decode exactly ([cr3.md](docs/cr3.md)). 235 models
verified; RAW decoding 76% → 77%; headline numbers unchanged.
- **2026-10-10 (UI docking):** Library, Tools, and Presets panels can be regrouped, split, floated within the app window, closed, and reopened. Tools keeps the current Edit/Crop/Masking mode; the photo view and filmstrip stay together. Panel moves and reset are available as UI commands, and saved UI preferences retain arrangements. Widget state styling uses the shared `craft-ui` theme helper, retaining the dark palette, typography, spacing and per-state borders. No readiness percentage change.
- 2026-10-10 (RAW): RAW measured model by model against Adobe's 1,446-model list (234 verified, 943
unverified, 233 preview-only, 36 unsupported; ~84% of photographers' cameras decode, ~40% on a
@ -157,6 +161,7 @@ Ranked toward beta; detail in [docs/roadmap.md](docs/roadmap.md), gaps in [docs/
| Date | Change | Summary |
|---|---|---|
| 2026-10-11 | minor | EOS R5 Mark II CR3 verified: CR3 on four verified bodies, RAW decoding 76% → 77%; headline numbers unchanged |
| 2026-10-10 | minor | RAW measured model by model; RAW decode and colour as explicit rows: full 59% → 61%, mainstream 51% → 49%, essentials 63% → 64%; beta ~14 points |
| 2026-10-10 | minor | Full ready restored to the additive weighted sum (~59%; method aligned with the standard, no new evidence); hours per audience; beta ~16 points away |
| 2026-10-10 | minor | Mainstream practitioner and essentials user numbers; full ready 55% → 46% (method written down); beta 340–600 h |

View File

@ -62,7 +62,7 @@ impl SettingsHashes {
}
/// Bump when the pipeline's output changes, to invalidate cached thumbnails.
pub const RENDER_CACHE_VERSION: u64 = 55;
pub const RENDER_CACHE_VERSION: u64 = 56;
/// Thumbnails render at one of these long edges (so window/cell size changes reuse the cache).
pub const THUMB_SIZES: [usize; 4] = [128, 256, 384, 512];

View File

@ -10,9 +10,12 @@
//!
//! Current support: version 0x100 lossless Bayer RAW and horizontal-tile C-RAW,
//! plus version 0x200 single-tile 14-bit C-RAW with adaptive QP quantization
//! (including odd-height QP maps, as on the EOS R7).
//! (including odd-height QP maps, as on the EOS R7, and odd-height Bayer planes, as on the EOS R5 Mark II).
//! Both ff01/ff02/ff03 and ff11/ff12/ff13 marker families are supported.
//! Six full M50/R100/R8 sensor fixtures match an external decoder sample for sample.
//! The QP map's first-symbol literal and its escape (the T.87 limited-length layout) were found
//! on EOS R5 Mark II maps, whose larger QP steps need them; every map of 33,665 R5 Mark II files
//! decodes to the exact end of its entropy stream with them.
//! Unverified coding variants return explicit unsupported errors.
use super::crx_wavelet::{self, Band as WaveletBand, TileEdges};
@ -25,6 +28,8 @@ const MAX_TILES: usize = 1024;
const MAX_HEADER_BYTES: usize = 1 << 20;
const MAX_CRX_SAMPLES: usize = 200_000_000;
const MAX_CRX_EDGE: u32 = 65_536;
/// Unary QP-map prefix length that announces an 8-bit escaped symbol.
const QP_ESCAPE_ZEROS: u32 = 23;
const RUN_EXPONENT: [u8; 32] = [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15];
fn corrupt(reason: &str) -> RawError {
@ -539,13 +544,17 @@ impl Bits<'_> {
}
fn qp_rice(&mut self, k: u32) -> Result<u32> {
// Limited-length code (the ITU-T T.87 layout for a 32-bit limit and 8-bit symbols):
// a quotient of 23 or more is sent as 23 zeros, the terminating 1 and the symbol in 8 bits.
let mut zeros = 0;
while zeros < 16 && self.take(1)? == 0 {
while self.take(1)? == 0 {
zeros += 1;
if zeros > QP_ESCAPE_ZEROS {
return Err(corrupt("QP Rice escape prefix exceeds 23 bits"));
}
}
if zeros == 16 {
// QP escape has no unary terminating 1 before the 16-bit literal.
self.take(16)
if zeros == QP_ESCAPE_ZEROS {
self.take(8)
} else if k <= 20 {
Ok((zeros << k) | self.take(k)?)
} else {
@ -763,7 +772,8 @@ fn qp_map(src: &[u8], width: usize, height: usize) -> Result<QpMap> {
let above = *previous.get(x).ok_or_else(|| corrupt("above QP outside row"))?;
let corner = if x == 0 { above } else { *previous.get(x - 1).ok_or_else(|| corrupt("corner QP outside row"))? };
let right = previous.get(x + 1).copied().unwrap_or(above);
let symbol = bits.qp_rice(k)?;
// The map opens with its first symbol as a 32-bit literal; every later one is Rice coded.
let symbol = if x == 0 && y == 0 { (bits.take(16)? << 16) | bits.take(16)? } else { bits.qp_rice(k)? };
let value = median(left, above, corner).checked_add(signed(symbol)).ok_or_else(|| corrupt("QP prediction overflow"))?;
if !(131..=168).contains(&value) {
return Err(RawError::Unsupported(format!("Canon CRX adaptive QP value {value}")));
@ -995,9 +1005,16 @@ mod tests {
#[test]
fn qp_escape_and_average_precede_the_quantization_table() {
let mut bits = Bits { src: &[0, 0, 1, 0x2c], at: 0 };
assert_eq!(bits.qp_rice(0).unwrap(), 300);
// 23 zeros, the terminating 1, then the symbol in 8 bits.
let mut bits = Bits { src: &[0, 0, 1, 0x18], at: 0 };
assert_eq!(bits.qp_rice(0).unwrap(), 24);
assert_eq!(bits.at, 32);
// 22 zeros are an ordinary Rice prefix.
let mut bits = Bits { src: &[0, 0, 2, 0], at: 0 };
assert_eq!(bits.qp_rice(0).unwrap(), 22);
assert_eq!(bits.at, 23);
assert!(Bits { src: &[0, 0, 0, 0x80, 0], at: 0 }.qp_rice(0).is_err());
// The map's first symbol is a 32-bit literal (300 = QP 150 from prediction 0).
let map = qp_map(&[0, 0, 1, 0x2c, 0x94], 1, 4).unwrap();
assert_eq!(map.data, [150; 4]);
assert!(qp_map(&[0, 0, 1, 0x2c, 0x95], 1, 4).is_err());
@ -1020,6 +1037,16 @@ mod tests {
assert!(matches!(qp_map(&[0, 0, 1, 0x52, 0x94], 1, 4), Err(RawError::Unsupported(_))));
}
fn long_qp_prefixes_and_escapes_as_on_the_eos_r5_mark_ii() {
// EOS R5 Mark II maps (QP 150–162) jump by up to 12 where k is 0: an 18-zero prefix that an
// escape after 16 zeros misread, then a real escape (23 zeros, 1, symbol 23 = −12).
let src = [0x00, 0x00, 0x01, 0x2c, 0x90, 0x00, 0x01, 0x90, 0x00, 0x00, 0x08, 0xb8];
assert_eq!(qp_map(&src, 7, 1).unwrap().data, [150, 150, 150, 159, 159, 159, 147]);
for end in 0..src.len() {
assert!(qp_map(&src[..end], 7, 1).is_err());
}
}
#[test]
fn odd_height_qp_map_uses_its_last_row_alone() {
// EOS R7 C-RAW: 4732 sensor rows give a 1183-row QP map, so the last

View File

@ -16,6 +16,10 @@ fn corpus() -> PathBuf {
}
fn check(name: &str, hash: u64, sensor: (usize, usize), developed: (usize, usize)) {
check_against(name, hash, sensor, Some(developed), "the independent reference");
}
fn check_against(name: &str, hash: u64, sensor: (usize, usize), developed: Option<(usize, usize)>, reference: &str) {
let path = corpus().join("raw").join(name);
let Ok(bytes) = std::fs::read(&path) else {
eprintln!("skip: {} absent", path.display());
@ -25,12 +29,14 @@ fn check(name: &str, hash: u64, sensor: (usize, usize), developed: (usize, usize
assert_eq!(raw.format, RawFormat::Cr3);
raw.validate().unwrap();
assert_eq!((raw.width, raw.height, raw.cpp), (sensor.0, sensor.1, 1));
assert_eq!(raw.info().developed_size(), developed);
if let Some(developed) = developed {
assert_eq!(raw.info().developed_size(), developed);
}
assert_eq!(raw.info(), probe_info(&bytes).unwrap());
let RawData::U16(samples) = &raw.data else { panic!("{name}: integer sensor data expected") };
let actual =
samples.iter().flat_map(|v| v.to_le_bytes()).fold(0xcbf2_9ce4_8422_2325u64, |h, byte| (h ^ u64::from(byte)).wrapping_mul(0x100_0000_01b3));
assert_eq!(actual, hash, "{name}: sensor pixels differ from the independent reference");
assert_eq!(actual, hash, "{name}: sensor pixels differ from {reference}");
assert!(raw.wb_multipliers.is_some(), "{name}: as-shot white balance missing");
assert!(raw.white_at(0) > raw.black.mean(), "{name}: invalid black/white levels");
}
@ -79,6 +85,33 @@ fn canon_r8_craw_sensor_is_exact() {
check("cr3-canon-r8-craw.cr3", 0xf836_a663_a795_a375, (6188, 4120), (6000, 4000));
}
/// EOS R5 Mark II (raw.pixls.us 7881–7884, CC0). No external decoder was run on these: the hashes pin
/// LightCraft's own decode. Lossless RAW is CRX 0x100, as in the oracle-checked fixtures above, with
/// odd-height (2825- and 1787-row) Bayer planes; every entropy stream decodes to its exact end. These
/// low-ISO C-RAW files need no QP-map escape (most of the camera's files do; that is covered by the unit
/// tests in `crx.rs`, see docs/cr3.md). The developed images match the camera's own previews.
fn check_r5m2(name: &str, hash: u64, sensor: (usize, usize), developed: Option<(usize, usize)>) {
check_against(name, hash, sensor, developed, "the pinned LightCraft decode");
}
#[test]
fn canon_r5m2_sensor_is_pinned() {
// raw.pixls.us/getfile.php/7881; SHA256 d6e6aa3b493ea8936dff0efb0cc17c87471437e7317bce37c8c82ba08b9cab7b
check_r5m2("cr3-canon-r5m2-raw.cr3", 0xff71_6fb3_0248_496f, (8480, 5650), Some((8192, 5464)));
// raw.pixls.us/getfile.php/7882; SHA256 b3c08a5c7a97299dfd58896a12b939e7b43ec78682761812524825e6e5d087be
check_r5m2("cr3-canon-r5m2-craw.cr3", 0xaf32_b453_57b5_34e5, (8480, 5650), Some((8192, 5464)));
}
/// Crop mode (1.6×): the sensor samples only. Its developed framing depends on how the file's misplaced valid
/// area is read, which is not part of the CRX decode.
#[test]
fn canon_r5m2_crop_mode_sensor_is_pinned() {
// raw.pixls.us/getfile.php/7883; SHA256 9f88c0ff012924193b7f4497559d133dfe626766d600b5d67689156721739ead
check_r5m2("cr3-canon-r5m2-apsc-raw.cr3", 0x31cf_630a_fe86_8958, (5376, 3574), None);
// raw.pixls.us/getfile.php/7884; SHA256 6a597497776a6abbfab8fcf12d0086ac7a3f8afea2879d61accf6bbf48d357d7
check_r5m2("cr3-canon-r5m2-apsc-craw.cr3", 0x4721_605b_2033_9332, (5376, 3574), None);
}
#[test]
fn canon_m50_craw_crop_is_the_shot_aspect() {
// raw.pixls.us/getfile.php/2663: the 1:1 square starts 1000 px right of the recommended crop's origin,

View File

@ -2063,5 +2063,8 @@
"Perceptual": "Perzeptiv",
"Relative": "Relativ",
"Simulate Paper & Ink": "Papier und Druckfarbe simulieren",
"Content-Aware": "Inhaltsbasiert"
"Content-Aware": "Inhaltsbasiert",
"imported earlier switch over with Photo ▸ Reload from Disk.": "Bereits importierte Fotos wechseln mit Foto → Vom Datenträger neu laden zur RAW-Bearbeitung.",
"Canon EOS R5 Mark II C-RAW files that opened as \"preview only\" (more than half of them, depending on the": "C-RAW-Dateien der Canon EOS R5 Mark II, die als „Nur Vorschau“ geöffnet wurden (je nach Motiv mehr als die Hälfte),",
"scene) now develop from their sensor data with every editing tool, like the camera's other raws. Photos": "werden jetzt wie die übrigen RAW-Dateien der Kamera aus ihren Sensordaten mit allen Werkzeugen bearbeitet."
}

View File

@ -24,7 +24,7 @@ are the public prose descriptions and patents cited in
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
and only four 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.
@ -55,6 +55,16 @@ control. The exact inputs and reference hashes are:
| Canon R8 RAW, raw.pixls.us 6585 | `7d5c6dbb11ff7e6ee58715d90a20f5d801e8b103f4711ff6ea329ceafcef254c` | `63c1c6d8d1eb2312` |
| Canon R8 C-RAW, raw.pixls.us 6587 | `df33cf394573645ce03dea1b2e9f0b5cc2b7734e9e3391ee7114151414cf2812` | `f836a663a795a375` |
The EOS R5 Mark II files (raw.pixls.us 7881–7884, CC0) are pinned to LightCraft's own decode; no external
decoder was run on them:
| File | Input SHA-256 | Sensor FNV-1a (u16 little-endian) |
|---|---|---|
| Canon R5 Mark II RAW, raw.pixls.us 7881 | `d6e6aa3b493ea8936dff0efb0cc17c87471437e7317bce37c8c82ba08b9cab7b` | `ff716fb30248496f` |
| Canon R5 Mark II C-RAW, raw.pixls.us 7882 | `b3c08a5c7a97299dfd58896a12b939e7b43ec78682761812524825e6e5d087be` | `af32b45357b534e5` |
| Canon R5 Mark II crop-mode RAW, raw.pixls.us 7883 | `9f88c0ff012924193b7f4497559d133dfe626766d600b5d67689156721739ead` | `31cf630afe868958` |
| Canon R5 Mark II crop-mode C-RAW, raw.pixls.us 7884 | `6a597497776a6abbfab8fcf12d0086ac7a3f8afea2879d61accf6bbf48d357d7` | `4721605b20339332` |
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
@ -69,6 +79,34 @@ 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 are rejected.
The QP map is coded as follows (established on the EOS R5 Mark II). Its first symbol is a 32-bit
big-endian literal, mapped like every other symbol and added to a prediction of zero. Every later
symbol is Rice coded with a limited-length escape: a quotient of 23 or more is written as 23 zeros,
the terminating 1 and the symbol in 8 bits. This is the escape layout of ITU-T T.87 for a 32-bit
code-length limit and 8-bit symbols, without that standard's minus-one offset. In the R8 maps only
the first symbol needs more than 15 leading zeros, and its bits read the same whether taken as a
32-bit literal or as an escape after 16 zeros with a 16-bit literal (the rule LightCraft used before).
The R7 maps decoded to their exact ends under that rule, which a later long prefix would have broken;
no R7 file was at hand to recheck them. R5 Mark II maps (QP 150–162) also jump by up to 12 where the Rice parameter is 0. That
gives 18- to 22-zero prefixes, which the 16-zero rule misread as escapes ("Canon CRX adaptive QP value
−21087" and other out-of-range values; the file then opened as a preview). It also gives real escapes,
symbols 23 and 24. Escapes were seen only where the Rice parameter is 0 (in 100 of 612 maps; all 351 inspected, up to 10 per map); at a larger
parameter they would use the same layout, which is unobserved. With this coding the QP maps of all
33,665 R5 Mark II C-RAW files in a private library (version `0x200`, 8480 × 5650) decode to the exact
end of their entropy streams, with values 150–162. So do the reduced-size tracks of 306 of those
files, the two CC0 R5 Mark II C-RAW files above and the R8 C-RAW fixture; all six fixture hashes are
unchanged. Under the 16-zero rule, 174 of those 306 files (57%) failed and opened as previews, all
with out-of-range values (none at QP 168). The two CC0 C-RAW files are low-ISO shots whose maps need no
long prefix: they decoded under the old rule too, so the escape is covered by synthetic unit tests in
`crx.rs` rather than by a public file. Render cache version 43 redraws thumbnails of files whose decode
changed; photos imported as preview-only switch over with Photo ▸ Reload from Disk.
The R5 Mark II sensor has 5650 rows (3574 in crop mode), so its Bayer planes have odd heights (2825,
1787). Lossless planes decode as before. In C-RAW every wavelet level has an odd height (2825 → 1413 →
707), and each subband's entropy stream ends exactly where the subband geometry says. The synthesis
uses the same boundary rules that are verified on the R8's odd lengths. Decoded rows show no step
down to the last sensor row, and the developed images match the camera's embedded JPEGs at 100 %.
An odd QP-map height (EOS R7: 4732 sensor rows give 1183 QP rows) leaves the
last row of the second-level high-frequency bands without a partner row; that
row's QP is used on its own. The odd-height map decodes to the exact end of its

View File

@ -1,6 +1,6 @@
# Gaps: where LightCraft falls short of Lightroom
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-11 · **Change:** minor (CR3 entry names the EOS R7 C-RAW fix and the refused CRX variants; CI and Windows / Linux entries note the 0.6.0 riscv64 build; camera colour: tone curve from black-and-white camera JPEGs; Compare and Reference get sharp zoom windows; gap 4 shrinks; gap 14: the HDR switch is read from crs XMP) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-11 · **Change:** minor (CR3 entry names the EOS R7 C-RAW fix and the refused CRX variants; CI and Windows / Linux entries note the 0.6.0 riscv64 build; camera colour: tone curve from black-and-white camera JPEGs; Compare and Reference get sharp zoom windows; gap 4 shrinks; gap 14: the HDR switch is read from crs XMP; gaps 2 and 10: EOS R5 Mark II CR3 verified) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6
Every known shortfall, one entry each, ranked by user impact (how many Lightroom users hit it, and
how hard it blocks them), then by effort. **Agents pick work from the top** (the first entry nobody is
@ -16,7 +16,7 @@ Hours are Opus 5.5 agent wall-clock hours (see [target-app-parity.md](target-app
| # | Gap | Evidence | User impact | Hours | Doc |
|---:|---|---|---|---:|---|
| 1 B | **Camera colour is estimated, not measured** (LR-PROF-CAMERACOLOR). Raws start from a per-file fit to the camera JPEG, 4 bundled profiles or 52 spectral matrices; others use a neutral matrix (a black-and-white camera JPEG gives its tone curve only, #577) | ΔE vs camera JPEG 2.9–10 after fitting (raw-parity.md); 0 chart-calibrated models vs 1,500 Adobe Standard profiles | every raw shooter sees colour that is close but not Lightroom's; some get neutral-matrix colour | 50–90 | [raw-parity](raw-parity.md#colour) |
| 2 B | **CR3 beyond three verified bodies** (LR-IMP-FORMATS): `crx.rs` refuses vertical-tile C-RAW, partial-subband and other plane coding, multi-tile 0x200 and adaptive low-frequency gains, and those files fall back to the preview; CR3 sRAW / mRAW and HEIF CR3 too. EOS R7 C-RAW (odd-height QP map) decodes since a45c2b66 and R6 Mark II C-RAW is reported working on 0.6.0, but neither is verified yet (no corpus test or recorded check) | measured: Canon is the largest bucket (33% of photographers) and its share whose camera fully works is the lowest of the big four, 72%; 17 of 22 popular Canon bodies write CR3, 2 verified (raw-parity.md); R7 rule checked only on paired RAW / C-RAW captures ([cr3.md](cr3.md)) | +6.5 points of photographers whose camera works, the biggest single raw gain | 25–45 | [raw-parity](raw-parity.md#remaining-work-ranked-by-photographers-unlocked-per-hour) |
| 2 B | **CR3 beyond four verified bodies** (LR-IMP-FORMATS): `crx.rs` refuses vertical-tile C-RAW, partial-subband and other plane coding, multi-tile 0x200 and adaptive low-frequency gains, and those files fall back to the preview; CR3 sRAW / mRAW and HEIF CR3 too. Verified: M50 / R100 / R8 / R5 Mark II. EOS R7 C-RAW (odd-height QP map) decodes since a45c2b66 and R6 Mark II C-RAW is reported working on 0.6.0, but neither is verified yet (no corpus test or recorded check) | measured: Canon is the largest bucket (33% of photographers) and its share whose camera fully works is the lowest of the big four, 73%; 18 of 22 popular Canon bodies write CR3, 4 verified (raw-parity.md); R7 rule checked only on paired RAW / C-RAW captures ([cr3.md](cr3.md)) | +6.2 points of photographers whose camera works, the biggest single raw gain | 25–45 | [raw-parity](raw-parity.md#remaining-work-ranked-by-photographers-unlocked-per-hour) |
| 3 B | **Render fidelity unmeasured** (LR-BEHAV-RENDER-FIDELITY): tone, highlights, texture / clarity / dehaze, NR and sharpening are tuned by eye | no side-by-side suite; a retune needs a new process version (only V1 exists) | edits imported from Lightroom look different; the look "isn't Lightroom's" | 30–60 | [raw-parity](raw-parity.md), [process-versions](process-versions.md) |
| 4 B | **Original-pixel detail at 100%** (LR-VIEW-ZOOM, P0): Detail, Before/After, Compare and Reference are sharp at 1:1–8:1 (zoom windows, #323). Mask overlays and soft proofing still render the whole frame at the drawn size instead of a window: sharp up to the GPU texture side, but a full-size render per edit at 1:1 | checklist row 🟡 | editing with a mask overlay or soft proof on at 1:1 is slow on large files, and blurry past the texture side | 4–8 | [ui-parity](ui-parity.md) |
| 5 B | **AI masks: Subject, Sky, People, Background, Landscape** are heuristics; Object / Describe run SAM 3 but its download has no mirror configured | `crates/segment`; ai-masks.md; MASK rows 67% | masking is how most Lightroom users edit today | 40–70 + model decision | [target-app-parity](target-app-parity.md#ai) |
@ -24,7 +24,7 @@ Hours are Opus 5.5 agent wall-clock hours (see [target-app-parity.md](target-app
| 7 | **Nikon High Efficiency NEF** (HE / HE★ on Z 8, Z 9, Z 6III, Z f, Z50II, Z5II when set to HE) | named and preview only (#193); needs a pure-Rust JPEG XS decoder | +1.1 points (only shots taken in HE; lossless works on the same bodies); low gain per hour (~0.04), so not a beta blocker | 20–40 | [raw-parity](raw-parity.md) |
| 8 B | **No lens profile database** (LR-EDIT-OPTICS-PROFILE): only DNG opcodes, RW2 in-file distortion and Sony ILCE-7RM4A distortion | Adobe ships 3,635 lens profiles; we never use them | distortion / vignetting correction is a default step for many | 40–80 + calibration shots | [raw-parity](raw-parity.md#lens-profiles) |
| 9 B | **Tests don't run in CI on macOS, Windows or Linux x64**: only FreeBSD runs `cargo test`; the others build packages | `.github/workflows/` (freebsd, packaging-lint, release, windows-arm64); the linux-riscv64 release job added in 0.6.0 (#844) runs only `lightcraft-cli --version` under QEMU | regressions reach users on the main platforms; `cargo xtask ci` runs only locally | 6–12 | [target-app-parity](target-app-parity.md#by-dimension) |
| 10 B | **Per-model verification thin, plus cheap per-body decode fixes**: 234 of 1,446 Adobe models verified (16%), ~40% of photographers on a verified body; Nikon 5 bodies verified, Canon 11. Cheap fixes: Z 6II packed 14-bit NEF (#769, PR #671), Sony A100 / F828 regression (#702), DSLR-A200…A390 / A850 12-bit ARW (#535) | measured: [raw/coverage.tsv](raw/coverage.tsv) | per-body bugs (levels, crops, WB) surface only from users | 25–45 | [raw-parity](raw-parity.md#by-maker-measured) |
| 10 B | **Per-model verification thin, plus cheap per-body decode fixes**: 235 of 1,446 Adobe models verified (16%), ~42% of photographers on a verified body; Nikon 5 bodies verified, Canon 12. Cheap fixes: Z 6II packed 14-bit NEF (#769, PR #671), Sony A100 / F828 regression (#702), DSLR-A200…A390 / A850 12-bit ARW (#535) | measured: [raw/coverage.tsv](raw/coverage.tsv) | per-body bugs (levels, crops, WB) surface only from users | 25–45 | [raw-parity](raw-parity.md#by-maker-measured) |
| 11 | **Enhance: Raw Details, Super Resolution; AI denoise without shippable weights or X-Trans** | ENH rows 0%; denoise Bayer only, RawNIND weights GPL and opt-in | Fujifilm users get no AI denoise; nobody gets it out of the box | 30–60 + model decision | [raw-parity](raw-parity.md#demosaic-levels-crops-and-lens-metadata) |
| 12 | **Content-aware / generative remove, detect distractions, reflections removal** | REM rows 75%; patch synthesis missing | cleanup work goes back to Photoshop | 25–45 (+ generative model) | [target-app-parity](target-app-parity.md#ai) |
| 13 | **Lightroom catalog migration is one-way and approximate**: unsupported Adobe profiles / AI settings archived, history kept as data | lightroom-catalog-import.md | switching users lose some looks | 8–12 | [file-format-parity](file-format-parity.md) |
@ -77,6 +77,7 @@ Beta-blocking gaps (B) total **~230–430 h**; with the stability and platform w
| 2026-10-11 | minor | Gap 4: Compare and Reference views get zoom windows per pane (1:1 was a 2,560 px render magnified); overlays and soft proofing remain, 8–15 h → 4–8 h |
| 2026-10-10 | minor | Compressed ORF entry links the two Olympus patents that describe the method |
| 2026-10-11 | minor | Gap 14: `crs:HDREditMode` is read from XMP (#663); the headroom limit and SDR rendition still aren't |
| 2026-10-11 | minor | Gaps 2 and 10 shrink: EOS R5 Mark II CR3 decodes and is verified (fourth CR3 body, Canon 12 verified, 235 models, ~42% on a verified body); CR3 gain +6.5 → +6.2 points |
| 2026-10-10 | minor | RAW gaps re-measured model by model (raw-parity.md): CR3, compressed ORF and verification entries carry measured shares; HE NEF no longer a beta blocker (+1.1 points for 20–40 h); verification entry absorbs the cheap per-body fixes (#769, #702, A200 series) |
| 2026-10-10 | minor | Beta total raised to 340–600 h to include the ~92 open core-path user issues |
| 2026-10-10 | major | Created from the checklist's Top gaps (whose items 1–2 had been duplicated by a merge) and ROADMAP's Where we stand; re-ranked; added evidence, impact, hours and beta flags; added platform-CI, lens-database, HE NEF and localization gaps |

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
# RAW parity: cameras, formats, demosaic, colour and lens profiles
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-10 · **Change:** major (model-by-model measurement against Adobe's published camera list; use-weighted coverage; variant matrix; colour and lens sections; ranked next cameras) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6 (Camera Raw 18.7)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (EOS R5 Mark II decoded and verified: CRX QP-map escape, odd-height planes) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6 (Camera Raw 18.7)
Raw processing is the deepest single dimension of Lightroom parity: a photographer whose camera
does not decode, or decodes with the wrong colour, cannot switch. This document measures it model by
@ -14,13 +14,13 @@ ranked in [gaps.md](gaps.md). Details per format: [cr3.md](cr3.md),
| Measure | Value | Kind |
|---|---:|---|
| Adobe-listed camera models | **1,446** | measured: [raw/adobe-cameras.tsv](raw/adobe-cameras.tsv) |
| Decoded from sensor data and **verified** on a real file | **234** (16%) | measured: [raw/evidence.tsv](raw/evidence.tsv) |
| Decoder path should handle it, **unverified** | **943** (65%) | measured from the format rules (632 of them DNG, mostly phones) |
| Decoded from sensor data and **verified** on a real file | **235** (16%) | measured: [raw/evidence.tsv](raw/evidence.tsv) |
| Decoder path should handle it, **unverified** | **942** (65%) | measured from the format rules (632 of them DNG, mostly phones) |
| **Preview-only** (embedded JPEG) | **233** (16%) | measured |
| **Unsupported** (not imported, refused or decodes wrongly) | **36** (2%) | measured |
| Models added since 2017 (Camera Raw 10+): verified / unverified / preview / unsupported | 81 / 641 / 24 / 8 of 754 | measured |
| **Share of photographers whose camera fully works** (decodes from sensor data), use-weighted | **~84%** | estimated: measured classes × written usage weights × per-format confidence |
| …of which on a body we have verified | **~40%** | estimated, same weights |
| Models added since 2017 (Camera Raw 10+): verified / unverified / preview / unsupported | 82 / 640 / 24 / 8 of 754 | measured |
| **Share of photographers whose camera fully works** (decodes from sensor data), use-weighted | **~85%** | estimated: measured classes × written usage weights × per-format confidence |
| …of which on a body we have verified | **~42%** | estimated, same weights |
| Camera colour: Adobe profiles vs ours | 1,500 Adobe Standard profiles, 481 models with Camera Matching profiles vs **4 bundled profiles** + per-file fits + 52 spectral matrices | measured (bundle listing, Adobe list, `assets/camera-profiles`) |
| Lens profiles: Adobe vs ours | **3,635 vs 0** (in-file corrections only) | measured |
| **RAW readiness** (decoding 60%, colour 25%, lens 15%) | **~56%** (range 50–60%) | estimated, see [Scores](#scores) |
@ -42,7 +42,8 @@ committed table is stale.
claims were not used.
- **Verified** means a real file from that body decoded from sensor data in: the corpus test over the
`RAW_SAMPLES` manifest (`xtask/src/main.rs`, 101 CC0 files; bodies whose sample is in
`KNOWN_UNSUPPORTED` excluded), `crates/raw/tests/cr3_corpus.rs` (3 bodies, exact), the RAF reference
`KNOWN_UNSUPPORTED` excluded), `crates/raw/tests/cr3_corpus.rs` (3 bodies exact against an external decoder;
the EOS R5 Mark II pinned, with a QP-map check of 33,665 private files), the RAF reference
check ([raf-compression.md](raf-compression.md)), and the raw.pixls.us bulk checks recorded in issue
#535 (all 100 Sony bodies there; 87 decode) and PR #215 (every Panasonic / Leica RW2 / RWL / RAW body
there, 178 files from 118 bodies). Bulk-check body lists were matched to Adobe names through the
@ -56,14 +57,14 @@ committed table is stale.
~8 years (listed in the file), 20% to the bucket's other Adobe models.
- **Per-format confidence** for unverified bodies (the chance their files decode correctly): DNG, CR2,
RAF, RW2 0.95; NEF, ARW, PEF 0.9; ORF, SRW, SR2 0.8; **CR3 0.6** (the CRX decoder refuses several
coding variants and only three bodies are verified; maintainers report the R7 working).
coding variants and only four bodies are verified; maintainers report the R7 working).
## By maker (measured)
| Maker | Adobe models | verified | unverified | preview | unsupported | Main reason for preview / unsupported |
|---|---:|---:|---:|---:|---:|---|
| Sony | 149 | 86 | 51 | 9 | 3 | DSLR-A200…A390 and A850 12-bit compressed ARW (preview, #535); A100 and DSC-F828 refused (regression #702); SRF not imported |
| Canon | 134 | 11 | 100 | 21 | 2 | CRW (2000–2004 bodies) preview; EOS-1D / 1Ds TIFF raws not imported |
| Canon | 134 | 12 | 99 | 21 | 2 | CRW (2000–2004 bodies) preview; EOS-1D / 1Ds TIFF raws not imported |
| Samsung | 128 | 1 | 118 | 9 | 0 | compressed SRW (NX1, NX30, NX300, NX500, NX2000, NX3000, NX3300, NX mini, Galaxy NX) |
| Apple | 113 | 1 | 112 | 0 | 0 | — (DNG / ProRAW) |
| Panasonic | 104 | 93 | 11 | 0 | 0 | — |
@ -80,13 +81,13 @@ committed table is stale.
| DJI | 21 | 0 | 21 | 0 | 0 | — (DNG) |
| OM Digital Solutions | 7 | 0 | 0 | 7 | 0 | **compressed ORF** |
| Kodak, Konica Minolta, Epson, Sigma, GoPro, Contax, others | 56 | 0 | 14 | 27 | 15 | DCR, GPR not imported; KDC, MRW, ERF, X3F preview |
| **All** | **1,446** | **234 (16%)** | **943 (65%)** | **233 (16%)** | **36 (2%)** | |
| **All** | **1,446** | **235 (16%)** | **942 (65%)** | **233 (16%)** | **36 (2%)** | |
## By use (estimated)
| Bucket | Weight | Camera fully works | On a verified body | Why |
|---|---:|---:|---:|---|
| Canon | 33% | 72% | 16% | 17 of the 22 popular bodies write CR3; 2 of them verified, the rest at 0.6 |
| Canon | 33% | 73% | 19% | 18 of the 22 popular bodies write CR3; 4 of them verified (M50, R8, R100, R5 Mark II), the rest at 0.6 |
| Sony | 27% | 98% | 91% | bulk-checked |
| Nikon | 16% | 91% | 12% | decoders cover every NEF coding but HE; few bodies verified |
| Fujifilm | 10% | 91% | 45% | |
@ -97,7 +98,7 @@ committed table is stale.
| Leica | 1% | 95% | 5% | |
| DJI | 1% | 95% | 0% | |
| Medium format and others | 0.5% | 23% | 0% | IIQ, 3FR, X3F |
| **Weighted** | 100% | **84%** | **40%** | |
| **Weighted** | 100% | **85%** | **42%** | |
About 5 in 6 raw photographers' cameras decode, but only about 2 in 5 use a body we have actually
checked, and Canon, the largest bucket, is the weakest of the big four.
@ -110,8 +111,8 @@ checked, and Canon, the largest bucket, is the weakest of the big four.
|---|---|---|---|
| CR2 | lossless JPEG slices | ✅ | 8 corpus bodies; CFA phase from `CR2CFAPattern` (#85, 35 bodies); masked-column black level |
| CR2 | sRAW / mRAW (YCbCr) | ✅ | `vendor/cr2/sraw.rs`, 31 samples from 16 models |
| CR3 | CRX lossless, version 0x100 | ✅ | M50, R100, R8 exact against a reference |
| CR3 | C-RAW 0x100 (horizontal tiles), 0x200 (single 14-bit tile, adaptive QP) | ✅ | same 3 bodies exact |
| CR3 | CRX lossless, version 0x100 | ✅ | M50, R100, R8 exact against a reference; R5 Mark II (odd-height planes) pinned |
| CR3 | C-RAW 0x100 (horizontal tiles), 0x200 (single 14-bit tile, adaptive QP incl. the QP-map escape) | ✅ | same 3 bodies exact; R5 Mark II pinned, QP maps of 33,665 files decode exactly, matches the camera JPEG |
| CR3 | other CRX variants (vertical tiles, partial subbands, other plane flags, 0x200 multi-tile) | ⬜ | refused in `crx.rs`, falls back to the preview; which bodies write them is unmeasured |
| CR3 | sRAW / mRAW | ⬜ | 4-plane Bayer only |
| CR3 | HEIF / HDR PQ | ⬜ | HEVC tracks recognised, not decoded |
@ -222,10 +223,10 @@ drone DNG users (~9% of photographers by the weights above); Adobe reaches nearl
| Part | Weight | Score | Basis |
|---|---:|---:|---|
| Decoding | 60% | **76%** | use-weighted 84% × 0.9 for per-body decode bugs still surfacing (levels, crops, WB: #535, #455, #461, #702) |
| Decoding | 60% | **77%** | use-weighted 85% × 0.9 (76.5%) for per-body decode bugs still surfacing (levels, crops, WB: #535, #455, #461, #702) |
| Colour | 25% | **35%** | see [Colour](#colour) |
| Lens profiles | 15% | **10%** | see [Lens profiles](#lens-profiles) |
| **RAW readiness** | 100% | **~56%** (range 50–60%) | 45.6 + 8.75 + 1.5; demosaic and highlight quality unmeasured |
| **RAW readiness** | 100% | **~56%** (range 50–60%) | 45.9 + 8.75 + 1.5; demosaic and highlight quality unmeasured |
The previous estimate (earlier on 2026-10-10) was ~50%, with decoding at ~78% weighted by maker
from the format list alone. Measured model by model, decoding comes out about the same; the change is
@ -241,7 +242,7 @@ works, from [raw/usage-weights.tsv](raw/usage-weights.tsv).
| # | Camera / variant | Gain (points of photographers) | Hours | Gain per hour | Needs |
|---:|---|---:|---:|---:|---|
| 1 | Compressed ORF (every Olympus / OM body since ~2008) | +2.6 | 8–15 | ~0.20 | CC0 samples (have 2) |
| 2 | CR3: remaining CRX variants, then verify the 17 popular CR3 bodies | +6.5 | 25–45 | ~0.19 | samples per body (raw.pixls.us has most) |
| 2 | CR3: remaining CRX variants, then verify the other 14 popular CR3 bodies | +6.2 | 25–45 | ~0.19 | samples per body (raw.pixls.us has most) |
| 3 | Verify popular Nikon, Fujifilm, Canon CR2 and Pentax bodies (one CC0 file each, fix what breaks) | +2.0 | 8–15 | ~0.17 | public samples |
| 4 | Nikon packed 14-bit under a compressed tag (Z 6II uncompressed, #769) | +0.2 | 1–2 | ~0.13 | PR #671 exists |
| 5 | Sony DSLR-A200…A390 / A850 12-bit compressed ARW | +0.4 | 3–6 | ~0.08 | samples on raw.pixls.us |
@ -265,5 +266,6 @@ Beyond decoding:
| Date | Change | Summary |
|---|---|---|
| 2026-10-10 | minor | Compressed ORF: pointer to the two Olympus patents that describe the method, as a clean-room starting point |
| 2026-10-11 | minor | EOS R5 Mark II verified (CRX QP-map first literal and limited-length escape, odd-height Bayer planes; 4 CC0 files pinned, QP maps of 33,665 private files): 235 verified, 942 unverified; use-weighted 85% (42% on verified bodies); decoding 77%, RAW readiness unchanged at ~56% |
| 2026-10-10 (later) | major | Model-by-model measurement against Adobe's published list (1,446 models: 234 verified, 943 unverified, 233 preview, 36 unsupported); `docs/raw/` data and re-measure script; use-weighted share 84% (40% on verified bodies); variant matrix; colour and lens sections with scores; ranked next cameras; RAW readiness ~56% from written parts |
| 2026-10-10 | major | Created: formats, makers, demosaic, colour and lens checklists; target counts from the installed Lightroom 9.6 bundle listing |

View File

@ -188,7 +188,7 @@ Canon EOS R1 CR3 2023 unverified CRX decoder: lossless and C-RAW 0x100 / 0x200 s
Canon EOS R3 CR3 2021 unverified CRX decoder: lossless and C-RAW 0x100 / 0x200 single-tile; other variants fall back to the preview
Canon EOS R5 CR3 2019 unverified CRX decoder: lossless and C-RAW 0x100 / 0x200 single-tile; other variants fall back to the preview
Canon EOS R5 C CR3 2021 unverified CRX decoder: lossless and C-RAW 0x100 / 0x200 single-tile; other variants fall back to the preview
Canon EOS R5 Mark II CR3 2023 unverified CRX decoder: lossless and C-RAW 0x100 / 0x200 single-tile; other variants fall back to the preview
Canon EOS R5 Mark II CR3 2023 verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hashes, docs/cr3.md); bulk: QP maps of 33,665 C-RAW files
Canon EOS R6 CR3 2019 unverified CRX decoder: lossless and C-RAW 0x100 / 0x200 single-tile; other variants fall back to the preview
Canon EOS R6 V CR3 2025 unverified CRX decoder: lossless and C-RAW 0x100 / 0x200 single-tile; other variants fall back to the preview
Canon EOS R6 Mark II CR3 2022 unverified CRX decoder: lossless and C-RAW 0x100 / 0x200 single-tile; other variants fall back to the preview

Can't render this file because it has a wrong number of fields in line 2.

View File

@ -11,6 +11,7 @@ Canon EOS 7D verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 80D verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Canon EOS M50 (EOS Kiss M) verified corpus: crates/raw/tests/cr3_corpus.rs (exact sensor hashes, docs/cr3.md)
Canon EOS R100 verified corpus: crates/raw/tests/cr3_corpus.rs (exact sensor hashes, docs/cr3.md)
Canon EOS R5 Mark II verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hashes, docs/cr3.md); bulk: QP maps of 33,665 C-RAW files
Canon EOS R8 verified corpus: crates/raw/tests/cr3_corpus.rs (exact sensor hashes, docs/cr3.md)
Canon EOS-5D Mark III verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm GFX 100 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)

Can't render this file because it contains an unexpected character in line 2 and column 3.

View File

@ -1,6 +1,6 @@
# Target-app parity: LightCraft vs Adobe Lightroom
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-10 · **Change:** major (full re-measure against Lightroom Classic 15.5 and the installed Lightroom 9.6; merged ROADMAP's parity estimate and honest assessment into this file) · **Target:** Adobe Lightroom Classic 15.5 (August 2026) and Lightroom 9.6 (desktop)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (EOS R5 Mark II CR3 verified: RAW decoding 76% → 77%; headline numbers unchanged) · **Target:** Adobe Lightroom Classic 15.5 (August 2026) and Lightroom 9.6 (desktop)
The authoritative assessment of how close LightCraft is to Lightroom. The row-by-row checklist is
[parity-checklist.md](parity-checklist.md); the ranked work list is [gaps.md](gaps.md); deep areas
@ -67,7 +67,7 @@ from the checklist sections and the deep-dive documents.
| Area | Weight | Breadth | Ready | Remaining | Notes |
|---|---:|---:|---:|---:|---|
| Import and library (import, folders, albums, smart albums, keywords, metadata, search, faces) | 15% | 90% | 80% | 25–45 h | checklist A–E 83–92%; robust journal; 85k-photo libraries |
| RAW decoding and camera coverage | 15% | 81% | 76% | 120–220 h | [raw-parity.md](raw-parity.md), measured model by model: 84% of photographers' cameras decode (use-weighted), × 0.9 for per-body bugs; CR3 variants, compressed ORF, HE NEF |
| RAW decoding and camera coverage | 15% | 81% | 77% | 120–220 h | [raw-parity.md](raw-parity.md), measured model by model: 85% of photographers' cameras decode (use-weighted), × 0.9 for per-body bugs; CR3 variants, compressed ORF, HE NEF |
| Colour, camera profiles, render fidelity | 10% | 65% | 35% | 80–150 h | 4 bundled profiles vs Adobe's 1,500; per-file fits median ΔE ~5 vs the camera JPEG, ~10% far off; no fidelity suite ([raw-parity.md](raw-parity.md#colour)) |
| Global develop adjustments (light, colour, curves, grading, effects, detail) | 15% | 93% | 70% | 30–60 h | checklist F 91.7%; character tuned by eye |
| Optics, lens profiles, crop and geometry | 6% | 80% | 50% | 40–80 h | no lens database; crop / Upright complete |
@ -129,7 +129,7 @@ valued from the model-by-model measurement in [raw-parity.md](raw-parity.md):
| Dimension | Weight | Ready |
|---|---:|---:|
| Features: the other 11 areas, weighted depth from [Features](#features) | 45% | 60.9% |
| RAW decoding and camera coverage | 9% | 76% (84% use-weighted × 0.9) |
| RAW decoding and camera coverage | 9% | 77% (85% use-weighted × 0.9) |
| Camera colour and default rendering | 6% | 35% |
| UI/UX fidelity | 8% | 70% |
| File formats (non-raw) | 6% | 70% |
@ -139,7 +139,7 @@ valued from the model-by-model measurement in [raw-parity.md](raw-parity.md):
| Stability | 8% | 60% |
| Platforms | 4% | 60% |
| Ecosystem / plug-ins | 2% | 15% |
| **Weighted sum** | 100% | **60.6% ≈ 61%** (range 56–66%) |
| **Weighted sum** | 100% | **60.7% ≈ 61%** (range 56–66%) |
Mainstream comes out lower than full: its scope is the raw-develop core, where LightCraft is weakest
(camera colour, CR3 coverage), and its discounts are multiplicative, while the full sum is lifted by
@ -171,18 +171,18 @@ than the user's own.
|---|---:|---:|
| Import and library | 18% | 80% |
| Cull: views, compare, zoom, ratings | 12% | 70% |
| Raw decoding for their camera | 27% | 84% (measured use-weighted share whose camera fully works, [raw-parity.md](raw-parity.md#by-use-estimated)) |
| Raw decoding for their camera | 27% | 85% (measured use-weighted share whose camera fully works, [raw-parity.md](raw-parity.md#by-use-estimated)) |
| Global develop adjustments | 15% | 70% |
| Crop, geometry, lens corrections | 6% | 50% |
| Masking (manual, subject / sky; no generative) | 8% | 45% |
| Heal / remove (no generative), denoise | 5% | 40% |
| Presets, copy / paste / sync | 5% | 85% |
| Export | 4% | 75% |
| **Weighted depth** | 100% | **71.8%** |
| **Weighted depth** | 100% | **72.1%** |
Colour fidelity is a written discount, **×0.85**: most raws start near the camera's own look (median
ΔE ~5), about 10% far off (ΔE ~18), none calibrated to Adobe Standard, so a working photographer
corrects colour by hand (33 open colour issues). 71.8% × 0.804 × 0.85 = **~49%** (range 44–54%).
corrects colour by hand (33 open colour issues). 72.1% × 0.804 × 0.85 = **~49%** (range 44–54%).
### Essentials user: ~64%
@ -199,11 +199,11 @@ basic sliders, crop, apply a preset, undo, export JPEGs.
| Crop and straighten | 10% | 80% |
| Presets and profiles | 8% | 80% |
| Undo and history | 5% | 90% |
| Their camera's raws: decode × default look | 10% | 63% (84% whose camera fully works × colour factor 0.75) |
| Their camera's raws: decode × default look | 10% | 64% (85% whose camera fully works × colour factor 0.75) |
| Export JPEG | 10% | 85% |
| **Weighted depth** | 100% | **77.4%** |
| **Weighted depth** | 100% | **77.5%** |
77.4% × 0.830 = **~64%** (range 59–69%).
77.5% × 0.830 = **~64%** (range 59–69%).
### User evidence (GitHub issues, excluding the four maintainers)
@ -297,6 +297,7 @@ P2 items 12–25 h; look tuning, performance, packaging, hardening 25–45 h.
| Date | Change | Summary |
|---|---|---|
| 2026-10-11 | minor | EOS R5 Mark II CR3 verified (raw-parity.md): use-weighted share whose camera decodes 84% → 85%, RAW decoding 76% → 77%; full 60.6% → 60.7%, mainstream depth 71.8% → 72.1%, essentials depth 77.4% → 77.5%; the rounded numbers (~61%, ~49%, ~64%) are unchanged |
| 2026-10-10 | minor | RAW measured model by model (raw-parity.md): RAW decoding (76%) and colour (35%) are explicit rows of the full sum (59% → 61%); mainstream uses the use-weighted 84% plus a ×0.85 colour discount (51% → 49%); essentials uses 84% × colour 0.75 (63% → 64%); beta ~14 points |
| 2026-10-10 | minor | Full number restored to an additive weighted sum over the dimensions (~59%; method aligned with the standard, no new evidence); hours to ~95% for each of the three audiences; beta distance ~16 points |
| 2026-10-10 | minor | Added mainstream practitioner (~51%) and essentials user (~63%) numbers; full ready re-derived from written weights × discounts (55% → 46%); user-issue evidence; beta hours 340–600 |

View File

@ -8,6 +8,11 @@
library open now stays, and LightCraft says "This is a Lightroom catalog, not a LightCraft library" and offers
**Import Lightroom Catalog…** with that catalog, or Cancel. `lightcraft-cli --library` refuses those folders too.
### Canon EOS R5 Mark II
- Canon EOS R5 Mark II C-RAW files that opened as "preview only" (more than half of them, depending on the
scene) now develop from their sensor data with every editing tool, like the camera's other raws. Photos
imported earlier switch over with Photo ▸ Reload from Disk.
## 2026-10-10
### Dialogs fit the window

View File

@ -524,6 +524,27 @@ const RAW_SAMPLES: &[(&str, &str, &str)] = &[
"https://raw.pixls.us/getfile.php/6587/nice/Canon%20-%20EOS%20R8%20-%203:2.CR3",
"df33cf394573645ce03dea1b2e9f0b5cc2b7734e9e3391ee7114151414cf2812",
),
// EOS R5 Mark II, full frame and 1.6x crop mode: odd-height (2825- / 1787-row) Bayer planes.
(
"cr3-canon-r5m2-raw.cr3",
"https://raw.pixls.us/getfile.php/7881/nice/Canon%20-%20EOS%20R5%20Mark%20II%20-%20RAW%20%283:2%29.CR3",
"d6e6aa3b493ea8936dff0efb0cc17c87471437e7317bce37c8c82ba08b9cab7b",
),
(
"cr3-canon-r5m2-craw.cr3",
"https://raw.pixls.us/getfile.php/7882/nice/Canon%20-%20EOS%20R5%20Mark%20II%20-%20CRAW%20%283:2%29.CR3",
"b3c08a5c7a97299dfd58896a12b939e7b43ec78682761812524825e6e5d087be",
),
(
"cr3-canon-r5m2-apsc-raw.cr3",
"https://raw.pixls.us/getfile.php/7883/nice/Canon%20-%20EOS%20R5%20Mark%20II%20-%20RAW%20%283:2%29.CR3",
"9f88c0ff012924193b7f4497559d133dfe626766d600b5d67689156721739ead",
),
(
"cr3-canon-r5m2-apsc-craw.cr3",
"https://raw.pixls.us/getfile.php/7884/nice/Canon%20-%20EOS%20R5%20Mark%20II%20-%20CRAW%20%283:2%29.CR3",
"6a597497776a6abbfab8fcf12d0086ac7a3f8afea2879d61accf6bbf48d357d7",
),
(
"dng-adobe-canon-5d3-linear-lj92.dng",
"https://raw.pixls.us/getfile.php/1032/nice/Adobe%20DNG%20Converter%20-%20Canon%20EOS%205D%20Mark%20III%20-%20Lossless%20JPEG%20compression%2C%20rgb%20%283:2%29.DNG",