auto_palette/image/
filter.rs1use crate::image::Rgba;
2
3pub trait Filter: Send + Sync + 'static {
5 #[must_use]
13 fn test(&self, pixel: &Rgba) -> bool;
14
15 #[must_use]
26 fn composite<F>(self, other: F) -> CompositeFilter<Self, F>
27 where
28 Self: Sized,
29 F: Filter,
30 {
31 CompositeFilter::new(self, other)
32 }
33}
34
35impl<F> Filter for F
42where
43 F: Fn(&Rgba) -> bool + Send + Sync + 'static,
44{
45 #[inline(always)]
46 fn test(&self, pixel: &Rgba) -> bool {
47 self(pixel)
48 }
49}
50
51#[derive(Debug)]
59pub struct CompositeFilter<F1, F2>
60where
61 F1: Filter,
62 F2: Filter,
63{
64 first: F1,
65 second: F2,
66}
67
68impl<F1, F2> CompositeFilter<F1, F2>
69where
70 F1: Filter,
71 F2: Filter,
72{
73 #[must_use]
82 pub fn new(first: F1, second: F2) -> Self {
83 Self { first, second }
84 }
85}
86
87impl<F1, F2> Filter for CompositeFilter<F1, F2>
88where
89 F1: Filter,
90 F2: Filter,
91{
92 #[inline(always)]
93 fn test(&self, pixel: &Rgba) -> bool {
94 self.first.test(pixel) && self.second.test(pixel)
97 }
98}
99
100#[derive(Debug)]
102pub struct AlphaFilter {
103 threshold: u8,
104}
105
106impl AlphaFilter {
107 #[must_use]
115 pub fn new(threshold: u8) -> Self {
116 Self { threshold }
117 }
118}
119
120impl Filter for AlphaFilter {
121 #[inline(always)]
122 fn test(&self, pixel: &Rgba) -> bool {
123 pixel[3] > self.threshold
124 }
125}
126
127impl Default for AlphaFilter {
128 fn default() -> Self {
129 Self::new(0)
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 fn test_closure_filter() {
139 let filter = |pixel: &Rgba| pixel[0] > 128; assert_eq!(filter.test(&[255, 0, 0, 255]), true);
142 assert_eq!(filter.test(&[129, 0, 0, 255]), true);
143 assert_eq!(filter.test(&[128, 0, 0, 255]), false);
144 assert_eq!(filter.test(&[0, 0, 0, 255]), false);
145 }
146
147 #[test]
148 fn test_composite_filter() {
149 let alpha_filter = |pixel: &Rgba| pixel[3] != 0;
151 let green_filter = |pixel: &Rgba| pixel[1] >= 128;
152
153 let filter = alpha_filter.composite(green_filter);
155
156 assert_eq!(filter.test(&[255, 127, 255, 0]), false); assert_eq!(filter.test(&[255, 255, 255, 0]), false); assert_eq!(filter.test(&[255, 127, 255, 255]), false); assert_eq!(filter.test(&[255, 128, 255, 255]), true); assert_eq!(filter.test(&[255, 255, 255, 255]), true); }
163
164 #[test]
165 fn test_alpha_filter() {
166 let filter = AlphaFilter::new(127);
168 assert_eq!(filter.test(&[255, 0, 0, 255]), true);
169 assert_eq!(filter.test(&[255, 0, 0, 128]), true);
170 assert_eq!(filter.test(&[255, 0, 0, 127]), false);
171 assert_eq!(filter.test(&[255, 0, 0, 0]), false);
172 }
173}