From 68103ad891520db55d8f84a8f938a37aca4f29d4 Mon Sep 17 00:00:00 2001 From: cc Date: Wed, 20 Aug 2025 22:43:06 -0700 Subject: Label Combination Routine Label Refresh Routine --- src/label_format.rs | 90 +++++++++++++++++++++++++++++++++++++++++++++++ src/large_label_format.rs | 4 +-- src/lib.rs | 37 ++++++++++++++++--- 3 files changed, 124 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/label_format.rs b/src/label_format.rs index afbb2ad..1762445 100644 --- a/src/label_format.rs +++ b/src/label_format.rs @@ -1,3 +1,5 @@ +use crate::flood_u16; + pub struct LabelFormat { pub buffer: Vec, pub width: usize, @@ -176,6 +178,54 @@ impl LabelFormat { pub fn dump(&self, filename: &str) -> Result<(), std::io::Error> { crate::binfile::dump_u16_vec(filename, self.buffer.clone()) } + + pub fn combine(&self, other: &LabelFormat) -> Option { + let width = self.width; + let height = self.height; + let rwidth = other.width; + let rheight = other.height; + if (width != rwidth) || (height != rheight) { + return None; + } + let mut output = LabelFormat { + buffer: vec![0u16; width * height], + width, + height, + }; + for y in 0..height { + for x in 0..width { + let index = x + y * width; + output.buffer[index] = self.buffer[index]; + if output.buffer[index] == 0 { + output.buffer[index] = other.buffer[index]; + } + } + } + return Some(output); + } + + pub fn refresh(&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_u16(self, &mut output_buffer, x, y, color, label); + label += 1; + } + } + } + return LabelFormat { + buffer: output_buffer, + width: self.width, + height: self.height, + }; + } } #[cfg(test)] @@ -224,4 +274,44 @@ mod tests { test_data.display(true); println!(); } + + #[test] + fn combination_test() { + const DIM: usize = 6; + let mut test_data_1 = LabelFormat { + buffer: vec![0u16; DIM*DIM], + width: DIM, + height: DIM, + }; + + test_data_1.buffer[2+3*DIM] = 1; + test_data_1.buffer[3+3*DIM] = 1; + test_data_1.buffer[4+3*DIM] = 2; + test_data_1.display(true); + println!(); + + let mut test_data_2 = LabelFormat { + buffer: vec![0u16; DIM*DIM], + width: DIM, + height: DIM, + }; + + test_data_2.buffer[2+1*DIM] = 2; + test_data_2.buffer[3+1*DIM] = 2; + test_data_2.buffer[3+2*DIM] = 2; + test_data_2.buffer[4+1*DIM] = 3; + test_data_2.display(true); + println!(); + + if let Some(out_data) = test_data_1.combine(&test_data_2) { + out_data.display(true); + println!(); + + let refreshed = out_data.refresh(); + refreshed.display(true); + println!(); + } else { + assert!(false); + } + } } diff --git a/src/large_label_format.rs b/src/large_label_format.rs index 5aef6b3..0a5c458 100644 --- a/src/large_label_format.rs +++ b/src/large_label_format.rs @@ -1,4 +1,4 @@ -use crate::{LabelFormat,flood}; +use crate::{LabelFormat,flood_u32}; pub struct LargeLabelFormat { pub buffer: Vec, @@ -27,7 +27,7 @@ impl LargeLabelFormat { } if output_buffer[index] == 0 { let color = self.buffer[index]; - flood(&self, &mut output_buffer, x, y, color, label); + flood_u32(&self, &mut output_buffer, x, y, color, label); label += 1; } } diff --git a/src/lib.rs b/src/lib.rs index e47bca8..46c7cd6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,7 @@ pub mod binfile; pub use large_label_format::LargeLabelFormat; pub use label_format::LabelFormat; -pub(crate) fn flood(source: &LargeLabelFormat, destination: &mut Vec, +pub(crate) fn flood_u32(source: &LargeLabelFormat, destination: &mut Vec, x: usize, y: usize, from_color: u32, to_color: u16) { let width = source.width; @@ -19,15 +19,42 @@ pub(crate) fn flood(source: &LargeLabelFormat, destination: &mut Vec, } destination[x + y * width] = to_color; if x > 0 { - flood(source, destination, x-1, y, from_color, to_color); + flood_u32(source, destination, x-1, y, from_color, to_color); } if (x+1) < width { - flood(source, destination, x+1, y, from_color, to_color); + flood_u32(source, destination, x+1, y, from_color, to_color); } if y > 0 { - flood(source, destination, x, y-1, from_color, to_color); + flood_u32(source, destination, x, y-1, from_color, to_color); } if (y+1) < source.height { - flood(source, destination, x, y+1, from_color, to_color); + flood_u32(source, destination, x, y+1, from_color, to_color); + } +} + +pub(crate) fn flood_u16(source: &LabelFormat, destination: &mut Vec, + x: usize, y: usize, + from_color: u16, 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_u16(source, destination, x-1, y, from_color, to_color); + } + if (x+1) < width { + flood_u16(source, destination, x+1, y, from_color, to_color); + } + if y > 0 { + flood_u16(source, destination, x, y-1, from_color, to_color); + } + if (y+1) < source.height { + flood_u16(source, destination, x, y+1, from_color, to_color); } } -- cgit v1.2.1