diff options
author | gennyble <gen@nyble.dev> | 2023-09-13 01:04:18 -0500 |
---|---|---|
committer | gennyble <gen@nyble.dev> | 2023-09-13 01:04:18 -0500 |
commit | 39437b2199b43581fceb51bebb64a5461abf1914 (patch) | |
tree | f2e642f2d4182d1494c44b21b9c1b9eaa2071b26 | |
parent | 491fdb4327a07c9705d59284ac20f13074944a91 (diff) | |
download | lri-rs-39437b2199b43581fceb51bebb64a5461abf1914.tar.gz lri-rs-39437b2199b43581fceb51bebb64a5461abf1914.zip |
write some docs
-rw-r--r-- | LRI.md | 54 | ||||
-rw-r--r-- | bayer_jpeg.md | 7 | ||||
-rw-r--r-- | lri-study/src/main.rs | 13 |
3 files changed, 65 insertions, 9 deletions
diff --git a/LRI.md b/LRI.md new file mode 100644 index 0000000..fa3a104 --- /dev/null +++ b/LRI.md @@ -0,0 +1,54 @@ +# Anatomy of an LRI +The file is made up of many blocks, usually 10 or 11 but cases of 40 have occurred. + +Blocks start with a header and contain some data. There is always a protobuf message within that data, and sometimes stuff like the images themselves. + +## Block Header +The header is 32 bytes long. and goes as follows: +| bytes | type | meaning | +| ----- | -----| ------- | +| 4 | - | Signature: "LELR" | +| 8 | u64 | block length | +| 8 | u64 | message offset from block start | +| 4 | u32 | message length | +| 1 | u8 | message type, see below | +| 7 | - | reserved | + +*message* to mean the protobuf message + +*Message Type* +0: LightHeader ([proto][lh-proto]) +1: ViewPreferences ([proto][vp-proto]) +2: GPSData ([proto][gps-proto]) + +[lh-proto]: /lri-proto/proto/lightheader.proto +[vp-proto]: /lri-proto/proto/view_preferences.proto +[gps-proto]: /lri-proto/proto/gps_data.proto + +## highlighting key parts +blocks have messages and that's pretty much all you need to know. you can look at the protobuf definitions and pretty readily build a parser, but there are some things i'd like to mention, too. + +### LightHeader +The most important header and frustratingly fractured between multiple blocks. + +#### RAW Images +What we're all here for, maybe. + +zero or more CameraModule ([proto][module-proto]) are collected in the `modules`. In a CameraModule we see a `sensor_data_surface` of type Surface (see line 33 of the CameraModule proto). + +[module-proto]: /lri-proto/proto/camera_module.proto + +- `start` might indicate a crop, but has always been (0,0) in my experience. +- `size` gives the width/height of the image. +- `data_offset` is the start of the image from the beginning of the block (meaning: it includes the length of the header). +- `format` indicates how we're meant to interpret the image data. It can be a few different things, but i've only seen RAW_BAYER_JPEG and RAW_PACKED_10BPP. +- `row_stride` gives you the number of bytes per row the image takes up. Multiply this by the width to get the size of the image (except Bayer JPEG; see below) + +##### Let's talk about Bayer JPEG. +We don't currently understand *why* the L16 makes these, just that it does. If it's from a colour sensor, you'll get four half-res JPEG (one for each bayer position). If it's monochrome, you'll get one full-res JPEG. For more information go here: [bayer_jpeg.md](/bayer_jpeg.md). + +In either colour-case, the `row_stride` in the `sensor_data_surface` will be 0. You'll have to parse the Bayer JPEG header to get the length of the sensor's image data. + +##### that's enough BayerJPEG + +Going back to CameraModule, there's some more important data for image interpretation. You'll want the `id` which indicates which camera took the exposure. We can map this to a sensor model later! Grab `sensor_bayer_red_override` while you're at it. It'll help with figuring out what CFA we need to use for debayering. diff --git a/bayer_jpeg.md b/bayer_jpeg.md index 94f7a6b..150fb63 100644 --- a/bayer_jpeg.md +++ b/bayer_jpeg.md @@ -1,6 +1,7 @@ # BayerJPEG -Th BayerJPEG is a strange format used by the Light L16... *sometimes*. We don't yet know when it switches from it's normal packed 10-bit raw format. +The BayerJPEG is a strange format used by the Light L16... *sometimes*. We don't yet know when it switches from it's normal packed 10-bit raw format to this, or why. +### BayerJPEG Header | size | type | meaning | | ------- | ------ | ------- | | 4 bytes | String | Magic Number "BJPG" | @@ -11,10 +12,10 @@ Th BayerJPEG is a strange format used by the Light L16... *sometimes*. We don't | 4 bytes | u32 | Length of Jpeg 3 | | 1552 bytes | | unknown | -***Monochrome*** +***Foramt Type: Monochrome*** Jpeg0 contains a full resolution grayscale image -***Colour*** +***Format Type: Colour*** The bayered image is split across the four Jpeg, one for each colour location. diff --git a/lri-study/src/main.rs b/lri-study/src/main.rs index a7368dc..3b386e5 100644 --- a/lri-study/src/main.rs +++ b/lri-study/src/main.rs @@ -79,15 +79,16 @@ fn gather() -> ! { ); match lri.hdr { - None => print!("{} ", "hdr".dimmed()), - Some(HdrMode::None) => print!("{} ", "hdr".blue()), - Some(HdrMode::Default) => print!("hdr "), - Some(HdrMode::Natural) => print!("{} ", "hdr".bright_green()), - Some(HdrMode::Surreal) => print!("{} ", "hdr".bright_magenta()), + None => print!("hdr:{} ", "non".dimmed()), + Some(HdrMode::None) => print!("hdr:{} ", "nop".dimmed()), + Some(HdrMode::Default) => print!("hdr:hdr "), + Some(HdrMode::Natural) => print!("hdr:{} ", "nat".bright_green()), + Some(HdrMode::Surreal) => print!("hdr:{} ", "sur".bright_magenta()), } match lri.scene { - None | Some(SceneMode::None) => print!("sc:{} ", "nop".dimmed()), + None => print!("sc:{} ", "non".dimmed()), + Some(SceneMode::None) => print!("sc:{} ", "nop".dimmed()), Some(SceneMode::Portrait) => print!("sc:prt "), Some(SceneMode::Landscape) => print!("sc:lnd "), Some(SceneMode::Macro) => print!("sc:mcr "), |