adder_codec_rs/framer/
scale_intensity.rs

1use crate::transcoder::source::video::FramedViewMode;
2use adder_codec_core::{
3    DeltaT, Event, EventCoordless, Intensity, SourceType, D_SHIFT, D_SHIFT_F64,
4};
5
6/// A trait for types that can be used as the value of a pixel in a `Frame`.
7pub trait FrameValue {
8    /// The type of the output intensity value
9    type Output;
10
11    /// Get the frame-normalized intensity value of an event
12    fn get_frame_value(
13        event: &Event,
14        source_type: SourceType,
15        delta_t: f64,
16        practical_d_max: f32,
17        delta_t_max: DeltaT,
18        view_mode: FramedViewMode,
19        px: Option<SaeTime>,
20    ) -> Self::Output;
21
22    /// The maximum value of the type, as an f32
23    fn max_f32() -> f32;
24}
25
26/// Surface of Active Events
27pub struct SaeTime {
28    pub(crate) running_t: DeltaT,
29    pub(crate) last_fired_t: DeltaT,
30}
31
32impl FrameValue for EventCoordless {
33    type Output = EventCoordless;
34    fn get_frame_value(
35        event: &Event,
36        _source_type: SourceType,
37        _tpf: f64,
38        _practical_d_max: f32,
39        _delta_t_max: DeltaT,
40        _view_mode: FramedViewMode,
41        _px: Option<SaeTime>,
42    ) -> Self::Output {
43        EventCoordless {
44            d: event.d,
45            t: event.t,
46        }
47    }
48
49    fn max_f32() -> f32 {
50        1.0
51    }
52}
53
54impl FrameValue for u8 {
55    type Output = u8;
56
57    #[inline(always)]
58    fn get_frame_value(
59        event: &Event,
60        source_type: SourceType,
61        tpf: f64,
62        practical_d_max: f32,
63        delta_t_max: DeltaT,
64        view_mode: FramedViewMode,
65        px: Option<SaeTime>,
66    ) -> Self::Output {
67        match view_mode {
68            FramedViewMode::Intensity => {
69                let intensity = event_to_intensity(event);
70                match source_type {
71                    SourceType::U8 => (intensity * tpf) as u8,
72                    SourceType::U16 => {
73                        (intensity / f64::from(u16::MAX) * tpf * f64::from(u8::MAX)) as u8
74                    }
75                    SourceType::U32 => {
76                        (intensity / f64::from(u32::MAX) * tpf * f64::from(u8::MAX)) as u8
77                    }
78                    SourceType::U64 => {
79                        (intensity / u64::MAX as f64 * tpf * f64::from(u8::MAX)) as u8
80                    }
81                    SourceType::F32 => {
82                        todo!()
83                    }
84                    SourceType::F64 => {
85                        todo!()
86                    }
87                }
88            }
89            FramedViewMode::D => {
90                ((f32::from(event.d) / practical_d_max) * f32::from(u8::MAX)) as u8
91            }
92            FramedViewMode::DeltaT => {
93                ((event.t as f32 / delta_t_max as f32) * f32::from(u8::MAX)) as u8
94            }
95            FramedViewMode::SAE => {
96                if let Some(px) = px {
97                    (((px.running_t - px.last_fired_t) as f32 / delta_t_max as f32) * 255.0) as u8
98                    // We assume that the dt component is an absolute_t in this case
99                } else {
100                    0
101                }
102            }
103        }
104    }
105
106    fn max_f32() -> f32 {
107        f32::from(u8::MAX)
108    }
109}
110
111impl FrameValue for u16 {
112    type Output = u16;
113
114    fn get_frame_value(
115        event: &Event,
116        source_type: SourceType,
117        tpf: f64,
118        practical_d_max: f32,
119        delta_t_max: DeltaT,
120        view_mode: FramedViewMode,
121        _px: Option<SaeTime>,
122    ) -> Self::Output {
123        match view_mode {
124            FramedViewMode::Intensity => {
125                let intensity = event_to_intensity(event);
126                match source_type {
127                    SourceType::U8 => {
128                        (intensity / f64::from(u8::MAX) * tpf * f64::from(u16::MAX)) as u16
129                    }
130                    SourceType::U16 => (intensity * tpf) as u16,
131                    SourceType::U32 => {
132                        (intensity / f64::from(u32::MAX) * tpf * f64::from(u16::MAX)) as u16
133                    }
134                    SourceType::U64 => {
135                        (intensity / u64::MAX as f64 * tpf * f64::from(u16::MAX)) as u16
136                    }
137                    SourceType::F32 => {
138                        todo!()
139                    }
140                    SourceType::F64 => {
141                        todo!()
142                    }
143                }
144            }
145            FramedViewMode::D => {
146                ((f32::from(event.d) / practical_d_max) * f32::from(u16::MAX)) as u16
147            }
148            FramedViewMode::DeltaT => {
149                ((event.t as f32 / delta_t_max as f32) * f32::from(u16::MAX)) as u16
150            }
151            FramedViewMode::SAE => {
152                todo!()
153            }
154        }
155    }
156
157    fn max_f32() -> f32 {
158        f32::from(u16::MAX)
159    }
160}
161
162impl FrameValue for u32 {
163    type Output = u32;
164
165    fn get_frame_value(
166        event: &Event,
167        source_type: SourceType,
168        tpf: f64,
169        practical_d_max: f32,
170        delta_t_max: DeltaT,
171        view_mode: FramedViewMode,
172        _px: Option<SaeTime>,
173    ) -> Self::Output {
174        match view_mode {
175            FramedViewMode::Intensity => {
176                let intensity = event_to_intensity(event);
177                match source_type {
178                    SourceType::U8 => {
179                        (intensity / f64::from(u8::MAX) * tpf * f64::from(u32::MAX)) as u32
180                    }
181                    SourceType::U16 => {
182                        (intensity / f64::from(u16::MAX) * tpf * f64::from(u32::MAX)) as u32
183                    }
184                    SourceType::U32 => (intensity * tpf) as u32,
185                    SourceType::U64 => {
186                        (intensity / u64::MAX as f64 * tpf * f64::from(u32::MAX)) as u32
187                    }
188                    SourceType::F32 => {
189                        todo!()
190                    }
191                    SourceType::F64 => {
192                        todo!()
193                    }
194                }
195            }
196            FramedViewMode::D => ((f32::from(event.d) / practical_d_max) * u32::MAX as f32) as u32,
197            FramedViewMode::DeltaT => {
198                ((event.t as f32 / delta_t_max as f32) * u32::MAX as f32) as u32
199            }
200            FramedViewMode::SAE => {
201                todo!()
202            }
203        }
204    }
205
206    fn max_f32() -> f32 {
207        u32::MAX as f32
208    }
209}
210
211impl FrameValue for u64 {
212    type Output = u64;
213
214    fn get_frame_value(
215        event: &Event,
216        source_type: SourceType,
217        tpf: f64,
218        practical_d_max: f32,
219        delta_t_max: DeltaT,
220        view_mode: FramedViewMode,
221        _px: Option<SaeTime>,
222    ) -> Self::Output {
223        match view_mode {
224            FramedViewMode::Intensity => {
225                let intensity = event_to_intensity(event);
226                match source_type {
227                    SourceType::U8 => {
228                        (intensity / f64::from(u8::MAX) * tpf * u64::MAX as f64) as u64
229                    }
230                    SourceType::U16 => {
231                        (intensity / f64::from(u16::MAX) * tpf * u64::MAX as f64) as u64
232                    }
233                    SourceType::U32 => {
234                        (intensity / f64::from(u32::MAX) * tpf * u64::MAX as f64) as u64
235                    }
236                    SourceType::U64 => (intensity * tpf) as u64,
237                    SourceType::F32 => {
238                        todo!()
239                    }
240                    SourceType::F64 => {
241                        todo!()
242                    }
243                }
244            }
245            FramedViewMode::D => ((f32::from(event.d) / practical_d_max) * u64::MAX as f32) as u64,
246            FramedViewMode::DeltaT => {
247                ((event.t as f32 / delta_t_max as f32) * u64::MAX as f32) as u64
248            }
249            FramedViewMode::SAE => {
250                todo!()
251            }
252        }
253    }
254
255    fn max_f32() -> f32 {
256        u64::MAX as f32
257    }
258}
259
260/// Convert an event to an intensity value.
261#[must_use]
262pub fn event_to_intensity(event: &Event) -> Intensity {
263    match event.d as usize {
264        a if a >= D_SHIFT.len() => f64::from(0),
265        _ => match event.t {
266            0 => D_SHIFT_F64[event.d as usize], // treat it as dt = 1
267            _ => D_SHIFT_F64[event.d as usize] / f64::from(event.t),
268        },
269    }
270}
271
272fn _eventcoordless_to_intensity(event: EventCoordless) -> Intensity {
273    match event.d as usize {
274        a if a >= D_SHIFT.len() => f64::from(0),
275        _ => D_SHIFT[event.d as usize] as Intensity / f64::from(event.t),
276    }
277}