rusterize/rasterization/
pixel_functions.rs1use crate::prelude::*;
2use ndarray::ArrayViewMut2;
3use num_traits::Num;
4use std::{ops::AddAssign, str::FromStr};
5
6#[derive(Clone)]
8pub enum PixelFunction {
9 Sum,
10 First,
11 Last,
12 Min,
13 Max,
14 Count,
15 Any,
16}
17
18impl FromStr for PixelFunction {
19 type Err = RusterizeError;
20
21 fn from_str(s: &str) -> RusterizeResult<Self> {
22 match s {
23 "sum" => Ok(Self::Sum),
24 "first" => Ok(Self::First),
25 "last" => Ok(Self::Last),
26 "min" => Ok(Self::Min),
27 "max" => Ok(Self::Max),
28 "count" => Ok(Self::Count),
29 "any" => Ok(Self::Any),
30 _ => Err(RusterizeError::ValueError("Unknown pixel function")),
31 }
32 }
33}
34
35impl PixelFunction {
36 pub(crate) fn to_function<N>(&self) -> PixelFn<N>
37 where
38 N: Num + Copy + AddAssign + PartialOrd + NaNAware,
39 {
40 match self {
41 Self::Sum => sum_values,
42 Self::First => first_values,
43 Self::Last => last_values,
44 Self::Min => min_values,
45 Self::Max => max_values,
46 Self::Count => count_values,
47 Self::Any => any_values,
48 }
49 }
50}
51
52pub(crate) type PixelFn<N> = fn(&mut ArrayViewMut2<N>, usize, usize, N, N);
54
55fn sum_values<N>(array: &mut ArrayViewMut2<N>, y: usize, x: usize, value: N, bg: N)
57where
58 N: Num + AddAssign + NaNAware + Copy,
59{
60 if array[[y, x]] == bg || array[[y, x]].is_nan() || value.is_nan() {
61 array[[y, x]] = value;
62 } else {
63 array[[y, x]] += value;
64 }
65}
66
67fn first_values<N>(array: &mut ArrayViewMut2<N>, y: usize, x: usize, value: N, bg: N)
69where
70 N: Num + NaNAware + Copy,
71{
72 if array[[y, x]] == bg || array[[y, x]].is_nan() {
73 array[[y, x]] = value;
74 }
75}
76
77fn last_values<N>(array: &mut ArrayViewMut2<N>, y: usize, x: usize, value: N, _bg: N)
79where
80 N: Num + Copy,
81{
82 array[[y, x]] = value;
83}
84
85fn min_values<N>(array: &mut ArrayViewMut2<N>, y: usize, x: usize, value: N, bg: N)
87where
88 N: Num + NaNAware + PartialOrd + Copy,
89{
90 if array[[y, x]] == bg || array[[y, x]].is_nan() || array[[y, x]] > value {
91 array[[y, x]] = value;
92 }
93}
94
95fn max_values<N>(array: &mut ArrayViewMut2<N>, y: usize, x: usize, value: N, bg: N)
97where
98 N: Num + NaNAware + PartialOrd + Copy,
99{
100 if array[[y, x]] == bg || array[[y, x]].is_nan() || array[[y, x]] < value {
101 array[[y, x]] = value;
102 }
103}
104
105fn count_values<N>(array: &mut ArrayViewMut2<N>, y: usize, x: usize, _value: N, bg: N)
107where
108 N: Num + AddAssign + NaNAware + Copy,
109{
110 if array[[y, x]] == bg || array[[y, x]].is_nan() {
111 array[[y, x]] = N::one();
112 } else {
113 array[[y, x]] += N::one();
114 }
115}
116
117fn any_values<N>(array: &mut ArrayViewMut2<N>, y: usize, x: usize, _value: N, _bg: N)
119where
120 N: Num,
121{
122 array[[y, x]] = N::one();
123}