>>>>,
-}
-
-impl OctTreeQuantizer {
- fn new(num_colors: usize) -> Self {
- let mut new_quantizer = Self {
- root: Rc::new(RefCell::new(OctTreeNode::new())),
- reduce_colors: usize::max(512, num_colors * 2),
- maximum_colors: num_colors,
- color_list: vec![],
- colors: 0,
- };
-
- for _ in 0..=MAX_LEVEL {
- new_quantizer.color_list.push(Vec::new());
- }
- new_quantizer
- }
-
- pub fn quantize(&mut self, image: &RgbaImage) -> RgbaImage {
- for pixel in image.pixels() {
- self.insert_color(pixel, Rc::clone(&self.root));
-
- if self.colors > self.reduce_colors {
- self.reduce_tree(self.reduce_colors);
- //reduce sets to None and the code below actually removes nodes from the list
- for level in &mut self.color_list {
- level.retain(|c| c.is_some());
- }
- }
- }
- let table = self.build_color_table();
-
- let mut imgbuf = RgbaImage::new(image.width(), image.height());
- for (x, y, pixel) in image.enumerate_pixels() {
- if let Some(index) = self.get_index_for_color(pixel, &self.root) {
- let color = &table[index];
- if let Some(color) = color {
- imgbuf.put_pixel(x, y, *color);
- }
- }
- }
-
- imgbuf
- }
-
- fn get_index_for_color(&self, color: &P, node: &Rc>) -> Option
- where
- P: Pixel + 'static,
- {
- fn get_index_for_color(
- quantizer: &OctTreeQuantizer,
- color: &P,
- level: usize,
- node: &Rc>,
- ) -> Option
- where
- P: Pixel + 'static,
- {
- if level > MAX_LEVEL {
- return None;
- }
- let node = Rc::clone(node);
- let index = get_bitmask(color, &level);
-
- let node_b = node.borrow();
- let child = &node_b.leaf[index];
-
- if let Some(child) = child {
- let child_b = child.borrow();
- if child_b.is_leaf {
- return Some(child_b.index);
- } else {
- return get_index_for_color(quantizer, color, level + 1, child);
- }
- } else {
- return Some(node_b.index);
- }
- }
-
- get_index_for_color(&self, color, 0, node)
- }
-
- fn build_color_table(&mut self) -> Vec