pub struct LabelFormat { pub buffer: Vec, pub width: usize, pub height: usize, } impl LabelFormat { pub fn get_left(&self, x: usize, y: usize) -> Option { if x > 0 { return Some(self.buffer[(x-1) + y * self.width]); } return None; } pub fn get_right(&self, x: usize, y: usize) -> Option { if (x+1) < self.width { return Some(self.buffer[(x+1) + y * self.width]); } return None; } pub fn get_up(&self, x: usize, y: usize) -> Option { if y > 0 { return Some(self.buffer[x + (y-1) * self.width]); } return None; } pub fn get_down(&self, x: usize, y: usize) -> Option { if (y+1) < self.height { return Some(self.buffer[x + (y+1) * self.width]); } return None; } pub fn display(&self, include_space: bool) { for y in 0..self.height { for x in 0..self.width { print!("{:04X}", self.buffer[x + y*self.width]); if include_space { print!(" "); } } println!(); } } pub fn idilate(&mut self) { let dilated = self.dilate(); self.buffer = dilated.buffer; } pub fn dilate(&self) -> LabelFormat { let width = self.width; let height = self.height; let mut output_buffer = vec![0u16; width*height]; for y in 0..height { for x in 0..width { let index = x + y * width; let current_color = self.buffer[index]; if current_color != 0 { output_buffer[index] = current_color; continue; } if let Some(color) = self.get_up(x,y) { if color != 0 { output_buffer[index] = color; continue; } } if let Some(color) = self.get_right(x,y) { if color != 0 { output_buffer[index] = color; continue; } } if let Some(color) = self.get_down(x,y) { if color != 0 { output_buffer[index] = color; continue; } } if let Some(color) = self.get_left(x,y) { if color != 0 { output_buffer[index] = color; continue; } } } } LabelFormat { buffer: output_buffer, width, height, } } pub fn ierode(&mut self) { let eroded = self.erode(); self.buffer = eroded.buffer; } pub fn erode(&self) -> LabelFormat { let width = self.width; let height = self.height; let mut output_buffer = vec![0u16; width*height]; for y in 0..height { for x in 0..width { let index = x + y * width; let current_color = self.buffer[index]; if current_color == 0 { continue; } if let Some(color) = self.get_up(x,y) { if color == 0 { continue; } } if let Some(color) = self.get_right(x,y) { if color == 0 { continue; } } if let Some(color) = self.get_down(x,y) { if color == 0 { continue; } } if let Some(color) = self.get_left(x,y) { if color == 0 { continue; } } output_buffer[index] = current_color; } } LabelFormat { buffer: output_buffer, width, height, } } pub fn icloseup(&mut self, n: usize) { for _ in 0..n { self.ierode(); } for _ in 0..n { self.idilate(); } } pub fn closeup(&self, n: usize) -> LabelFormat { let mut x = self.erode(); x.icloseup(n-1); x.idilate(); x } pub fn ifill(&mut self, n: usize) { for _ in 0..n { self.idilate(); } for _ in 0..n { self.ierode(); } } pub fn fill(&self, n: usize) -> LabelFormat { let mut x = self.dilate(); x.icloseup(n-1); x.ierode(); x } } #[cfg(test)] mod tests { use super::*; #[test] fn label_morphology_test() { const DIM: usize = 6; let mut test_data = LabelFormat { buffer: vec![0u16; DIM*DIM], width: DIM, height: DIM, }; test_data.buffer[2+3*DIM] = 1; test_data.buffer[3+3*DIM] = 1; test_data.buffer[4+3*DIM] = 2; test_data.display(true); println!(); let dilated = test_data.dilate(); dilated.display(true); println!(); let restored = dilated.erode(); restored.display(true); } #[test] fn mutable_morphology_test() { const DIM: usize = 6; let mut test_data = LabelFormat { buffer: vec![0u16; DIM*DIM], width: DIM, height: DIM, }; test_data.buffer[2+3*DIM] = 1; test_data.buffer[3+3*DIM] = 1; test_data.buffer[4+3*DIM] = 2; test_data.display(true); println!(); test_data.idilate(); test_data.display(true); println!(); test_data.ierode(); test_data.display(true); println!(); } }