use crate::flat_se::{AnalyzedSe, FlatSe};
use crate::structuring_element::KernelShape;
use std::ops::Add;
pub(crate) unsafe fn scan_se(
structuring_element: &[u8],
structuring_element_size: KernelShape,
) -> AnalyzedSe {
let mut left_front = vec![];
let kernel_width = structuring_element_size.width;
let kernel_height = structuring_element_size.height;
let half_kernel_width = kernel_width as i32 / 2;
let half_kernel_height = kernel_height as i32 / 2;
structuring_element
.chunks_exact(kernel_width)
.enumerate()
.for_each(|(y, row)| {
for (x, &element) in row.iter().enumerate() {
if element != 0 {
left_front.push(ScanPoint::new(
x as i32 - half_kernel_width,
y as i32 - half_kernel_height,
));
}
}
});
let iv_left: Vec<ScanPoint> = left_front.to_vec();
AnalyzedSe::new(structuring_element.to_vec(), FlatSe::new(iv_left))
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct ScanPoint {
pub x: i32,
pub y: i32,
}
impl Add<ScanPoint> for ScanPoint {
type Output = ScanPoint;
fn add(self, rhs: ScanPoint) -> Self::Output {
ScanPoint::new(self.x + rhs.x, self.y + rhs.y)
}
}
impl ScanPoint {
pub fn new(x: i32, y: i32) -> ScanPoint {
ScanPoint { x, y }
}
}
impl Default for ScanPoint {
fn default() -> Self {
ScanPoint::new(0, 0)
}
}