ndarray_vision/core/
traits.rs

1/// When working with pixel data types may have odd bitdepths or not use the
2/// full range of the value. We can't assume every image with `u8` ranges from
3/// [0..255]. Additionally, floating point representations of pixels normally
4/// range from [0.0..1.0]. `PixelBound` is an attempt to solve this issue.
5///
6/// Unfortunately, type aliases don't really create new types so if you wanted
7/// to create a pixel with a reduced bound you'd have to create something like:
8///
9/// ```Rust
10/// struct LimitedU8(u8);
11/// impl PixelBound for LimitedU8 {
12///     fn min_pixel() -> Self {
13///         LimitedU8(16u8)
14///     }
15///     
16///     fn max_pixel() -> Self {
17///         LimitedU8(160u8)
18///     }
19/// }
20///
21/// And then implement the required numerical traits just calling the
22/// corresponding methods in `u8`
23/// ```
24pub trait PixelBound {
25    /// The minimum value a pixel can take
26    fn min_pixel() -> Self;
27    /// The maximum value a pixel can take
28    fn max_pixel() -> Self;
29    /// If this is a non-floating point value return true
30    fn is_integral() -> bool {
31        true
32    }
33}
34
35impl PixelBound for f64 {
36    fn min_pixel() -> Self {
37        0.0f64
38    }
39
40    fn max_pixel() -> Self {
41        1.0f64
42    }
43
44    fn is_integral() -> bool {
45        false
46    }
47}
48
49impl PixelBound for f32 {
50    fn min_pixel() -> Self {
51        0.0f32
52    }
53
54    fn max_pixel() -> Self {
55        1.0f32
56    }
57
58    fn is_integral() -> bool {
59        false
60    }
61}
62
63impl PixelBound for u8 {
64    fn min_pixel() -> Self {
65        Self::min_value()
66    }
67
68    fn max_pixel() -> Self {
69        Self::max_value()
70    }
71}
72
73impl PixelBound for u16 {
74    fn min_pixel() -> Self {
75        Self::min_value()
76    }
77
78    fn max_pixel() -> Self {
79        Self::max_value()
80    }
81}
82
83impl PixelBound for u32 {
84    fn min_pixel() -> Self {
85        Self::min_value()
86    }
87
88    fn max_pixel() -> Self {
89        Self::max_value()
90    }
91}
92
93impl PixelBound for u64 {
94    fn min_pixel() -> Self {
95        Self::min_value()
96    }
97
98    fn max_pixel() -> Self {
99        Self::max_value()
100    }
101}
102
103impl PixelBound for u128 {
104    fn min_pixel() -> Self {
105        Self::min_value()
106    }
107
108    fn max_pixel() -> Self {
109        Self::max_value()
110    }
111}
112
113impl PixelBound for i8 {
114    fn min_pixel() -> Self {
115        Self::min_value()
116    }
117
118    fn max_pixel() -> Self {
119        Self::max_value()
120    }
121}
122
123impl PixelBound for i16 {
124    fn min_pixel() -> Self {
125        Self::min_value()
126    }
127
128    fn max_pixel() -> Self {
129        Self::max_value()
130    }
131}
132
133impl PixelBound for i32 {
134    fn min_pixel() -> Self {
135        Self::min_value()
136    }
137
138    fn max_pixel() -> Self {
139        Self::max_value()
140    }
141}
142
143impl PixelBound for i64 {
144    fn min_pixel() -> Self {
145        Self::min_value()
146    }
147
148    fn max_pixel() -> Self {
149        Self::max_value()
150    }
151}
152
153impl PixelBound for i128 {
154    fn min_pixel() -> Self {
155        Self::min_value()
156    }
157
158    fn max_pixel() -> Self {
159        Self::max_value()
160    }
161}
162
163#[cfg(test)]
164mod tests {
165    use super::*;
166
167    #[test]
168    fn integral_correct() {
169        assert!(!f64::is_integral());
170        assert!(!f32::is_integral());
171        assert!(u128::is_integral());
172        assert!(u64::is_integral());
173        assert!(u32::is_integral());
174        assert!(u16::is_integral());
175        assert!(u8::is_integral());
176        assert!(i128::is_integral());
177        assert!(i64::is_integral());
178        assert!(i32::is_integral());
179        assert!(i16::is_integral());
180        assert!(i8::is_integral());
181    }
182
183    #[test]
184    fn max_more_than_min() {
185        assert!(f64::max_pixel() > f64::min_pixel());
186        assert!(f32::max_pixel() > f32::min_pixel());
187        assert!(u8::max_pixel() > u8::min_pixel());
188        assert!(u16::max_pixel() > u16::min_pixel());
189        assert!(u32::max_pixel() > u32::min_pixel());
190        assert!(u64::max_pixel() > u64::min_pixel());
191        assert!(u128::max_pixel() > u128::min_pixel());
192        assert!(i8::max_pixel() > i8::min_pixel());
193        assert!(i16::max_pixel() > i16::min_pixel());
194        assert!(i32::max_pixel() > i32::min_pixel());
195        assert!(i64::max_pixel() > i64::min_pixel());
196        assert!(i128::max_pixel() > i128::min_pixel());
197    }
198}