diff options
author | Hubert Figuière <hub@figuiere.net> | 2023-08-18 23:38:09 -0400 |
---|---|---|
committer | Hubert Figuière <hub@figuiere.net> | 2023-08-18 23:39:23 -0400 |
commit | 2b2c4c10d62702b025ab19a3b771419f2f147dd3 (patch) | |
tree | 380e4426529ae51922803719db5ac0dd64e3fbea /src | |
parent | 2822d89e15018d2582bc990d0201ed60d6aa7ccd (diff) |
arw: Extract white balance from some files
- also extract the whites and blacks
Diffstat (limited to 'src')
-rw-r--r-- | src/sony.rs | 56 | ||||
-rw-r--r-- | src/tiff/dir.rs | 10 | ||||
-rw-r--r-- | src/tiff/exif/tags.rs | 7 |
3 files changed, 68 insertions, 5 deletions
diff --git a/src/sony.rs b/src/sony.rs index 334afab..621c5ed 100644 --- a/src/sony.rs +++ b/src/sony.rs @@ -31,10 +31,12 @@ use crate::colour::BuiltinMatrix; use crate::container::RawContainer; use crate::io::Viewer; use crate::rawfile::{RawFileHandleType, ThumbnailStorage}; -use crate::tiff; use crate::tiff::exif; use crate::tiff::Dir; -use crate::{Dump, Error, RawFile, RawFileHandle, RawFileImpl, RawImage, Result, Type, TypeId}; +use crate::{tiff, utils}; +use crate::{ + Bitmap, Dump, Error, RawFile, RawFileHandle, RawFileImpl, RawImage, Rect, Result, Type, TypeId, +}; macro_rules! sony { ($id:expr, $model:ident) => { @@ -818,7 +820,55 @@ impl RawFileImpl for ArwFile { self.ifd(tiff::IfdType::Raw) .ok_or(Error::NotFound) .and_then(|dir| { - tiff::tiff_get_rawdata(self.container.get().unwrap(), dir, self.type_()) + tiff::tiff_get_rawdata(self.container.get().unwrap(), dir, self.type_()).map( + |mut rawimage| { + let active_area = dir + .uint_value_array(exif::ARW_TAG_SONY_CROP_TOP_LEFT) + .and_then(|top_left| { + if top_left.len() < 2 { + log::error!("Top Left: not enough elements"); + return None; + } + dir.uint_value_array(exif::ARW_TAG_SONY_CROP_SIZE).and_then( + |size| { + if size.len() < 2 { + log::error!("Crop Size: not enough elements"); + return None; + } + Some(Rect { + x: top_left[1], + y: top_left[0], + width: size[0], + height: size[1], + }) + }, + ) + }) + .unwrap_or_else(|| Rect { + x: 0, + y: 0, + width: rawimage.width(), + height: rawimage.height(), + }); + rawimage.set_active_area(Some(active_area)); + + if let Some(wb) = + dir.int_value_array(exif::ARW_TAG_WB_RGGB_LEVELS).map(|v| { + let g = v[1] as f64; + [g / v[0] as f64, 1.0, g / v[3] as f64] + }) + { + rawimage.set_as_shot_neutral(&wb); + } + if let Some(blacks) = dir.uint_value_array(exif::ARW_TAG_BLACK_LEVELS) { + rawimage.set_blacks(utils::to_quad(&blacks)); + } + if let Some(whites) = dir.uint_value_array(exif::DNG_TAG_WHITE_LEVEL) { + rawimage.set_whites(utils::to_quad(&whites)); + } + rawimage + }, + ) }) } } diff --git a/src/tiff/dir.rs b/src/tiff/dir.rs index ff766db..316985d 100644 --- a/src/tiff/dir.rs +++ b/src/tiff/dir.rs @@ -548,13 +548,19 @@ impl Dir { }) } - /// Get and unsigned integer that could be either size. + /// Get an array of unsigned integers that could be either size. pub fn uint_value_array(&self, tag: u16) -> Option<Vec<u32>> { self.entry(tag) .and_then(|e| e.uint_value_array(self.endian())) } - /// Get and unsigned integer that could be either size. + /// Get an array of signed integers that could be either size. + pub fn int_value_array(&self, tag: u16) -> Option<Vec<i32>> { + self.entry(tag) + .and_then(|e| e.int_value_array(self.endian())) + } + + /// Get an array of floats that could be either size. pub fn float_value_array(&self, tag: u16) -> Option<Vec<f64>> { self.entry(tag) .and_then(|e| e.float_value_array(self.endian())) diff --git a/src/tiff/exif/tags.rs b/src/tiff/exif/tags.rs index 10450f2..40e4134 100644 --- a/src/tiff/exif/tags.rs +++ b/src/tiff/exif/tags.rs @@ -154,11 +154,18 @@ pub const DNG_TAG_REDUCTION_MATRIX2: u16 = 0xc626; pub const DNG_TAG_ANALOG_BALANCE: u16 = 0xc627; pub const DNG_TAG_AS_SHOT_NEUTRAL: u16 = 0xc628; pub const DNG_TAG_AS_SHOT_WHITE_XY: u16 = 0xc629; +pub const DNG_TAG_DNG_PRIVATE: u16 = 0xc634; pub const DNG_TAG_CALIBRATION_ILLUMINANT1: u16 = 0xc65a; pub const DNG_TAG_CALIBRATION_ILLUMINANT2: u16 = 0xc65b; pub const DNG_TAG_ORIGINAL_RAW_FILE_NAME: u16 = 0xc68b; pub const DNG_TAG_ACTIVE_AREA: u16 = 0xc68d; +/* ARW tags */ +pub const ARW_TAG_BLACK_LEVELS: u16 = 0x7310; +pub const ARW_TAG_WB_RGGB_LEVELS: u16 = 0x7313; +pub const ARW_TAG_SONY_CROP_TOP_LEFT: u16 = 0x74c7; +pub const ARW_TAG_SONY_CROP_SIZE: u16 = 0x74c8; + /* ERF tags */ pub const ERF_TAG_PREVIEW_IMAGE: u16 = 0x280; |