about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgennyble <gen@nyble.dev>2023-06-07 22:16:46 -0500
committergennyble <gen@nyble.dev>2023-06-07 22:16:46 -0500
commitfec06e239bc30f1268faa1716598ba4901f29f22 (patch)
treeb7f81dd756d77fee5eb531c78344e5e42713d532
parentc9b378dedf79b9b372991c283b9dd49536e8fc64 (diff)
downloadlri-rs-fec06e239bc30f1268faa1716598ba4901f29f22.tar.gz
lri-rs-fec06e239bc30f1268faa1716598ba4901f29f22.zip
file has no gaps!!!
-rw-r--r--README.md10
-rw-r--r--src/main.rs145
2 files changed, 92 insertions, 63 deletions
diff --git a/README.md b/README.md
index e32f239..9d27d22 100644
--- a/README.md
+++ b/README.md
@@ -32,4 +32,12 @@ The header is 32 bytes long. and goes as follows:
 | 1     | type (?) |
 | 7     | reserved |
 
-and then follows the message which already has a known length
\ No newline at end of file
+and then follows the message which already has a known length
+
+## Image Sensors
+
+| Sensor | Resolutions | Output |
+| - | - | - |
+| AR0835HS | 8 Mp: 3264 × 2448, 6 Mp: 3264 × 1836 | 10−bit Raw, 10−to−8 bit A−Law, 8/6−bit DPCM |
+| AR1335 | 4208 × 3120 | DPCM: 10-8-10, 10-6-10 |
+| IMX386 | 4032 x 3024 | ? |
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
index da8750e..e7491ba 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,7 @@
-use std::fs::File;
+use std::{fs::File, path::Path};
 
 use lri_rs::Message;
+use png::{BitDepth, ColorType};
 
 // This code is going to be rough. Just trying to parse this using the technique
 // I know: just play with the raw data
@@ -10,91 +11,98 @@ fn main() {
 
 	println!("Read {:.2}MB", data.len() as f32 / (1024.0 * 1024.0));
 
-	let header = LightHeader::new(&data[0..32]);
-	let whole_data = &data;
-	let data = &data[32..];
-
-	let LightHeader {
-		magic_number,
-		combined_length,
-		header_length,
-		message_length,
-		kind,
-		reserved,
-	} = header;
-
-	//AHHH it does not seem the combined legth or header length are correct? it seems like nonsense?
-	//drat. we'll know when I try and parse the message I think I extracted. 1510 bytes seems too
-	//small almost.
-	//the thing that makes me suspicious, and think it's right, is that the reserved are all 0x00
-	//and then the next byte is data, so.
-	println!("\nMagic: {magic_number}\nCombined Length: {combined_length}\nHeader Length: {header_length}\nMessage Length: {message_length}\nKind: {kind}\nReserved: {reserved:?}\nNext 8 Bytes: {:?}", &data[0..8]);
-
-	let message = &data[..message_length as usize];
-	//let data = &data[message_length as usize..];
-
-	//let asdf = lri_rs::LightHeader::parse_from_bytes(&data).unwrap();
-	//println!("{:?}", asdf.get_image_time_stamp());
-
-	// The camera says wall.lri was taken Jun 7, 2023 at 07:14 PM. Perhaps I can search the data for this
-	// to try and find a reference
-	// Used protobufpal.com to make this so i can look for it. it's the year/month/day of the date
-	let looking = [
-		0x08, 0xe7, 0x0f, 0x10, 0x06, 0x18, 0x07, 0x20, 0x13, 0x28, 0x0e,
-	];
-
-	println!("\nTook Message of {message_length} bytes");
-	println!("{} bytes left", data.len());
-
-	println!("\nLooking for timestamp...");
-
-	for idx in 0..data.len() - looking.len() {
-		if &data[idx..idx + looking.len()] == looking.as_slice() {
-			println!("Found! Offset {idx}");
-		}
-	}
-
 	let magic_id = [76, 69, 76, 82];
 	let magic_id_skip = 21;
 	let reserved = [0, 0, 0, 0, 0, 0, 0];
 	let look_length = magic_id.len() + magic_id_skip + reserved.len();
 
+	let mut heads = vec![];
+
 	println!("\nLooking for LELR");
-	for idx in 0..whole_data.len() - look_length {
-		if &whole_data[idx..idx + magic_id.len()] == magic_id.as_slice() {
+	for idx in 0..data.len() - look_length {
+		if &data[idx..idx + magic_id.len()] == magic_id.as_slice() {
 			print!("Found! Offset {idx} - ");
 
 			let reserved_start = idx + magic_id.len() + magic_id_skip;
-			if &whole_data[reserved_start..reserved_start + reserved.len()] == reserved.as_slice() {
+			if &data[reserved_start..reserved_start + reserved.len()] == reserved.as_slice() {
 				println!("Reserved matched!");
+
+				let header = LightHeader::new(&data[idx..]);
+				let start = idx;
+				let end = start + header.combined_length as usize;
+
+				heads.push(HeaderAndOffset { header, start, end });
 			} else {
 				println!("No reserve match :(");
 			}
 		}
 	}
 
-	let rt = (data.len() as f32 / 2.0).sqrt().floor() as usize;
-	println!("\n{} png", rt * rt);
+	println!("\nFound {} LightHeaders", heads.len());
+	for idx in 1..heads.len() {
+		let this = &heads[idx];
+		let before = &heads[idx - 1];
+
+		if before.end != this.start {
+			println!(
+				"Headers {} and {} are gapped by {} bytes",
+				idx - 1,
+				idx,
+				this.start - before.end
+			);
+		} else {
+			println!("{} and {} are consecutive with no gap!", idx - 1, idx);
+		}
+	}
 
-	println!("{:?}", &data[0..32]);
+	let end_difference = heads.last().unwrap().end - data.len();
+	if end_difference > 0 {
+		println!("{} bytes at the end", end_difference);
+	} else {
+		println!("File has no extraneous data at the end!");
+	}
+}
 
-	let width = rt / 8;
-	let height = rt * 4;
-	let pixels = width * height;
+fn make_png<P: AsRef<Path>>(
+	path: P,
+	width: usize,
+	height: usize,
+	color: ColorType,
+	depth: BitDepth,
+	data: &[u8],
+) {
+	let bpp = match (color, depth) {
+		(ColorType::Grayscale, BitDepth::Eight) => 1,
+		(ColorType::Grayscale, BitDepth::Sixteen) => 2,
+		(ColorType::Rgb, BitDepth::Eight) => 3,
+		(ColorType::Rgb, BitDepth::Sixteen) => 6,
+		_ => panic!("unsupported color or depth"),
+	};
+
+	let pix = width * height;
 
 	let file = File::create("ahh.png").unwrap();
 	let mut enc = png::Encoder::new(file, width as u32, height as u32);
-	enc.set_color(png::ColorType::Grayscale);
-	enc.set_depth(png::BitDepth::Sixteen);
+	enc.set_color(color);
+	enc.set_depth(depth);
 	let mut writer = enc.write_header().unwrap();
-	writer
-		.write_image_data(&data[rt * 3..(rt * 3) + pixels * 2])
-		.unwrap();
+	writer.write_image_data(&data[..pix * bpp]).unwrap();
+}
+
+struct HeaderAndOffset {
+	header: LightHeader,
+	// Inclusive
+	start: usize,
+	// Exclusive
+	end: usize,
 }
 
 struct LightHeader {
 	magic_number: String,
 	combined_length: u64,
+	//FIXME: This appears to be the content length and not the header length? I thought
+	//it was weird that they were putting the header length here. Is the java decomp
+	//wrong?
 	header_length: u64,
 	message_length: u32,
 	// type
@@ -106,13 +114,13 @@ impl LightHeader {
 	pub fn new(data: &[u8]) -> Self {
 		let magic_number = String::from_utf8(data[0..4].to_vec()).unwrap();
 		let combined_length = u64::from_le_bytes(data[4..12].try_into().unwrap());
-		println!("Combined Length: {:?}", &data[4..12]);
+		//println!("Combined Length: {:?}", &data[4..12]);
 
 		let header_length = u64::from_le_bytes(data[12..20].try_into().unwrap());
-		println!("Header Length: {:?}", &data[12..20]);
+		//println!("Header Length: {:?}", &data[12..20]);
 
 		let message_length = u32::from_le_bytes(data[20..24].try_into().unwrap());
-		println!("Message Length: {:?}", &data[20..24]);
+		//println!("Message Length: {:?}", &data[20..24]);
 
 		let kind = data[24];
 		let reserved = data[25..32].try_into().unwrap();
@@ -126,4 +134,17 @@ impl LightHeader {
 			reserved,
 		}
 	}
+
+	pub fn print_info(&self) {
+		let LightHeader {
+			magic_number,
+			combined_length,
+			header_length,
+			message_length,
+			kind,
+			reserved,
+		} = self;
+
+		println!("\nMagic: {magic_number}\nCombined Length: {combined_length}\nHeader Length: {header_length}\nMessage Length: {message_length}\nKind: {kind}\nReserved: {reserved:?}");
+	}
 }