about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitignore11
-rw-r--r--Cargo.lock751
-rw-r--r--Cargo.toml19
-rw-r--r--LICENSE121
-rw-r--r--lri-proto/.gitignore1
-rw-r--r--lri-proto/Cargo.lock45
-rw-r--r--lri-proto/Cargo.toml13
-rw-r--r--lri-proto/LICENSE (renamed from lri-rs/LICENSE)0
-rw-r--r--lri-proto/README.md2
-rw-r--r--lri-proto/build.rs50
-rw-r--r--lri-proto/proto/camera_id.proto (renamed from lri-rs/proto/camera_id.proto)0
-rw-r--r--lri-proto/proto/camera_module.proto (renamed from lri-rs/proto/camera_module.proto)0
-rw-r--r--lri-proto/proto/color_calibration.proto (renamed from lri-rs/proto/color_calibration.proto)0
-rw-r--r--lri-proto/proto/dead_pixel_map.proto (renamed from lri-rs/proto/dead_pixel_map.proto)0
-rw-r--r--lri-proto/proto/device_temp.proto (renamed from lri-rs/proto/device_temp.proto)0
-rw-r--r--lri-proto/proto/distortion.proto (renamed from lri-rs/proto/distortion.proto)0
-rw-r--r--lri-proto/proto/face_data.proto (renamed from lri-rs/proto/face_data.proto)0
-rw-r--r--lri-proto/proto/flash_calibration.proto (renamed from lri-rs/proto/flash_calibration.proto)0
-rw-r--r--lri-proto/proto/geometric_calibration.proto (renamed from lri-rs/proto/geometric_calibration.proto)0
-rw-r--r--lri-proto/proto/gps_data.proto (renamed from lri-rs/proto/gps_data.proto)0
-rw-r--r--lri-proto/proto/hot_pixel_map.proto (renamed from lri-rs/proto/hot_pixel_map.proto)0
-rw-r--r--lri-proto/proto/hw_info.proto (renamed from lri-rs/proto/hw_info.proto)0
-rw-r--r--lri-proto/proto/imu_data.proto (renamed from lri-rs/proto/imu_data.proto)0
-rw-r--r--lri-proto/proto/lightheader.proto (renamed from lri-rs/proto/lightheader.proto)0
-rw-r--r--lri-proto/proto/matrix3x3f.proto (renamed from lri-rs/proto/matrix3x3f.proto)0
-rw-r--r--lri-proto/proto/matrix4x4f.proto (renamed from lri-rs/proto/matrix4x4f.proto)0
-rw-r--r--lri-proto/proto/mirror_system.proto (renamed from lri-rs/proto/mirror_system.proto)0
-rw-r--r--lri-proto/proto/point2f.proto (renamed from lri-rs/proto/point2f.proto)0
-rw-r--r--lri-proto/proto/point2i.proto (renamed from lri-rs/proto/point2i.proto)0
-rw-r--r--lri-proto/proto/point3f.proto (renamed from lri-rs/proto/point3f.proto)0
-rw-r--r--lri-proto/proto/proximity_sensors.proto (renamed from lri-rs/proto/proximity_sensors.proto)0
-rw-r--r--lri-proto/proto/range2f.proto (renamed from lri-rs/proto/range2f.proto)0
-rw-r--r--lri-proto/proto/rectanglei.proto (renamed from lri-rs/proto/rectanglei.proto)0
-rw-r--r--lri-proto/proto/sensor_characterization.proto (renamed from lri-rs/proto/sensor_characterization.proto)0
-rw-r--r--lri-proto/proto/sensor_type.proto (renamed from lri-rs/proto/sensor_type.proto)0
-rw-r--r--lri-proto/proto/time_stamp.proto (renamed from lri-rs/proto/time_stamp.proto)0
-rw-r--r--lri-proto/proto/tof_calibration.proto (renamed from lri-rs/proto/tof_calibration.proto)0
-rw-r--r--lri-proto/proto/view_preferences.proto (renamed from lri-rs/proto/view_preferences.proto)0
-rw-r--r--lri-proto/proto/vignetting_characterization.proto (renamed from lri-rs/proto/vignetting_characterization.proto)0
-rw-r--r--lri-proto/src/lib.rs4
-rw-r--r--lri-rs/.gitignore2
-rw-r--r--lri-rs/Cargo.lock380
-rw-r--r--lri-rs/Cargo.toml11
-rw-r--r--lri-rs/README.md4
-rw-r--r--lri-rs/build.rs50
-rw-r--r--lri-rs/src/lib.rs400
-rw-r--r--lri-rs/src/main.rs22
-rw-r--r--prism/Cargo.toml (renamed from unpacker/Cargo.toml)4
-rw-r--r--prism/src/main.rs78
-rw-r--r--prism/src/unpack.rs62
-rw-r--r--src/main.rs424
-rw-r--r--unpacker/Cargo.lock7
-rw-r--r--unpacker/src/lib.rs44
-rw-r--r--unpacker/src/main.rs31
54 files changed, 766 insertions, 1770 deletions
diff --git a/.gitignore b/.gitignore
index fd89993..54466f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,2 @@
-**/target
-*.png
-*.jpg
-*.lri_part
-*.protodump
+/target
 
-# MacOS you exhaust me. Leave me alone
-**/.DS_Store
-
-fordatadog.packed
-afterimg2
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index b28109e..253ba71 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -9,34 +9,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 
 [[package]]
-name = "adler32"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
-
-[[package]]
 name = "aho-corasick"
-version = "1.0.2"
+version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41"
+checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783"
 dependencies = [
  "memchr",
 ]
 
 [[package]]
 name = "anyhow"
-version = "1.0.71"
+version = "1.0.75"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
-
-[[package]]
-name = "approx"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
-dependencies = [
- "num-traits",
-]
+checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
 
 [[package]]
 name = "autocfg"
@@ -51,28 +36,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
-name = "bytemuck"
-version = "1.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea"
-
-[[package]]
-name = "byteorder"
-version = "1.4.3"
+name = "bitflags"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
 
 [[package]]
 name = "bytes"
-version = "1.4.0"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
+checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
 
 [[package]]
 name = "cc"
-version = "1.0.79"
+version = "1.0.83"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
+dependencies = [
+ "libc",
+]
 
 [[package]]
 name = "cfg-if"
@@ -81,12 +63,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
-name = "color_quant"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
-
-[[package]]
 name = "crc32fast"
 version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -96,80 +72,16 @@ dependencies = [
 ]
 
 [[package]]
-name = "crossbeam-channel"
-version = "0.5.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-deque"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
-dependencies = [
- "cfg-if",
- "crossbeam-epoch",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-epoch"
-version = "0.9.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
-dependencies = [
- "autocfg",
- "cfg-if",
- "crossbeam-utils",
- "memoffset",
- "scopeguard",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "deflate"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174"
-dependencies = [
- "adler32",
- "byteorder",
-]
-
-[[package]]
 name = "either"
-version = "1.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
-
-[[package]]
-name = "enumn"
-version = "0.1.8"
+version = "1.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48016319042fb7c87b78d2993084a831793a897a5cd1a2a67cab9d1eeb4b7d76"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.18",
-]
+checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
 
 [[package]]
 name = "errno"
-version = "0.3.1"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
+checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
 dependencies = [
  "errno-dragonfly",
  "libc",
@@ -188,12 +100,9 @@ dependencies = [
 
 [[package]]
 name = "fastrand"
-version = "1.9.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
-dependencies = [
- "instant",
-]
+checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
 
 [[package]]
 name = "fdeflate"
@@ -206,79 +115,27 @@ dependencies = [
 
 [[package]]
 name = "flate2"
-version = "1.0.26"
+version = "1.0.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
+checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010"
 dependencies = [
  "crc32fast",
- "miniz_oxide 0.7.1",
+ "miniz_oxide",
 ]
 
 [[package]]
-name = "getrandom"
-version = "0.2.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
-dependencies = [
- "cfg-if",
- "libc",
- "wasi",
-]
-
-[[package]]
-name = "gif"
-version = "0.11.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06"
-dependencies = [
- "color_quant",
- "weezl",
-]
-
-[[package]]
-name = "glob"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
-
-[[package]]
 name = "hashbrown"
 version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
 
 [[package]]
-name = "hermit-abi"
-version = "0.2.6"
+name = "home"
+version = "0.5.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
+checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
 dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hermit-abi"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
-
-[[package]]
-name = "image"
-version = "0.23.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1"
-dependencies = [
- "bytemuck",
- "byteorder",
- "color_quant",
- "gif",
- "jpeg-decoder",
- "num-iter",
- "num-rational 0.3.2",
- "num-traits",
- "png 0.16.8",
- "scoped_threadpool",
- "tiff",
+ "windows-sys",
 ]
 
 [[package]]
@@ -292,126 +149,43 @@ dependencies = [
 ]
 
 [[package]]
-name = "instant"
-version = "0.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "io-lifetimes"
-version = "1.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
-dependencies = [
- "hermit-abi 0.3.1",
- "libc",
- "windows-sys",
-]
-
-[[package]]
-name = "jpeg-decoder"
-version = "0.1.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2"
-dependencies = [
- "rayon",
-]
-
-[[package]]
-name = "l16-lri"
-version = "0.1.0"
-dependencies = [
- "lri-rs",
- "nalgebra",
- "png 0.17.8",
- "protobuf",
- "protobuf-json-mapping",
- "rawloader",
- "rawproc",
- "unpacker",
-]
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
-[[package]]
 name = "libc"
-version = "0.2.146"
+version = "0.2.147"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
+checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.3.8"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
+checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
 
 [[package]]
 name = "log"
-version = "0.4.19"
+version = "0.4.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
+checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
 
 [[package]]
-name = "lri-rs"
+name = "lri-proto"
 version = "0.1.0"
 dependencies = [
- "anyhow",
- "image",
  "protobuf",
  "protobuf-codegen",
- "serde",
 ]
 
 [[package]]
-name = "matrixmultiply"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "090126dc04f95dc0d1c1c91f61bdd474b3930ca064c1edc8a849da2c6cbe1e77"
+name = "lri-rs"
+version = "0.1.0"
 dependencies = [
- "autocfg",
- "rawpointer",
+ "lri-proto",
 ]
 
 [[package]]
 name = "memchr"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
-
-[[package]]
-name = "memoffset"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "miniz_oxide"
-version = "0.3.7"
+version = "2.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
-dependencies = [
- "adler32",
-]
-
-[[package]]
-name = "miniz_oxide"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
-dependencies = [
- "adler",
- "autocfg",
-]
+checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
 
 [[package]]
 name = "miniz_oxide"
@@ -424,151 +198,37 @@ dependencies = [
 ]
 
 [[package]]
-name = "nalgebra"
-version = "0.31.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20bd243ab3dbb395b39ee730402d2e5405e448c75133ec49cc977762c4cba3d1"
-dependencies = [
- "approx",
- "matrixmultiply",
- "nalgebra-macros",
- "num-complex",
- "num-rational 0.4.1",
- "num-traits",
- "simba",
- "typenum",
-]
-
-[[package]]
-name = "nalgebra-macros"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "num-complex"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
-name = "num-integer"
-version = "0.1.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
-dependencies = [
- "autocfg",
- "num-traits",
-]
-
-[[package]]
-name = "num-iter"
-version = "0.1.43"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-rational"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-rational"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-traits"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "num_cpus"
-version = "1.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
-dependencies = [
- "hermit-abi 0.2.6",
- "libc",
-]
-
-[[package]]
 name = "once_cell"
 version = "1.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
 
 [[package]]
-name = "paste"
-version = "1.0.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
-
-[[package]]
-name = "png"
-version = "0.16.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6"
-dependencies = [
- "bitflags",
- "crc32fast",
- "deflate",
- "miniz_oxide 0.3.7",
-]
-
-[[package]]
 name = "png"
-version = "0.17.8"
+version = "0.17.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aaeebc51f9e7d2c150d3f3bfeb667f2aa985db5ef1e3d212847bdedb488beeaa"
+checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64"
 dependencies = [
- "bitflags",
+ "bitflags 1.3.2",
  "crc32fast",
  "fdeflate",
  "flate2",
- "miniz_oxide 0.7.1",
+ "miniz_oxide",
 ]
 
 [[package]]
-name = "ppv-lite86"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+name = "prism"
+version = "0.1.0"
+dependencies = [
+ "lri-rs",
+ "png",
+]
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.60"
+version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
+checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
 dependencies = [
  "unicode-ident",
 ]
@@ -601,17 +261,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "protobuf-json-mapping"
-version = "3.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce19fee00c35e62179f79d622f440c27466c9f8dff68ca907d8f59dfc8a88adb"
-dependencies = [
- "protobuf",
- "protobuf-support",
- "thiserror",
-]
-
-[[package]]
 name = "protobuf-parse"
 version = "3.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -638,215 +287,75 @@ dependencies = [
 
 [[package]]
 name = "quote"
-version = "1.0.28"
+version = "1.0.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
+checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
 dependencies = [
  "proc-macro2",
 ]
 
 [[package]]
-name = "rand"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
-dependencies = [
- "libc",
- "rand_chacha",
- "rand_core",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
-dependencies = [
- "ppv-lite86",
- "rand_core",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
-dependencies = [
- "getrandom",
-]
-
-[[package]]
-name = "rawloader"
-version = "0.37.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d8c6f168c492ffd326537b3aa5a8d5fe07f0d8a3970c5957f286bcd13f888aa"
-dependencies = [
- "byteorder",
- "enumn",
- "glob",
- "lazy_static",
- "rayon",
- "rustc_version",
- "toml",
-]
-
-[[package]]
-name = "rawpointer"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
-
-[[package]]
-name = "rawproc"
-version = "0.1.0"
-source = "git+https://github.com/eclecticnybles/gaze#47dbf3f29edd932bb8e363146e7a5d1505d90c22"
-dependencies = [
- "nalgebra",
- "num-traits",
- "rand",
- "rawloader",
- "thiserror",
-]
-
-[[package]]
-name = "rayon"
-version = "1.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
-dependencies = [
- "either",
- "rayon-core",
-]
-
-[[package]]
-name = "rayon-core"
-version = "1.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
-dependencies = [
- "crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-utils",
- "num_cpus",
-]
-
-[[package]]
 name = "redox_syscall"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
 dependencies = [
- "bitflags",
+ "bitflags 1.3.2",
 ]
 
 [[package]]
 name = "regex"
-version = "1.8.4"
+version = "1.9.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
+checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47"
 dependencies = [
  "aho-corasick",
  "memchr",
+ "regex-automata",
  "regex-syntax",
 ]
 
 [[package]]
-name = "regex-syntax"
-version = "0.7.2"
+name = "regex-automata"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
+checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
 
 [[package]]
-name = "rustc_version"
-version = "0.4.0"
+name = "regex-syntax"
+version = "0.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
-dependencies = [
- "semver",
-]
+checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
 
 [[package]]
 name = "rustix"
-version = "0.37.20"
+version = "0.38.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
+checksum = "bdf14a7a466ce88b5eac3da815b53aefc208ce7e74d1c263aabb04d88c4abeb1"
 dependencies = [
- "bitflags",
+ "bitflags 2.4.0",
  "errno",
- "io-lifetimes",
  "libc",
  "linux-raw-sys",
  "windows-sys",
 ]
 
 [[package]]
-name = "safe_arch"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62a7484307bd40f8f7ccbacccac730108f2cae119a3b11c74485b48aa9ea650f"
-dependencies = [
- "bytemuck",
-]
-
-[[package]]
-name = "scoped_threadpool"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
-
-[[package]]
-name = "scopeguard"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
-
-[[package]]
-name = "semver"
-version = "1.0.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
-
-[[package]]
-name = "serde"
-version = "1.0.163"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2"
-
-[[package]]
-name = "simba"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f3fd720c48c53cace224ae62bef1bbff363a70c68c4802a78b5cc6159618176"
-dependencies = [
- "approx",
- "num-complex",
- "num-traits",
- "paste",
- "wide",
-]
-
-[[package]]
 name = "simd-adler32"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f"
-
-[[package]]
-name = "syn"
-version = "1.0.109"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
+checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
 
 [[package]]
 name = "syn"
-version = "2.0.18"
+version = "2.0.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e"
+checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -855,11 +364,10 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.6.0"
+version = "3.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
+checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
 dependencies = [
- "autocfg",
  "cfg-if",
  "fastrand",
  "redox_syscall",
@@ -869,91 +377,40 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "1.0.40"
+version = "1.0.48"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
+checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.40"
+version = "1.0.48"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
+checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.18",
-]
-
-[[package]]
-name = "tiff"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437"
-dependencies = [
- "jpeg-decoder",
- "miniz_oxide 0.4.4",
- "weezl",
-]
-
-[[package]]
-name = "toml"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
-dependencies = [
- "serde",
+ "syn",
 ]
 
 [[package]]
-name = "typenum"
-version = "1.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
-
-[[package]]
 name = "unicode-ident"
-version = "1.0.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
-
-[[package]]
-name = "unpacker"
-version = "0.1.0"
-
-[[package]]
-name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
-
-[[package]]
-name = "weezl"
-version = "0.1.7"
+version = "1.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
+checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
 
 [[package]]
 name = "which"
-version = "4.4.0"
+version = "4.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
+checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
 dependencies = [
  "either",
- "libc",
+ "home",
  "once_cell",
-]
-
-[[package]]
-name = "wide"
-version = "0.7.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40018623e2dba2602a9790faba8d33f2ebdebf4b86561b83928db735f8784728"
-dependencies = [
- "bytemuck",
- "safe_arch",
+ "rustix",
 ]
 
 [[package]]
@@ -967,9 +424,9 @@ dependencies = [
 
 [[package]]
 name = "windows-targets"
-version = "0.48.0"
+version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
 dependencies = [
  "windows_aarch64_gnullvm",
  "windows_aarch64_msvc",
@@ -982,42 +439,42 @@ dependencies = [
 
 [[package]]
 name = "windows_aarch64_gnullvm"
-version = "0.48.0"
+version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
 
 [[package]]
 name = "windows_aarch64_msvc"
-version = "0.48.0"
+version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
 
 [[package]]
 name = "windows_i686_gnu"
-version = "0.48.0"
+version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
 
 [[package]]
 name = "windows_i686_msvc"
-version = "0.48.0"
+version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
 
 [[package]]
 name = "windows_x86_64_gnu"
-version = "0.48.0"
+version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
 
 [[package]]
 name = "windows_x86_64_gnullvm"
-version = "0.48.0"
+version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
 
 [[package]]
 name = "windows_x86_64_msvc"
-version = "0.48.0"
+version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
diff --git a/Cargo.toml b/Cargo.toml
index 1650d6e..a33de68 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,16 +1,3 @@
-[package]
-name = "l16-lri"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-png = "0.17.8"
-lri-rs = { path = "lri-rs" }
-unpacker = { path = "unpacker" }
-rawproc = { git = "https://github.com/eclecticnybles/gaze" }
-rawloader = "0.37.1"
-nalgebra = "0.31.4"
-protobuf-json-mapping = "3.2.0"
-protobuf = "3.2.0"
+[workspace]
+members = ["lri-proto", "lri-rs", "prism"]
+resolver = "2"
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 0e259d4..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,121 +0,0 @@
-Creative Commons Legal Code
-
-CC0 1.0 Universal
-
-    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
-    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
-    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
-    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
-    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
-    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
-    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
-    HEREUNDER.
-
-Statement of Purpose
-
-The laws of most jurisdictions throughout the world automatically confer
-exclusive Copyright and Related Rights (defined below) upon the creator
-and subsequent owner(s) (each and all, an "owner") of an original work of
-authorship and/or a database (each, a "Work").
-
-Certain owners wish to permanently relinquish those rights to a Work for
-the purpose of contributing to a commons of creative, cultural and
-scientific works ("Commons") that the public can reliably and without fear
-of later claims of infringement build upon, modify, incorporate in other
-works, reuse and redistribute as freely as possible in any form whatsoever
-and for any purposes, including without limitation commercial purposes.
-These owners may contribute to the Commons to promote the ideal of a free
-culture and the further production of creative, cultural and scientific
-works, or to gain reputation or greater distribution for their Work in
-part through the use and efforts of others.
-
-For these and/or other purposes and motivations, and without any
-expectation of additional consideration or compensation, the person
-associating CC0 with a Work (the "Affirmer"), to the extent that he or she
-is an owner of Copyright and Related Rights in the Work, voluntarily
-elects to apply CC0 to the Work and publicly distribute the Work under its
-terms, with knowledge of his or her Copyright and Related Rights in the
-Work and the meaning and intended legal effect of CC0 on those rights.
-
-1. Copyright and Related Rights. A Work made available under CC0 may be
-protected by copyright and related or neighboring rights ("Copyright and
-Related Rights"). Copyright and Related Rights include, but are not
-limited to, the following:
-
-  i. the right to reproduce, adapt, distribute, perform, display,
-     communicate, and translate a Work;
- ii. moral rights retained by the original author(s) and/or performer(s);
-iii. publicity and privacy rights pertaining to a person's image or
-     likeness depicted in a Work;
- iv. rights protecting against unfair competition in regards to a Work,
-     subject to the limitations in paragraph 4(a), below;
-  v. rights protecting the extraction, dissemination, use and reuse of data
-     in a Work;
- vi. database rights (such as those arising under Directive 96/9/EC of the
-     European Parliament and of the Council of 11 March 1996 on the legal
-     protection of databases, and under any national implementation
-     thereof, including any amended or successor version of such
-     directive); and
-vii. other similar, equivalent or corresponding rights throughout the
-     world based on applicable law or treaty, and any national
-     implementations thereof.
-
-2. Waiver. To the greatest extent permitted by, but not in contravention
-of, applicable law, Affirmer hereby overtly, fully, permanently,
-irrevocably and unconditionally waives, abandons, and surrenders all of
-Affirmer's Copyright and Related Rights and associated claims and causes
-of action, whether now known or unknown (including existing as well as
-future claims and causes of action), in the Work (i) in all territories
-worldwide, (ii) for the maximum duration provided by applicable law or
-treaty (including future time extensions), (iii) in any current or future
-medium and for any number of copies, and (iv) for any purpose whatsoever,
-including without limitation commercial, advertising or promotional
-purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
-member of the public at large and to the detriment of Affirmer's heirs and
-successors, fully intending that such Waiver shall not be subject to
-revocation, rescission, cancellation, termination, or any other legal or
-equitable action to disrupt the quiet enjoyment of the Work by the public
-as contemplated by Affirmer's express Statement of Purpose.
-
-3. Public License Fallback. Should any part of the Waiver for any reason
-be judged legally invalid or ineffective under applicable law, then the
-Waiver shall be preserved to the maximum extent permitted taking into
-account Affirmer's express Statement of Purpose. In addition, to the
-extent the Waiver is so judged Affirmer hereby grants to each affected
-person a royalty-free, non transferable, non sublicensable, non exclusive,
-irrevocable and unconditional license to exercise Affirmer's Copyright and
-Related Rights in the Work (i) in all territories worldwide, (ii) for the
-maximum duration provided by applicable law or treaty (including future
-time extensions), (iii) in any current or future medium and for any number
-of copies, and (iv) for any purpose whatsoever, including without
-limitation commercial, advertising or promotional purposes (the
-"License"). The License shall be deemed effective as of the date CC0 was
-applied by Affirmer to the Work. Should any part of the License for any
-reason be judged legally invalid or ineffective under applicable law, such
-partial invalidity or ineffectiveness shall not invalidate the remainder
-of the License, and in such case Affirmer hereby affirms that he or she
-will not (i) exercise any of his or her remaining Copyright and Related
-Rights in the Work or (ii) assert any associated claims and causes of
-action with respect to the Work, in either case contrary to Affirmer's
-express Statement of Purpose.
-
-4. Limitations and Disclaimers.
-
- a. No trademark or patent rights held by Affirmer are waived, abandoned,
-    surrendered, licensed or otherwise affected by this document.
- b. Affirmer offers the Work as-is and makes no representations or
-    warranties of any kind concerning the Work, express, implied,
-    statutory or otherwise, including without limitation warranties of
-    title, merchantability, fitness for a particular purpose, non
-    infringement, or the absence of latent or other defects, accuracy, or
-    the present or absence of errors, whether or not discoverable, all to
-    the greatest extent permissible under applicable law.
- c. Affirmer disclaims responsibility for clearing rights of other persons
-    that may apply to the Work or any use thereof, including without
-    limitation any person's Copyright and Related Rights in the Work.
-    Further, Affirmer disclaims responsibility for obtaining any necessary
-    consents, permissions or other rights required for any use of the
-    Work.
- d. Affirmer understands and acknowledges that Creative Commons is not a
-    party to this document and has no duty or obligation with respect to
-    this CC0 or use of the Work.
diff --git a/lri-proto/.gitignore b/lri-proto/.gitignore
new file mode 100644
index 0000000..c1aa2a7
--- /dev/null
+++ b/lri-proto/.gitignore
@@ -0,0 +1 @@
+src/proto
\ No newline at end of file
diff --git a/lri-proto/Cargo.lock b/lri-proto/Cargo.lock
new file mode 100644
index 0000000..35e50c9
--- /dev/null
+++ b/lri-proto/Cargo.lock
@@ -0,0 +1,45 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "bytes"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
+
+[[package]]
+name = "lri-proto"
+version = "0.1.0"
+dependencies = [
+ "protobuf",
+ "protobuf-codegen-pure",
+]
+
+[[package]]
+name = "protobuf"
+version = "2.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94"
+dependencies = [
+ "bytes",
+]
+
+[[package]]
+name = "protobuf-codegen"
+version = "2.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "033460afb75cf755fcfc16dfaed20b86468082a2ea24e05ac35ab4a099a017d6"
+dependencies = [
+ "protobuf",
+]
+
+[[package]]
+name = "protobuf-codegen-pure"
+version = "2.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95a29399fc94bcd3eeaa951c715f7bea69409b2445356b00519740bcd6ddd865"
+dependencies = [
+ "protobuf",
+ "protobuf-codegen",
+]
diff --git a/lri-proto/Cargo.toml b/lri-proto/Cargo.toml
new file mode 100644
index 0000000..2dd0cd7
--- /dev/null
+++ b/lri-proto/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "lri-proto"
+version = "0.1.0"
+#authors = ["Daniel L. Lu <daniel@lawrence.lu>"]
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+protobuf = { version = "3.2", features = ["with-bytes"] }
+
+[build-dependencies]
+protobuf-codegen = "3"
diff --git a/lri-rs/LICENSE b/lri-proto/LICENSE
index b5ef890..b5ef890 100644
--- a/lri-rs/LICENSE
+++ b/lri-proto/LICENSE
diff --git a/lri-proto/README.md b/lri-proto/README.md
new file mode 100644
index 0000000..fa4d7ed
--- /dev/null
+++ b/lri-proto/README.md
@@ -0,0 +1,2 @@
+# lri-proto
+Rust crate holding the protobuf definitions for lri-rs. A gently modified version of [dllu/lri.rs](https://github.com/dllu/lri-rs)
\ No newline at end of file
diff --git a/lri-proto/build.rs b/lri-proto/build.rs
new file mode 100644
index 0000000..31aee5a
--- /dev/null
+++ b/lri-proto/build.rs
@@ -0,0 +1,50 @@
+use std::fs;
+
+use protobuf_codegen::Customize;
+use std::path::Path;
+
+fn main() {
+    let proto_dir = "src/proto";
+
+    if Path::new(&proto_dir).exists() {
+        fs::remove_dir_all(&proto_dir).unwrap();
+    }
+    fs::create_dir(&proto_dir).unwrap();
+
+    protobuf_codegen::Codegen::new()
+        .pure()
+        .customize(Customize::default().gen_mod_rs(true).lite_runtime(true))
+        .out_dir(proto_dir)
+        .input("proto/camera_id.proto")
+        .input("proto/camera_module.proto")
+        .input("proto/color_calibration.proto")
+        .input("proto/dead_pixel_map.proto")
+        .input("proto/device_temp.proto")
+        .input("proto/distortion.proto")
+        .input("proto/face_data.proto")
+        .input("proto/flash_calibration.proto")
+        .input("proto/geometric_calibration.proto")
+        .input("proto/gps_data.proto")
+        .input("proto/hot_pixel_map.proto")
+        .input("proto/hw_info.proto")
+        .input("proto/imu_data.proto")
+        .input("proto/lightheader.proto")
+        .input("proto/matrix3x3f.proto")
+        .input("proto/matrix4x4f.proto")
+        .input("proto/mirror_system.proto")
+        .input("proto/point2f.proto")
+        .input("proto/point2i.proto")
+        .input("proto/point3f.proto")
+        .input("proto/proximity_sensors.proto")
+        .input("proto/range2f.proto")
+        .input("proto/rectanglei.proto")
+        .input("proto/sensor_characterization.proto")
+        .input("proto/sensor_type.proto")
+        .input("proto/time_stamp.proto")
+        .input("proto/tof_calibration.proto")
+        .input("proto/view_preferences.proto")
+        .input("proto/vignetting_characterization.proto")
+        .include("proto")
+        .run()
+        .unwrap();
+}
diff --git a/lri-rs/proto/camera_id.proto b/lri-proto/proto/camera_id.proto
index f34e474..f34e474 100644
--- a/lri-rs/proto/camera_id.proto
+++ b/lri-proto/proto/camera_id.proto
diff --git a/lri-rs/proto/camera_module.proto b/lri-proto/proto/camera_module.proto
index 9506941..9506941 100644
--- a/lri-rs/proto/camera_module.proto
+++ b/lri-proto/proto/camera_module.proto
diff --git a/lri-rs/proto/color_calibration.proto b/lri-proto/proto/color_calibration.proto
index bef82f7..bef82f7 100644
--- a/lri-rs/proto/color_calibration.proto
+++ b/lri-proto/proto/color_calibration.proto
diff --git a/lri-rs/proto/dead_pixel_map.proto b/lri-proto/proto/dead_pixel_map.proto
index b4df63b..b4df63b 100644
--- a/lri-rs/proto/dead_pixel_map.proto
+++ b/lri-proto/proto/dead_pixel_map.proto
diff --git a/lri-rs/proto/device_temp.proto b/lri-proto/proto/device_temp.proto
index 1412a82..1412a82 100644
--- a/lri-rs/proto/device_temp.proto
+++ b/lri-proto/proto/device_temp.proto
diff --git a/lri-rs/proto/distortion.proto b/lri-proto/proto/distortion.proto
index cdd8f33..cdd8f33 100644
--- a/lri-rs/proto/distortion.proto
+++ b/lri-proto/proto/distortion.proto
diff --git a/lri-rs/proto/face_data.proto b/lri-proto/proto/face_data.proto
index 669970a..669970a 100644
--- a/lri-rs/proto/face_data.proto
+++ b/lri-proto/proto/face_data.proto
diff --git a/lri-rs/proto/flash_calibration.proto b/lri-proto/proto/flash_calibration.proto
index 1327442..1327442 100644
--- a/lri-rs/proto/flash_calibration.proto
+++ b/lri-proto/proto/flash_calibration.proto
diff --git a/lri-rs/proto/geometric_calibration.proto b/lri-proto/proto/geometric_calibration.proto
index d89d2e7..d89d2e7 100644
--- a/lri-rs/proto/geometric_calibration.proto
+++ b/lri-proto/proto/geometric_calibration.proto
diff --git a/lri-rs/proto/gps_data.proto b/lri-proto/proto/gps_data.proto
index bc57f14..bc57f14 100644
--- a/lri-rs/proto/gps_data.proto
+++ b/lri-proto/proto/gps_data.proto
diff --git a/lri-rs/proto/hot_pixel_map.proto b/lri-proto/proto/hot_pixel_map.proto
index 4cd53dc..4cd53dc 100644
--- a/lri-rs/proto/hot_pixel_map.proto
+++ b/lri-proto/proto/hot_pixel_map.proto
diff --git a/lri-rs/proto/hw_info.proto b/lri-proto/proto/hw_info.proto
index 70bd90f..70bd90f 100644
--- a/lri-rs/proto/hw_info.proto
+++ b/lri-proto/proto/hw_info.proto
diff --git a/lri-rs/proto/imu_data.proto b/lri-proto/proto/imu_data.proto
index 7106fa3..7106fa3 100644
--- a/lri-rs/proto/imu_data.proto
+++ b/lri-proto/proto/imu_data.proto
diff --git a/lri-rs/proto/lightheader.proto b/lri-proto/proto/lightheader.proto
index 6a729bb..6a729bb 100644
--- a/lri-rs/proto/lightheader.proto
+++ b/lri-proto/proto/lightheader.proto
diff --git a/lri-rs/proto/matrix3x3f.proto b/lri-proto/proto/matrix3x3f.proto
index a1558b2..a1558b2 100644
--- a/lri-rs/proto/matrix3x3f.proto
+++ b/lri-proto/proto/matrix3x3f.proto
diff --git a/lri-rs/proto/matrix4x4f.proto b/lri-proto/proto/matrix4x4f.proto
index de2de61..de2de61 100644
--- a/lri-rs/proto/matrix4x4f.proto
+++ b/lri-proto/proto/matrix4x4f.proto
diff --git a/lri-rs/proto/mirror_system.proto b/lri-proto/proto/mirror_system.proto
index 4bb057e..4bb057e 100644
--- a/lri-rs/proto/mirror_system.proto
+++ b/lri-proto/proto/mirror_system.proto
diff --git a/lri-rs/proto/point2f.proto b/lri-proto/proto/point2f.proto
index 726d594..726d594 100644
--- a/lri-rs/proto/point2f.proto
+++ b/lri-proto/proto/point2f.proto
diff --git a/lri-rs/proto/point2i.proto b/lri-proto/proto/point2i.proto
index 3da325d..3da325d 100644
--- a/lri-rs/proto/point2i.proto
+++ b/lri-proto/proto/point2i.proto
diff --git a/lri-rs/proto/point3f.proto b/lri-proto/proto/point3f.proto
index 71e5cbd..71e5cbd 100644
--- a/lri-rs/proto/point3f.proto
+++ b/lri-proto/proto/point3f.proto
diff --git a/lri-rs/proto/proximity_sensors.proto b/lri-proto/proto/proximity_sensors.proto
index e7c6ab4..e7c6ab4 100644
--- a/lri-rs/proto/proximity_sensors.proto
+++ b/lri-proto/proto/proximity_sensors.proto
diff --git a/lri-rs/proto/range2f.proto b/lri-proto/proto/range2f.proto
index 8c905fe..8c905fe 100644
--- a/lri-rs/proto/range2f.proto
+++ b/lri-proto/proto/range2f.proto
diff --git a/lri-rs/proto/rectanglei.proto b/lri-proto/proto/rectanglei.proto
index 8360ee4..8360ee4 100644
--- a/lri-rs/proto/rectanglei.proto
+++ b/lri-proto/proto/rectanglei.proto
diff --git a/lri-rs/proto/sensor_characterization.proto b/lri-proto/proto/sensor_characterization.proto
index d66aa4a..d66aa4a 100644
--- a/lri-rs/proto/sensor_characterization.proto
+++ b/lri-proto/proto/sensor_characterization.proto
diff --git a/lri-rs/proto/sensor_type.proto b/lri-proto/proto/sensor_type.proto
index 98cc824..98cc824 100644
--- a/lri-rs/proto/sensor_type.proto
+++ b/lri-proto/proto/sensor_type.proto
diff --git a/lri-rs/proto/time_stamp.proto b/lri-proto/proto/time_stamp.proto
index 238eebe..238eebe 100644
--- a/lri-rs/proto/time_stamp.proto
+++ b/lri-proto/proto/time_stamp.proto
diff --git a/lri-rs/proto/tof_calibration.proto b/lri-proto/proto/tof_calibration.proto
index 441eb5e..441eb5e 100644
--- a/lri-rs/proto/tof_calibration.proto
+++ b/lri-proto/proto/tof_calibration.proto
diff --git a/lri-rs/proto/view_preferences.proto b/lri-proto/proto/view_preferences.proto
index 592fc6f..592fc6f 100644
--- a/lri-rs/proto/view_preferences.proto
+++ b/lri-proto/proto/view_preferences.proto
diff --git a/lri-rs/proto/vignetting_characterization.proto b/lri-proto/proto/vignetting_characterization.proto
index ccf93ec..ccf93ec 100644
--- a/lri-rs/proto/vignetting_characterization.proto
+++ b/lri-proto/proto/vignetting_characterization.proto
diff --git a/lri-proto/src/lib.rs b/lri-proto/src/lib.rs
new file mode 100644
index 0000000..02c0048
--- /dev/null
+++ b/lri-proto/src/lib.rs
@@ -0,0 +1,4 @@
+mod proto;
+
+pub use proto::*;
+pub use protobuf::Message;
diff --git a/lri-rs/.gitignore b/lri-rs/.gitignore
deleted file mode 100644
index 3d74ae9..0000000
--- a/lri-rs/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/target
-src/proto
diff --git a/lri-rs/Cargo.lock b/lri-rs/Cargo.lock
deleted file mode 100644
index 74c59a9..0000000
--- a/lri-rs/Cargo.lock
+++ /dev/null
@@ -1,380 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-[[package]]
-name = "adler"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
-
-[[package]]
-name = "adler32"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
-
-[[package]]
-name = "anyhow"
-version = "1.0.38"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
-
-[[package]]
-name = "autocfg"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
-
-[[package]]
-name = "bitflags"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
-
-[[package]]
-name = "bytemuck"
-version = "1.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bed57e2090563b83ba8f83366628ce535a7584c9afa4c9fc0612a03925c6df58"
-
-[[package]]
-name = "byteorder"
-version = "1.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
-
-[[package]]
-name = "bytes"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "color_quant"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
-
-[[package]]
-name = "crc32fast"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "crossbeam-channel"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-deque"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
-dependencies = [
- "cfg-if",
- "crossbeam-epoch",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-epoch"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
- "lazy_static",
- "memoffset",
- "scopeguard",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
-dependencies = [
- "autocfg",
- "cfg-if",
- "lazy_static",
-]
-
-[[package]]
-name = "deflate"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174"
-dependencies = [
- "adler32",
- "byteorder",
-]
-
-[[package]]
-name = "either"
-version = "1.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
-
-[[package]]
-name = "gif"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02efba560f227847cb41463a7395c514d127d4f74fff12ef0137fff1b84b96c4"
-dependencies = [
- "color_quant",
- "weezl",
-]
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "image"
-version = "0.23.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1"
-dependencies = [
- "bytemuck",
- "byteorder",
- "color_quant",
- "gif",
- "jpeg-decoder",
- "num-iter",
- "num-rational",
- "num-traits",
- "png",
- "scoped_threadpool",
- "tiff",
-]
-
-[[package]]
-name = "jpeg-decoder"
-version = "0.1.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2"
-dependencies = [
- "rayon",
-]
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
-[[package]]
-name = "libc"
-version = "0.2.88"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a"
-
-[[package]]
-name = "lri-rs"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "image",
- "protobuf",
- "protobuf-codegen-pure",
- "serde",
-]
-
-[[package]]
-name = "memoffset"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "miniz_oxide"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
-dependencies = [
- "adler32",
-]
-
-[[package]]
-name = "miniz_oxide"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
-dependencies = [
- "adler",
- "autocfg",
-]
-
-[[package]]
-name = "num-integer"
-version = "0.1.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
-dependencies = [
- "autocfg",
- "num-traits",
-]
-
-[[package]]
-name = "num-iter"
-version = "0.1.42"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-rational"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-traits"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "num_cpus"
-version = "1.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
-dependencies = [
- "hermit-abi",
- "libc",
-]
-
-[[package]]
-name = "png"
-version = "0.16.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6"
-dependencies = [
- "bitflags",
- "crc32fast",
- "deflate",
- "miniz_oxide 0.3.7",
-]
-
-[[package]]
-name = "protobuf"
-version = "2.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73f72884896d22e0da0e5b266cb9a780b791f6c3b2f5beab6368d6cd4f0dbb86"
-dependencies = [
- "bytes",
-]
-
-[[package]]
-name = "protobuf-codegen"
-version = "2.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8217a1652dbc91d19c509c558234145faed729191a966896414e5889f62d543"
-dependencies = [
- "protobuf",
-]
-
-[[package]]
-name = "protobuf-codegen-pure"
-version = "2.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f239d71417bdc5f8d83c07aeb265f911346e5540a1a6c4285f9c3d1966ed6e3"
-dependencies = [
- "protobuf",
- "protobuf-codegen",
-]
-
-[[package]]
-name = "rayon"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
-dependencies = [
- "autocfg",
- "crossbeam-deque",
- "either",
- "rayon-core",
-]
-
-[[package]]
-name = "rayon-core"
-version = "1.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
-dependencies = [
- "crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-utils",
- "lazy_static",
- "num_cpus",
-]
-
-[[package]]
-name = "scoped_threadpool"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
-
-[[package]]
-name = "scopeguard"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
-
-[[package]]
-name = "serde"
-version = "1.0.124"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f"
-
-[[package]]
-name = "tiff"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437"
-dependencies = [
- "jpeg-decoder",
- "miniz_oxide 0.4.4",
- "weezl",
-]
-
-[[package]]
-name = "weezl"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a32b378380f4e9869b22f0b5177c68a5519f03b3454fde0b291455ddbae266c"
diff --git a/lri-rs/Cargo.toml b/lri-rs/Cargo.toml
index 844806b..b8451a6 100644
--- a/lri-rs/Cargo.toml
+++ b/lri-rs/Cargo.toml
@@ -1,16 +1,9 @@
 [package]
 name = "lri-rs"
 version = "0.1.0"
-authors = ["Daniel L. Lu <daniel@lawrence.lu>"]
-edition = "2018"
+edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-protobuf = { version = "3.2", features = ["with-bytes"] }
-serde = "1.0"
-image = "0.23.14"
-anyhow = "1.0"
-
-[build-dependencies]
-protobuf-codegen = "3"
+lri-proto = { path = "../lri-proto" }
diff --git a/lri-rs/README.md b/lri-rs/README.md
deleted file mode 100644
index 6bc9c52..0000000
--- a/lri-rs/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-## Hey, hi! This is [dllu/lri-rs](https://github.com/dllu/lri-rs) with an added minimal `lib.rs`.
-
-# lri-rs
-Rust code to deal with .lri files from Light L16 camera
diff --git a/lri-rs/build.rs b/lri-rs/build.rs
deleted file mode 100644
index 35ae756..0000000
--- a/lri-rs/build.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-use std::fs;
-
-use protobuf_codegen::Customize;
-use std::path::Path;
-
-fn main() {
-	let proto_dir = "src/proto";
-
-	if Path::new(&proto_dir).exists() {
-		fs::remove_dir_all(&proto_dir).unwrap();
-	}
-	fs::create_dir(&proto_dir).unwrap();
-
-	protobuf_codegen::Codegen::new()
-		.pure()
-		.customize(Customize::default().gen_mod_rs(true))
-		.out_dir(proto_dir)
-		.input("proto/camera_id.proto")
-		.input("proto/camera_module.proto")
-		.input("proto/color_calibration.proto")
-		.input("proto/dead_pixel_map.proto")
-		.input("proto/device_temp.proto")
-		.input("proto/distortion.proto")
-		.input("proto/face_data.proto")
-		.input("proto/flash_calibration.proto")
-		.input("proto/geometric_calibration.proto")
-		.input("proto/gps_data.proto")
-		.input("proto/hot_pixel_map.proto")
-		.input("proto/hw_info.proto")
-		.input("proto/imu_data.proto")
-		.input("proto/lightheader.proto")
-		.input("proto/matrix3x3f.proto")
-		.input("proto/matrix4x4f.proto")
-		.input("proto/mirror_system.proto")
-		.input("proto/point2f.proto")
-		.input("proto/point2i.proto")
-		.input("proto/point3f.proto")
-		.input("proto/proximity_sensors.proto")
-		.input("proto/range2f.proto")
-		.input("proto/rectanglei.proto")
-		.input("proto/sensor_characterization.proto")
-		.input("proto/sensor_type.proto")
-		.input("proto/time_stamp.proto")
-		.input("proto/tof_calibration.proto")
-		.input("proto/view_preferences.proto")
-		.input("proto/vignetting_characterization.proto")
-		.include("proto")
-		.run()
-		.unwrap();
-}
diff --git a/lri-rs/src/lib.rs b/lri-rs/src/lib.rs
index 0a86fab..6d38e90 100644
--- a/lri-rs/src/lib.rs
+++ b/lri-rs/src/lib.rs
@@ -1,2 +1,398 @@
-pub mod proto;
-pub use protobuf::Message;
+use std::{fmt, vec::IntoIter};
+
+use lri_proto::Message as PbMessage;
+use lri_proto::{
+    camera_id::CameraID,
+    camera_module::{camera_module::surface::FormatType, CameraModule},
+    color_calibration::color_calibration::IlluminantType,
+    gps_data::GPSData,
+    lightheader::LightHeader,
+    view_preferences::ViewPreferences,
+};
+
+pub struct LriFile {
+    pub blocks: Vec<Block>,
+    pub models: Vec<SensorModel>,
+}
+
+impl LriFile {
+    /// Read
+    pub fn decode(mut data: Vec<u8>) -> Self {
+        let mut blocks = vec![];
+
+        loop {
+            let header = Header::ingest(&data[..]);
+            let end = header.combined_length as usize;
+
+            if end == data.len() {
+                blocks.push(Block { header, data });
+                break;
+            } else {
+                let remain = data.split_off(end);
+                blocks.push(Block { header, data });
+                data = remain;
+            }
+        }
+
+        let models = Self::grab_sensor_models(&blocks);
+
+        Self { blocks, models }
+    }
+
+    fn grab_sensor_models(blocks: &[Block]) -> Vec<SensorModel> {
+        let mut models = vec![];
+
+        for blk in blocks {
+            match blk.message() {
+                Message::LightHeader(LightHeader {
+                    module_calibration, ..
+                }) => {
+                    for mcal in module_calibration {
+                        let id = mcal.camera_id().into();
+                        let color = match mcal.color.first() {
+                            None => continue,
+                            Some(c) => c,
+                        };
+                        let whitepoint = color.type_().into();
+                        let forward = color.forward_matrix.clone().unwrap();
+                        let our_forward = [
+                            forward.x00(),
+                            forward.x01(),
+                            forward.x02(),
+                            forward.x10(),
+                            forward.x11(),
+                            forward.x12(),
+                            forward.x20(),
+                            forward.x21(),
+                            forward.x22(),
+                        ];
+
+                        let forward = color.color_matrix.clone().unwrap();
+                        let our_color = [
+                            forward.x00(),
+                            forward.x01(),
+                            forward.x02(),
+                            forward.x10(),
+                            forward.x11(),
+                            forward.x12(),
+                            forward.x20(),
+                            forward.x21(),
+                            forward.x22(),
+                        ];
+
+                        let rg = color.rg_ratio();
+                        let bg = color.bg_ratio();
+
+                        let model = SensorModel {
+                            id,
+                            whitepoint,
+                            forward_matrix: our_forward,
+                            color_matrix: our_color,
+                            rg,
+                            bg,
+                        };
+                        models.push(model);
+                    }
+                }
+                _ => (),
+            }
+        }
+
+        models
+    }
+
+    pub fn image_count(&self) -> usize {
+        let mut count = 0;
+
+        for block in &self.blocks {
+            match block.message() {
+                Message::LightHeader(LightHeader { modules, .. }) => {
+                    for cam in modules {
+                        count += 1;
+                    }
+                }
+                _ => (),
+            }
+        }
+
+        count
+    }
+
+    pub fn images(&self) -> ImageIterator {
+        ImageIterator {
+            blocks: &self.blocks,
+            modules: None,
+        }
+    }
+
+    pub fn color_models(&self, cameraid: SensorId) -> Vec<&SensorModel> {
+        self.models.iter().filter(|sm| sm.id == cameraid).collect()
+    }
+}
+
+pub struct ImageIterator<'lri> {
+    blocks: &'lri [Block],
+    modules: Option<(&'lri Block, IntoIter<CameraModule>)>,
+}
+
+impl<'lri> Iterator for ImageIterator<'lri> {
+    type Item = RawImage<'lri>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        loop {
+            match self.modules.as_mut() {
+                None => match self.blocks.first() {
+                    None => return None,
+                    Some(block) => {
+                        self.blocks = &self.blocks[1..];
+
+                        if let Message::LightHeader(lh) = block.message() {
+                            let mod_iter = lh.modules.into_iter();
+                            self.modules = Some((block, mod_iter));
+                        } else {
+                            continue;
+                        }
+                    }
+                },
+                Some((block, mods)) => {
+                    for module in mods {
+                        let sensor_id = module.id().into();
+                        let mut surface = module.sensor_data_surface.unwrap();
+                        let size = surface.size.take().unwrap();
+                        let offset = surface.data_offset() as usize;
+                        let data_length = surface.row_stride() as usize * size.y() as usize;
+
+                        let data = &block.data[offset..offset + data_length];
+
+                        return Some(RawImage {
+                            sensor_id,
+                            width: size.x() as usize,
+                            height: size.y() as usize,
+                            format: surface.format().into(),
+                            data,
+                        });
+                    }
+
+                    self.modules = None;
+                }
+            }
+        }
+    }
+}
+
+pub struct Block {
+    pub header: Header,
+    /// This includes the 32 bytes that make up the header.
+    pub data: Vec<u8>,
+}
+
+impl Block {
+    pub fn body(&self) -> &[u8] {
+        &self.data[32..]
+    }
+
+    pub fn message_data(&self) -> &[u8] {
+        let end = self.header.message_offset + self.header.message_length;
+        &self.data[self.header.message_offset..end]
+    }
+
+    pub fn message(&self) -> Message {
+        match self.header.kind {
+            BlockType::LightHeader => {
+                Message::LightHeader(LightHeader::parse_from_bytes(self.message_data()).unwrap())
+            }
+            BlockType::ViewPreferences => Message::ViewPreferences(
+                ViewPreferences::parse_from_bytes(self.message_data()).unwrap(),
+            ),
+            BlockType::GPSData => {
+                Message::Gps(GPSData::parse_from_bytes(self.message_data()).unwrap())
+            }
+        }
+    }
+}
+
+pub enum Message {
+    LightHeader(LightHeader),
+    ViewPreferences(ViewPreferences),
+    Gps(GPSData),
+}
+
+pub struct Header {
+    /// The length of this header and it's associated block
+    pub combined_length: usize,
+    /// An offset from the start of the header to the block's protobuf message
+    pub message_offset: usize,
+    /// block's protobuf message length
+    pub message_length: usize,
+    /// The kind of protobuf message in the block
+    pub kind: BlockType,
+}
+
+impl Header {
+    pub fn ingest(data: &[u8]) -> Self {
+        let magic = b"LELR";
+
+        if &data[0..4] != magic {
+            panic!("Magic nubmer is wrong");
+        }
+
+        let combined_length = u64::from_le_bytes(data[4..12].try_into().unwrap()) as usize;
+        let message_offset = u64::from_le_bytes(data[12..20].try_into().unwrap()) as usize;
+        let message_length = u32::from_le_bytes(data[20..24].try_into().unwrap()) as usize;
+
+        let kind = match data[24] {
+            0 => BlockType::LightHeader,
+            1 => BlockType::ViewPreferences,
+            2 => BlockType::GPSData,
+            t => panic!("block type {t} is unknown"),
+        };
+
+        Header {
+            combined_length,
+            message_offset,
+            message_length,
+            kind,
+        }
+    }
+}
+
+pub enum BlockType {
+    LightHeader,
+    ViewPreferences,
+    GPSData,
+}
+
+pub struct RawImage<'img> {
+    pub sensor_id: SensorId,
+    pub width: usize,
+    pub height: usize,
+    pub format: ImageFormat,
+    pub data: &'img [u8],
+}
+
+pub struct SensorModel {
+    pub id: SensorId,
+    pub whitepoint: Whitepoint,
+    /// From the camera debayered data to XYZ in the given whitepoint
+    pub forward_matrix: [f32; 9],
+    /// ??? is this cam -> sRGB?
+    pub color_matrix: [f32; 9],
+    pub rg: f32,
+    pub bg: f32,
+}
+
+pub enum ImageFormat {
+    // I'm not sure what this is?? Do we ever see it???
+    BayerJpeg,
+    Packed10bpp,
+    Packed12bpp,
+    Packed14bpp,
+}
+
+impl fmt::Display for ImageFormat {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let str = match self {
+            Self::BayerJpeg => "BayerJpeg",
+            Self::Packed10bpp => "Packed10bpp",
+            Self::Packed12bpp => "Packed12bpp",
+            Self::Packed14bpp => "Packed14bpp",
+        };
+
+        write!(f, "{str}")
+    }
+}
+
+impl From<FormatType> for ImageFormat {
+    fn from(proto: FormatType) -> Self {
+        match proto {
+            FormatType::RAW_BAYER_JPEG => Self::BayerJpeg,
+            FormatType::RAW_PACKED_10BPP => Self::Packed10bpp,
+            FormatType::RAW_PACKED_12BPP => Self::Packed12bpp,
+            FormatType::RAW_PACKED_14BPP => Self::Packed14bpp,
+            FormatType::RAW_RESERVED_0
+            | FormatType::RAW_RESERVED_1
+            | FormatType::RAW_RESERVED_2
+            | FormatType::RAW_RESERVED_3
+            | FormatType::RAW_RESERVED_4
+            | FormatType::RAW_RESERVED_5 => unimplemented!(),
+        }
+    }
+}
+
+#[derive(Copy, Clone, Debug, PartialEq)]
+pub enum SensorId {
+    A1,
+    A2,
+    A3,
+    A4,
+    A5,
+    B1,
+    B2,
+    B3,
+    B4,
+    B5,
+    C1,
+    C2,
+    C3,
+    C4,
+    C5,
+    C6,
+}
+
+impl From<CameraID> for SensorId {
+    fn from(pbid: CameraID) -> Self {
+        match pbid {
+            CameraID::A1 => Self::A1,
+            CameraID::A2 => Self::A2,
+            CameraID::A3 => Self::A3,
+            CameraID::A4 => Self::A4,
+            CameraID::A5 => Self::A5,
+            CameraID::B1 => Self::B1,
+            CameraID::B2 => Self::B2,
+            CameraID::B3 => Self::B3,
+            CameraID::B4 => Self::B4,
+            CameraID::B5 => Self::B5,
+            CameraID::C1 => Self::C1,
+            CameraID::C2 => Self::C2,
+            CameraID::C3 => Self::C3,
+            CameraID::C4 => Self::C4,
+            CameraID::C5 => Self::C5,
+            CameraID::C6 => Self::C6,
+        }
+    }
+}
+
+impl fmt::Display for SensorId {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        // this is good; i write good code
+        write!(f, "{self:?}")
+    }
+}
+
+#[derive(Debug)]
+pub enum Whitepoint {
+    A,
+    D50,
+    D65,
+    D75,
+    F2,
+    F7,
+    F11,
+    TL84,
+}
+
+impl From<IlluminantType> for Whitepoint {
+    fn from(it: IlluminantType) -> Self {
+        match it {
+            IlluminantType::A => Self::A,
+            IlluminantType::D50 => Self::D50,
+            IlluminantType::D65 => Self::D65,
+            IlluminantType::D75 => Self::D75,
+            IlluminantType::F2 => Self::F2,
+            IlluminantType::F7 => Self::F7,
+            IlluminantType::F11 => Self::F11,
+            IlluminantType::TL84 => Self::TL84,
+            IlluminantType::UNKNOWN => unimplemented!(),
+        }
+    }
+}
diff --git a/lri-rs/src/main.rs b/lri-rs/src/main.rs
deleted file mode 100644
index 1fd2fac..0000000
--- a/lri-rs/src/main.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-mod proto;
-
-use std::io::Read;
-
-use protobuf::Message;
-
-use proto::lightheader::LightHeader;
-
-fn read() -> anyhow::Result<()> {
-    let mut f = std::fs::File::open("/home/dllu/pictures/l16/L16_00078.lri")?;
-    let mut buf = Vec::new();
-    f.read_to_end(&mut buf)?;
-
-    let asdf = LightHeader::parse_from_bytes(&buf)?;
-    dbg!(&asdf.get_device_model_name());
-    dbg!(&asdf.get_device_fw_version());
-    Ok(())
-}
-
-fn main() {
-    read().unwrap();
-}
diff --git a/unpacker/Cargo.toml b/prism/Cargo.toml
index 147529a..7301109 100644
--- a/unpacker/Cargo.toml
+++ b/prism/Cargo.toml
@@ -1,8 +1,10 @@
 [package]
-name = "unpacker"
+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;
+		}
+	}
+}
diff --git a/src/main.rs b/src/main.rs
deleted file mode 100644
index 0c1842e..0000000
--- a/src/main.rs
+++ /dev/null
@@ -1,424 +0,0 @@
-use std::{fs::File, io::Write, os::unix::prelude::FileExt, path::Path};
-
-use lri_rs::{
-	proto::{self, camera_module::CameraModule},
-	Message,
-};
-use nalgebra::Matrix3;
-use png::{BitDepth, ColorType};
-use rawloader::CFA;
-use rawproc::{
-	colorspace::BayerRgb,
-	image::{Image, RawMetadata},
-};
-use unpacker::Unpacker;
-
-// This code is going to be rough. Just trying to parse this using the technique
-// I know: just play with the raw data
-fn main() {
-	let fname = std::env::args().nth(1).unwrap();
-	let mut data = std::fs::read(fname).unwrap();
-
-	println!("Read {:.2}MB", data.len() as f32 / (1024.0 * 1024.0));
-
-	let mut blocks = vec![];
-
-	loop {
-		let header = DataHeader::new(&data[..]);
-		let end = header.combined_length as usize;
-		if end == data.len() {
-			blocks.push(Block { header, data });
-			break;
-		} else {
-			let remain = data.split_off(end);
-			blocks.push(Block { header, data });
-			data = remain;
-		}
-	}
-
-	println!("Found {} blocks", blocks.len());
-
-	for (idx, block) in blocks.iter().enumerate() {
-		if block.is_sensor() {
-			println!("\nIDX {idx}");
-			block.header.print_info();
-			fuckwithsensordata(block, idx);
-		} else {
-			block.header.nice_info();
-			dump_lightheader(block, idx);
-		}
-	}
-
-	/*
-	// Grabbed, quickly, from the sensor datasheets. (or in the case of the
-	// imx386 on some random website (canwe have a datasheet? shit)).
-	let ar835 = 3264 * 2448;
-	let ar835_6mp = 3264 * 1836;
-	let ar1335 = 4208 * 3120;
-	let imx386 = 4032 * 3024;
-
-	// Determined by lak experimentally
-	let ar1335_crop = 4160 * 3120;
-
-	println!("\nAttemtping to unpack image in idx0");
-	let head = &heads[0];
-	let mut msg = body(head, &data);
-	for AHH in 0..2 {
-		let mut up = Unpacker::new();
-		for idx in (0..16224000 * 2).rev() {
-			up.push(msg[idx]);
-		}
-		up.finish();
-
-		dump(&msg[..16224000], "fordatadog.packed");
-
-		let mut imgdata = vec![];
-		for (idx, chnk) in up.out.chunks(2).enumerate() {
-			let mut sixteen = (u16::from_le_bytes([chnk[0], chnk[1]]) as f32 / 1024.0) * 255.0;
-
-			imgdata.push(sixteen.min(255.0) as u8);
-		}
-
-		let rawimg: Image<u8, BayerRgb> = Image::from_raw_parts(
-			4160,
-			3120 * 2,
-			RawMetadata {
-				whitebalance: [1.0, 1.0, 1.35],
-				whitelevels: [1024, 1024, 1024],
-				crop: None,
-				cfa: CFA::new("BGGR"),
-				cam_to_xyz: Matrix3::new(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0),
-			},
-			imgdata.clone(),
-		);
-		let mut img = rawimg.debayer();
-
-		for px in img.data.chunks_mut(3) {
-			px[0] = (px[0] as f32 * 1.95).min(255.0) as u8;
-			px[2] = (px[2] as f32 * 1.36).min(255.0) as u8;
-		}
-
-		let png = format!("image_{AHH}.png");
-		make_png(
-			&png,
-			4160,
-			3120 * 2,
-			ColorType::Rgb,
-			BitDepth::Eight,
-			&img.data,
-		);
-		println!("Wrote {png}");
-
-		msg = &msg[16224000..]; // + head.header.message_length as usize * 2..];
-	}
-
-	println!("\nDumping the Message of idx 4");
-	dump_body(&heads[4], &data, "msg4.lri_part");
-
-	let mut modules = vec![];
-	let mut sensor_data = vec![];
-
-	for (idx, head) in heads.iter().enumerate() {
-		print!("Head {idx} - ");
-		let msg = body(head, &data);
-
-		match (head.header.header_length == 32, head.header.kind) {
-			(true, 1) => {
-				match lri_rs::proto::view_preferences::ViewPreferences::parse_from_bytes(msg) {
-					Ok(_) => println!("View Preferences: Parsed"),
-					Err(e) => println!("View Preferences, failed: {e}"),
-				}
-			}
-			(true, 0) => match lri_rs::proto::lightheader::LightHeader::parse_from_bytes(msg) {
-				Ok(data) => {
-					let mods = &data.modules;
-					let datas = &data.sensor_data;
-
-					print!(
-						" [claimed: {} | actual: {}] - ",
-						head.header.message_length,
-						data.compute_size()
-					);
-
-					println!(
-						"LightHeader! Modules: {} - Datas: {} \\ ModCal: {}",
-						mods.len(),
-						datas.len(),
-						data.module_calibration.len()
-					);
-					modules.extend_from_slice(&mods);
-					sensor_data.extend_from_slice(&datas);
-
-					if false && data.module_calibration.len() > 0 {
-						for modc in data.module_calibration {
-							print!(" - {:?}", modc.get_camera_id());
-						}
-						println!("");
-					}
-				}
-				Err(e) => println!("LightHeader, failed: {e}"),
-			},
-			(true, knd) => {
-				println!("Unknown header kind [{knd}] and header_length is 32, skipping...");
-			}
-			(false, _) => {
-				println!("SensorData! Skipping for now...");
-			}
-		}
-	}*/
-}
-
-fn fuckwithsensordata(block: &Block, idx: usize) {
-	let Block { header, data } = block;
-
-	let clen = header.combined_length;
-	let hlen = header.header_length;
-	let mlen = header.message_length;
-
-	println!("\n== Fuck With Sensor Data {idx} ==");
-
-	println!("Combined: {clen}");
-	println!("Header:   {hlen}");
-	println!("Message:  {mlen}\n");
-
-	let width = 4160;
-	let height = 3120;
-	let pixel_count = width * height;
-	let packed_count = ((pixel_count as f32 * 10.0) / 8.0) as usize;
-
-	println!("Assuming {width}x{height} [{pixel_count}] [packed: {packed_count}]");
-
-	let mut data = block.body();
-	// I'm lazy and don't want to manually increment
-	for x in 0..10 {
-		let fname = format!("block{idx}_image{x}.png");
-
-		// Use my really efficient (read that sarcastically, please) 10-bit unpacker
-		let mut up = Unpacker::new();
-		for idx in (0..packed_count).rev() {
-			up.push(data[idx]);
-		}
-		up.finish();
-
-		// Sixteen - eightbits
-		let mut imgdata = vec![];
-		for chnk in up.out.chunks(2) {
-			let sixteen = (u16::from_le_bytes([chnk[0], chnk[1]]) as f32 / 1024.0) * 255.0;
-
-			imgdata.push(sixteen.min(255.0) as u8);
-		}
-
-		// we want it to be RGB not weird bayer
-		let rawimg: Image<u8, BayerRgb> = Image::from_raw_parts(
-			width,
-			height,
-			// use mostly fake data except the CFA
-			RawMetadata {
-				whitebalance: [1.0, 1.0, 1.0],
-				whitelevels: [1024, 1024, 1024],
-				crop: None,
-				cfa: CFA::new("BGGR"),
-				cam_to_xyz: Matrix3::new(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0),
-			},
-			imgdata,
-		);
-		let img = rawimg.debayer();
-
-		// Yay PNG
-		make_png(
-			&fname,
-			width,
-			height,
-			ColorType::Rgb,
-			BitDepth::Eight,
-			&img.data,
-		);
-		println!("Wrote file {fname}");
-
-		let skip = packed_count + mlen as usize;
-		if data.len() <= skip + packed_count {
-			println!(
-				"Only {} bytes will be left in data after output! Which is not enough",
-				data.len() - skip
-			);
-			break;
-		} else {
-			data = &data[skip..]
-		}
-	}
-
-	println!("===================================\n");
-}
-
-fn dump_lightheader(block: &Block, idx: usize) {
-	let fname = format!("block{idx}_lightheader.protodump");
-
-	if !block.is_lightheader() {
-		return;
-	}
-
-	match lri_rs::proto::lightheader::LightHeader::parse_from_bytes(block.body()) {
-		Err(_e) => {
-			println!("Failed parse I'm so toried to write mote");
-		}
-		Ok(lh) => {
-			let proto = protobuf::text_format::print_to_string_pretty(&lh);
-			std::fs::write(&fname, proto).unwrap();
-			println!("Write protobuf data to {fname}");
-		}
-	}
-}
-
-fn dump(data: &[u8], path: &str) {
-	let mut file = File::create(&path).unwrap();
-	file.write_all(data).unwrap();
-	println!(
-		"Wrote {:.2}KB to disk as {path}",
-		data.len() as f32 / 1024.0
-	);
-}
-
-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(path).unwrap();
-	let mut enc = png::Encoder::new(file, width as u32, height as u32);
-	enc.set_color(color);
-	enc.set_depth(depth);
-	let mut writer = enc.write_header().unwrap();
-	writer.write_image_data(&data[..pix * bpp]).unwrap();
-}
-
-#[derive(Clone, Debug)]
-struct Block {
-	header: DataHeader,
-	data: Vec<u8>,
-}
-
-impl Block {
-	pub fn body(&self) -> &[u8] {
-		&self.data[32..]
-	}
-
-	/// Block contains sensor data.
-	pub fn is_sensor(&self) -> bool {
-		self.header.header_length != 32
-	}
-
-	pub fn is_lightheader(&self) -> bool {
-		!self.is_sensor() && self.header.kind == 0
-	}
-}
-
-#[derive(Clone, Debug)]
-struct DataHeader {
-	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
-	kind: u8,
-	reserved: [u8; 7],
-}
-
-impl DataHeader {
-	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]);
-
-		let header_length = u64::from_le_bytes(data[12..20].try_into().unwrap());
-		//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]);
-
-		let kind = data[24];
-		let reserved = data[25..32].try_into().unwrap();
-
-		DataHeader {
-			magic_number,
-			combined_length,
-			header_length,
-			message_length,
-			kind,
-			reserved,
-		}
-	}
-
-	pub fn print_info(&self) {
-		let Self {
-			magic_number,
-			combined_length,
-			header_length,
-			message_length,
-			kind,
-			reserved,
-		} = self;
-
-		let combined_human = humanish(*combined_length as usize);
-		let header_human = humanish(*header_length as usize);
-		let message_human = humanish(*message_length as usize);
-
-		println!("Magic: {magic_number}\nCombined Length: {combined_human}\nHeader Length: {header_human}\nMessage Length: {message_human}\nKind: {kind}\nReserved: {reserved:?}");
-	}
-
-	pub fn nice_info(&self) {
-		let Self {
-			magic_number: _a,
-			combined_length: _b,
-			header_length,
-			message_length: _c,
-			kind,
-			reserved: _d,
-		} = self;
-
-		println!(
-			"Content length: {:.2}KB | Kind {kind}",
-			*header_length as f32 / 1024.0
-		);
-	}
-
-	pub fn bin_info(&self) {
-		let Self {
-			magic_number,
-			combined_length,
-			header_length: _a,
-			message_length: _b,
-			kind: _c,
-			reserved: _d,
-		} = self;
-
-		println!("{magic_number} {:b}", combined_length);
-	}
-}
-
-pub fn humanish(bytes: usize) -> String {
-	if bytes > 1024 * 10 {
-		// Ehhhhh 10KB
-		format!("{:.2} KB", bytes as f32 / 1024.0)
-	} else if bytes > 1024 * 1024 {
-		// A MB is enough to justify this I guess
-		format!("{:.2} MB", bytes as f32 / 1024.0 * 1024.0)
-	} else {
-		format!("{}", bytes)
-	}
-}
diff --git a/unpacker/Cargo.lock b/unpacker/Cargo.lock
deleted file mode 100644
index 44d0a0f..0000000
--- a/unpacker/Cargo.lock
+++ /dev/null
@@ -1,7 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "unpacker"
-version = "0.1.0"
diff --git a/unpacker/src/lib.rs b/unpacker/src/lib.rs
deleted file mode 100644
index f649581..0000000
--- a/unpacker/src/lib.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-#[derive(Debug)]
-pub struct Unpacker {
-	pub out: Vec<u8>,
-	pub work: u16,
-	pub work_idx: usize,
-}
-
-impl Unpacker {
-	pub fn new() -> Self {
-		Self {
-			out: vec![],
-			work: 0,
-			work_idx: 0,
-		}
-	}
-
-	pub fn push(&mut self, byte: u8) {
-		self.work = self.work << 8;
-		self.work |= byte as u16;
-		self.work_idx += 8;
-
-		//println!("[{work_idx}]");
-
-		if self.work_idx >= 10 {
-			let to_front = self.work_idx - 10;
-			let fronted = self.work >> to_front;
-			let masked = fronted & 0b000_000_111_11_111_11;
-
-			let fixwork = fronted << to_front;
-
-			self.out.extend(masked.to_le_bytes());
-			self.work_idx -= 10;
-			self.work ^= fixwork;
-		}
-	}
-
-	pub fn finish(&mut self) {
-		if self.work_idx > 0 {
-			let remain = 10 - self.work_idx;
-			let out = self.work << remain;
-			self.out.extend(out.to_le_bytes())
-		}
-	}
-}
diff --git a/unpacker/src/main.rs b/unpacker/src/main.rs
deleted file mode 100644
index 36d8131..0000000
--- a/unpacker/src/main.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-use unpacker::Unpacker;
-
-fn main() {
-	// Four bits padding at the end.
-	let testdata = vec![
-		0b10000000, 0b00010000, 0b00000010, 0b00000000, 0b01000000, 0b00001000, 0b00000001,
-		0b00000000, 0b00100000, 0b00000100, 0b00000000, 0b10000000, 0b00010000,
-	];
-
-	let mut up = Unpacker {
-		out: vec![],
-		work: 0,
-		work_idx: 0,
-	};
-
-	let count = (10.0 as f32 * (10.0 / 8.0)).ceil() as usize;
-	for byte in testdata {
-		up.push(byte);
-
-		if count == up.out.len() {
-			break;
-		}
-	}
-	if count > up.out.len() {
-		up.finish();
-	}
-
-	for chnk in up.out.chunks(2) {
-		println!("{:02b} {:08b}", chnk[1], chnk[0]);
-	}
-}