use crate::border_mode::{BorderMode, MorphScalar};
use crate::difference::MorphGradient;
use crate::filter::Row2DFilter;
use crate::morph_base::MorphNativeOp;
use crate::op_impl::make_morphology;
use crate::op_type::{MorphExOp, MorphOp};
use crate::structuring_element::KernelShape;
use crate::{ImageSize, MorphologyThreadingPolicy};
use num_traits::AsPrimitive;
pub fn dilate(
src: &[u8],
dst: &mut [u8],
image_size: ImageSize,
structuring_element: &[u8],
structuring_element_size: KernelShape,
border_mode: BorderMode,
border_scalar: MorphScalar,
threading_policy: MorphologyThreadingPolicy,
) -> Result<(), String> {
make_morphology::<u8, { MorphOp::Dilate as u8 }, 1>(
src,
dst,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}
pub fn dilate_rgb(
src: &[u8],
dst: &mut [u8],
image_size: ImageSize,
structuring_element: &[u8],
structuring_element_size: KernelShape,
border_mode: BorderMode,
border_scalar: MorphScalar,
threading_policy: MorphologyThreadingPolicy,
) -> Result<(), String> {
make_morphology::<u8, { MorphOp::Dilate as u8 }, 3>(
src,
dst,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}
pub fn erode(
src: &[u8],
dst: &mut [u8],
image_size: ImageSize,
structuring_element: &[u8],
structuring_element_size: KernelShape,
border_mode: BorderMode,
border_scalar: MorphScalar,
threading_policy: MorphologyThreadingPolicy,
) -> Result<(), String> {
make_morphology::<u8, { MorphOp::Erode as u8 }, 1>(
src,
dst,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}
pub fn erode_rgb(
src: &[u8],
dst: &mut [u8],
image_size: ImageSize,
structuring_element: &[u8],
structuring_element_size: KernelShape,
border_mode: BorderMode,
border_scalar: MorphScalar,
threading_policy: MorphologyThreadingPolicy,
) -> Result<(), String> {
make_morphology::<u8, { MorphOp::Erode as u8 }, 3>(
src,
dst,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}
pub fn erode_rgba(
src: &[u8],
dst: &mut [u8],
image_size: ImageSize,
structuring_element: &[u8],
structuring_element_size: KernelShape,
border_mode: BorderMode,
border_scalar: MorphScalar,
threading_policy: MorphologyThreadingPolicy,
) -> Result<(), String> {
make_morphology::<u8, { MorphOp::Erode as u8 }, 4>(
src,
dst,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}
pub fn dilate_rgba(
src: &[u8],
dst: &mut [u8],
image_size: ImageSize,
structuring_element: &[u8],
structuring_element_size: KernelShape,
border_mode: BorderMode,
border_scalar: MorphScalar,
threading_policy: MorphologyThreadingPolicy,
) -> Result<(), String> {
make_morphology::<u8, { MorphOp::Dilate as u8 }, 4>(
src,
dst,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}
pub fn erode_gray_alpha(
src: &[u8],
dst: &mut [u8],
image_size: ImageSize,
structuring_element: &[u8],
structuring_element_size: KernelShape,
border_mode: BorderMode,
border_scalar: MorphScalar,
threading_policy: MorphologyThreadingPolicy,
) -> Result<(), String> {
make_morphology::<u8, { MorphOp::Erode as u8 }, 2>(
src,
dst,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}
pub fn dilate_gray_alpha(
src: &[u8],
dst: &mut [u8],
image_size: ImageSize,
structuring_element: &[u8],
structuring_element_size: KernelShape,
border_mode: BorderMode,
border_scalar: MorphScalar,
threading_policy: MorphologyThreadingPolicy,
) -> Result<(), String> {
make_morphology::<u8, { MorphOp::Dilate as u8 }, 2>(
src,
dst,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}
pub fn morphology(
src: &[u8],
dst: &mut [u8],
morph_op: MorphExOp,
image_size: ImageSize,
structuring_element: &[u8],
structuring_element_size: KernelShape,
border_mode: BorderMode,
border_scalar: MorphScalar,
threading_policy: MorphologyThreadingPolicy,
) -> Result<(), String> {
morph_impl::<u8, 1>(
src,
dst,
morph_op,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}
pub fn morphology_rgb(
src: &[u8],
dst: &mut [u8],
morph_op: MorphExOp,
image_size: ImageSize,
structuring_element: &[u8],
structuring_element_size: KernelShape,
border_mode: BorderMode,
border_scalar: MorphScalar,
threading_policy: MorphologyThreadingPolicy,
) -> Result<(), String> {
morph_impl::<u8, 3>(
src,
dst,
morph_op,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}
pub fn morphology_gray_alpha(
src: &[u8],
dst: &mut [u8],
morph_op: MorphExOp,
image_size: ImageSize,
structuring_element: &[u8],
structuring_element_size: KernelShape,
border_mode: BorderMode,
border_scalar: MorphScalar,
threading_policy: MorphologyThreadingPolicy,
) -> Result<(), String> {
morph_impl::<u8, 2>(
src,
dst,
morph_op,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}
pub(crate) fn morph_impl<
T: Copy + MorphGradient<T> + Default + 'static + Send + Sync + MorphNativeOp<T> + Row2DFilter<T>,
const CN: usize,
>(
src: &[T],
dst: &mut [T],
morph_op: MorphExOp,
image_size: ImageSize,
structuring_element: &[u8],
structuring_element_size: KernelShape,
border_mode: BorderMode,
border_scalar: MorphScalar,
threading_policy: MorphologyThreadingPolicy,
) -> Result<(), String>
where
f64: AsPrimitive<T>,
{
match morph_op {
MorphExOp::Dilate => make_morphology::<T, { MorphOp::Dilate as u8 }, CN>(
src,
dst,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
),
MorphExOp::Erode => make_morphology::<T, { MorphOp::Erode as u8 }, CN>(
src,
dst,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
),
MorphExOp::Opening => {
let mut transient = vec![T::default(); dst.len()];
make_morphology::<T, { MorphOp::Erode as u8 }, CN>(
src,
&mut transient,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)?;
make_morphology::<T, { MorphOp::Dilate as u8 }, CN>(
&transient,
dst,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}
MorphExOp::Closing => {
let mut transient = vec![T::default(); dst.len()];
make_morphology::<T, { MorphOp::Dilate as u8 }, CN>(
src,
&mut transient,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)?;
make_morphology::<T, { MorphOp::Erode as u8 }, CN>(
&transient,
dst,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}
MorphExOp::Gradient => {
let mut dilation = vec![T::default(); dst.len()];
make_morphology::<T, { MorphOp::Dilate as u8 }, CN>(
src,
&mut dilation,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)?;
let mut erosion = vec![T::default(); dst.len()];
make_morphology::<T, { MorphOp::Erode as u8 }, CN>(
src,
&mut erosion,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)?;
T::morph_gradient(&dilation, &erosion, dst);
Ok(())
}
MorphExOp::TopHat => {
let mut opened = vec![T::default(); dst.len()];
morph_impl::<T, CN>(
src,
&mut opened,
MorphExOp::Opening,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)?;
T::morph_gradient(src, &opened, dst);
Ok(())
}
MorphExOp::BlackHat => {
let mut closed = vec![T::default(); dst.len()];
morph_impl::<T, CN>(
src,
&mut closed,
MorphExOp::Closing,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)?;
T::morph_gradient(&closed, src, dst);
Ok(())
}
}
}
pub fn morphology_rgba(
src: &[u8],
dst: &mut [u8],
morph_op: MorphExOp,
image_size: ImageSize,
structuring_element: &[u8],
structuring_element_size: KernelShape,
border_mode: BorderMode,
border_scalar: MorphScalar,
threading_policy: MorphologyThreadingPolicy,
) -> Result<(), String> {
morph_impl::<u8, 4>(
src,
dst,
morph_op,
image_size,
structuring_element,
structuring_element_size,
border_mode,
border_scalar,
threading_policy,
)
}