about summary refs log tree commit diff
path: root/lri-rs/src/block.rs
diff options
context:
space:
mode:
Diffstat (limited to 'lri-rs/src/block.rs')
-rw-r--r--lri-rs/src/block.rs106
1 files changed, 94 insertions, 12 deletions
diff --git a/lri-rs/src/block.rs b/lri-rs/src/block.rs
index 2dc921b..4ee0ea1 100644
--- a/lri-rs/src/block.rs
+++ b/lri-rs/src/block.rs
@@ -1,9 +1,11 @@
+use std::time::Duration;
+
 use lri_proto::{
 	gps_data::GPSData, lightheader::LightHeader, matrix3x3f::Matrix3x3F,
 	view_preferences::ViewPreferences, Message as PbMessage,
 };
 
-use crate::{CameraId, CameraInfo, ColorInfo, RawImage, SensorModel};
+use crate::{CameraId, CameraInfo, ColorInfo, DataFormat, RawData, RawImage, SensorModel};
 
 pub(crate) struct Block<'lri> {
 	pub header: Header,
@@ -37,24 +39,27 @@ impl<'lri> Block<'lri> {
 
 	pub fn extract_meaningful_data(
 		&self,
+		ext: &mut ExtractedData,
 		images: &mut Vec<RawImage<'lri>>,
 		colors: &mut Vec<ColorInfo>,
 		infos: &mut Vec<CameraInfo>,
-	) -> ExtractedData {
-		let mut ext = ExtractedData {
-			reference_camera: None,
-		};
-
+	) {
 		let LightHeader {
 			mut hw_info,
-			mut module_calibration,
-			mut modules,
-			mut image_reference_camera,
+			module_calibration,
+			modules,
+			image_reference_camera,
+			device_fw_version,
+			image_focal_length,
+			af_info,
 			..
 		} = if let Message::LightHeader(lh) = self.message() {
 			lh
+		} else if let Message::ViewPreferences(vp) = self.message() {
+			self.extract_view(vp, ext);
+			return;
 		} else {
-			return ext;
+			return;
 		};
 
 		// Form the CameraInfo struct for mapping CameraId to SensorType
@@ -117,7 +122,51 @@ impl<'lri> Block<'lri> {
 			let data_length = surface.row_stride() as usize * height;
 
 			let format = surface.format().into();
-			let image_data = &self.data[offset..offset + data_length];
+			let image_data = match format {
+				DataFormat::BayerJpeg => {
+					let bjpg_header_len = 1576;
+					let mut wrk = &self.data[offset..];
+
+					let format = u32::from_le_bytes(wrk[4..8].try_into().unwrap());
+
+					let jpeg0_len = u32::from_le_bytes(wrk[8..12].try_into().unwrap()) as usize;
+					let jpeg1_len = u32::from_le_bytes(wrk[12..16].try_into().unwrap()) as usize;
+					let jpeg2_len = u32::from_le_bytes(wrk[16..20].try_into().unwrap()) as usize;
+					let jpeg3_len = u32::from_le_bytes(wrk[20..24].try_into().unwrap()) as usize;
+
+					let mut get = |len: usize| -> &[u8] {
+						let data = &wrk[..len];
+						wrk = &wrk[len..];
+						data
+					};
+
+					let header = get(bjpg_header_len);
+					let jpeg0 = get(jpeg0_len);
+
+					match format {
+						1 => RawData::BayerJpeg {
+							header,
+							format,
+							jpeg0,
+							jpeg1: &wrk[0..0],
+							jpeg2: &wrk[0..0],
+							jpeg3: &wrk[0..0],
+						},
+						0 => RawData::BayerJpeg {
+							header,
+							format,
+							jpeg0,
+							jpeg1: get(jpeg1_len),
+							jpeg2: get(jpeg2_len),
+							jpeg3: get(jpeg3_len),
+						},
+						_ => unreachable!(),
+					}
+				}
+				DataFormat::Packed10bpp => RawData::Packed10bpp {
+					data: &self.data[offset..offset + data_length],
+				},
+			};
 
 			let sbro = module.sensor_bayer_red_override.clone().unwrap();
 
@@ -139,7 +188,17 @@ impl<'lri> Block<'lri> {
 			ext.reference_camera = Some(irc.into());
 		}
 
-		ext
+		if let Some(afd) = af_info.clone().take() {
+			ext.af_achieved.get_or_insert(afd.focus_achieved());
+		}
+
+		if let Some(fwv) = device_fw_version {
+			ext.fw_version.get_or_insert(fwv);
+		}
+
+		if let Some(x) = image_focal_length {
+			ext.focal_length.get_or_insert(x);
+		}
 	}
 
 	// It kept making my neat little array very, very tall
@@ -151,10 +210,33 @@ impl<'lri> Block<'lri> {
 			mat.x20(), mat.x21(), mat.x22(),
 		]
 	}
+
+	fn extract_view(&self, vp: ViewPreferences, ext: &mut ExtractedData) {
+		let ViewPreferences {
+			image_integration_time_ns,
+			image_gain,
+			..
+		} = vp;
+
+		if let Some(ns) = image_integration_time_ns {
+			ext.image_integration_time = Some(Duration::from_nanos(ns));
+		}
+
+		if let Some(g) = image_gain {
+			ext.image_gain.get_or_insert(g);
+		}
+	}
 }
 
+#[derive(Debug, Default)]
 pub(crate) struct ExtractedData {
 	pub reference_camera: Option<CameraId>,
+	pub fw_version: Option<String>,
+	pub focal_length: Option<i32>,
+
+	pub image_gain: Option<f32>,
+	pub image_integration_time: Option<Duration>,
+	pub af_achieved: Option<bool>,
 }
 
 pub enum Message {