use super::LabelFormat; pub struct LargeLabelFormat { pub buffer: Vec, pub width: usize, pub height: usize, } impl std::fmt::Debug for LargeLabelFormat { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("LargeLabelFormat") .field("width", &self.width) .field("height", &self.height) .finish() } } fn flood(source: &LargeLabelFormat, destination: &mut Vec, x: usize, y: usize, from_color: u32, to_color: u16) { let width = source.width; let destination_color = destination[x + y * width]; if destination_color != 0 { return; } let source_color = source.buffer[x + y * width]; if source_color != from_color { return; } destination[x + y * width] = to_color; if x > 0 { flood(source, destination, x-1, y, from_color, to_color); } if (x+1) < width { flood(source, destination, x+1, y, from_color, to_color); } if y > 0 { flood(source, destination, x, y-1, from_color, to_color); } if (y+1) < source.height { flood(source, destination, x, y+1, from_color, to_color); } } impl LargeLabelFormat { pub fn compress(&self) -> LabelFormat { let mut label: u16 = 1; let mut output_buffer: Vec = vec![0u16; self.buffer.len()]; for y in 0..self.height { for x in 0..self.width { let index = x + y*self.width; if self.buffer[index] == 0 { continue; } if output_buffer[index] == 0 { let color = self.buffer[index]; flood(&self, &mut output_buffer, x, y, color, label); label += 1; } } } return LabelFormat { buffer: output_buffer, width: self.width, height: self.height, }; } }