LR-RAW-NEF: stretch non-square pixels (D1X/D1H) to square

The D1X/D1H raw SubIFD is 4028x1324 with XResolution 600 / YResolution 300:
the pixel is twice as tall as it is wide. Nothing read that, so the
picture came out about 3:1. Add a pixel aspect to RawImage/RawInfo, read
it from the raw IFD resolution ratio (NEF) and from DefaultScale (DNG),
accept only 1.5..4, and resample the rows after demosaic. developed_size()
reports the stretched size, binning is off for non-square pixels, and the
catalog and lens-profile sizing use developed_size().
This commit is contained in:
radialmonster
2026-10-13 06:01:40 -04:00
parent b3d392b499
commit 2dad18d2ec
24 changed files with 99 additions and 12 deletions
+3
View File
@@ -1656,6 +1656,7 @@ mod tests {
color: ColorData::default(),
wb_multipliers: Some([1.0; 3]),
linearized: true,
pixel_aspect: 1.0,
opcodes: OpcodeLists::default(),
metadata: lightcraft_meta::Metadata::default(),
};
@@ -1999,6 +2000,7 @@ mod tests {
color,
wb_multipliers: Some([2.0, 1.0, 1.5]),
linearized: false,
pixel_aspect: 1.0,
opcodes: Default::default(),
metadata: lightcraft_raw::Metadata { make: Some(make.to_owned()), model: Some(model.to_owned()), ..Default::default() },
}
@@ -3125,6 +3127,7 @@ mod tests {
color: ColorData::default(),
wb_multipliers: Some([1.0; 3]),
linearized: true,
pixel_aspect: 1.0,
opcodes: OpcodeLists::default(),
metadata: lightcraft_meta::Metadata { make: Some("SONY".into()), model: Some("ILCE-7M4".into()), ..Default::default() },
};
+2 -4
View File
@@ -158,10 +158,8 @@ pub fn probe_bytes(name: &str, bytes: &[u8]) -> Result<ProbeInfo, String> {
}
Err(Err(e)) => return Err(e),
};
let (mut w, mut h) = (raw.crop.width.max(1) as u32, raw.crop.height.max(1) as u32);
if w <= 1 || h <= 1 {
(w, h) = (raw.active_area.width as u32, raw.active_area.height as u32);
}
let (w, h) = raw.developed_size();
let (mut w, mut h) = (w.max(1) as u32, h.max(1) as u32);
if raw.orientation.swaps_axes() {
std::mem::swap(&mut w, &mut h);
}
+1 -2
View File
@@ -64,8 +64,7 @@ fn frame_crop_factor(camera: Option<f64>, focal: f64, focal_35mm: Option<f64>) -
pub fn for_raw(raw: &lightcraft_raw::RawInfo, meta: impl FnOnce() -> lightcraft_meta::Metadata) -> Option<EmbeddedLens> {
crate::files::embedded_lens(raw).or_else(|| {
let db = database()?;
let c = raw.crop.clipped(raw.active_area.width, raw.active_area.height);
let (w, h) = if c.width == 0 || c.height == 0 { (raw.active_area.width, raw.active_area.height) } else { (c.width, c.height) };
let (w, h) = raw.developed_size();
lookup(db, &meta(), w as f64, h as f64, raw.orientation)
})
}
+1
View File
@@ -584,6 +584,7 @@ pub(crate) fn synthetic_dng_of(w: usize, h: usize, cfa: &str, data: Vec<u16>, xm
},
wb_multipliers: None,
linearized: false,
pixel_aspect: 1.0,
opcodes: OpcodeLists::default(),
metadata,
};