use crate::quantize::quantizer::{Quantizer, QuantizerResult};
use crate::quantize::quantizer_wsmeans::QuantizerWsmeans;
use crate::quantize::quantizer_wu::QuantizerWu;
use crate::utils::color_utils::Argb;
#[derive(Default)]
pub struct QuantizerCelebi;
impl QuantizerCelebi {
#[must_use]
pub const fn new() -> Self {
Self
}
}
impl Quantizer for QuantizerCelebi {
fn quantize(&mut self, pixels: &[Argb], max_colors: usize) -> QuantizerResult {
let mut wu = QuantizerWu::new();
let wu_result = wu.quantize(pixels, max_colors);
let starting_clusters: Vec<Argb> = wu_result.color_to_count.keys().copied().collect();
let clusters = QuantizerWsmeans::quantize(pixels, &starting_clusters, max_colors);
QuantizerResult::new(clusters)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::hct::Hct;
#[test]
fn test_quantize_celebi_basic() {
let pixels = vec![
Argb(0xFFFF0000), Argb(0xFFFF0000),
Argb(0xFFFF0000),
Argb(0xFFDD0000), Argb(0xFF00FF00), Argb(0xFF00FF00),
Argb(0xFF0000FF), Argb(0xFF0000FF),
Argb(0xFF0000FF),
];
let mut celebi = QuantizerCelebi::new();
let result = celebi.quantize(&pixels, 3);
assert!(!result.color_to_count.is_empty());
assert!(result.color_to_count.len() <= 3);
for (argb, count) in result.color_to_count {
let hue = Hct::from_argb(argb).hue();
if (0.0 - hue).abs() < 55.0 {
assert_eq!(count, 4);
continue;
}
if (120.0 - hue).abs() < 55.0 {
assert_eq!(count, 2);
continue;
}
if (240.0 - hue).abs() < 55.0 {
assert_eq!(count, 3);
continue;
}
panic!("Unknown color in result.color_to_count");
}
}
#[test]
fn test_quantize_celebi_single_color() {
let pixels = vec![Argb(0xFFFF0000); 10];
let mut celebi = QuantizerCelebi::new();
let result = celebi.quantize(&pixels, 128);
assert_eq!(result.color_to_count.len(), 1);
assert!(result.color_to_count.contains_key(&Argb(0xFFFF0000)));
}
}