Skip to main content

material_colors/quantize/
quantizer_celebi.rs

1use super::{Quantizer, QuantizerResult, QuantizerWsmeans, QuantizerWu};
2use crate::color::Argb;
3#[cfg(not(feature = "std"))]
4use alloc::vec::Vec;
5#[cfg(feature = "std")]
6use std::vec::Vec;
7
8#[derive(Default)]
9pub struct QuantizerCelebi;
10
11impl Quantizer for QuantizerCelebi {
12    fn quantize(pixels: &[Argb], max_colors: usize) -> QuantizerResult {
13        let wu_result = QuantizerWu::quantize(pixels, max_colors);
14
15        QuantizerWsmeans::quantize(
16            pixels,
17            max_colors,
18            &wu_result.color_to_count.into_keys().collect::<Vec<_>>(),
19        )
20    }
21}
22
23#[cfg(test)]
24mod tests {
25    use super::QuantizerCelebi;
26    use crate::{color::Argb, quantize::Quantizer};
27    #[cfg(not(feature = "std"))]
28    use alloc::vec::Vec;
29    #[cfg(feature = "std")]
30    use std::vec::Vec;
31
32    const RED: Argb = Argb::from_u32(0xffff0000);
33    const GREEN: Argb = Argb::from_u32(0xff00ff00);
34    const BLUE: Argb = Argb::from_u32(0xff0000ff);
35    // const WHITE: Argb = Argb::from_u32(0xffffffff);
36    // const RANDOM: Argb = Argb::from_u32(0xff426088);
37    const MAX_COLORS: usize = 256;
38
39    const IMAGE_PIXELS: [Argb; 84] = [
40        Argb::from_u32(0xff050505),
41        Argb::from_u32(0xff000000),
42        Argb::from_u32(0xff000000),
43        Argb::from_u32(0xff000000),
44        Argb::from_u32(0xff000000),
45        Argb::from_u32(0xff090909),
46        Argb::from_u32(0xff060404),
47        Argb::from_u32(0xff030102),
48        Argb::from_u32(0xff080607),
49        Argb::from_u32(0xff070506),
50        Argb::from_u32(0xff010001),
51        Argb::from_u32(0xff070506),
52        Argb::from_u32(0xff364341),
53        Argb::from_u32(0xff223529),
54        Argb::from_u32(0xff14251c),
55        Argb::from_u32(0xff11221a),
56        Argb::from_u32(0xff1f3020),
57        Argb::from_u32(0xff34443a),
58        Argb::from_u32(0xff64817e),
59        Argb::from_u32(0xff638777),
60        Argb::from_u32(0xff486d58),
61        Argb::from_u32(0xff2f5536),
62        Argb::from_u32(0xff467258),
63        Argb::from_u32(0xff7fb7b9),
64        Argb::from_u32(0xff6d8473),
65        Argb::from_u32(0xff859488),
66        Argb::from_u32(0xff7a947e),
67        Argb::from_u32(0xff5f815d),
68        Argb::from_u32(0xff3a5d46),
69        Argb::from_u32(0xff497469),
70        Argb::from_u32(0xff737a73),
71        Argb::from_u32(0xff656453),
72        Argb::from_u32(0xff445938),
73        Argb::from_u32(0xff657c4b),
74        Argb::from_u32(0xff65715b),
75        Argb::from_u32(0xff6a816e),
76        Argb::from_u32(0xff667366),
77        Argb::from_u32(0xff5b5547),
78        Argb::from_u32(0xff3b391e),
79        Argb::from_u32(0xff705e3d),
80        Argb::from_u32(0xff7f6c5e),
81        Argb::from_u32(0xff6d7c6c),
82        Argb::from_u32(0xffa99c9c),
83        Argb::from_u32(0xff8b7671),
84        Argb::from_u32(0xff6a3229),
85        Argb::from_u32(0xff80514b),
86        Argb::from_u32(0xff857970),
87        Argb::from_u32(0xff4f5a4c),
88        Argb::from_u32(0xff897273),
89        Argb::from_u32(0xff745451),
90        Argb::from_u32(0xff512823),
91        Argb::from_u32(0xff78585a),
92        Argb::from_u32(0xff535552),
93        Argb::from_u32(0xff40493f),
94        Argb::from_u32(0xff151616),
95        Argb::from_u32(0xff0a0c0c),
96        Argb::from_u32(0xff050808),
97        Argb::from_u32(0xff010303),
98        Argb::from_u32(0xff000100),
99        Argb::from_u32(0xff010200),
100        Argb::from_u32(0xff191816),
101        Argb::from_u32(0xff181818),
102        Argb::from_u32(0xff0c0c0c),
103        Argb::from_u32(0xff040404),
104        Argb::from_u32(0xff0c0c0c),
105        Argb::from_u32(0xff151514),
106        Argb::from_u32(0xffb1c3b9),
107        Argb::from_u32(0xffbfbfbf),
108        Argb::from_u32(0xffbababa),
109        Argb::from_u32(0xffb7b7b7),
110        Argb::from_u32(0xffb3b3b3),
111        Argb::from_u32(0xffadadad),
112        Argb::from_u32(0xff535756),
113        Argb::from_u32(0xff575656),
114        Argb::from_u32(0xff555555),
115        Argb::from_u32(0xff555555),
116        Argb::from_u32(0xff545454),
117        Argb::from_u32(0xff474646),
118        Argb::from_u32(0xff000000),
119        Argb::from_u32(0xff000000),
120        Argb::from_u32(0xff0b0b0b),
121        Argb::from_u32(0xff0b0b0b),
122        Argb::from_u32(0xff000000),
123        Argb::from_u32(0xff000000),
124    ];
125
126    #[test]
127    fn test_1rando() {
128        let result = QuantizerCelebi::quantize(&[Argb::from_u32(0xff141216)], MAX_COLORS);
129        let colors = result.color_to_count.keys().collect::<Vec<_>>();
130
131        assert_eq!(colors.len(), 1);
132        assert_eq!(colors[0], &Argb::from_u32(0xff141216));
133    }
134
135    #[test]
136    fn test_1r() {
137        let result = QuantizerCelebi::quantize(&[RED], MAX_COLORS);
138        let colors = result.color_to_count.keys().collect::<Vec<_>>();
139
140        assert_eq!(colors.len(), 1);
141        assert_eq!(colors[0], &RED);
142    }
143
144    #[test]
145    fn test_1g() {
146        let result = QuantizerCelebi::quantize(&[GREEN], MAX_COLORS);
147        let colors = result.color_to_count.keys().collect::<Vec<_>>();
148
149        assert_eq!(colors.len(), 1);
150        assert_eq!(colors[0], &GREEN);
151    }
152
153    #[test]
154    fn test_1b() {
155        let result = QuantizerCelebi::quantize(&[BLUE], MAX_COLORS);
156        let colors = result.color_to_count.keys().collect::<Vec<_>>();
157
158        assert_eq!(colors.len(), 1);
159        assert_eq!(colors[0], &BLUE);
160    }
161
162    #[test]
163    fn test_5b() {
164        let result = QuantizerCelebi::quantize(&[BLUE, BLUE, BLUE, BLUE, BLUE], MAX_COLORS);
165        let colors = result.color_to_count.keys().collect::<Vec<_>>();
166
167        assert_eq!(colors.len(), 1);
168        assert_eq!(colors[0], &BLUE);
169    }
170
171    #[test]
172    fn test_2r_3g() {
173        let result = QuantizerCelebi::quantize(&[RED, RED, GREEN, GREEN, GREEN], MAX_COLORS);
174
175        assert_eq!(result.color_to_count.keys().len(), 2);
176        assert_eq!(result.color_to_count.get(&GREEN).unwrap(), &3);
177        assert_eq!(result.color_to_count.get(&RED).unwrap(), &2);
178    }
179
180    #[test]
181    fn test_1r_1g_1b() {
182        let result = QuantizerCelebi::quantize(&[RED, GREEN, BLUE], MAX_COLORS);
183
184        assert_eq!(result.color_to_count.keys().len(), 3);
185        assert_eq!(result.color_to_count.get(&GREEN).unwrap(), &1);
186        assert_eq!(result.color_to_count.get(&RED).unwrap(), &1);
187        assert_eq!(result.color_to_count.get(&BLUE).unwrap(), &1);
188    }
189
190    /// Verifies QuantizerCelebi.quantize returns identical result given same input.
191    #[test]
192    fn test_stability() {
193        let result1 = QuantizerCelebi::quantize(&IMAGE_PIXELS, 16).color_to_count;
194        let result2 = QuantizerCelebi::quantize(&IMAGE_PIXELS, 16).color_to_count;
195
196        assert_eq!(result1, result2);
197    }
198}