diff --git a/src/decoders/dng.rs b/src/decoders/dng.rs index 38111e2..5d4dfce 100644 --- a/src/decoders/dng.rs +++ b/src/decoders/dng.rs @@ -76,6 +76,7 @@ impl<'a> Decoder for DngDecoder<'a> { xyz_to_cam: try!(self.get_color_matrix()), cfa: if linear {CFA::new("")} else {try!(self.get_cfa(raw))}, crops: try!(self.get_crops(raw, width, height)), + blackarea: self.get_masked_areas(raw), orientation: orientation, }) } @@ -124,6 +125,23 @@ impl<'a> DngDecoder<'a> { } } + fn get_masked_areas(&self, raw: &TiffIFD) -> Vec<(u64, u64, u64, u64)> { + let mut areas = Vec::new(); + + if let Some(masked_area) = raw.find_entry(Tag::MaskedAreas) { + for x in (0..masked_area.count()).step_by(4) { + areas.push(( + masked_area.get_u32(x).into(), + masked_area.get_u32(x + 1).into(), + masked_area.get_u32(x + 2).into(), + masked_area.get_u32(x + 3).into() + )); + } + } + + areas + } + fn get_color_matrix(&self) -> Result<[[f32;3];4],String> { let mut matrix: [[f32;3];4] = [[0.0;3];4]; let cmatrix = { diff --git a/src/decoders/image.rs b/src/decoders/image.rs index 050fe10..2690147 100644 --- a/src/decoders/image.rs +++ b/src/decoders/image.rs @@ -31,6 +31,11 @@ pub struct RawImage { pub cfa: CFA, /// how much to crop the image to get all the usable area, order is top, right, bottom, left pub crops: [usize;4], + + /// Areas of the sensor that is masked to prevent it from receiving light. Used to calculate + /// black levels and noise. Each tuple represents a masked rectangle's top, right, bottom, left + pub blackarea: Vec<(u64,u64,u64,u64)>, + /// orientation of the image as indicated by the image metadata pub orientation: Orientation, /// image data itself, has width*height*cpp elements @@ -73,6 +78,19 @@ impl RawImage { camera.blacklevels }; + // tuple format is top, right, bottom left + let mut blackarea: Vec<(u64,u64,u64,u64)> = Vec::new(); + + if camera.blackareah.1 != 0 { + blackarea.push((camera.blackareah.0 as u64, width as u64, + (camera.blackareah.0 + camera.blackareah.1) as u64, 0)); + } + + if camera.blackareav.1 != 0 { + blackarea.push((0, (camera.blackareav.0 + camera.blackareav.1) as u64, + height as u64, camera.blackareav.0 as u64)) + } + RawImage { make: camera.make.clone(), model: camera.model.clone(), @@ -88,6 +106,7 @@ impl RawImage { xyz_to_cam: camera.xyz_to_cam, cfa: camera.cfa.clone(), crops: camera.crops, + blackarea: blackarea, orientation: camera.orientation, } } diff --git a/src/decoders/raf.rs b/src/decoders/raf.rs index b2f7e3f..f2217f2 100644 --- a/src/decoders/raf.rs +++ b/src/decoders/raf.rs @@ -80,6 +80,7 @@ impl<'a> Decoder for RafDecoder<'a> { xyz_to_cam: camera.xyz_to_cam, cfa: camera.cfa.clone(), crops: [0,0,0,0], + blackarea: Vec::new(), orientation: camera.orientation, }) } else { diff --git a/src/decoders/tiff.rs b/src/decoders/tiff.rs index ad754a4..f9741a1 100644 --- a/src/decoders/tiff.rs +++ b/src/decoders/tiff.rs @@ -81,6 +81,7 @@ pub enum Tag { DNGPrivateArea = 0xC634, Cr2StripeWidths = 0xC640, ActiveArea = 0xC68D, + MaskedAreas = 0xC68E, RafRawSubIFD = 0xF000, RafImageWidth = 0xF001, RafImageLength = 0xF002,