aboutsummaryrefslogtreecommitdiff
path: root/src/label_format.rs
diff options
context:
space:
mode:
authorcc <cc@localhost>2025-08-28 02:02:37 -0700
committercc <cc@localhost>2025-08-28 02:02:58 -0700
commitb2bb714ad8287a33a1ee399999e340471b0bb4b4 (patch)
tree9a7567ef8e8cbd9dab0dc91f4c33e2ef2100ed3c /src/label_format.rs
parent6b82dd150073836e57a148d7eccae5276b9baea7 (diff)
Unifying label formats
Diffstat (limited to 'src/label_format.rs')
-rw-r--r--src/label_format.rs139
1 files changed, 99 insertions, 40 deletions
diff --git a/src/label_format.rs b/src/label_format.rs
index 38c5d19..c127e81 100644
--- a/src/label_format.rs
+++ b/src/label_format.rs
@@ -1,12 +1,65 @@
-use crate::flood_u16;
+use core::cmp::PartialEq;
+use core::marker::Copy;
+use crate::flood;
+use crate::color;
-pub struct LabelFormat {
- pub buffer: Vec<u16>,
+pub trait LabelU16 {
+ fn zero(&self) -> Self;
+}
+
+impl LabelU16 for u16 {
+ fn zero(&self) -> Self {
+ 0u16
+ }
+}
+
+impl LabelU16 for u32 {
+ fn zero(&self) -> Self {
+ 0u32
+ }
+}
+
+pub struct LabelFormat<T: LabelU16 + PartialEq> {
+ pub buffer: Vec<T>,
pub width: usize,
pub height: usize,
}
-impl LabelFormat {
+impl<T: LabelU16 + PartialEq> std::fmt::Debug for LabelFormat<T> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_struct("LabelFormat")
+ .field("width", &self.width)
+ .field("height", &self.height)
+ .finish()
+ }
+}
+
+impl<T: LabelU16 + PartialEq + Copy> LabelFormat<T> {
+ pub fn compress(&self) -> LabelFormat<u16> {
+ let mut label: u16 = 1;
+ let mut output_buffer: Vec<u16> = 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] == self.buffer[index].zero() {
+ continue;
+ }
+ if output_buffer[index] == 0 {
+ let color = self.buffer[index];
+ flood(&self, &mut output_buffer, x, y, color, label);
+ label += 1;
+ }
+ }
+ }
+ LabelFormat::<u16> {
+ buffer: output_buffer,
+ width: self.width,
+ height: self.height,
+ }
+ }
+}
+
+impl LabelFormat<u16> {
pub fn get_left(&self, x: usize, y: usize) -> Option<u16> {
if x > 0 {
return Some(self.buffer[(x-1) + y * self.width]);
@@ -52,7 +105,7 @@ impl LabelFormat {
self.buffer = dilated.buffer;
}
- pub fn dilate(&self) -> LabelFormat {
+ pub fn dilate(&self) -> LabelFormat<u16> {
let width = self.width;
let height = self.height;
let mut output_buffer = vec![0u16; width*height];
@@ -90,7 +143,7 @@ impl LabelFormat {
}
}
}
- LabelFormat {
+ LabelFormat::<u16> {
buffer: output_buffer,
width,
height,
@@ -102,7 +155,7 @@ impl LabelFormat {
self.buffer = eroded.buffer;
}
- pub fn erode(&self) -> LabelFormat {
+ pub fn erode(&self) -> LabelFormat<u16> {
let width = self.width;
let height = self.height;
let mut output_buffer = vec![0u16; width*height];
@@ -136,7 +189,7 @@ impl LabelFormat {
output_buffer[index] = current_color;
}
}
- LabelFormat {
+ LabelFormat::<u16> {
buffer: output_buffer,
width,
height,
@@ -152,7 +205,7 @@ impl LabelFormat {
}
}
- pub fn closeup(&self, n: usize) -> LabelFormat {
+ pub fn closeup(&self, n: usize) -> LabelFormat<u16> {
let mut x = self.erode();
x.icloseup(n-1);
x.idilate();
@@ -168,7 +221,7 @@ impl LabelFormat {
}
}
- pub fn fill(&self, n: usize) -> LabelFormat {
+ pub fn fill(&self, n: usize) -> LabelFormat<u16> {
let mut x = self.dilate();
x.icloseup(n-1);
x.ierode();
@@ -179,7 +232,7 @@ impl LabelFormat {
crate::binfile::dump_u16_vec(filename, self.buffer.clone())
}
- pub fn combine(&self, other: &LabelFormat) -> Option<LabelFormat> {
+ pub fn combine(&self, other: &LabelFormat<u16>) -> Option<LabelFormat<u16>> {
let width = self.width;
let height = self.height;
let rwidth = other.width;
@@ -187,7 +240,7 @@ impl LabelFormat {
if (width != rwidth) || (height != rheight) {
return None;
}
- let mut output = LabelFormat {
+ let mut output = LabelFormat::<u16> {
buffer: vec![0u16; width * height],
width,
height,
@@ -204,7 +257,7 @@ impl LabelFormat {
return Some(output);
}
- pub fn refresh(&self) -> LabelFormat {
+ pub fn refresh(&self) -> LabelFormat<u16> {
let mut label: u16 = 1;
let mut output_buffer: Vec<u16> = vec![0u16; self.buffer.len()];
for y in 0..self.height {
@@ -215,12 +268,12 @@ impl LabelFormat {
}
if output_buffer[index] == 0 {
let color = self.buffer[index];
- flood_u16(self, &mut output_buffer, x, y, color, label);
+ flood(self, &mut output_buffer, x, y, color, label);
label += 1;
}
}
}
- return LabelFormat {
+ return LabelFormat::<u16> {
buffer: output_buffer,
width: self.width,
height: self.height,
@@ -241,35 +294,41 @@ impl LabelFormat {
}
-mod color {
- pub(crate) fn reset_color() {
- print!("\x1b[0m");
- }
-
- // Set background color from a number
- pub(crate) fn set_color(color: usize) {
- if color == 0 {
- reset_color();
- return;
- }
- let paint_color = color-1;
- let paint_color = paint_color % 13;
- if paint_color < 7 {
- print!("\x1b[{}m", 40 + (paint_color+1));
- } else {
- print!("\x1b[{}m", 100 + (paint_color+1-7));
- }
- }
-}
-
#[cfg(test)]
mod tests {
use super::*;
#[test]
+ fn label_compress_test() {
+ const DIM: usize = 6;
+ let mut test_data = LabelFormat::<u32> {
+ buffer: vec![0u32; DIM*DIM],
+ width: DIM,
+ height: DIM,
+ };
+
+ let expected: [Vec<u16>;1] = [
+ [
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 2, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ ].to_vec(),
+ ];
+
+ test_data.buffer[2+3*DIM] = 2;
+ test_data.buffer[3+3*DIM] = 2;
+ test_data.buffer[4+3*DIM] = 1;
+ let compressed_data = test_data.compress();
+ assert_eq!(compressed_data.buffer, expected[0]);
+ }
+
+ #[test]
fn label_morphology_test() {
const DIM: usize = 6;
- let mut test_data = LabelFormat {
+ let mut test_data = LabelFormat::<u16> {
buffer: vec![0u16; DIM*DIM],
width: DIM,
height: DIM,
@@ -317,7 +376,7 @@ mod tests {
#[test]
fn mutable_morphology_test() {
const DIM: usize = 6;
- let mut test_data = LabelFormat {
+ let mut test_data = LabelFormat::<u16> {
buffer: vec![0u16; DIM*DIM],
width: DIM,
height: DIM,
@@ -365,7 +424,7 @@ mod tests {
#[test]
fn combination_test() {
const DIM: usize = 6;
- let mut test_data_1 = LabelFormat {
+ let mut test_data_1 = LabelFormat::<u16> {
buffer: vec![0u16; DIM*DIM],
width: DIM,
height: DIM,
@@ -410,7 +469,7 @@ mod tests {
test_data_1.buffer[3+3*DIM] = 1;
test_data_1.buffer[4+3*DIM] = 2;
- let mut test_data_2 = LabelFormat {
+ let mut test_data_2 = LabelFormat::<u16> {
buffer: vec![0u16; DIM*DIM],
width: DIM,
height: DIM,