From fe9e6e3433f6e56f860ccfd64bfc5622f807fd49 Mon Sep 17 00:00:00 2001 From: radialmonster Date: Tue, 13 Oct 2026 02:44:22 -0400 Subject: [PATCH] LR-RAW-NEF: size the NRW word packing by the row, not by the padded strip (P7000 stripes) --- crates/raw/src/vendor/nef.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/crates/raw/src/vendor/nef.rs b/crates/raw/src/vendor/nef.rs index 695d55712..ad792b2e4 100644 --- a/crates/raw/src/vendor/nef.rs +++ b/crates/raw/src/vendor/nef.rs @@ -232,7 +232,8 @@ fn uncompressed(bytes: &[u8], info: &ImageInfo, order: ByteOrder, mn: Option<&ma let packing = if bytes_per_row >= row_samples * 2 { Packing::Word16 } else if bits == 12 && bytes_per_row * 8 >= row_samples * 12 && bytes_per_row * 8 < row_samples * 13 { - if nrw_data(mn).is_some() && bytes_per_row.is_multiple_of(4) { Packing::Words32Msb } else { Packing::Msb } + // the row's own size (a strip may be padded past the last row, which skews `bytes_per_row`) + if nrw_data(mn).is_some() && (row_samples * 12).div_ceil(8).is_multiple_of(4) { Packing::Words32Msb } else { Packing::Msb } } else if info.compression == 1 && bits != 8 && bits != 16 { return Err(RawError::Unsupported(format!("NEF uncompressed packing ({bytes_per_row} bytes per {row_samples}-sample row)"))); } else { @@ -575,6 +576,17 @@ mod tests { assert_eq!(decode(Some(both)).black.values, vec![100.0, 101.0, 102.0, 103.0]); } + #[test] + fn nrw_padded_strip_keeps_32_bit_word_packing() { + // 16 x 6 12-bit samples are 24 bytes a row; a strip padded past the last row must not change the packing + let (w, h) = (16usize, 6usize); + let px: Vec = (0..w * h).map(|i| (200 + i * 131 % 3800) as u16).collect(); + let mut packed = words32(&px, w, ByteOrder::Little); + packed.extend_from_slice(&[0u8; 6]); + let r = crate::decode(&nef_in(ByteOrder::Little, 1, 12, vec![packed], w as u32, h as u32, h as u32, Some(nrw_note(0)))).unwrap(); + assert_eq!(r.data, RawData::U16(px)); + } + #[test] fn compressed_without_table_is_unsupported() { let bytes = nef(34713, 14, vec![vec![0; 64]], 8, 8, 8);