diff options
Diffstat (limited to 'prism/src')
-rw-r--r-- | prism/src/main.rs | 78 | ||||
-rw-r--r-- | prism/src/unpack.rs | 62 |
2 files changed, 140 insertions, 0 deletions
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; + } + } +} |