about summary refs log tree commit diff
path: root/prism
diff options
context:
space:
mode:
authorgennyble <gen@nyble.dev>2023-09-10 02:44:01 -0500
committergennyble <gen@nyble.dev>2023-09-10 02:44:01 -0500
commita962ba9c853a797e9a41b2830ec0181b167d8cd9 (patch)
tree7de53dfcaf87c5d4b43f2e8b38161eb193c136ad /prism
parent70187683361d97a8b5a251567323c323c90302f2 (diff)
downloadlri-rs-a962ba9c853a797e9a41b2830ec0181b167d8cd9.tar.gz
lri-rs-a962ba9c853a797e9a41b2830ec0181b167d8cd9.zip
reorg
Diffstat (limited to 'prism')
-rw-r--r--prism/Cargo.toml10
-rw-r--r--prism/src/main.rs78
-rw-r--r--prism/src/unpack.rs62
3 files changed, 150 insertions, 0 deletions
diff --git a/prism/Cargo.toml b/prism/Cargo.toml
new file mode 100644
index 0000000..7301109
--- /dev/null
+++ b/prism/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "prism"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+lri-rs = { path = "../lri-rs" }
+png = "0.17.10"
diff --git a/prism/src/main.rs b/prism/src/main.rs
new file mode 100644
index 0000000..7660ae3
--- /dev/null
+++ b/prism/src/main.rs
@@ -0,0 +1,78 @@
+use lri_rs::LriFile;
+
+fn main() {
+    let file_name = std::env::args().nth(1).unwrap();
+    let bytes = std::fs::read(file_name).unwrap();
+    let lri = LriFile::decode(bytes);
+
+    println!("{} blocks", lri.blocks.len());
+    println!("{} images", lri.image_count());
+}
+
+/*fn good(models: &[&SensorModel], img: RawImage, img_id: usize) {
+    let RawImage {
+        sensor_id,
+        width,
+        height,
+        format,
+        data,
+    } = img;
+
+    println!(
+        "{sensor_id} {width}x{height} {format} - {} kB",
+        data.len() / 1024
+    );
+    return;
+
+    for model in models {
+        println!("{:?}", model.whitepoint);
+    }
+
+    for color in models {
+        let size = width * height;
+        let mut ten_data = vec![0; size];
+        crate::unpack::tenbit(data, width * height, ten_data.as_mut_slice());
+
+        let mut rawimg: Image<u16, BayerRgb> = Image::from_raw_parts(
+            4160,
+            3120,
+            RawMetadata {
+                whitebalance: [1.0 / color.rg, 1.0, 1.0 / color.bg],
+                whitelevels: [1024, 1024, 1024],
+                crop: None,
+                cfa: CFA::new("BGGR"),
+                cam_to_xyz: Matrix3::from_row_slice(&color.forward_matrix),
+            },
+            ten_data,
+        );
+
+        /*rawimg
+        .data
+        .iter_mut()
+        .for_each(|p| *p = p.saturating_sub(42));*/
+
+        rawimg.whitebalance();
+        let img = rawimg.debayer();
+        let srgb = img.to_xyz().to_linsrgb().gamma();
+        let bytes = srgb.floats().bytes();
+
+        make_png(
+            format!("tenbit_{img_id}_{:?}.png", color.whitepoint),
+            width,
+            height,
+            &bytes.data,
+        );
+    }
+}*/
+
+fn make_png<P: AsRef<std::path::Path>>(path: P, width: usize, height: usize, data: &[u8]) {
+    //return;
+    use std::fs::File;
+
+    let file = File::create(path).unwrap();
+    let mut enc = png::Encoder::new(file, width as u32, height as u32);
+    enc.set_color(png::ColorType::Rgb);
+    enc.set_depth(png::BitDepth::Eight);
+    let mut writer = enc.write_header().unwrap();
+    writer.write_image_data(data).unwrap();
+}
diff --git a/prism/src/unpack.rs b/prism/src/unpack.rs
new file mode 100644
index 0000000..03e0018
--- /dev/null
+++ b/prism/src/unpack.rs
@@ -0,0 +1,62 @@
+const TEN_MASK: u64 = 1023; // ten bits
+
+pub fn tenbit(packd: &[u8], count: usize, upack: &mut [u16]) {
+	let required_len_packd = (count as f32 * (10.0 / 8.0)).ceil() as usize;
+
+	println!(
+		"requires {required_len_packd} bytes | {} groups of 5",
+		count / 4
+	);
+
+	if count > upack.len() {
+		panic!(
+			"expected output buffer to be {count} bytes, got {} bytes",
+			upack.len()
+		)
+	}
+
+	if required_len_packd > packd.len() {
+		panic!(
+			"expected input to be at least {required_len_packd} bytes, it was {}",
+			packd.len()
+		)
+	}
+
+	let mut packd = packd[..required_len_packd].to_vec();
+	packd.reverse();
+	let chunker = packd.chunks_exact(5);
+	let remain = chunker.remainder();
+
+	for (idx, chnk) in chunker.enumerate() {
+		let long = u64::from_be_bytes([
+			0x00, 0x00, 0x00, chnk[0], chnk[1], chnk[2], chnk[3], chnk[4],
+		]);
+
+		let b4 = long & TEN_MASK;
+		let b3 = (long >> 10) & TEN_MASK;
+		let b2 = (long >> 20) & TEN_MASK;
+		let b1 = (long >> 30) & TEN_MASK;
+
+		let idx = idx * 4;
+		upack[idx] = b1 as u16;
+		upack[idx + 1] = b2 as u16;
+		upack[idx + 2] = b3 as u16;
+		upack[idx + 3] = b4 as u16;
+	}
+
+	if remain.len() > 0 {
+		let mut long_bytes = [0x00; 8];
+
+		for (idx, byte) in remain.iter().enumerate() {
+			long_bytes[idx] = *byte;
+		}
+
+		let long = u64::from_le_bytes(long_bytes);
+
+		let count_remain = count % 4;
+		let start = count - count_remain;
+		for idx in 0..count_remain {
+			upack[start + idx] = ((long >> (10 * idx)) & TEN_MASK) as u16;
+		}
+	}
+}