Merge upstream/main (integration batch 43) into feat/issue-1290-launch-library-choice

docs/parity-checklist.md: header lists both sides' changes, revision rows of
both sides newest-first, summary recomputed (`cargo xtask parity --write`).
docs/whats-new.md: #1290's entry joins upstream's 2026-10-23 section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
francoisgn
2026-10-24 02:32:25 +03:00
co-authored by Claude Opus 5.5
184 changed files with 3891 additions and 2009 deletions
+1 -1
View File
@@ -238,7 +238,7 @@ wait and return the result (when built with the `sam` feature; the default CLI h
the model on the CPU from the start.
- Hostile documents: a selection keeps at most 4 detail patches (when read and when rendered),
each at most 1024² logits; more than 64 clicks are never sent to the model.
- Accuracy: `crates/segment/tests/reference.rs` compares every stage against the Python
- Accuracy: `crates/segment/tests/it/reference.rs` compares every stage against the Python
reference (`tools/sam3_reference.py`); on Metal the backbone matches to 7e-5 relative error
and masks to ~5e-5. f16 was tried and rejected (overflow, ~7 % faster).
- The engine feature `sam` (on in the desktop app, off for web and CLI) gates the model; without
+12 -1
View File
@@ -1,6 +1,6 @@
# Architecture
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (`cargo xtask ci` reports the machine and skipped tests; `testkit`) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-23 · **Change:** minor (`cargo xtask ci`: one integration-test binary per crate, doctests apart, one WASM check) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6
How LightCraft is built today. The longer design document (`plan/architecture.md`) is local-only
(`plan/` is gitignored); this page is the committed, current summary. Sizes are Rust lines counted
@@ -63,6 +63,16 @@ dispatch by id, and headless snapshots render the UI without a window.
`assets` (every asset attributed, no Adobe formats) and the WASM build. Other workflows build and
test FreeBSD and Windows ARM64, lint packaging, and build releases.
The tests run under `cargo test --workspace --lib --bins --tests`, or `cargo nextest run` with the
same targets when `LIGHTCRAFT_NEXTEST=1` is set and cargo-nextest is installed; doctests run after
them with `cargo test --workspace --doc`. `cargo test` is the default because the demo library's
generated scenes are cached per process, and nextest's process per test regenerates them.
Examples are left out of the test build (clippy `--all-targets` still
checks them). Each crate links its integration tests into one binary, `tests/it/main.rs` with one
module per file (`cargo test -p <crate> --test it <module>::`); a test that changes state for its
whole process (a global allocator, closing the GPU) keeps a binary of its own in `tests/`. The WASM
build is one `cargo check --target wasm32-unknown-unknown --keep-going` over the wasm-safe crates.
`ci` also probes the machine: OS, CPUs, RAM, the GPU adapters of each backend (from the ignored
`gpu_probe` test of `lightcraft-gpu`, run after the workspace tests so it reuses their build; xtask
has no wgpu), the corpus and `CRAFT_FONTS_DIR`. Tests
@@ -77,5 +87,6 @@ the `lightcraft-gpu` tests once per backend with a hardware adapter (`LIGHTCRAFT
| Date | Change | Summary |
|---|---|---|
| 2026-10-23 | minor | Quality gates: one integration-test binary per crate, doctests apart, nextest on request, one WASM check |
| 2026-10-11 | minor | Quality gates: the CI machine probe, visible skips (`testkit`) and `target/ci/report.json` |
| 2026-10-10 | major | Created from the code (crate sizes, layers, data model, rendering, control, gates) |
+3 -3
View File
@@ -39,7 +39,7 @@ decoded.
## Variant status
The supported and rejected CRX coding variants. Every rejection is an explicit `RawError::Unsupported` whose
text is part of the contract: `crates/raw/tests/cr3_variants.rs` rebuilds each variant as a synthetic CR3
text is part of the contract: `crates/raw/tests/it/cr3_variants.rs` rebuilds each variant as a synthetic CR3
fixture and asserts the exact string, and that header probing (`probe_info`, the import path) and full
decoding fail with the same error, because the engine shows that reason when it falls back to the embedded
preview. The same tests decode a control fixture at both edges of each accepted range, so a rejection can
@@ -87,7 +87,7 @@ CMP1 bit depth. A lossless sample outside the bit depth is still corrupt data.
Other unverified coding variants return explicit unsupported errors (the table above lists them all). 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
`crates/raw/tests/it/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:
@@ -194,7 +194,7 @@ All 110 CR3 files on raw.pixls.us (2026-10-12, every one CC0, 31 folders) decode
falls back to the preview, so none of them uses a CRX variant the decoder refuses (vertical C-RAW tiles,
partial-subband or rounded-plane coding, multi-tile 0x200, adaptive low-frequency gains) or a CR3
sRAW / mRAW. HEIF stills are separate `.HIF` files, not CR3. One file per body is pinned in
`canon_cr3_bodies_decode_like_the_camera_jpeg` (`crates/raw/tests/cr3_corpus.rs`; URLs and SHA-256 in
`canon_cr3_bodies_decode_like_the_camera_jpeg` (`crates/raw/tests/it/cr3_corpus.rs`; URLs and SHA-256 in
`RAW_SAMPLES`, `xtask/src/main.rs`): EOS-1D X Mark III, 90D, 250D, 850D, M200, M50 Mark II, M6 Mark II,
R, R3, R5, R6, R6 Mark II, R6 Mark III, R7, R10, RP, R50, R50 V and PowerShot G5 X Mark II, G7 X Mark III,
SX70 HS and V1, C-RAW where the body has a CC0 C-RAW sample. No external decoder was run: the sensor
+2 -2
View File
@@ -117,8 +117,8 @@ Fresh checks can be run using an already installed model and CC0 raw samples:
```text
LC_DENOISE_MODEL=<model.onnx> cargo test --release -p lightcraft-gpu --lib real_model_on_the_gpu_matches_cpu -- --ignored --nocapture
LC_DENOISE_MODEL=<model.onnx> LC_DENOISE_RAW=<corpus/raw> cargo test --release -p lightcraft-engine --features rawnind-model --test denoise_cpu -- --ignored --nocapture
LC_DENOISE_MODEL=<model.onnx> LC_DENOISE_RAW=<corpus/raw> cargo test --release -p lightcraft-engine --features rawnind-model --test denoise_real -- --ignored --nocapture
LC_DENOISE_MODEL=<model.onnx> LC_DENOISE_RAW=<corpus/raw> cargo test --release -p lightcraft-engine --features rawnind-model --test it denoise_cpu:: -- --ignored --nocapture
LC_DENOISE_MODEL=<model.onnx> LC_DENOISE_RAW=<corpus/raw> cargo test --release -p lightcraft-engine --features rawnind-model --test it denoise_real:: -- --ignored --nocapture
```
## Another computer's graphics card
+1 -1
View File
@@ -161,5 +161,5 @@ before demosaicing would be needed.
vignette gain on the X-T4's real arrays, and the X-T4 geometry against its measured free fit.
- `crates/raw/src/vendor/raf.rs`: a synthetic RAF through header and full decode, only for validated models, and a DNG
round trip.
- `crates/raw/tests/corpus.rs` `fuji_embedded_lens_tables_follow_the_validated_models`: the corpus' `raf-fuji-*` files,
- `crates/raw/tests/it/corpus.rs` `fuji_embedded_lens_tables_follow_the_validated_models`: the corpus' `raf-fuji-*` files,
or any folder of RAFs in `LIGHTCRAFT_FUJI` (the pixls set: 129 decoded, 88 warps, 98 vignette gains).
+12 -3
View File
@@ -1,6 +1,6 @@
# Gaps: where LightCraft falls short of Lightroom
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-21 · **Change:** minor (gap 28: F8 shows / hides the right panel; import review album hierarchy, #2362; gap 20: Minolta MRW decodes; gap 10: 551 models verified; gap 15: Print Page Options — page numbers, page info, crop marks; gap 15: Print Page Options — page numbers, page info, crop marks; gap 28: `\` shows / hides the Filter Bar in the grids; gap 21: Indonesian interface shipped, every message but What's New; gap 27: the Windows x64 installer verified on Windows 11; the Settings → Apps uninstall confirmation remains)
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-23 · **Change:** minor (gap 28: ⌘L Enable Filters switches the filter off and on; gap 28: F8 shows / hides the right panel; import review album hierarchy, #2362; gap 20: Minolta MRW decodes; gap 10: 551 models verified; gap 15: Print Page Options — page numbers, page info, crop marks; gap 15: Print Page Options — page numbers, page info, crop marks; gap 28: `\` shows / hides the Filter Bar in the grids; gap 21: Indonesian interface shipped, every message but What's New; gap 27: the Windows x64 installer verified on Windows 11; the Settings → Apps uninstall confirmation remains)
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
@@ -43,7 +43,8 @@ Hours are Opus 5.5 agent wall-clock hours (see [target-app-parity.md](target-app
| 26 | **Performance at scale**: 85k-photo library opens in 1.7–4.7 s; 100k grid test pending; colour NR at half resolution; at 100k photos stack and album lookups are indexed (an "In a Stack" or "Album" smart album counts in ~14 ms, was 0.6–2.7 s) | ROADMAP log, gpu-pipeline.md | large-catalog users | 15–30 | [target-app-parity](target-app-parity.md#by-dimension) |
| 27 | **Windows / Linux runtime coverage**: the Windows x64 installer is verified on Windows 11 (0.9.1: install and upgrade end on the completion page, a custom folder is kept, Launch works, removal is clean), but uninstalling from Settings → Apps ends with no confirmation (#892, #931); GPU path proven on Apple and on one AMD GPU on Linux (Radeon 8060S, Vulkan); NVIDIA, Intel and DX12 unverified; the Linux riscv64 tarball (new in 0.6.0, #844) is cross-compiled and never run beyond a QEMU smoke test | ROADMAP, issues, `release.yml` | non-Mac users find bugs first | 13–27 | [hardware-parity](hardware-parity.md) |
| 29 | **HDR merge leftovers** (LR-MERGE-HDR): AI Denoise doesn't run on merged (linear) DNGs; JPEG brackets are treated as linear (no camera response curve); every frame is held as 32-bit float, ~0.86 GB per 67 MP frame (half-float frames would halve it) | tested on Sony A7R VI brackets 2026-10-14 ([merge.md](merge.md)); Lightroom's Denoise supports HDR DNGs | HDR shooters who denoise their merges, merge JPEGs, or merge 7+ frames of high-resolution raws on 16 GB machines | 10–20 (+ denoise linear-RGB contract, gap 11) | [merge](merge.md) |
| 28 | **Small Classic shortcuts and keys**: ⌘L (Enable Filters), Tab / ⇧Tab (hide the side panels / all panels; Tab moves the keyboard focus here) and F5. Rating `[` `]`, flag cycling (`` ` ``), `\` (Filter Bar), F1 help, F6 / F7 / F8 (filmstrip, left panel, right panel) are bound | [ui-parity](ui-parity.md#shortcuts) | Classic muscle memory | 2–4 | [ui-parity](ui-parity.md) |
| 28 | **Small Classic shortcuts and keys**: Tab / ⇧Tab (hide the side panels / all panels; Tab moves the keyboard focus here) and F5. Rating `[` `]`, flag cycling (`` ` ``), `\` (Filter Bar), ⌘L (Enable Filters), F1 help, F6 / F7 / F8 (filmstrip, left panel, right panel) are bound | [ui-parity](ui-parity.md#shortcuts) | Classic muscle memory | 2–4 | [ui-parity](ui-parity.md) |
| 30 | **Multi-select metadata editing in the UI**: `photo.setMeta` already iterates all selected photos, so the engine applies changes to every target, but the Info panel and All Metadata dialog always show one photo's values with no "mixed" indication when selected photos differ — users cannot tell whether a field is uniform or mixed across the selection before editing | standard in Lightroom Classic's multi-select Info panel | anyone editing metadata on a batch (copyright, keywords, custom fields) | 4–8 | [ui-parity](ui-parity.md) |
Beta-blocking gaps (B) total **~230–430 h**; with the stability and platform work they need around them,
**~340–600 h** to beta (incl. 40–80 h for the ~92 open core-path user issues) (see [target-app-parity.md](target-app-parity.md#stage)).
@@ -51,7 +52,7 @@ Beta-blocking gaps (B) total **~230–430 h**; with the stability and platform w
## Gaps by kind
- **Feature:** 5, 8, 11, 12, 13, 15, 16, 18, 19, 29
- **UI / UX:** 4, 23, 24, 28
- **UI / UX:** 4, 23, 24, 28, 30
- **File format:** 2, 6, 7, 10, 13, 20, 25 (raw ones in [raw-parity.md](raw-parity.md))
- **Hardware:** 14, 17, 22, 27
- **Localization:** 21
@@ -60,6 +61,10 @@ Beta-blocking gaps (B) total **~230–430 h**; with the stability and platform w
## Closed recently (kept for calibration)
- 2026-10-22: saving XMP preserves foreign namespaces even when they use `lc:` or `xmp:` prefixes; importing them no longer interprets their properties as native settings or ratings. Parser, merge and save-command regressions cover the correction; no ranked gap or readiness estimate changes.
- 2026-10-22: PSD/PSB imports and metadata readers now expose embedded EXIF resource 1058 and XMP resource 1060 for capture dates, GPS and All Metadata (#2519); imported PSD edit copies retain their capture date, and the `removeLocation` Original-export guard sees embedded PSD/PSB GPS. No ranked gap or headline feature count closes.
- 2026-10-20: the import review album picker follows the sidebar folder hierarchy and searches album paths (#2362, LR-IMP-ADD-DIALOG), retaining None/New album and existing destination IDs. This closes a usability subgap; no ranked gap or headline feature count closes.
- 2026-10-12: original-pixel detail at 100% (gap 4, LR-VIEW-ZOOM, #323): soft proofing gets zoom windows like
@@ -79,6 +84,9 @@ Beta-blocking gaps (B) total **~230–430 h**; with the stability and platform w
| Date | Change | Summary |
|---|---|---|
| 2026-10-22 | patch | XMP namespace-prefix collisions no longer overwrite foreign metadata; ranked gaps and estimates unchanged |
| 2026-10-22 | patch | Issue #2519: PSD/PSB EXIF resource 1058 and XMP resource 1060 now use the common metadata extractor, and `.psb` files are accepted by import; no ranked gap or readiness count changes |
| 2026-10-22 | minor | Gap 30 added: multi-select metadata editing — Info panel and All Metadata dialog show one photo's values with no mixed-value indication |
| 2026-10-21 | minor | Gap 28 shrinks: F8 shows / hides the right panel (`view.rightPanel`); rating `[` `]`, flag cycling and F1 help were already bound, so the entry lists only filter-bar keys, Tab / ⇧Tab and F5; 2–4 h (was 4–8) |
| 2026-10-20 | minor | #2362: import destination albums use the shared hierarchy/search picker instead of a flat name list; existing import workflows retained; ranked gaps/readiness counts unchanged |
| 2026-10-19 | minor | Gap 21: Indonesian (`id`) shipped with every catalog message but What's New; four new languages left (Hindi, Arabic, Korean, Vietnamese), 135–239 h |
@@ -86,6 +94,7 @@ Beta-blocking gaps (B) total **~230–430 h**; with the stability and platform w
| 2026-10-18 | patch | Gap 1: six X-Trans CMOS 4 Fujifilm bodies (X-T30 …) take the X-T3's spectral matrices instead of the neutral matrix |
| 2026-10-15 | minor | Gap 15 shrinks: the Page panel's Page Options (Page Numbers, Page Info, Crop Marks) print on Single Image and Contact Sheet pages; identity plate, watermark, photo info, Cut Guides, direct printing and JPEG output remain |
| 2026-10-12 | minor | Gap 10: SR2/SRF folder discovery fixed; F828 imports as preview-only. Sensor decoding remains a gap; readiness scores unchanged |
| 2026-10-23 | minor | Gap 28: ⌘L / Ctrl+L (Library ▸ Enable Filters) puts the filter aside and brings it back as it was; the entry drops ⌘L; hours unchanged |
| 2026-10-15 | minor | Gap 28: `\` shows / hides the Filter Bar in the grids; the entry drops `[` `]` (#509), flag cycling (#1490) and F1 (Help), already on main; ⌘L is the filter-bar key left; hours unchanged |
| 2026-10-14 | minor | Gap 26: at 100k photos stack and album lookups are indexed, so an "In a Stack" or "Album" smart album counts in ~14 ms (was 0.6–2.7 s); open time unchanged |
| 2026-10-14 | minor | Gap 10: Camera-coverage sweep (#1327): 30 models verified on 40 CC0 files (coverage.py 515 → 545 verified); sensor verification does not establish colour parity (#1277) |
+3 -3
View File
@@ -229,7 +229,7 @@ passes on as `RenderResult::gpu_fallback`; an export carries it as `Exported::gp
each file of an `app.export` batch result has `gpuFallback` when its render fell back (issue #675).
**Reproducing a smaller GPU:** `LIGHTCRAFT_GPU_LIMITS=webgpu` (or `downlevel`) creates the device
with 128 MiB storage bindings / 256 MiB buffers, `LIGHTCRAFT_GPU_LIMITS=<n>` with n MiB / 2n MiB.
Tests inject failures with `lightcraft_gpu::inject_fault` (`crates/gpu/tests/fallback.rs`,
Tests inject failures with `lightcraft_gpu::inject_fault` (`crates/gpu/tests/it/fallback.rs`,
`export_falls_back_to_the_cpu_when_gpu_work_is_lost`). The fault is thread-local, and so are its
consequences: a simulated fatal failure stops GPU use on the injecting thread only (`available()`
false, `unavailable_reason()` set there), until `reset_failures()`, which undoes nothing else — a
@@ -237,7 +237,7 @@ real failure still stops the whole process. Such a test asserts on its own rende
`last_fallback()`, so it can run beside other tests rendering on the GPU (issue #675).
## Correctness: CPU oracle and equivalence tests
`crates/gpu/tests/equivalence.rs` renders the same settings on both and compares 8-bit sRGB:
`crates/gpu/tests/it/equivalence.rs` renders the same settings on both and compares 8-bit sRGB:
bounds **mean |Δ| < 0.5 LSB and max |Δ| ≤ 3 LSB** per channel. Measured (Apple M4 Pro, Metal):
**max 1 LSB, mean ≤ 0.0003 LSB** for every case — 26 settings cases (all tone/colour/effects tools,
3 vignette styles, grain, curves, grading, B&W, WB, NR, crop/straighten/flip, lens + perspective,
@@ -254,7 +254,7 @@ cut back after the readback. The tests skip (pass with a note) when no adapter e
non-Apple GPU verified: all 16 tests pass, 135 compared cases. 124 differ by max 1 LSB, 10 are
bit-identical, and one (the point colour range overlay) has max 2 LSB on 0.0002% of pixels. Worst
mean 0.0003 LSB. That is the same picture as on Metal, inside the bounds
(`cargo test -p lightcraft-gpu --release --test equivalence -- --nocapture`).
(`cargo test -p lightcraft-gpu --release --test it equivalence:: -- --nocapture`).
Remaining differences come from f32 vs f64 coordinate math, fast-math transcendental functions on
Metal and summation order in the box filters — all far below one 8-bit step.
+1
View File
@@ -17,6 +17,7 @@ Select photos in Photo Grid or Square Grid, then use:
| `Cmd`/`Ctrl` + `↑` / `↓` | Raise / lower flag status (reject < unflagged < pick; stops at either end) |
| `Shift` + `0`–`9`, `P`, `X` or `U` | Apply the action and select the next photo |
| `\` (backslash) | Show / hide the Filter Bar |
| ⌘L / Ctrl+L | Enable Filters: switch the filter off and on |
Enter opens the active photo without changing the selection. Text fields, dialogs and open popups keep the key; a custom Enter binding takes precedence. Enter has no additional action in Detail.
+3 -2
View File
@@ -46,8 +46,9 @@ ani anglické zdrojové řetězce. Rozložení panelů a seznamu jazyků je beze
## Ověření a revize
Testy `i18n::tests` ověřují registraci příkazu, přepínání přes nabídku a řídicí kanál,
uložení jazyka, pokrytí katalogů, placeholdery, neutrální formulace počtů, datum, čas
a české glyfy. Překladové šablony kontroluje také Rust při sestavení.
uložení jazyka, placeholdery, datum, čas a české glyfy. Překladové šablony kontroluje také
Rust při sestavení. Chybějící překlady se zobrazují anglicky a vypisuje je
`i18n::tests::translation_gaps_report`; žádný test kvůli nim neselže.
Při jazykové korektuře doporučujeme zkontrolovat „asistované třídění“, „sada“ pro Stack,
„bodová barva“, „měkký nátisk“ a názvy kreativních přednastavení.
+3 -3
View File
@@ -29,8 +29,8 @@ cargo test -p lightcraft-ui-egui i18n::tests
LIGHTCRAFT_LANGUAGE=de lightcraft-cli snapshot --demo -o deutsch.png --size 1600x1000
```
Die Tests prüfen Katalogabdeckung, Platzhalter, Sprachwechsel per Menü und Steuerkanal,
Speicherung, Datumsformate, unveränderte Benutzernamen und gerenderte Texte sowie Umlaute
und ß. Ein weiterer Render-Test prüft die Schaltflächenbreiten; der Importtest prüft
Die Tests prüfen Platzhalter, Sprachwechsel per Menü und Steuerkanal, Speicherung,
Datumsformate, unveränderte Benutzernamen und gerenderte Texte sowie Umlaute und ß. Fehlende
Übersetzungen erscheinen auf Englisch; `i18n::tests::translation_gaps_report` listet sie auf. Ein weiterer Render-Test prüft die Schaltflächenbreiten; der Importtest prüft
auch den Sprachwechsel nach der Hintergrundprüfung der Quellen. Akzeptierte Sprachangaben umfassen `de`, `de-DE`, `de_AT.UTF-8` und `de-CH`;
gespeichert wird stets `de`. Weitere Hinweise stehen in [localization.md](localization.md).
+3 -2
View File
@@ -52,8 +52,9 @@ englanniksi. Käännös ei muuta kirjastotietoja eikä englanninkielisiä lähde
## Testaus
`i18n::tests` tarkistaa komennon rekisteröinnin, vaihdon valikosta ja ohjauskanavasta,
kielen tallennuksen, luetteloiden kattavuuden, paikkamerkit, määrämuodot, päivämäärän, ajan ja
suomen kirjaimet. Rust tarkistaa muotoilumallit käännösvaiheessa.
kielen tallennuksen, paikkamerkit, päivämäärän, ajan ja suomen kirjaimet. Rust tarkistaa
muotoilumallit käännösvaiheessa. Puuttuvat käännökset näkyvät englanniksi, ja
`i18n::tests::translation_gaps_report` luettelee ne; mikään testi ei epäonnistu niiden takia.
Kielentarkistuksessa kannattaa katsoa erityisesti: ”Väriluokittelu” (Color Grading),
”Valoalueet / Valkoiset” (Highlights / Whites), ”Näyttövedos” (Soft Proofing),
+4 -4
View File
@@ -19,7 +19,7 @@ not translated. Descriptions for SAM 3 go to the model unchanged.
## Georgian script
Mkhedruli has no upper and lower case: `i18n::upper_first` leaves Georgian letters alone, and the
interface never uses Mtavruli (a test checks the whole catalog). Commands are verbal nouns. Counts
interface never uses Mtavruli. Commands are verbal nouns. Counts
are count-neutral, noun first (`იმპორტირებულია ფოტო: 3`); English plural endings are dropped with
`{:.0}`. Dates read `კვირა, 20.09.2026` (`{weekday}, {day:02}.{month:02}.{year}`), months `09.2026`.
@@ -73,7 +73,7 @@ cargo test -p lightcraft-ui-egui i18n::tests -- --nocapture
LIGHTCRAFT_LANGUAGE=ka lightcraft-cli snapshot --demo -o georgian.png --size 1600x1000
```
The tests check catalog coverage, placeholders, switching language by menu and control channel,
saving, the `ka` locale tags, dates, count wording, the absence of Mtavruli and that sentence case
keeps Georgian lowercase. More notes are in
The tests check placeholders, switching language by menu and control channel, saving, the `ka`
locale tags, dates and that sentence case keeps Georgian lowercase. Messages Georgian lacks show in
English; `i18n::tests::translation_gaps_report` lists them. More notes are in
[localization.md](localization.md).
+3 -2
View File
@@ -66,8 +66,9 @@ LIGHTCRAFT_LANGUAGE=vi lightcraft-cli snapshot --demo -o vi.png --size 1600x1000
LIGHTCRAFT_LANGUAGE=vi lightcraft-cli snapshot --demo -o vi-narrow.png --size 1280x800
```
Các test tiếng Việt bắt buộc phủ catalog union, nhãn lệnh/control/Settings/Smart Album,
đổi ngôn ngữ, lưu `vi`, formats, ngày, dữ liệu người dùng, và glyph dấu.
Các test tiếng Việt kiểm tra đổi ngôn ngữ, lưu `vi`, formats, ngày, dữ liệu người dùng và glyph
dấu. Chuỗi còn thiếu hiện bằng tiếng Anh và được `i18n::tests::translation_gaps_report` liệt kê;
không test nào thất bại vì thiếu bản dịch.
## Nguồn dịch (clean-room)
+2 -1
View File
@@ -34,5 +34,6 @@ LightCraft 的界面支持英语、简体中文、繁体中文(台湾)和日
`LIGHTCRAFT_LANGUAGE=zh-hans lightcraft-cli snapshot ...` 可以渲染中文界面用于检查。
翻译是否完整、两种目录的键与占位符是否一致、字形是否齐全,都由
两种目录的占位符是否一致、字形是否齐全,由
`cargo test -p lightcraft-ui-egui i18n::tests` 验证(字形检查只在指定 `CRAFT_FONTS_DIR` 时实际执行)。
缺少的译文显示为英文,由 `i18n::tests::translation_gaps_report` 列出,不会让测试失败。
+16 -12
View File
@@ -12,11 +12,10 @@ are in [`localization-zh-hans.md`](localization-zh-hans.md), [`localization-zh-h
1. **Translate the two catalogs.** Copy `locales/ja.json` and `locales/ja-formats.json` to
`locales/<code>.json` and `locales/<code>-formats.json`, then translate the values. Keys are the
English source strings and must stay byte-for-byte identical. The plain catalog may grow at its
own pace: a message it lacks shows in English, and `cargo test -p lightcraft-ui-egui i18n::tests
-- --nocapture` lists the gaps (it fails on an empty entry or mismatched placeholders). The
formats catalog must carry every message (the build fails otherwise; a message copied in English,
value equal to its key, is an untranslated placeholder until someone translates it), including the date
English source strings and must stay byte-for-byte identical. Both catalogs may grow at their
own pace: a message a catalog lacks, or translates as an empty string, shows in English, and
nothing fails. The translation gaps report lists what each language lacks (see
[Testing and looking at it](#testing-and-looking-at-it)). The formats catalog also holds the date
patterns (`{year}`, `{month} {year}`, `{weekday}, {day} {month} {year}`…) that date headings and
capture times use in every language but English; weekday names go in the plain catalog.
2. **Add the table entry** in `crates/ui-egui/src/i18n.rs`:
@@ -81,18 +80,23 @@ tr_format!("Added {n} photo{} to “{}”", if n == 1 { "" } else { "s" }, album
`"已将 {n} 张照片添加到“{1}”{0:.0}"`. Keep the source's spec (`{:.1}`, `{d:+}`, `{:.0}%`).
- `format!` rejects an unused argument, so a value a language does not need — the English plural
suffix (`"s"` / `""`) — is consumed as `{:.0}` (a string at precision 0 prints nothing).
- Every formats catalog carries the same messages (`build.rs` fails the build otherwise), and a
`tr_format!` call whose message is in no catalog does not compile: add it to every
`*-formats.json` file.
- A language whose formats catalog lacks a message shows the English source there, and a
`tr_format!` call whose message is in no catalog formats the English source (the macro's last
arm). A new message builds with no catalog entry.
## Testing and looking at it
```sh
cargo test -p lightcraft-ui-egui i18n::tests # catalogs, keys, placeholders, commands
cargo test -p lightcraft-ui-egui i18n::tests # catalogs load, placeholders, switching
CRAFT_FONTS_DIR=../craft-fonts cargo test -p lightcraft-ui-egui i18n::tests # + glyph coverage
cargo test -p lightcraft-ui-egui --lib -- --exact i18n::tests::translation_gaps_report --nocapture
```
The glyph tests are skipped without `CRAFT_FONTS_DIR` (there are no CJK faces to check then).
The tests fail on a broken catalog (malformed JSON, a repeated key, placeholders that differ from
the source), never on a missing translation. The last command is the translation gaps report: per
language, the count and list of plain and format messages it lacks and the number of untranslated
What's New lines. It always passes, and `cargo xtask ci` prints it after its test step. The glyph
tests are skipped without `CRAFT_FONTS_DIR` (there are no CJK faces to check then).
To look at a language, render it headless:
```sh
@@ -114,5 +118,5 @@ when a region has no dedicated entry.
Help ▸ What's New shows `docs/whats-new.md`, and each of its lines (a heading, or one wrapped line of a
bullet, without the `- ` or `### `) is looked up like any message, so a catalog can translate the notes
line by line (German does). A line that is re-wrapped or edited no longer matches its translation and
shows in English until the catalog is updated; untranslated lines are reported by
`display_label_gaps_are_reported`, never failed.
shows in English until the catalog is updated; the translation gaps report counts the untranslated
lines.
+2 -2
View File
@@ -316,10 +316,10 @@ lightcraft-cli calibrate --max 300 ~/Pictures/2026 # camera colour profiles (d
## Tests
- `crates/mcp/tests/e2e.rs` — M0.9 acceptance: over the stdio framing, set exposure and render;
- `crates/mcp/tests/it/e2e.rs` — M0.9 acceptance: over the stdio framing, set exposure and render;
checks the decoded PNG gets brighter/darker. Runs headless and through the TCP transport
(`Remote`) against a stand-in control server; also import → render → JPEG export of a real file.
- `apps/lightcraft-cli/tests/cli.rs` — spawns `lightcraft-cli mcp` with real pipes; `render`;
- `apps/lightcraft-cli/tests/it/cli.rs` — spawns `lightcraft-cli mcp` with real pipes; `render`;
`commands`.
## Add to Apple Photos (macOS)
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -46,11 +46,11 @@ unsupported to preview-only in the counts; sensor-decoding readiness is unchange
version. The year a model was added is approximated from that Camera Raw major version.
- **What we decode**: the decoders and their refusals in `crates/raw/src` (`lib.rs` routing, `vendor/*.rs`
coding variants, `crx.rs` CRX limits, `orf.rs` / `srw.rs` compressed refusals), the import list
`lightcraft_engine::import::EXTENSIONS`, and `KNOWN_UNSUPPORTED` in `crates/raw/tests/corpus.rs`. Doc
`lightcraft_engine::import::EXTENSIONS`, and `KNOWN_UNSUPPORTED` in `crates/raw/tests/it/corpus.rs`. Doc
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`, 105 CC0 files; bodies whose sample is in
`KNOWN_UNSUPPORTED` excluded), `crates/raw/tests/cr3_corpus.rs` (3 bodies exact against an external decoder;
`KNOWN_UNSUPPORTED` excluded), `crates/raw/tests/it/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; 22 more bodies pinned on one CC0
file each and checked against the camera JPEG, [cr3.md](cr3.md#further-bodies-one-cc0-file-each)), the RAF reference
check ([raf-compression.md](raf-compression.md)), and the raw.pixls.us bulk checks recorded in issue
@@ -64,7 +64,7 @@ unsupported to preview-only in the counts; sensor-decoding readiness is unchange
decoded on main `25ef65c8`; [raw/coverage-sweep.tsv](raw/coverage-sweep.tsv) records the URLs,
SHA-256, dimensions, FNV-1a sensor hashes and render/reference luminance correlations (0.6801
to 0.9998). The hashes pin LightCraft's own output. The regression test is
`crates/raw/tests/coverage_sweep_corpus.rs`; downloads are in `RAW_SAMPLES`. Ten references are
`crates/raw/tests/it/coverage_sweep_corpus.rs`; downloads are in `RAW_SAMPLES`. Ten references are
embedded TIFF images; the rest are JPEGs. FFF TIFF previews are not display-ready and check
image structure only. Eleven candidate models were excluded for identity, provenance or
missing/mismatched reference images. D6 / Z 6 / Z 7 verification covers compressed NEF only;
+3 -3
View File
@@ -144,15 +144,15 @@ use the largest JPEG, so their geometry and colour do not depend on the size lev
sRGB stays on the fast path. A synthetic DNG with a full-size and a half-size JPEG gets, on the plan
path, the half-size one for a box it covers and the full-size one otherwise, with the same pixels as
the whole-file path (`preview_loading_plans_the_smallest_covering_jpeg`).
- `crates/raw/tests/sparse_corpus.rs`: `preview_plan` is asked for **every** corpus file, not only
- `crates/raw/tests/it/sparse_corpus.rs`: `preview_plan` is asked for **every** corpus file, not only
the ones whose header plan is `Ready`, and the preview it yields must equal the whole file's with
the skipped bytes `0` and `0xFF`. The test prints what each format reads.
- `crates/engine/tests/preview_read.rs` (opt-in, `#[ignore]`): the same measurement on a **real**
- `crates/engine/tests/it/preview_read.rs` (opt-in, `#[ignore]`): the same measurement on a **real**
file, typically on a share:
```sh
LC_PREVIEW_RAW="/mnt/nas/…/DSCF0001.RAF" \
cargo test --release -p lightcraft-engine --test preview_read -- --ignored --nocapture
cargo test --release -p lightcraft-engine --test it preview_read:: -- --ignored --nocapture
```
No raw fixture is committed (media never is, see `AGENTS.md`).
+2 -2
View File
@@ -29,7 +29,7 @@ HERE = os.path.dirname(os.path.abspath(__file__))
# Olympus ORF bodies that write uncompressed / packed data (crates/raw/src/vendor/orf.rs). Everything else
# writes compressed ORF, which is preview-only (the E-M5 II / PEN-F high-res mode alone is decoded).
ORF_DECODED = re.compile(r"^(E-1|E-10|E-20|EVOLT E-300|EVOLT E-330|EVOLT E-400|EVOLT E-500|E-300|E-330|E-500|Camedia C-\S+.*|Stylus XZ-2 iHS)$")
ORF_DECODED = re.compile(r"^(E-1|E-10|E-20|EVOLT E-300|EVOLT E-330|EVOLT E-400|EVOLT E-500|E-300|E-330|E-500|Camedia C-\S.*|Stylus XZ-2 iHS)$")
# Samsung SRW bodies with compressed raw data (crates/raw/src/vendor/srw.rs refuses 32770 / 32772 / 32773).
SRW_COMPRESSED = re.compile(r"(^|\W)(NX1|NX30|NX300|NX300M|NX500|NX2000|NX3000|NX3300|NX mini|EK-GN\d+|EK-KN\d+)(\W|$)")
# Fujifilm bodies before the X series whose RAF has no raw IFD (crates/raw/src/vendor/raf.rs).
@@ -123,7 +123,7 @@ def main():
classes = ["verified", "unverified", "preview", "unsupported"]
by_maker = {}
for r in rows:
by_maker.setdefault(r["maker"], {c: 0 for c in classes})[r["class"]] += 1
by_maker.setdefault(r["maker"], dict.fromkeys(classes, 0))[r["class"]] += 1
print("| Maker | Adobe models | verified | unverified | preview | unsupported |")
print("|---|---:|---:|---:|---:|---:|")
for m, c in sorted(by_maker.items(), key=lambda kv: -sum(kv[1].values())):
+354 -354
View File
File diff suppressed because it is too large Load Diff
+354 -354
View File
@@ -1,119 +1,119 @@
# Per-model evidence that overrides the format rules in coverage.py. status: verified | preview | unsupported.
# "verified" means a real file from this body decoded from sensor data in a corpus test or a recorded bulk check (source column).
maker camera status source
Apple iPhone 12 Pro Rear Wide Camera verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 40D verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 550D (EOS Digital Rebel T2i, EOS Kiss X4 Digital) verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 5D Mark II verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 5DS R verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 6D verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
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-1D X Mark III verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS 90D verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS 250D (EOS Rebel SL3, EOS 200D II, EOS Kiss X10) verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS 850D (EOS Kiss X10i, EOS Rebel T8i) verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS M200 verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS M50 Mark II verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS M6 Mark II verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R (** see note) verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R3 verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R5 verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R6 verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R6 Mark II verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md; C-RAW with adaptive QP above 168 still opens as the preview)
Canon EOS R6 Mark III verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R7 verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md; lossless only, C-RAW unverified)
Canon EOS R10 verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS RP verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R50 verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R50 V verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon PowerShot G5 X Mark II verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon PowerShot G7 X Mark III verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon PowerShot SX70 HS verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon PowerShot V1 verified corpus: crates/raw/tests/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS-5D Mark III verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 70D verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 800D (EOS Digital Rebel T7i, EOS Kiss X9i) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G9X verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 3000D (EOS Rebel T100, EOS 4000D) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 1000D (EOS Digital Rebel XS, EOS Kiss F) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G1 X Mark II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 500D (EOS Digital Rebel T1i, EOS Kiss X3 Digital) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 400D (EOS Digital Rebel XTi, EOS Kiss Digital X) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot S110 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 1300D (EOS Digital Rebel T6, EOS Kiss X80) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 600D (EOS Digital Rebel T3i, EOS Kiss X5 Digital) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G1 X verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G16 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G3 X verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS-1D X Mark II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 750D (EOS Digital Rebel T6i, EOS Kiss X8i) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 5DS verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot S100V verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 350D (EOS Digital Rebel XT, EOS Kiss Digital N) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 1200D (EOS Digital Rebel T5, EOS Kiss X70) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G11 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 100D (EOS Digital Rebel SL1, EOS Kiss X7) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G15 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS-1D Mark IV verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M5 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot S100 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 650D (EOS Digital Rebel T4i, EOS Kiss X4i) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot SX50 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M2 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M3 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G12 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 6D Mark II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M10 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 700D (EOS Digital Rebel T5i, EOS Kiss X7i) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 1100D (EOS Digital Rebel T3, EOS Kiss X50 Digital) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 77D (EOS 9000D) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 1500D (EOS Rebel T7, EOS Kiss X90, EOS 2000D) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS-5D Mark IV (** see note) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS-1D Mark III verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 60D verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS-1D Mark II N verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M100 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G5 X verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G9 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 5D verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M6 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G7 X Mark II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 7D Mark II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot S120 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot S95 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G1 X Mark III verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 50D verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 20D verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G7 X verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 450D (EOS Digital Rebel XSi, EOS Kiss Digital X2) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot SX60 HS verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 200D (EOS Kiss X9, EOS Rebel SL2) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G9 X Mark II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 760D (EOS Digital Rebel T6s, EOS Kiss 8000D) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 30D verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm GFX 100 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm GFX 100RF (Final Support) verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm GFX 100S verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm GFX 50S verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-A2 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-A5 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-E1 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-E5 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-H2 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Apple iPhone 12 Pro Rear Wide Camera verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 40D verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 550D (EOS Digital Rebel T2i, EOS Kiss X4 Digital) verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 5D Mark II verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 5DS R verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 6D verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 7D verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 80D verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Canon EOS M50 (EOS Kiss M) verified corpus: crates/raw/tests/it/cr3_corpus.rs (exact sensor hashes, docs/cr3.md)
Canon EOS R100 verified corpus: crates/raw/tests/it/cr3_corpus.rs (exact sensor hashes, docs/cr3.md)
Canon EOS R5 Mark II verified corpus: crates/raw/tests/it/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/it/cr3_corpus.rs (exact sensor hashes, docs/cr3.md)
Canon EOS-1D X Mark III verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS 90D verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS 250D (EOS Rebel SL3, EOS 200D II, EOS Kiss X10) verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS 850D (EOS Kiss X10i, EOS Rebel T8i) verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS M200 verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS M50 Mark II verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS M6 Mark II verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R (** see note) verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R3 verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R5 verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R6 verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R6 Mark II verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md; C-RAW with adaptive QP above 168 still opens as the preview)
Canon EOS R6 Mark III verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R7 verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md; lossless only, C-RAW unverified)
Canon EOS R10 verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS RP verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R50 verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS R50 V verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon PowerShot G5 X Mark II verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon PowerShot G7 X Mark III verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon PowerShot SX70 HS verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon PowerShot V1 verified corpus: crates/raw/tests/it/cr3_corpus.rs (pinned sensor hash, camera-JPEG check, docs/cr3.md)
Canon EOS-5D Mark III verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Canon EOS 70D verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 800D (EOS Digital Rebel T7i, EOS Kiss X9i) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G9X verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 3000D (EOS Rebel T100, EOS 4000D) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 1000D (EOS Digital Rebel XS, EOS Kiss F) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G1 X Mark II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 500D (EOS Digital Rebel T1i, EOS Kiss X3 Digital) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 400D (EOS Digital Rebel XTi, EOS Kiss Digital X) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot S110 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 1300D (EOS Digital Rebel T6, EOS Kiss X80) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 600D (EOS Digital Rebel T3i, EOS Kiss X5 Digital) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G1 X verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G16 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G3 X verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS-1D X Mark II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 750D (EOS Digital Rebel T6i, EOS Kiss X8i) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 5DS verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot S100V verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 350D (EOS Digital Rebel XT, EOS Kiss Digital N) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 1200D (EOS Digital Rebel T5, EOS Kiss X70) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G11 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 100D (EOS Digital Rebel SL1, EOS Kiss X7) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G15 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS-1D Mark IV verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M5 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot S100 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 650D (EOS Digital Rebel T4i, EOS Kiss X4i) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot SX50 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M2 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M3 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G12 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 6D Mark II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M10 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 700D (EOS Digital Rebel T5i, EOS Kiss X7i) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 1100D (EOS Digital Rebel T3, EOS Kiss X50 Digital) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 77D (EOS 9000D) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 1500D (EOS Rebel T7, EOS Kiss X90, EOS 2000D) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS-5D Mark IV (** see note) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS-1D Mark III verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 60D verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS-1D Mark II N verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M100 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G5 X verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G9 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 5D verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS M6 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G7 X Mark II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 7D Mark II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot S120 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot S95 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G1 X Mark III verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 50D verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 20D verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G7 X verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 450D (EOS Digital Rebel XSi, EOS Kiss Digital X2) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot SX60 HS verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 200D (EOS Kiss X9, EOS Rebel SL2) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon PowerShot G9 X Mark II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 760D (EOS Digital Rebel T6s, EOS Kiss 8000D) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Canon EOS 30D verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm GFX 100 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm GFX 100RF (Final Support) verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm GFX 100S verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm GFX 50S verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-A2 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-A5 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-E1 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-E5 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-H2 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-H2S verified docs/raf-compression.md (supplied files, exact sensor arrays)
Fujifilm X-M5 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-T2 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-T20 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-T4** verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-T5 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-T50 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Google Pixel 2 XL verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-M5 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-T2 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-T20 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-T4** verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-T5 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Fujifilm X-T50 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Google Pixel 2 XL verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Hasselblad Lunar verified issue #1275: raw.pixls.us 4051 (a Sony NEX-7 ARW under Make HASSELBLAD) decodes from sensor data; black 512 and SR2SubIFD WB as on a NEX-7
Leica C (Typ 112) verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format
Leica D-Lux (Typ 109) verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format
@@ -129,147 +129,147 @@ Leica V-LUX (Typ 114) verified PR #215: 178 raw.pixls.us files from 118 Panasoni
Leica V-LUX 1 verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format
Leica V-LUX 4 verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format
Leica V-LUX 5 verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format
Leica M Monochrom verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash)
Leica CL verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica M10 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica C-Lux verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica M Monochrom (Typ 246) verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash)
Leica M8 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash)
Leica X2 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica Q2 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica SL (Typ 601) verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica M10-R verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica SL2 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica M9 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash)
Leica Q (Typ 116) verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon COOLPIX B700 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Nikon D5100 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Nikon D7000 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Nikon D7500 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Nikon Z f verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Nikon D700 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm XF10 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-A10 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D5300 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T100 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-Pro1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 V1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 J4 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm GFX 100S II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D610 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D5 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D2H verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 6 II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon COOLPIX P1000 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix X100 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X30 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix X10 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D2Xs verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D4 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D800 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D780 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D850 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-E2S verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D500 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm GFX 50R verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Df verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-S10 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 V2 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 V3 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3s verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z fc verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D810 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-A3 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D40 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D800E verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3X verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X100V** verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D4S verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T30 III verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm XQ2 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T10 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D2X verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X70 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D80 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-H1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 J5 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 J1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D7200 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T30 II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 50 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D5000 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm XQ1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix HS30 EXR verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D70S verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D5200 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon COOLPIX P1100 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-S20 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 30 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-E2 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D60 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 J2 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D5600 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D300 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix SL1000 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-Pro3** verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-Pro2 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 S1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X100VI verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T200 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3200 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T3 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix F550 EXR verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D5500 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-A7 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3300 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 5 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 J3 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 9 (*See note) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon COOLPIX A1000 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X100S verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D2Hs verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D90 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D50 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3000 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X100T verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 50 II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D600 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm XF1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D7100 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-E3 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-A1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3500 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix HS50 EXR verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm GFX 100 II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X100F verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D40x verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon COOLPIX A verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X20 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-E4 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm GFX 50S II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D1H verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D200 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix HS33 EXR verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix S1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 7 II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D70 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D300s verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix X-S1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D750 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3100 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3400 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix X-M1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T30 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon COOLPIX P950 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix F770 EXR verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica M Monochrom verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash)
Leica CL verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica M10 verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica C-Lux verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica M Monochrom (Typ 246) verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash)
Leica M8 verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash)
Leica X2 verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica Q2 verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica SL (Typ 601) verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica M10-R verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica SL2 verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Leica M9 verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash)
Leica Q (Typ 116) verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon COOLPIX B700 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Nikon D5100 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Nikon D7000 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Nikon D7500 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Nikon Z f verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Nikon D700 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm XF10 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-A10 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D5300 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T100 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-Pro1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 V1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 J4 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm GFX 100S II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D610 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D5 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D2H verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 6 II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon COOLPIX P1000 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix X100 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X30 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix X10 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D2Xs verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D4 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D800 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D780 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D850 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-E2S verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D500 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm GFX 50R verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Df verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-S10 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 V2 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 V3 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3s verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z fc verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D810 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-A3 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D40 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D800E verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3X verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X100V** verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D4S verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T30 III verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm XQ2 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T10 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D2X verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X70 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D80 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-H1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 J5 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 J1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D7200 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T30 II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 50 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D5000 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm XQ1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix HS30 EXR verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D70S verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D5200 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon COOLPIX P1100 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-S20 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 30 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-E2 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D60 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 J2 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D5600 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D300 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix SL1000 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-Pro3** verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-Pro2 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 S1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X100VI verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T200 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3200 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T3 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix F550 EXR verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D5500 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-A7 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3300 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 5 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon 1 J3 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 9 (*See note) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon COOLPIX A1000 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X100S verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D2Hs verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D90 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D50 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3000 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X100T verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 50 II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D600 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm XF1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D7100 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-E3 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-A1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3500 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix HS50 EXR verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm GFX 100 II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X100F verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D40x verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon COOLPIX A verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X20 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-E4 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm GFX 50S II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D1H verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D200 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix HS33 EXR verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix S1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon Z 7 II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D70 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D300s verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix X-S1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D750 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3100 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon D3400 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix X-M1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm X-T30 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon COOLPIX P950 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Fujifilm FinePix F770 EXR verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Nikon COOLPIX 5700 unsupported bulk: raw.pixls.us CC0 file decodes wrongly (two stacked half-height fields, CMYG mosaic read as RGB; green vs camera JPEG r 0.12-0.36)
Nikon COOLPIX 8400 unsupported bulk: raw.pixls.us CC0 file decodes wrongly (two stacked half-height fields, CMYG mosaic read as RGB; green vs camera JPEG r 0.12-0.36)
Nikon COOLPIX 8800 unsupported bulk: raw.pixls.us CC0 file decodes wrongly (two stacked half-height fields, CMYG mosaic read as RGB; green vs camera JPEG r 0.12-0.36)
Olympus E-1 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Olympus EVOLT E-400 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Olympus Stylus XZ-2 iHS verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Olympus E-1 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Olympus EVOLT E-400 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Olympus Stylus XZ-2 iHS verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Panasonic LUMIX DC - G97 (DC-G99M2) verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format
Panasonic LUMIX DC-FZ1000M2 (DC-FZ10002) verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format
Panasonic LUMIX DC-FZ80 (DC-FZ82, DC-FZ85) verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format
@@ -363,47 +363,47 @@ Panasonic LUMIX DMC-ZS40 (DMC-TZ60, DMC-TZ61) verified PR #215: 178 raw.pixls.us
Panasonic LUMIX DMC-ZS50 (DMC-TZ70, DMC-TZ71) verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format
Panasonic LUMIX DMC-ZS60 (DMC-TZ80, DMC-TZ81, DMC-TZ85) verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format
Panasonic LUMIX ZS200 (DC-TX2, DC-TZ200, DC-TZ202, DC-TZ220, DC-ZS220) verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format
Pentax K-3 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Pentax K-5 IIs verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Pentax K10D verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Ricoh GR III verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Pentax K-1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax *ist DL verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Ricoh GX200 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash)
Pentax KP verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-3 Mark III Monochrome verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash)
Pentax K-70 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Ricoh GR IIIx verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K20D verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax *ist DS verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-3 Mark III verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-01 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K110D verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax Q7 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-S1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax *ist D verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-30 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K200D verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-5 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-x verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Ricoh GR verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax 645D verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K100D verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-500 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K2000 K-m verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-50 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax 645Z verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-5 II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax Q verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax MX-1 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K100D Super verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Ricoh GR II verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-S2 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-r verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax KF verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-3 II († see note) verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-7 verified corpus: crates/raw/tests/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Samsung TL500 (EX1) verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Pentax K-3 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Pentax K-5 IIs verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Pentax K10D verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Ricoh GR III verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Pentax K-1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax *ist DL verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Ricoh GX200 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash)
Pentax KP verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-3 Mark III Monochrome verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash)
Pentax K-70 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Ricoh GR IIIx verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K20D verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax *ist DS verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-3 Mark III verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-01 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K110D verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax Q7 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-S1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax *ist D verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-30 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K200D verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-5 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-x verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Ricoh GR verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax 645D verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K100D verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-500 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K2000 K-m verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-50 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax 645Z verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-5 II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax Q verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax MX-1 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K100D Super verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Ricoh GR II verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-S2 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-r verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax KF verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-3 II († see note) verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Pentax K-7 verified corpus: crates/raw/tests/it/body_corpus.rs (pinned sensor hash, camera-JPEG check)
Samsung TL500 (EX1) verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Sony A100 (DSLR-A100) preview issue #702 fixed (#774): opens from its embedded JPEG; its raw (no CFA image IFD) is not decoded
Sony A200 (DSLR-A200) preview issue #535: preview-only on the raw.pixls.us sample
Sony A230 (DSLR-A230) preview issue #535: preview-only on the raw.pixls.us sample
@@ -502,70 +502,70 @@ Sony RX1R II (DSC-RX1RM2) verified issue #535: raw.pixls.us bulk check of all 10
Sony ZV-1 (DCZV1/B) verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool)
Sony ZV-E1 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool)
Sony ZV-E10 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool)
Sony ZV-1M2 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony ZV-E10M2 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony RX1R III (DSC-RX1RM3) verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony A1 II (ILCE-1M2) (** see note) verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony DSC-RX100M7A verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony A7 V (ILCE-7M5) (** see note) verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony FX2 (ILMEFX2) (** see note) verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony ILCE - 6400A verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus SP-550 UZ verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus E-10 verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash)
Olympus Camedia C-5060 Zoom verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus SP-565 UZ verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus OM-D E-M5 Mark II verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus EVOLT E-300 verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus Stylus SH-2 verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus Camedia C-7070 Wide Zoom verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus Stylus XZ-10 verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus EVOLT E-330 verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus SP-570 UZ verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus SP-510 UZ verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus PEN-F verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus EVOLT E-500 verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Samsung TL350 (WB2000) verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Samsung NX1000 verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Samsung NX1100 verified corpus: crates/raw/tests/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony ZV-1M2 verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony ZV-E10M2 verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony RX1R III (DSC-RX1RM3) verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony A1 II (ILCE-1M2) (** see note) verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony DSC-RX100M7A verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony A7 V (ILCE-7M5) (** see note) verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony FX2 (ILMEFX2) (** see note) verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony ILCE - 6400A verified corpus: crates/raw/tests/it/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus SP-550 UZ verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus E-10 verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash)
Olympus Camedia C-5060 Zoom verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus SP-565 UZ verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus OM-D E-M5 Mark II verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus EVOLT E-300 verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus Stylus SH-2 verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus Camedia C-7070 Wide Zoom verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus Stylus XZ-10 verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus EVOLT E-330 verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus SP-570 UZ verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus SP-510 UZ verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus PEN-F verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Olympus EVOLT E-500 verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Samsung TL350 (WB2000) verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Samsung NX1000 verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Samsung NX1100 verified corpus: crates/raw/tests/it/olympus_samsung_corpus.rs (pinned sensor hash, camera-JPEG check)
Sony A100 (DSLR-A100) unsupported issue #702: regression, refused as not a readable photo
Sony DSC-F828 preview 2026-10-12 release CLI: raw.pixls.us DSC06227.SRF imports as preview-only through recursive and direct import (docs/raw-parity.md)
Epson R-D1 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Epson R-D1s verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Epson R-D1x verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Mamiya ZD verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Apple iPhone 6s Plus verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Apple iPhone 7 Plus verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Apple iPhone XS verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
DJI DJI Mavic 2 Pro (Hasselblad L1D-20c) verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
DJI DJI Mavic 3 (Hasselblad L2D-20c) verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
DJI DJI Mavic 4 Pro (DJI FC9287) verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
DJI DJI Mini 2 verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Google Pixel 4 XL verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Google Pixel 4a Rear Wide Camera verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Google Pixel 6 Pro Rear Main Camera verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Google Pixel 8 Pro Wide Camera* verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Hasselblad CFV-50c verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); decode verified, not colour calibration
Hasselblad H5D-40 verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); decode verified, not colour calibration
Hasselblad H5D-50c verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); decode verified, not colour calibration
Hasselblad X1D verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); decode verified, not colour calibration
Hasselblad X1D II 50C verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); decode verified, not colour calibration
Hasselblad X2D 100C verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); decode verified, not colour calibration
Nikon D6 verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); checked compressed NEF only; uncompressed remains preview-only (#671)
Nikon Z 6 verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); checked compressed NEF only; uncompressed remains preview-only (#671)
Nikon Z 7 verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); checked compressed NEF only; uncompressed remains preview-only (#671)
Nikon Z 8 verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); HE / HE* remain preview-only
Parrot Anafi verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Samsung Galaxy S21 Ultra Rear Main Camera verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Samsung Galaxy S22 Ultra Rear Wide Camera verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Samsung Galaxy S23 Rear Wide Camera verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Samsung Galaxy S7 Edge verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Samsung Galaxy S8 verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Samsung Galaxy S8+ verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Sigma fp verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Sigma fp L verified corpus: crates/raw/tests/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Konica Minolta DiMAGE 7Hi verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Konica Minolta DiMAGE A1 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Konica Minolta DiMAGE A200 verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Konica Minolta Maxxum 7D Dynax 7D verified corpus: crates/raw/tests/corpus.rs (xtask RAW_SAMPLES)
Epson R-D1 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Epson R-D1s verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Epson R-D1x verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Mamiya ZD verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Apple iPhone 6s Plus verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Apple iPhone 7 Plus verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Apple iPhone XS verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
DJI DJI Mavic 2 Pro (Hasselblad L1D-20c) verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
DJI DJI Mavic 3 (Hasselblad L2D-20c) verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
DJI DJI Mavic 4 Pro (DJI FC9287) verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
DJI DJI Mini 2 verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Google Pixel 4 XL verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Google Pixel 4a Rear Wide Camera verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Google Pixel 6 Pro Rear Main Camera verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Google Pixel 8 Pro Wide Camera* verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Hasselblad CFV-50c verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); decode verified, not colour calibration
Hasselblad H5D-40 verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); decode verified, not colour calibration
Hasselblad H5D-50c verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); decode verified, not colour calibration
Hasselblad X1D verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); decode verified, not colour calibration
Hasselblad X1D II 50C verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); decode verified, not colour calibration
Hasselblad X2D 100C verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); decode verified, not colour calibration
Nikon D6 verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); checked compressed NEF only; uncompressed remains preview-only (#671)
Nikon Z 6 verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); checked compressed NEF only; uncompressed remains preview-only (#671)
Nikon Z 7 verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); checked compressed NEF only; uncompressed remains preview-only (#671)
Nikon Z 8 verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check); HE / HE* remain preview-only
Parrot Anafi verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Samsung Galaxy S21 Ultra Rear Main Camera verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Samsung Galaxy S22 Ultra Rear Wide Camera verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Samsung Galaxy S23 Rear Wide Camera verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Samsung Galaxy S7 Edge verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Samsung Galaxy S8 verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Samsung Galaxy S8+ verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Sigma fp verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Sigma fp L verified corpus: crates/raw/tests/it/coverage_sweep_corpus.rs (pinned sensor hashes); bulk: docs/raw/coverage-sweep.tsv (CC0, SHA-256, camera-image check)
Konica Minolta DiMAGE 7Hi verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Konica Minolta DiMAGE A1 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Konica Minolta DiMAGE A200 verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Konica Minolta Maxxum 7D Dynax 7D verified corpus: crates/raw/tests/it/corpus.rs (xtask RAW_SAMPLES)
Konica Minolta DiMAGE 7 verified raw.pixls.us check: CC0 sample decoded and its WB / CFA matched to the embedded preview (vendor/mrw.rs)
Konica Minolta DiMAGE A2 verified raw.pixls.us check: CC0 sample decoded and its WB / CFA matched to the embedded preview (vendor/mrw.rs)
Can't render this file because it contains an unexpected character in line 2 and column 3.
+2 -2
View File
@@ -181,7 +181,7 @@ profile correction control when an existing edit has it disabled.
## Local inventory check
`crates/raw/tests/sony_lens_inventory.rs` is opt-in and does nothing in CI. With `LIGHTCRAFT_SONY_LENS_DIR` naming a
`crates/raw/tests/it/sony_lens_inventory.rs` is opt-in and does nothing in CI. With `LIGHTCRAFT_SONY_LENS_DIR` naming a
directory of ARWs it decodes each from its headers and prints its record (settings, sources, copies' agreement,
sample ranges, statuses); `LIGHTCRAFT_SONY_LENS_FULL=1` also compares header and full decode. With
`LIGHTCRAFT_SONY_LENS_INVENTORY` naming a CSV inventory it checks every file's table counts, sizes, sample counts,
@@ -300,7 +300,7 @@ The current `cargo xtask corpus --download` manifest contains 25 Sony CC0 sample
including samples 4822 (A7R IVA / 24–105 mm) and 3989 (A9 II / 200–600 mm), each with a pinned SHA-256 that the
download checks. `sony_embedded_distortion_is_limited_to_validated_models` checks 23 of them (the two ILCE-7CM2
codings have their own test), and `sony_lens_records_of_the_public_samples` verifies all 25 against their pins
(`SONY_SAMPLES` in `crates/raw/tests/corpus.rs`, itself anchored by a pinned digest and compared with the manifest)
(`SONY_SAMPLES` in `crates/raw/tests/it/corpus.rs`, itself anchored by a pinned digest and compared with the manifest)
before decoding. **No CI job fetches the corpus**: these fixture tests run only where it has been downloaded, and
otherwise skip each absent file. `LIGHTCRAFT_CORPUS_REQUIRED=1` makes `sony_lens_records_of_the_public_samples`
fail on any absent pinned file instead.
+1 -1
View File
@@ -12,7 +12,7 @@ Run the evidence without private samples:
```sh
cargo test -p lightcraft-pipeline tint_ -- --nocapture
cargo test -p lightcraft-gpu --test equivalence tint_directions -- --nocapture
cargo test -p lightcraft-gpu --test it equivalence::tint_directions -- --nocapture
cargo test -p lightcraft-color cct
```
+4 -3
View File
@@ -1,6 +1,6 @@
# UI parity
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-21 · **Change:** minor (context menus: a right-click elsewhere on the same widget moves its open menu instead of flashing it, issue #1877; Reference Escape, catalog-local pins and deleted-photo handling verified on Windows; KEYC-RATING: `\` shows / hides the Filter Bar in the grids; earlier: zoom row soft proofing sharp at 1:1, canvas tools by keyboard, focus-order test, ~50 unnamed hand-drawn widgets named) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-23 · **Change:** minor (KEYC-RATING: ⌘L Enable Filters; context menus: a right-click elsewhere on the same widget moves its open menu instead of flashing it, issue #1877; Reference Escape, catalog-local pins and deleted-photo handling verified on Windows; KEYC-RATING: `\` shows / hides the Filter Bar in the grids; earlier: zoom row soft proofing sharp at 1:1, canvas tools by keyboard, focus-order test, ~50 unnamed hand-drawn widgets named) · **Target:** Adobe Lightroom Classic 15.5 / Lightroom 9.6
How LightCraft's interaction compares with Lightroom's: views, panels, tools and handles, modifier
keys, shortcuts, zoom, context menus and feel. Rows for individual menu items and shortcuts live in
@@ -66,7 +66,7 @@ under the UI command that wraps it (a no-op error); the UI command now wins.
| Create Version | ⌘⇧S (+ ⇧M) | ⇧M (Windows: Ctrl+⇧S) | — |
| Select None | ⌘⇧A (+ ⌘D) | ⌘D | — |
**Library culling (KEYC-RATING):** `0–5`, `6–9` and `P/X/U` reach egui on macOS even when displayed in the native menu (adapted from PR #261; issue #283). `Shift+0–9` applies and advances once; `Shift+P` picks and advances in Photo Grid / Square Grid and retains Presets elsewhere. See [library shortcuts](library-shortcuts.md) for the verified Classic mapping and regression coverage. F6, F7 and F8 show / hide the filmstrip, the left panel and the right panel (F8 brings back the panel it hid; `view.rightPanel`). `` ` `` cycles the flag (unflagged → pick → reject → unflagged) and ⌘↑ / ⌘↓ raise / lower it; the native menu leaves ⌘↑ / ⌘↓ to egui so Compare/Survey act on the active photo. `\` shows / hides the Filter Bar in Photo Grid / Square Grid and keeps Show Original in Detail. Remaining Classic gaps: ⌘L (Enable Filters).
**Library culling (KEYC-RATING):** `0–5`, `6–9` and `P/X/U` reach egui on macOS even when displayed in the native menu (adapted from PR #261; issue #283). `Shift+0–9` applies and advances once; `Shift+P` picks and advances in Photo Grid / Square Grid and retains Presets elsewhere. See [library shortcuts](library-shortcuts.md) for the verified Classic mapping and regression coverage. F6, F7 and F8 show / hide the filmstrip, the left panel and the right panel (F8 brings back the panel it hid; `view.rightPanel`). `` ` `` cycles the flag (unflagged → pick → reject → unflagged) and ⌘↑ / ⌘↓ raise / lower it; the native menu leaves ⌘↑ / ⌘↓ to egui so Compare/Survey act on the active photo. `\` shows / hides the Filter Bar in Photo Grid / Square Grid and keeps Show Original in Detail. ⌘L / Ctrl+L (Enable Filters) puts the filter aside and shows every photo, and the next press brings back the same filter, stars, flag and text together; setting or clearing a filter while it is off drops the one put aside (not documented by Adobe, our choice).
**Grid thumbnail size (KEYC-COMPARE):** Classic's `=` and `-` increase and decrease the Grid thumbnail size (same keys on macOS and Windows; `+` also works for the larger size here, as Shift+`=` or the keypad). They step the bottom-bar slider by 30 pt inside its 90–480 pt range, in Photo Grid, Square Grid and People only; Detail, Compare, Survey and Reference ignore them, and ⌘= / ⌘− stay Zoom In / Out. See [library shortcuts](library-shortcuts.md).
@@ -80,7 +80,7 @@ under the UI command that wraps it (a no-op error); the UI command now wins.
## Accessibility audit
`crates/ui-egui/tests/accessibility.rs` walks the AccessKit tree egui hands to VoiceOver, Narrator and
`crates/ui-egui/tests/it/accessibility.rs` walks the AccessKit tree egui hands to VoiceOver, Narrator and
AT-SPI, headless, in Photo Grid, Square Grid, Detail, Compare, Survey and Reference, in each right
panel (Edit, Profiles, Crop, Remove, Masking, Red Eye, Versions, Activity, Keywords, Info) and in 13
dialogs (Export, Copy / Paste Settings, Create Preset, Rename, New Album, New Smart Album, Capture
@@ -149,6 +149,7 @@ establish OS keyboard delivery or cross-platform acceptance.
| Date | Change | Summary |
|---|---|---|
| 2026-10-15 | patch | Context menus: a right-click elsewhere on the same widget while its menu is open moves the menu to the pointer; before it flashed at the new spot and closed (issue #1877); every site uses `widgets::context_menu`; 70% unchanged |
| 2026-10-23 | patch | KEYC-RATING: ⌘L / Ctrl+L (Library ▸ Enable Filters) switches the filter off and on, restoring it as it was |
| 2026-10-15 | patch | KEYC-RATING: `\` shows / hides the Filter Bar in Photo Grid and Square Grid (Show Original in Detail); ⌘L is the filter-bar key left |
| 2026-10-14 | patch | Shortcuts: Visualize HDR loses its default ⇧H, which cycles the Tool Overlay (issue #224); both PRs had claimed it |
| 2026-10-12 | minor | Accessibility: crop handles, spots, gradient handles and mask pins operable by keyboard with AccessKit names and values; Tab order test for the right panels; hand-drawn icons and rows named; 55% → 75%; UI remaining 34–58 h → 32–54 h |
+44
View File
@@ -24,6 +24,50 @@
library you open and are imported into it, as files given on the command line are; presets dropped then are
refused with a note, since they belong to a library.
### Tab leaves the name field in New Album, New Smart Album and the name prompts
- In New Album, New Smart Album, Save Metadata Preset and the other dialogs with one name field, the field has the
keyboard focus when the dialog opens, and Tab now moves on to the check box, Cancel and OK (Shift+Tab goes back).
Before, the field took the focus back every frame, so only Return and Esc got you out of it. Return still
confirms and Esc still cancels.
### Foreign XMP metadata survives namespace-prefix collisions
- Saving a sidecar keeps another application's properties even when its namespace uses prefixes such as `lc`
or `xmp`. Those foreign properties no longer become LightCraft settings or ratings when imported.
### Find Missing Photos finds the files of a library made on Windows
- A library made on Windows records its originals with Windows paths. Opened on macOS or Linux, its photos are
missing until relinked, and Find Missing Photos found them only by their content, so it missed every photo it had
no fingerprint for (such as photos brought in from a Lightroom catalog) or that had been edited since, even in a
folder holding every file under the same name. It now matches them by name as it does any other photo: the name
after the last `/` or `\`, in any letter case, checked against the size when the library has one. Several files
of that name are still reported rather than guessed, and undo puts back the paths as they were.
### Auto straighten leaves straight photos alone
- Auto straighten (Auto in the crop panel, or a double-click with the Straighten tool) no longer turns a photo by
more than 10°, and acts only when at least three lines agree. Before, it often turned photos that were straight:
the edges of wooden planks, a branch or a bird's wing were taken for the horizon, sometimes for a 25° turn.
- When it finds no horizon or vertical lines, it says so instead of doing nothing without a word.
### PSD and PSB metadata stays available
- LightCraft now imports PSD and PSB files with EXIF and XMP image resources. Capture dates, GPS and descriptive fields
stay available in All Metadata; PSD edit copies keep their capture date. Original exports with Remove Location Info enabled
are refused when a PSD or PSB embeds GPS, since LightCraft cannot strip metadata from a byte-for-byte original copy.
## 2026-10-22
### Reliability
- Opening a library no longer writes through a link left at the lock's owner note (`catalog.lock.owner`): the link
is removed and a new note made in its place, so the file it pointed to is never changed (as for the catalog's
temporary files, issue #1502).
### Keys reach text fields and the shortcut editor on macOS
- While a text field has focus, the native menu now lets go of the keys the field needs (`G`, the digits `0`–`9`,
`P`, `U` and the like), and while Keyboard Shortcuts is recording a key it lets go of all of them (⌘, and ⌘Q in
the LightCraft menu too), except the system's own items (Hide LightCraft ⌘H, Hide Others ⌥⌘H, Close Window ⌘W
and Minimize ⌘M) and the two keys of the Help menu (⌘/ and F1). Before, the menu item kept its key on macOS, so the
key could still run the menu command instead of reaching the field or the editor. The keys come back on the menu
items when the field loses focus or recording ends; the menu's order, checkmarks and enabled state are unchanged.
## 2026-10-21
### Sharper resampling in HDR and panorama merges
+3
View File
@@ -81,6 +81,9 @@ the only copy of those edits outside that application's catalog. Saving never dr
ones), `xmp:CreatorTool`, comments, the packet wrapper and padding. LightCraft's properties go into one
`rdf:Description` of their own; owned properties written by another application (in attribute or element form) are
removed from its description, which otherwise stays as it was.
- Ownership follows the namespace URI, not the prefix spelling. A foreign namespace bound to `lc:` or `xmp:`
stays foreign: its properties are preserved and do not become LightCraft settings or ratings. Genuine namespace
aliases remain interchangeable, including namespace declarations containing XML character references.
- A sidecar that can't be read as XMP (not well-formed, not UTF-8, no `rdf:RDF`) is first copied to
`<name>.xmp.bak-<date><time>` (`-1`, `-2`… if taken — a backup is never overwritten), then replaced. A sidecar that
can't be read at all (permissions) is left alone and the save fails.