summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHubert Figuière <hub@figuiere.net>2023-08-18 23:38:09 -0400
committerHubert Figuière <hub@figuiere.net>2023-08-18 23:39:23 -0400
commit2b2c4c10d62702b025ab19a3b771419f2f147dd3 (patch)
tree380e4426529ae51922803719db5ac0dd64e3fbea /src
parent2822d89e15018d2582bc990d0201ed60d6aa7ccd (diff)
arw: Extract white balance from some files
- also extract the whites and blacks
Diffstat (limited to 'src')
-rw-r--r--src/sony.rs56
-rw-r--r--src/tiff/dir.rs10
-rw-r--r--src/tiff/exif/tags.rs7
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;