diff --git a/ROADMAP.md b/ROADMAP.md index 1221c835e..90b54dfae 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -175,6 +175,7 @@ Ranked toward beta; detail in [docs/roadmap.md](docs/roadmap.md), gaps in [docs/ |---|---|---| | 2026-10-13 | minor | Sony ILCA-99M2 camera colour profile in the log; numbers unchanged | | 2026-10-14 | minor | Localization ~52% → ~55% (mean of the 12 key languages): de, es, fr, ja and uk catalogs filled | +| 2026-10-14 | minor | 21 Sony and Leica models verified (258 models, 18%); headline numbers unchanged | | 2026-10-12 | minor | UI/UX remaining 40–70 h → 34–58 h (accessibility audit landed); headline numbers unchanged | | 2026-10-12 | minor | 22 more CR3 bodies verified, EOS R6 Mark III white balance: RAW decoding 77% → 83%, RAW ~56% → ~60%; mainstream 49% → 51%, essentials 64% → 65%; full unchanged at ~61% | | 2026-10-12 | minor | 117 Nikon and Fujifilm bodies verified (354 models, 24%); headline numbers unchanged | diff --git a/crates/raw/tests/sony_leica_corpus.rs b/crates/raw/tests/sony_leica_corpus.rs new file mode 100644 index 000000000..edd04cac3 --- /dev/null +++ b/crates/raw/tests/sony_leica_corpus.rs @@ -0,0 +1,114 @@ +//! One CC0 file per Sony and Leica body not covered by an earlier check from raw.pixls.us (URLs and SHA-256 in `RAW_SAMPLES`, +//! xtask/src/main.rs; downloaded into the gitignored corpus/raw by `cargo xtask corpus --download`). +//! +//! No external decoder was run on these: the FNV-1a hashes over the decoded u16 samples (row-major, +//! little-endian, masked borders included) pin LightCraft's own decode, and the check against the camera is +//! black-box: the green sites of the active area, on a 24 × 16 grid, must follow the camera's own embedded +//! JPEG (gamma-encoded Pearson r; 0.62–1.00 on these files, a misread layout or stream gives r near 0). Five files are +//! pinned only: the M8 and M9 DNGs carry no JPEG, the two M Monochrom bodies have no colour filter, and the +//! M (Typ 240) preview covers a different field (r 0.58); their renders were inspected by eye. +//! Missing files are reported as skipped. + +use lightcraft_raw::{RawData, decode, embedded_preview, probe_info}; +use std::path::{Path, PathBuf}; + +fn corpus() -> PathBuf { + std::env::var_os("LIGHTCRAFT_CORPUS").map(PathBuf::from).unwrap_or_else(|| Path::new(env!("CARGO_MANIFEST_DIR")).join("../../corpus")) +} + +/// Green of the decoded mosaic against the camera's embedded JPEG on a `gw × gh` grid of the active area. +fn green_vs_camera_jpeg(raw: &lightcraft_raw::RawImage, jpeg: &[u8], gw: usize, gh: usize) -> f64 { + use zune_core::{bytestream::ZCursor, colorspace::ColorSpace, options::DecoderOptions}; + let opts = DecoderOptions::default().jpeg_set_out_colorspace(ColorSpace::RGB); + let mut d = zune_jpeg::JpegDecoder::new_with_options(ZCursor::new(jpeg), opts); + let px = d.decode().unwrap(); + let info = d.info().unwrap(); + let (jw, jh) = (info.width as usize, info.height as usize); + let mean = |sum: Vec, n: Vec| sum.iter().zip(&n).map(|(s, n)| s / n.max(1.0)).collect::>(); + let (mut js, mut jn) = (vec![0f64; gw * gh], vec![0f64; gw * gh]); + for y in 0..jh { + for x in 0..jw { + let i = (y * gh / jh) * gw + x * gw / jw; + js[i] += f64::from(px[(y * jw + x) * 3 + 1]); + jn[i] += 1.0; + } + } + let RawData::U16(samples) = &raw.data else { panic!("integer sensor data expected") }; + let cfa = raw.cfa.clone().expect("colour-filter layout"); + let (a, black, white) = (raw.active_area, f64::from(raw.black.mean()), f64::from(raw.white_at(0))); + let (mut rs, mut rn) = (vec![0f64; gw * gh], vec![0f64; gw * gh]); + for y in a.y..a.y + a.height { + for x in a.x..a.x + a.width { + if cfa.color_at(x, y) == 1 { + let i = ((y - a.y) * gh / a.height) * gw + (x - a.x) * gw / a.width; + rs[i] += ((f64::from(samples[y * raw.width + x]) - black).max(0.0) / (white - black)).powf(1.0 / 2.2); + rn[i] += 1.0; + } + } + } + let (r, j) = (mean(rs, rn), mean(js, jn)); + let n = r.len() as f64; + let (mr, mj) = (r.iter().sum::() / n, j.iter().sum::() / n); + let cov: f64 = r.iter().zip(&j).map(|(x, y)| (x - mr) * (y - mj)).sum(); + let vr: f64 = r.iter().map(|x| (x - mr).powi(2)).sum(); + let vj: f64 = j.iter().map(|y| (y - mj).powi(2)).sum(); + cov / (vr * vj).sqrt() +} + +#[test] +fn sony_and_leica_bodies_decode_like_the_camera_jpeg() { + // (file, sensor width × height, pinned FNV-1a of the sensor samples, compare with the camera JPEG) + let cases: &[(&str, (usize, usize), u64, bool)] = &[ + ("arw-sony-dsc-rx100m7a.arw", (5504, 3672), 0xd307_0cab_69e7_be05, true), + ("arw-sony-dsc-rx1rm3.arw", (9600, 6376), 0x15a1_1634_d24c_0ba2, true), + ("arw-sony-ilce-1m2.arw", (8672, 5784), 0x7e88_f7b5_8759_d3e9, true), + ("arw-sony-ilce-6400a.arw", (6048, 4024), 0x538b_bd85_9783_7d07, true), + ("arw-sony-ilce-7m5.arw", (7168, 5120), 0x337c_89f0_d11a_3153, true), + ("arw-sony-ilme-fx2.arw", (7040, 4688), 0x0897_d087_2ac8_b8a5, true), + ("arw-sony-zv-1m2.arw", (5504, 3672), 0x25c4_09f4_ae51_5ada, true), + ("arw-sony-zv-e10m2.arw", (6656, 4608), 0x47e5_b9b2_3912_b2ac, true), + ("dng-leica-cl.dng", (6120, 4016), 0xc59f_487f_bb92_6877, true), + ("dng-leica-m-monochrom-typ-246.dng", (5984, 4000), 0xc0d0_57fa_ed5c_0d1d, false), + ("dng-leica-m-monochrom.dng", (5216, 3472), 0x17ef_5964_1abc_6b39, false), + ("dng-leica-m-typ-240.dng", (5984, 4000), 0x7955_7612_8c83_a10f, false), + ("dng-leica-m10-r.dng", (7872, 5208), 0x573a_9fc4_9aa2_284c, true), + ("dng-leica-m10.dng", (5984, 3992), 0x1594_dd1c_ca00_d124, true), + ("dng-leica-m8.dng", (3920, 2638), 0x8354_ac17_b3ca_f4b8, false), + ("dng-leica-m9.dng", (5216, 3472), 0x141c_4039_429d_5676, false), + ("dng-leica-q-typ-116.dng", (6120, 4016), 0x11f9_9859_db23_b42e, true), + ("dng-leica-q2.dng", (8424, 5632), 0xbb4b_2bf3_ffd0_e412, true), + ("dng-leica-sl-typ-601.dng", (6120, 4016), 0xa3df_d8cf_9d7c_eff2, true), + ("dng-leica-sl2.dng", (8424, 5632), 0xadbf_7522_c3d0_a02d, true), + ("dng-leica-x2.dng", (4944, 3272), 0xbde8_5411_9431_1bd6, true), + ("rwl-leica-c-lux.rwl", (5488, 3664), 0x3c13_2cae_7028_aa0d, true), + ]; + let mut seen = 0; + for &(name, sensor, hash, jpeg_check) in cases { + let path = corpus().join("raw").join(name); + let Ok(bytes) = std::fs::read(&path) else { + eprintln!("skip: {} absent", path.display()); + continue; + }; + let raw = decode(&bytes).unwrap_or_else(|e| panic!("{name}: {e}")); + raw.validate().unwrap(); + assert_eq!((raw.width, raw.height, raw.cpp), (sensor.0, sensor.1, 1), "{name}: sensor size"); + assert_eq!(raw.info(), probe_info(&bytes).unwrap(), "{name}: probe and decode disagree"); + let RawData::U16(samples) = &raw.data else { panic!("{name}: integer sensor data expected") }; + let actual = samples + .iter() + .flat_map(|v| v.to_le_bytes()) + .fold(0xcbf2_9ce4_8422_2325u64, |h, byte| (h ^ u64::from(byte)).wrapping_mul(0x100_0000_01b3)); + assert_eq!(actual, hash, "{name}: sensor pixels differ from the pinned decode"); + assert!(raw.white_at(0) > raw.black.mean(), "{name}: invalid black/white levels"); + if !jpeg_check { + seen += 1; + continue; + } + let jpeg = embedded_preview(&bytes).unwrap_or_else(|| panic!("{name}: no camera JPEG")); + let r = green_vs_camera_jpeg(&raw, &jpeg, 24, 16); + eprintln!("{name:40} {}x{}: green follows the camera JPEG, r = {r:.3}", raw.width, raw.height); + assert!(r > 0.6, "{name}: decoded mosaic does not follow the camera JPEG (r = {r:.3})"); + seen += 1; + } + eprintln!("Sony / Leica bodies checked on {seen} files"); +} diff --git a/docs/gaps.md b/docs/gaps.md index 9bda09232..f65e8f8de 100644 --- a/docs/gaps.md +++ b/docs/gaps.md @@ -76,6 +76,7 @@ Beta-blocking gaps (B) total **~230–430 h**; with the stability and platform w | 2026-10-14 | minor | Gap 21: de, es, fr, ja and uk catalogs filled (97–99%); 55–90 h → 40–70 h | | 2026-10-13 | patch | Gaps 10, 22 and 23 each had two rows (two branches edited them; the merges kept both): the older copies are removed, and `cargo xtask parity` (in `ci`) now fails when a gap number is listed twice | | 2026-10-13 | minor | Closed recently: Sony ILCA-99M2 profile | +| 2026-10-14 | minor | Gap 10: 21 Sony and Leica models verified on one CC0 file each (258 models) | | 2026-10-11 | minor | Gap 10 shrinks: Leica Q3 verified by a recorded check of 38 private DNGs (236 models verified; Leica 14); gap not closed | | 2026-10-12 | minor | Camera-look deep shadows follow the JPEG toe (#1307); camera calibration remains partial | | 2026-10-12 | minor | Gap 23 (accessibility): the AccessKit tree audit and its fixes landed; what is left is canvas placement by keyboard and a real screen-reader session; 10–20 h → 4–8 h; gap not closed | diff --git a/docs/parity-checklist.md b/docs/parity-checklist.md index 2167a0071..d440400ae 100644 --- a/docs/parity-checklist.md +++ b/docs/parity-checklist.md @@ -800,6 +800,7 @@ Latin stays upright. Advanced Japanese composition remains open. Regression cove | 2026-10-13 | patch | LR-EXP-DIM: an enlarged export stops at 512 megapixels and is refused when it needs more memory than the computer has, instead of aborting the app; status unchanged | | 2026-10-13 | minor | LR-PROF-CAMERACOLOR: bundled ILCA-99M2 profile with its held-out measurement | | 2026-10-12 | minor | LR-MASK-EFFECTS (new, ✅): local adjustment (effect / brush) presets: Effect menu, New Effect Preset dialog, Manage window, groups and favorites; imports Lightroom Classic local `.lrtemplate`, Camera Raw local `.xmp`, `.lceffect` and `.zip`. LR-IMP-PROFILES and LR-MASK-SLIDERS notes updated | +| 2026-10-14 | minor | LR-IMP-CAMERA-COVERAGE: 21 Sony and Leica Adobe models verified on one CC0 file each; status unchanged (🟡) | | 2026-10-11 | minor | LR-MERGE-HDR: HDR and panorama merges of raws without colour matrices (CR2, NEF, ARW…) write the colour they open with as DNG tags (issue #965); status unchanged | | 2026-10-12 | minor | LR-META-XMP: Read Metadata from File no longer auto-writes the sidecar it has just read, which added `lc:settings` and hid another app's later `crs:` edits (#934); status unchanged (✅) | | 2026-10-12 | patch | LR-IMP-CAMERA-COVERAGE: CR2 white level from the active area, not the saturated masked rows above it (issue #1272); status unchanged (🟡) | diff --git a/docs/raw-parity.md b/docs/raw-parity.md index 9af4a6a6f..8709f1c15 100644 --- a/docs/raw-parity.md +++ b/docs/raw-parity.md @@ -19,7 +19,7 @@ ranked in [gaps.md](gaps.md). Details per format: [cr3.md](cr3.md), | Decoder path should handle it, **unverified** | **919** (64%) | measured from the format rules (631 of them DNG, mostly phones) | | **Preview-only** (embedded JPEG) | **232** (16%) | measured | | **Unsupported** (not imported, refused or decodes wrongly) | **36** (2%) | measured | -| Models added since 2017 (Camera Raw 10+): verified / unverified / preview / unsupported | 83 / 639 / 24 / 8 of 754 | measured | +| Models added since 2017 (Camera Raw 10+): verified / unverified / preview / unsupported | 95 / 627 / 24 / 8 of 754 | measured | | **Share of photographers whose camera fully works** (decodes from sensor data), use-weighted | **~85%** | estimated: measured classes × written usage weights × per-format confidence | | …of which on a body we have verified | **~42%** | estimated, same weights | | Camera colour: Adobe profiles vs ours | 1,500 Adobe Standard profiles, 481 models with Camera Matching profiles vs **5 bundled profiles** + per-file fits + 52 spectral matrices | measured (bundle listing, Adobe list, `assets/camera-profiles`) | @@ -76,7 +76,7 @@ committed table is stale. | Fujifilm | 97 | 65 | 9 | 23 | 0 | pre-X FinePix RAF without a raw IFD (estimated split) | | Google | 88 | 1 | 87 | 0 | 0 | — | | Olympus | 71 | 3 | 9 | 59 | 0 | **compressed ORF** | -| Leica | 61 | 14 | 47 | 0 | 0 | — | +| Leica | 61 | 27 | 34 | 0 | 0 | — | | Xiaomi, Oppo, LG, Huawei, OnePlus, Motorola, Nokia | 139 | 0 | 139 | 0 | 0 | — (DNG) | | Pentax / Ricoh | 60 | 4 | 56 | 0 | 0 | — | | Hasselblad | 34 | 1 | 2 | 31 | 0 | Hasselblad-compressed 3FR / FFF | @@ -99,7 +99,7 @@ committed table is stale. | OM / Olympus | 3% | 3% | 1% | compressed ORF | | Phones | 3% | 93% | 1% | DNG | | Pentax / Ricoh | 1.5% | 94% | 14% | | -| Leica | 1% | 96% | 21% | the Q3 verified | +| Leica | 1% | 99% | 72% | the Q3 verified, 13 more bodies pinned on CC0 files | | DJI | 1% | 95% | 0% | | | Medium format and others | 0.5% | 23% | 1% | IIQ, 3FR, X3F | | **Weighted** | 100% | **92%** | **59%** | | @@ -273,6 +273,7 @@ Beyond decoding: | Date | Change | Summary | |---|---|---| | 2026-10-13 | minor | Bundled camera profiles 4 → 5 (ILCA-99M2) | +| 2026-10-14 | minor | 21 Sony and Leica models verified (one CC0 raw.pixls.us file each, pinned; `sony_leica_corpus.rs`): 258 verified, 920 unverified; Leica on a verified body 21% → 72%, Sony 91% → 92%, use-weighted 85% and 43% | | 2026-10-11 | minor | Leica Q3 verified by a recorded check of 38 private DNGs (no decode failure; mean ΔE to the camera JPEG 6.3–13.9): 236 verified, 941 unverified, Leica bucket on a verified body 5% → 21%, weighted shares unchanged | | 2026-10-12 | patch | CR2 white level from the active area, not the saturated masked rows above it (#1272: EOS 50D, 60D, 450D (Rebel XSi), 500D (Rebel T1i), 550D (Rebel T2i), 1200D (Rebel T5) and 100D (Rebel SL1)); scores unchanged | | 2026-10-12 | minor | Canon PowerShot G9: as-shot white balance from WBInfo (`0x0029`, the row of the preset in ShotInfo), issue #1273; render unchanged (the camera-look fit already absorbed it), As Shot now the camera's; counts unchanged | diff --git a/docs/raw/coverage.tsv b/docs/raw/coverage.tsv index 8aeb140aa..fde7ab368 100644 --- a/docs/raw/coverage.tsv +++ b/docs/raw/coverage.tsv @@ -586,8 +586,8 @@ Leaf Credo 50 IIQ 2013 preview IIQ is opened from its embedded JPEG only Leaf Credo 60 IIQ 2012 preview IIQ is opened from its embedded JPEG only Leaf Credo 80 IIQ 2012 preview IIQ is opened from its embedded JPEG only Leica C (Typ 112) RWL 2013 verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format -Leica CL DNG 2017 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) -Leica C-Lux DNG 2017 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) +Leica CL DNG 2017 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) +Leica C-Lux DNG 2017 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) Leica D-Lux 2 RAW 2005 unverified Panasonic decoder, every raw format Leica D-Lux 3 RAW 2005 verified PR #215: raw.pixls.us bulk check of every RW2 / RWL / RAW body Leica D-Lux 4 RWL 2008 verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format @@ -601,26 +601,26 @@ Leica Digilux 2 RAW 2003 verified PR #215: raw.pixls.us bulk check of every RW2 Leica Digilux 3 RAW 2005 verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format Leica Digital-Modul-R DNG 2003 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica Leitz Phone 3 DNG 2023 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) -Leica M8 DNG 2003 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) -Leica M9 DNG 2008 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) -Leica M10 DNG 2015 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) +Leica M8 DNG 2003 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash) +Leica M9 DNG 2008 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash) +Leica M10 DNG 2015 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) Leica M10-D DNG 2018 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica M10-P DNG 2018 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) -Leica M10-R DNG 2019 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) +Leica M10-R DNG 2019 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) Leica M11-D DNG 2023 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica M (Typ 262) DNG 2015 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica M-D (Typ 262) DNG 2015 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica M-E DNG 2012 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica M-EV1 DNG 2024 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica M-P DNG 2013 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) -Leica M Monochrom DNG 2012 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) -Leica M Monochrom (Typ 246) DNG 2015 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) +Leica M Monochrom DNG 2012 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash) +Leica M Monochrom (Typ 246) DNG 2015 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash) Leica M10 Monochrom DNG 2019 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica M11 DNG 2020 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica M11 MONOCHROM DNG 2022 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica M11-P DNG 2023 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) -Leica Q (Typ 116) DNG 2015 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) -Leica Q2 DNG 2018 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) +Leica Q (Typ 116) DNG 2015 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) +Leica Q2 DNG 2018 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) Leica Q2 Monochrom DNG 2020 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica Q3 DNG 2022 verified recorded check 2026-10-11: 38 private Q3 DNGs (landscape and portrait) decoded from sensor data and developed at full size without error, mean CIE76 dE to the camera JPEG 6.3-13.9 at 400 px (not committed; docs/raw-parity.md) Leica Q3 43 DNG 2023 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) @@ -628,8 +628,8 @@ Leica Q3 Monochrom DNG 2025 unverified DNG decoder (uncompressed, LJ92, lossy, D Leica S2 DNG 2010 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica S (Typ 007) DNG 2015 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica S3 DNG 2019 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) -Leica SL (Typ 601) DNG 2015 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) -Leica SL2 DNG 2019 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) +Leica SL (Typ 601) DNG 2015 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) +Leica SL2 DNG 2019 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) Leica SL2-S DNG 2020 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica SL3 DNG 2023 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica SL3-P DNG 2025 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) @@ -643,7 +643,7 @@ Leica V-LUX 3 RAW 2010 unverified Panasonic decoder, every raw format Leica V-LUX 4 RWL 2012 verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format Leica V-LUX 5 RWL 2018 verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format Leica V-LUX (Typ 114) RWL 2013 verified PR #215: 178 raw.pixls.us files from 118 Panasonic / Leica bodies, every RW2 format -Leica X2 RWL 2012 unverified Panasonic decoder, every raw format +Leica X2 RWL 2012 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) Leica X (Typ 113) DNG 2013 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Leica X-U (Typ 113) DNG 2015 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) LG G7 ThinQ DNG 2018 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) @@ -1243,12 +1243,12 @@ Sony Xperia 1 V Front Camera DNG 2022 unverified DNG decoder (uncompressed, LJ92 Sony Xperia 1 V Ultrawide Camera DNG 2022 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Sony Xperia 1 V Wide Camera DNG 2022 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Sony Xperia 1 V Zoom Camera DNG 2022 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) -Sony A1 II (ILCE-1M2) (** see note) ARW 2024 unverified ARW decoder (uncompressed, cRAW, packed 12-bit, lossless, downsized YCbCr) +Sony A1 II (ILCE-1M2) (** see note) ARW 2024 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) Sony A7 (ILCE-7) ARW 2013 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool) Sony A7 II (ILCE-A7M2) ARW 2013 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies Sony A7 III (ILCE-7M3) ARW 2017 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool) Sony A7 IV (ILCE-7M4) ARW 2021 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool) -Sony A7 V (ILCE-7M5) (** see note) ARW 2025 unverified ARW decoder (uncompressed, cRAW, packed 12-bit, lossless, downsized YCbCr) +Sony A7 V (ILCE-7M5) (** see note) ARW 2025 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) Sony A7C (ILCE-7C) ARW 2020 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool) Sony A7C II (ILCE-7CM2) ARW 2023 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool) Sony A7CR (ILCE-7CR) ARW 2023 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool) @@ -1310,7 +1310,7 @@ Sony DSC-F828 SRF 2003 unsupported SRF not in the import list (the probe accepts Sony DSC-HX95 ARW 2018 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool) Sony DSC-HX99 ARW 2018 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool) Sony DSC-V3 SRF 2005 unsupported SRF not in the import list -Sony DSC-RX100M7A ARW 2024 unverified ARW decoder (uncompressed, cRAW, packed 12-bit, lossless, downsized YCbCr) +Sony DSC-RX100M7A ARW 2024 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) Sony FX3 (ILME-FX3) ARW 2020 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool) Sony FX30 (ILME-FX30) ARW 2022 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool) Sony NEX-3 ARW 2010 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool) @@ -1375,16 +1375,16 @@ Sony Xperia 5 V Wide Camera DNG 2023 unverified DNG decoder (uncompressed, LJ92, Sony Xperia Pro-I Rear Wide Camera DNG 2021 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Sony ZV-E10 ARW 2021 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool) Sony ZV-E1 ARW 2022 verified issue #535: raw.pixls.us bulk check of all 100 Sony bodies (decodes; BL/WL/crop/WB vs ExifTool) -Sony ZV-E10M2 ARW unverified ARW decoder (uncompressed, cRAW, packed 12-bit, lossless, downsized YCbCr) -Sony ZV-1M2 ARW 2022 unverified ARW decoder (uncompressed, cRAW, packed 12-bit, lossless, downsized YCbCr) +Sony ZV-E10M2 ARW verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) +Sony ZV-1M2 ARW 2022 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) Sony ZV-1A ARW 2024 unverified ARW decoder (uncompressed, cRAW, packed 12-bit, lossless, downsized YCbCr) Sony ILX-LR1 ARW 2023 unverified ARW decoder (uncompressed, cRAW, packed 12-bit, lossless, downsized YCbCr) Sony ILCE - 1M2 (Final Support) ARW 2024 unverified ARW decoder (uncompressed, cRAW, packed 12-bit, lossless, downsized YCbCr) Sony ILCE - 6100A ARW 2024 unverified ARW decoder (uncompressed, cRAW, packed 12-bit, lossless, downsized YCbCr) -Sony ILCE - 6400A ARW 2024 unverified ARW decoder (uncompressed, cRAW, packed 12-bit, lossless, downsized YCbCr) -Sony FX2 (ILMEFX2) (** see note) ARW 2024 unverified ARW decoder (uncompressed, cRAW, packed 12-bit, lossless, downsized YCbCr) +Sony ILCE - 6400A ARW 2024 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) +Sony FX2 (ILMEFX2) (** see note) ARW 2024 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) Sony FX3A (ILMEFX3A) ARW 2024 unverified ARW decoder (uncompressed, cRAW, packed 12-bit, lossless, downsized YCbCr) -Sony RX1R III (DSC-RX1RM3) ARW 2024 unverified ARW decoder (uncompressed, cRAW, packed 12-bit, lossless, downsized YCbCr) +Sony RX1R III (DSC-RX1RM3) ARW 2024 verified corpus: crates/raw/tests/sony_leica_corpus.rs (pinned sensor hash, camera-JPEG check) Xiaomi Mi 11 Lite Front Camera DNG 2021 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Xiaomi Mi 11 Lite Rear Ultrawide Camera DNG 2021 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) Xiaomi Mi 11 Lite Rear Wide Camera DNG 2021 unverified DNG decoder (uncompressed, LJ92, lossy, Deflate, JPEG XL, LinearRaw) diff --git a/docs/raw/evidence.tsv b/docs/raw/evidence.tsv index 051e44569..4363c943e 100644 --- a/docs/raw/evidence.tsv +++ b/docs/raw/evidence.tsv @@ -68,6 +68,19 @@ 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) @@ -392,3 +405,11 @@ 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) diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 4d81fbf78..e735fae59 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1618,6 +1618,116 @@ const RAW_SAMPLES: &[(&str, &str, &str)] = &[ "https://raw.pixls.us/getfile.php/3039/nice/Fujifilm%20-%20FinePix%20F770EXR%20-%2012bit%2012bit%20uncompressed%20%284:3%29.RAF", "ffc905e325a00c57a5335681654fdf226b724269cd5d26cd976983939f88043d", ), + ( + "dng-leica-m-monochrom.dng", + "https://raw.pixls.us/getfile.php/974/nice/Leica%20-%20M%20Monochrom%20-%2016bit%20%283:2%29.DNG", + "149d5b3fbd5cd40d51c1f56d5e392a81870d129e047a6c8a596447590e7a0e4f", + ), + ( + "dng-leica-cl.dng", + "https://raw.pixls.us/getfile.php/2489/nice/Leica%20-%20CL%20-%2014bit%2014bit%20uncompressed%20%283:2%29.DNG", + "1f4cfa565d176d85838d96bd3eb598bbeed719cac8acb9999d5823c527635950", + ), + ( + "dng-leica-m10.dng", + "https://raw.pixls.us/getfile.php/1603/nice/Leica%20-%20M10%20-%2016bit%2016bit%20uncompressed%20%283:2%29.dng", + "26be5e06dfb53a2938dab3ca8f06024533a9c0dd0c652938f39eb48bc325f95e", + ), + ( + "rwl-leica-c-lux.rwl", + "https://raw.pixls.us/getfile.php/3863/nice/Leica%20-%20C-Lux%20-%204:3.RWL", + "286106ec2df65539912709c64e84a9b94686443fe5ea05b8ebada76daa1feb2d", + ), + ( + "arw-sony-zv-1m2.arw", + "https://raw.pixls.us/getfile.php/8461/nice/Sony%20-%20ZV-1M2%20-%2012bit%20%283:2%29.ARW", + "2a45845a93ab5e428868366d6575a264818b184541b1c114ab4de980872a7184", + ), + ( + "dng-leica-m-monochrom-typ-246.dng", + "https://raw.pixls.us/getfile.php/1087/nice/Leica%20-%20M%20Monochrom%20%28Typ%20246%29%20-%2012bit%20%283:2%29.DNG", + "3fb74d1fc402daaa48a9c3f1d6279d7e85fb58dfdaf816f036927d49ab228977", + ), + ( + "arw-sony-zv-e10m2.arw", + "https://raw.pixls.us/getfile.php/8021/nice/Sony%20-%20ZV-E10M2%20-%2012bit%20%284:3%29.ARW", + "49db06da969cf3894cf070d9171fe0ed4d0f125e16a87b5eba7eaec27cd75595", + ), + ( + "arw-sony-dsc-rx1rm3.arw", + "https://raw.pixls.us/getfile.php/8544/nice/Sony%20-%20DSC-RX1RM3%20-%2014bit%20uncompressed%20%283:2%29.ARW", + "6ef9956b343051748a6a16ba9ba7bd0d314a4ae0b4f8d8e2f1c13b4a1e50cfb8", + ), + ( + "arw-sony-ilce-1m2.arw", + "https://raw.pixls.us/getfile.php/7827/nice/Sony%20-%20ILCE-1M2%20-%2014bit%20uncompressed%20%283:2%29.ARW", + "7def3c8d80537f79af199052c6e13d86750203122dcb94888ada65291dabb793", + ), + ( + "dng-leica-m8.dng", + "https://raw.pixls.us/getfile.php/2988/nice/Leica%20-%20M8%20-%208bit%208bit%20uncompressed%20%283:2%29.DNG", + "7fdcca2371bb07fbf9483fcb08e3b5ab093eca1ca3924cbc86d6863736c31153", + ), + ( + "arw-sony-dsc-rx100m7a.arw", + "https://raw.pixls.us/getfile.php/8096/nice/Sony%20-%20DSC-RX100M7A%20-%2012bit%20%283:2%29.ARW", + "80adbc5b1cb3342058d5998cf2eda1e6b408565169462d6d26dfe02f0c140b30", + ), + ( + "arw-sony-ilce-7m5.arw", + "https://raw.pixls.us/getfile.php/8845/nice/Sony%20-%20ILCE-7M5%20-%2014bit%20%284:3%29.ARW", + "8c35cd1ab0ca36b487ae50ae5e0333a8e967122700fce5678e1e5b97561896a4", + ), + ( + "arw-sony-ilme-fx2.arw", + "https://raw.pixls.us/getfile.php/8807/nice/Sony%20-%20ILME-FX2%20-%2014bit%20uncompressed%20%283:2%29.ARW", + "924a6e4efd5c068883dd7de2bf2a2d155c7c13bdde668232077bdf9d92a201a8", + ), + ( + "dng-leica-x2.dng", + "https://raw.pixls.us/getfile.php/882/nice/Leica%20-%20X2%20-%2012bit%20%283:2%29.DNG", + "a67eca6271afb10510ffc9cf998b641d0e8a0ebfa4c779a7bc0bfed5d28b62dd", + ), + ( + "dng-leica-q2.dng", + "https://raw.pixls.us/getfile.php/3204/nice/Leica%20-%20Q2%20-%2014bit%2014bit%20uncompressed%20%283:2%29.DNG", + "a71f98405e9e9c1e4ac0f2d2e6c52d65daae3234fc0a9f6eed2a84ee4ce794ad", + ), + ( + "arw-sony-ilce-6400a.arw", + "https://raw.pixls.us/getfile.php/7826/nice/Sony%20-%20ILCE-6400A%20-%2014bit%20%283:2%29.ARW", + "a8a45e9b6c437eba6724fcda24c3efd084c05389711b955d84b2af67635e241b", + ), + ( + "dng-leica-sl-typ-601.dng", + "https://raw.pixls.us/getfile.php/1951/nice/Leica%20-%20SL%20%28Typ%20601%29%20-%2014bit%20%283:2%29.DNG", + "aa9fd9ef937ed34467d6f91bfa2603be00cb47542b7fffd7258b79652d3b7bef", + ), + ( + "dng-leica-m10-r.dng", + "https://raw.pixls.us/getfile.php/7853/nice/Leica%20-%20M10-R%20-%2016bit%20compressed%20%283:2%29.DNG", + "ba35d25d521c7ddbc4feca69c8cdbe071ac65dcd6cf2c93374391bf6f3662b8d", + ), + ( + "dng-leica-m-typ-240.dng", + "https://raw.pixls.us/getfile.php/2317/nice/Leica%20-%20M%20%28Typ%20240%29%20-%2016bit%2016bit%20compressed%20%283:2%29.DNG", + "bf35a4da121f853cb644253b69515b441748f95fcbd6fdea2de025a76e6c24cd", + ), + ( + "dng-leica-sl2.dng", + "https://raw.pixls.us/getfile.php/7872/nice/Leica%20-%20SL2%20-%2014bit%20uncompressed%20%283:2%29.DNG", + "d00f05468793e4509b53230e90dcdc078e823b254eee95f1c68b29e217df99bf", + ), + ( + "dng-leica-m9.dng", + "https://raw.pixls.us/getfile.php/753/nice/Leica%20-%20M9%20-%208bit%208bit%20compressed%20%283:2%29.DNG", + "d1d162fce62210b8951c862189a6098329b5163b7f7492dc397c6e53bba04239", + ), + ( + "dng-leica-q-typ-116.dng", + "https://raw.pixls.us/getfile.php/1797/nice/Leica%20-%20Q%20%28Typ%20116%29%20-%2014bit%20%283:2%29.DNG", + "f7b2a6b6d7684536511cf2db2e2bfa46fae1ad7e52214093714f35e7ca60acbf", + ), ]; fn cmd_corpus(download: bool) -> Result<(), String> {