From d41de88c05f965bb7e0b3440ae6c4099e5e222cb Mon Sep 17 00:00:00 2001 From: Marco Arnulfo Date: Mon, 12 Oct 2026 21:02:48 +0200 Subject: [PATCH] LR-IMP-FORMATS: active_rows steps an odd number of rows, so a plateau on red or blue sites alone is found (#1272) --- crates/raw/src/vendor/mod.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/crates/raw/src/vendor/mod.rs b/crates/raw/src/vendor/mod.rs index 46c401cd5..0d59fd6ed 100644 --- a/crates/raw/src/vendor/mod.rs +++ b/crates/raw/src/vendor/mod.rs @@ -64,9 +64,10 @@ pub(crate) fn black_from_columns(data: &[u16], width: usize, cols: Range, } /// Samples of up to 512 evenly spaced rows of the active area, for [`white_from_data`]: the borders can hold -/// their own saturated runs (0xffff junk on RW2, masked rows at 16383 on some Canon CR2s). +/// their own saturated runs (0xffff junk on RW2, masked rows at 16383 on some Canon CR2s). The step is odd so both +/// row parities, and with them every CFA site, are read. pub(crate) fn active_rows(data: &[u16], w: usize, a: Rect) -> Vec { - let step = (a.height / 512).max(1); + let step = (a.height / 512).max(1) | 1; (a.y..a.y + a.height).step_by(step).filter_map(|y| data.get(y * w + a.x..y * w + a.x + a.width)).flatten().copied().collect() } @@ -142,6 +143,15 @@ mod tests { /// A Canon EOS 70D CR2 saturates at 13583 but has a handful of samples up to 14426 (out of ~20M): the plateau /// is still found instead of falling back to 16383 (≈0.3 EV too dark, highlights never seen as clipped). + /// A plateau on the blue sites alone (odd rows) is still found: an even row step would read one row parity only. + #[test] + fn active_rows_reads_both_row_parities() { + let n = 2048; + let d: Vec = (0..n * n).map(|i| if (i / n) % 2 == 1 && i % 2 == 1 { 15000 } else { (i % 10000) as u16 }).collect(); + let w = white_from_data(&active_rows(&d, n, Rect::new(0, 0, n, n)), 14); + assert!((14900.0..=15000.0).contains(&w), "{w}"); + } + #[test] fn white_plateau_with_strays_above() { let mut d: Vec = (0..100_000).map(|i| (2048 + i % 10000) as u16).collect();