1#![warn(missing_docs)]
2
3pub mod codec;
9
10pub use bitstream_io;
11use bitstream_io::{BigEndian, BitReader};
12use std::cmp::Ordering;
13use std::fs::File;
14use std::io::BufReader;
15use std::ops::Add;
16
17use thiserror::Error;
18
19#[allow(missing_docs)]
21#[derive(Error, Debug)]
22pub enum PlaneError {
23 #[error(
24 "plane dimensions invalid. All must be positive. Found {width:?}, {height:?}, {channels:?}"
25 )]
26 InvalidPlane {
27 width: u16,
28 height: u16,
29 channels: u8,
30 },
31}
32
33#[allow(missing_docs)]
34#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq)]
35pub enum SourceCamera {
36 #[default]
37 FramedU8,
38 FramedU16,
39 FramedU32,
40 FramedU64,
41 FramedF32,
42 FramedF64,
43 Dvs,
44 DavisU8,
45 Atis,
46 Asint,
47}
48
49pub fn is_framed(source_camera: SourceCamera) -> bool {
51 matches!(
52 source_camera,
53 SourceCamera::FramedU8
54 | SourceCamera::FramedU16
55 | SourceCamera::FramedU32
56 | SourceCamera::FramedU64
57 | SourceCamera::FramedF32
58 | SourceCamera::FramedF64
59 )
60}
61
62#[cfg(feature = "compression")]
65use crate::codec::compressed::stream::CompressedInput;
66use crate::codec::decoder::Decoder;
67use crate::codec::raw::stream::RawInput;
68use crate::codec::CodecError;
69use serde::{Deserialize, Serialize};
70
71#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq)]
73pub enum TimeMode {
74 DeltaT,
76
77 #[default]
79 AbsoluteT,
80
81 Mixed,
83}
84
85#[derive(Clone, Copy, Debug, PartialEq)]
87pub struct PlaneSize {
88 width: u16,
89 height: u16,
90 channels: u8,
91}
92
93impl Default for PlaneSize {
94 fn default() -> Self {
95 PlaneSize {
96 width: 1,
97 height: 1,
98 channels: 1,
99 }
100 }
101}
102
103impl PlaneSize {
104 pub fn new(width: u16, height: u16, channels: u8) -> Result<Self, PlaneError> {
106 if width == 0 || height == 0 || channels == 0 {
107 return Err(PlaneError::InvalidPlane {
108 width,
109 height,
110 channels,
111 });
112 }
113 Ok(Self {
114 width,
115 height,
116 channels,
117 })
118 }
119 pub fn w(&self) -> u16 {
121 self.width
122 }
123
124 pub fn w_usize(&self) -> usize {
126 self.width as usize
127 }
128
129 pub fn h(&self) -> u16 {
131 self.height
132 }
133
134 pub fn h_usize(&self) -> usize {
136 self.height as usize
137 }
138
139 pub fn c(&self) -> u8 {
141 self.channels
142 }
143
144 pub fn c_usize(&self) -> usize {
146 self.channels as usize
147 }
148
149 pub fn area_wh(&self) -> usize {
151 self.width as usize * self.height as usize
152 }
153
154 pub fn area_wc(&self) -> usize {
156 self.width as usize * self.channels as usize
157 }
158
159 pub fn area_hc(&self) -> usize {
161 self.height as usize * self.channels as usize
162 }
163
164 pub fn volume(&self) -> usize {
166 self.area_wh() * self.channels as usize
167 }
168
169 pub fn min_resolution(&self) -> u16 {
171 self.width.min(self.height)
172 }
173
174 pub fn max_resolution(&self) -> u16 {
176 self.width.max(self.height)
177 }
178}
179
180pub type D = u8;
182
183pub const D_MAX: D = 127;
185
186pub const D_EMPTY: D = 255;
188
189pub const D_ZERO_INTEGRATION: D = 128;
191
192pub const D_NO_EVENT: D = 253;
194
195#[derive(Clone, Copy, PartialEq, Default, Debug)]
196pub enum Mode {
197 #[default]
201 FramePerfect,
202
203 Continuous,
205}
206
207#[derive(Clone, Copy, PartialEq, Default, Debug)]
208pub enum PixelMultiMode {
209 Normal,
210
211 #[default]
212 Collapse,
213}
214
215pub type UDshift = u128;
217
218use seq_macro::seq;
219
220macro_rules! make_d_shift_array {
221 ($name:ident, $type:ty) => {
222 seq!(N in 0..=128 {
223 pub const $name: [$type; 129] = [
225 #(
226 if N == 128 { 0 as $type } else { (1_u128 << N) as $type },
227 )*
228 ];
229 });
230 };
231}
232
233make_d_shift_array!(D_SHIFT, UDshift);
234make_d_shift_array!(D_SHIFT_F64, f64);
235make_d_shift_array!(D_SHIFT_F32, f32);
236
237pub const MAX_INTENSITY: f32 = 255.0; pub const D_START: D = 7;
242
243pub type DeltaT = u32;
245
246pub type AbsoluteT = u32;
249
250pub type BigT = u64;
252
253pub type Intensity = f64;
255
256pub type PixelAddress = u16;
258
259pub const EOF_PX_ADDRESS: PixelAddress = u16::MAX;
261
262#[repr(packed)]
264#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
265pub struct Coord {
266 pub x: PixelAddress,
268
269 pub y: PixelAddress,
271
272 pub c: Option<u8>,
274}
275
276impl Default for Coord {
277 fn default() -> Self {
278 Self {
279 x: 0,
280 y: 0,
281 c: Some(0),
282 }
283 }
284}
285
286impl Coord {
287 pub fn new(x: PixelAddress, y: PixelAddress, c: Option<u8>) -> Self {
289 Self { x, y, c }
290 }
291
292 pub fn new_2d(x: PixelAddress, y: PixelAddress) -> Self {
294 Self { x, y, c: None }
295 }
296
297 pub fn new_3d(x: PixelAddress, y: PixelAddress, c: u8) -> Self {
299 Self { x, y, c: Some(c) }
300 }
301
302 pub fn x(&self) -> PixelAddress {
304 self.x
305 }
306
307 pub fn y(&self) -> PixelAddress {
309 self.y
310 }
311
312 pub fn c(&self) -> Option<u8> {
314 self.c
315 }
316
317 pub fn x_usize(&self) -> usize {
319 self.x as usize
320 }
321
322 pub fn y_usize(&self) -> usize {
324 self.y as usize
325 }
326
327 pub fn c_usize(&self) -> usize {
329 self.c.unwrap_or(0) as usize
330 }
331
332 pub fn is_2d(&self) -> bool {
334 self.c.is_none()
335 }
336
337 pub fn is_3d(&self) -> bool {
339 self.c.is_some()
340 }
341
342 pub fn is_valid(&self) -> bool {
344 self.x != EOF_PX_ADDRESS && self.y != EOF_PX_ADDRESS
345 }
346
347 pub fn is_eof(&self) -> bool {
349 self.x == EOF_PX_ADDRESS && self.y == EOF_PX_ADDRESS
350 }
351
352 pub fn is_border(&self, width: usize, height: usize, cs: usize) -> bool {
354 self.x_usize() < cs
355 || self.x_usize() >= width - cs
356 || self.y_usize() < cs
357 || self.y_usize() >= height - cs
358 }
359}
360
361#[allow(missing_docs)]
363#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
364pub struct CoordSingle {
365 pub x: PixelAddress,
366 pub y: PixelAddress,
367}
368
369#[allow(missing_docs)]
371#[repr(packed)]
372#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, Hash, Serialize, Deserialize)]
373pub struct Event {
374 pub coord: Coord,
375 pub d: D,
376 pub t: AbsoluteT,
377}
378
379#[allow(missing_docs)]
380#[repr(packed)]
381#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, Hash, Serialize, Deserialize)]
382pub struct EventRelative {
383 pub coord: Coord,
384 pub d: D,
385 pub delta_t: DeltaT,
386}
387
388#[allow(missing_docs)]
390#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
391pub struct EventSingle {
392 pub coord: CoordSingle,
393 pub d: D,
394 pub t: DeltaT,
395}
396
397impl From<&Event> for EventSingle {
398 fn from(event: &Event) -> Self {
399 Self {
400 coord: CoordSingle {
401 x: event.coord.x,
402 y: event.coord.y,
403 },
404 d: event.d,
405 t: event.t,
406 }
407 }
408}
409
410impl From<EventSingle> for Event {
411 fn from(event: EventSingle) -> Self {
412 Self {
413 coord: Coord {
414 x: event.coord.x,
415 y: event.coord.y,
416 c: None,
417 },
418 d: event.d,
419 t: event.t,
420 }
421 }
422}
423
424impl Ord for Event {
425 fn cmp(&self, other: &Self) -> Ordering {
426 let b = other.t;
427 let a = self.t;
428 b.cmp(&a)
429 }
430}
431
432impl PartialOrd for Event {
433 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
434 Some(self.cmp(other))
435 }
436}
437
438#[allow(missing_docs)]
440#[derive(Debug, Copy, Clone, PartialEq, Eq)]
441pub enum SourceType {
442 U8,
443 U16,
444 U32,
445 U64,
446 F32,
447 F64,
448}
449
450const EOF_EVENT: Event = Event {
451 coord: Coord {
452 x: EOF_PX_ADDRESS,
453 y: EOF_PX_ADDRESS,
454 c: Some(0),
455 },
456 d: 0,
457 t: 0,
458};
459
460pub fn open_file_decoder(
462 file_path: &str,
463) -> Result<
464 (
465 Decoder<BufReader<File>>,
466 BitReader<BufReader<File>, BigEndian>,
467 ),
468 CodecError,
469> {
470 let mut bufreader = BufReader::new(File::open(file_path)?);
471 let compression = RawInput::new();
472 let mut bitreader = BitReader::endian(bufreader, BigEndian);
473
474 let stream = match Decoder::new_raw(compression, &mut bitreader) {
476 Ok(reader) => reader,
477 Err(CodecError::WrongMagic) => {
478 #[cfg(feature = "compression")]
479 {
480 dbg!("Opening as compressed");
481 bufreader = BufReader::new(File::open(file_path)?);
482 let compression = CompressedInput::new(0, 0, 0); bitreader = BitReader::endian(bufreader, BigEndian);
484 Decoder::new_compressed(compression, &mut bitreader)?
485 }
486
487 #[cfg(not(feature = "compression"))]
488 return Err(CodecError::WrongMagic);
489 }
490 Err(e) => {
491 return Err(e);
492 }
493 };
494 Ok((stream, bitreader))
495}
496
497#[allow(missing_docs)]
499#[derive(Debug, Copy, Clone, Default, serde::Serialize, serde::Deserialize, PartialEq)]
500pub struct EventCoordless {
501 pub d: D,
502
503 pub t: AbsoluteT,
504}
505
506#[allow(missing_docs)]
507#[derive(Debug, Copy, Clone, Default, serde::Serialize, serde::Deserialize, PartialEq)]
508pub struct EventCoordlessRelative {
509 pub d: D,
510
511 pub delta_t: DeltaT,
512}
513
514impl From<EventCoordless> for f64 {
515 fn from(val: EventCoordless) -> Self {
516 panic!("Not implemented")
517 }
518}
519
520impl EventCoordless {
521 #[inline(always)]
523 pub fn t(&self) -> AbsoluteT {
524 self.t as AbsoluteT
525 }
526}
527
528impl From<Event> for EventCoordless {
529 fn from(event: Event) -> Self {
530 Self {
531 d: event.d,
532 t: event.t,
533 }
534 }
535}
536
537impl Add<EventCoordless> for EventCoordless {
538 type Output = EventCoordless;
539
540 fn add(self, _rhs: EventCoordless) -> EventCoordless {
541 todo!()
542 }
543}
544
545impl num_traits::Zero for EventCoordless {
546 fn zero() -> Self {
547 EventCoordless { d: 0, t: 0 }
548 }
549
550 fn is_zero(&self) -> bool {
551 self.d.is_zero() && self.t.is_zero()
552 }
553}
554
555#[cfg(test)]
556mod tests {
557 use super::*;
558
559 #[test]
560 fn test_dshift_arrays() {
561 assert_eq!(D_SHIFT[0], 1);
562 assert_eq!(D_SHIFT_F64[0], 1.0);
563 assert_eq!(D_SHIFT_F32[0], 1.0);
564 assert_eq!(D_SHIFT.len(), 129);
565 assert_eq!(D_SHIFT_F64.len(), 129);
566 assert_eq!(D_SHIFT_F32.len(), 129);
567 assert_eq!(D_SHIFT[127], 1_u128 << 127);
568 assert_eq!(D_SHIFT_F64[127], D_SHIFT[127] as f64);
569 assert_eq!(D_SHIFT_F32[127], D_SHIFT[127] as f32);
570 }
571
572 #[test]
573 fn test_plane_size() {
574 let plane_size = PlaneSize::new(1, 1, 1).unwrap();
575 assert_eq!(plane_size.area_wh(), 1);
576 assert_eq!(plane_size.area_wc(), 1);
577 assert_eq!(plane_size.area_hc(), 1);
578 assert_eq!(plane_size.volume(), 1);
579
580 let plane_size = PlaneSize::new(2, 2, 1).unwrap();
581 assert_eq!(plane_size.area_wh(), 4);
582 assert_eq!(plane_size.area_wc(), 2);
583 assert_eq!(plane_size.area_hc(), 2);
584 assert_eq!(plane_size.volume(), 4);
585
586 let plane_size = PlaneSize::new(2, 2, 2).unwrap();
587 assert_eq!(plane_size.area_wh(), 4);
588 assert_eq!(plane_size.area_wc(), 4);
589 assert_eq!(plane_size.area_hc(), 4);
590 assert_eq!(plane_size.volume(), 8);
591 }
592
593 #[test]
594 fn test_coord() {
595 let coord = Coord::new(1, 2, Some(3));
596 assert_eq!(coord.x(), 1);
597 assert_eq!(coord.y(), 2);
598 assert_eq!(coord.c(), Some(3));
599 assert_eq!(coord.x_usize(), 1);
600 assert_eq!(coord.y_usize(), 2);
601 assert_eq!(coord.c_usize(), 3);
602 assert!(coord.is_3d());
603 assert!(!coord.is_2d());
604 assert!(coord.is_valid());
605 assert!(!coord.is_eof());
606
607 let coord = Coord::new(1, 2, None);
608 assert_eq!(coord.x(), 1);
609 assert_eq!(coord.y(), 2);
610 assert_eq!(coord.c(), None);
611 assert_eq!(coord.x_usize(), 1);
612 assert_eq!(coord.y_usize(), 2);
613 assert_eq!(coord.c_usize(), 0);
614 assert!(!coord.is_3d());
615 assert!(coord.is_2d());
616 assert!(coord.is_valid());
617 assert!(!coord.is_eof());
618
619 let coord = Coord::new(EOF_PX_ADDRESS, EOF_PX_ADDRESS, None);
620 assert_eq!(coord.x(), EOF_PX_ADDRESS);
621 assert_eq!(coord.y(), EOF_PX_ADDRESS);
622 assert_eq!(coord.c(), None);
623 assert_eq!(coord.x_usize(), EOF_PX_ADDRESS as usize);
624 assert_eq!(coord.y_usize(), EOF_PX_ADDRESS as usize);
625 assert_eq!(coord.c_usize(), 0);
626 assert!(!coord.is_3d());
627 assert!(coord.is_2d());
628 assert!(!coord.is_valid());
629 assert!(coord.is_eof());
630
631 let coord = Coord::new(EOF_PX_ADDRESS, EOF_PX_ADDRESS, Some(0));
632 assert_eq!(coord.x(), EOF_PX_ADDRESS);
633 assert_eq!(coord.y(), EOF_PX_ADDRESS);
634 assert_eq!(coord.c(), Some(0));
635 assert_eq!(coord.x_usize(), EOF_PX_ADDRESS as usize);
636 assert_eq!(coord.y_usize(), EOF_PX_ADDRESS as usize);
637 assert_eq!(coord.c_usize(), 0);
638 assert!(coord.is_3d());
639 assert!(!coord.is_2d());
640 assert!(!coord.is_valid());
641 assert!(coord.is_eof());
642
643 let coord = Coord::new(EOF_PX_ADDRESS, EOF_PX_ADDRESS, Some(1));
644 assert_eq!(coord.x(), EOF_PX_ADDRESS);
645 assert_eq!(coord.y(), EOF_PX_ADDRESS);
646 assert_eq!(coord.c(), Some(1));
647 assert_eq!(coord.x_usize(), EOF_PX_ADDRESS as usize);
648 assert_eq!(coord.y_usize(), EOF_PX_ADDRESS as usize);
649 assert_eq!(coord.c_usize(), 1);
650 assert!(coord.is_3d());
651 assert!(!coord.is_2d());
652 assert!(!coord.is_valid());
653 assert!(coord.is_eof());
654 }
655}