Skip to main content

singe_npp/image/
morphology_border.rs

1use super::*;
2
3macro_rules! impl_morphology_mask_border {
4    ($name:ident, $ty:ty, $layout:ty, $ffi:ident) => {
5        pub fn $name(
6            stream_context: &StreamContext,
7            source: &ImageView<'_, $ty, $layout>,
8            source_offset: Point,
9            destination: &mut ImageViewMut<'_, $ty, $layout>,
10            mask: &[u8],
11            mask_size: Size,
12            anchor: Point,
13            border_type: BorderType,
14        ) -> Result<()> {
15            validate_border_roi(source.size(), source_offset, destination.size())?;
16            validate_mask(mask, mask_size, anchor)?;
17
18            unsafe {
19                try_ffi!(sys::$ffi(
20                    source.as_ptr().cast(),
21                    source.step(),
22                    source.size().into(),
23                    source_offset.into(),
24                    destination.as_mut_ptr().cast(),
25                    destination.step(),
26                    destination.size().into(),
27                    mask.as_ptr().cast(),
28                    mask_size.into(),
29                    anchor.into(),
30                    border_type.into(),
31                    stream_context.as_raw(),
32                ))?;
33            }
34            Ok(())
35        }
36    };
37}
38
39macro_rules! impl_generic_morphology_mask_border {
40    ($trait:ident, $method:ident, $function:ident, $layout:ty, [$($ty:ty => $direct:ident),* $(,)?]) => {
41        pub trait $trait<Layout>: DataTypeLike + Sized {
42            fn $method(
43                stream_context: &StreamContext,
44                source: &ImageView<'_, Self, Layout>,
45                source_offset: Point,
46                destination: &mut ImageViewMut<'_, Self, Layout>,
47                mask: &[u8],
48                mask_size: Size,
49                anchor: Point,
50                border_type: BorderType,
51            ) -> Result<()>;
52        }
53
54        pub fn $function<T>(
55            stream_context: &StreamContext,
56            source: &ImageView<'_, T, $layout>,
57            source_offset: Point,
58            destination: &mut ImageViewMut<'_, T, $layout>,
59            mask: &[u8],
60            mask_size: Size,
61            anchor: Point,
62            border_type: BorderType,
63        ) -> Result<()>
64        where
65            T: $trait<$layout>,
66        {
67            T::$method(
68                stream_context,
69                source,
70                source_offset,
71                destination,
72                mask,
73                mask_size,
74                anchor,
75                border_type,
76            )
77        }
78
79        $(
80            impl $trait<$layout> for $ty {
81                fn $method(
82                    stream_context: &StreamContext,
83                    source: &ImageView<'_, Self, $layout>,
84                    source_offset: Point,
85                    destination: &mut ImageViewMut<'_, Self, $layout>,
86                    mask: &[u8],
87                    mask_size: Size,
88                    anchor: Point,
89                    border_type: BorderType,
90                ) -> Result<()> {
91                    $direct(
92                        stream_context,
93                        source,
94                        source_offset,
95                        destination,
96                        mask,
97                        mask_size,
98                        anchor,
99                        border_type,
100                    )
101                }
102            }
103        )*
104    };
105}
106
107impl_morphology_mask_border!(dilate_border_u8_c1, u8, C1, nppiDilateBorder_8u_C1R_Ctx);
108impl_morphology_mask_border!(dilate_border_u8_c3, u8, C3, nppiDilateBorder_8u_C3R_Ctx);
109impl_morphology_mask_border!(dilate_border_u8_c4, u8, C4, nppiDilateBorder_8u_C4R_Ctx);
110impl_morphology_mask_border!(dilate_border_u8_ac4, u8, AC4, nppiDilateBorder_8u_AC4R_Ctx);
111impl_morphology_mask_border!(dilate_border_u16_c1, u16, C1, nppiDilateBorder_16u_C1R_Ctx);
112impl_morphology_mask_border!(dilate_border_u16_c3, u16, C3, nppiDilateBorder_16u_C3R_Ctx);
113impl_morphology_mask_border!(dilate_border_u16_c4, u16, C4, nppiDilateBorder_16u_C4R_Ctx);
114impl_morphology_mask_border!(
115    dilate_border_u16_ac4,
116    u16,
117    AC4,
118    nppiDilateBorder_16u_AC4R_Ctx
119);
120impl_morphology_mask_border!(dilate_border_f32_c1, f32, C1, nppiDilateBorder_32f_C1R_Ctx);
121impl_morphology_mask_border!(dilate_border_f32_c3, f32, C3, nppiDilateBorder_32f_C3R_Ctx);
122impl_morphology_mask_border!(dilate_border_f32_c4, f32, C4, nppiDilateBorder_32f_C4R_Ctx);
123impl_morphology_mask_border!(
124    dilate_border_f32_ac4,
125    f32,
126    AC4,
127    nppiDilateBorder_32f_AC4R_Ctx
128);
129
130impl_morphology_mask_border!(erode_border_u8_c1, u8, C1, nppiErodeBorder_8u_C1R_Ctx);
131impl_morphology_mask_border!(erode_border_u8_c3, u8, C3, nppiErodeBorder_8u_C3R_Ctx);
132impl_morphology_mask_border!(erode_border_u8_c4, u8, C4, nppiErodeBorder_8u_C4R_Ctx);
133impl_morphology_mask_border!(erode_border_u8_ac4, u8, AC4, nppiErodeBorder_8u_AC4R_Ctx);
134impl_morphology_mask_border!(erode_border_u16_c1, u16, C1, nppiErodeBorder_16u_C1R_Ctx);
135impl_morphology_mask_border!(erode_border_u16_c3, u16, C3, nppiErodeBorder_16u_C3R_Ctx);
136impl_morphology_mask_border!(erode_border_u16_c4, u16, C4, nppiErodeBorder_16u_C4R_Ctx);
137impl_morphology_mask_border!(erode_border_u16_ac4, u16, AC4, nppiErodeBorder_16u_AC4R_Ctx);
138impl_morphology_mask_border!(erode_border_f32_c1, f32, C1, nppiErodeBorder_32f_C1R_Ctx);
139impl_morphology_mask_border!(erode_border_f32_c3, f32, C3, nppiErodeBorder_32f_C3R_Ctx);
140impl_morphology_mask_border!(erode_border_f32_c4, f32, C4, nppiErodeBorder_32f_C4R_Ctx);
141impl_morphology_mask_border!(erode_border_f32_ac4, f32, AC4, nppiErodeBorder_32f_AC4R_Ctx);
142
143impl_generic_morphology_mask_border!(DilateBorderC1, dilate_border, dilate_border_c1, C1, [
144    u8 => dilate_border_u8_c1,
145    u16 => dilate_border_u16_c1,
146    f32 => dilate_border_f32_c1,
147]);
148impl_generic_morphology_mask_border!(DilateBorderC3, dilate_border, dilate_border_c3, C3, [
149    u8 => dilate_border_u8_c3,
150    u16 => dilate_border_u16_c3,
151    f32 => dilate_border_f32_c3,
152]);
153impl_generic_morphology_mask_border!(DilateBorderC4, dilate_border, dilate_border_c4, C4, [
154    u8 => dilate_border_u8_c4,
155    u16 => dilate_border_u16_c4,
156    f32 => dilate_border_f32_c4,
157]);
158impl_generic_morphology_mask_border!(DilateBorderAc4, dilate_border, dilate_border_ac4, AC4, [
159    u8 => dilate_border_u8_ac4,
160    u16 => dilate_border_u16_ac4,
161    f32 => dilate_border_f32_ac4,
162]);
163impl_generic_morphology_mask_border!(ErodeBorderC1, erode_border, erode_border_c1, C1, [
164    u8 => erode_border_u8_c1,
165    u16 => erode_border_u16_c1,
166    f32 => erode_border_f32_c1,
167]);
168impl_generic_morphology_mask_border!(ErodeBorderC3, erode_border, erode_border_c3, C3, [
169    u8 => erode_border_u8_c3,
170    u16 => erode_border_u16_c3,
171    f32 => erode_border_f32_c3,
172]);
173impl_generic_morphology_mask_border!(ErodeBorderC4, erode_border, erode_border_c4, C4, [
174    u8 => erode_border_u8_c4,
175    u16 => erode_border_u16_c4,
176    f32 => erode_border_f32_c4,
177]);
178impl_generic_morphology_mask_border!(ErodeBorderAc4, erode_border, erode_border_ac4, AC4, [
179    u8 => erode_border_u8_ac4,
180    u16 => erode_border_u16_ac4,
181    f32 => erode_border_f32_ac4,
182]);
183
184macro_rules! impl_gray_morphology_mask_border {
185    ($name:ident, $ty:ty, $mask_ty:ty, $ffi:ident) => {
186        pub fn $name(
187            stream_context: &StreamContext,
188            source: &ImageView<'_, $ty, C1>,
189            source_offset: Point,
190            destination: &mut ImageViewMut<'_, $ty, C1>,
191            mask: &[$mask_ty],
192            mask_size: Size,
193            anchor: Point,
194            border_type: BorderType,
195        ) -> Result<()> {
196            validate_border_roi(source.size(), source_offset, destination.size())?;
197            validate_mask_shape(mask, mask_size, anchor)?;
198
199            unsafe {
200                try_ffi!(sys::$ffi(
201                    source.as_ptr().cast(),
202                    source.step(),
203                    source.size().into(),
204                    source_offset.into(),
205                    destination.as_mut_ptr().cast(),
206                    destination.step(),
207                    destination.size().into(),
208                    mask.as_ptr().cast(),
209                    mask_size.into(),
210                    anchor.into(),
211                    border_type.into(),
212                    stream_context.as_raw(),
213                ))?;
214            }
215            Ok(())
216        }
217    };
218}
219
220macro_rules! impl_generic_gray_morphology_mask_border {
221    ($trait:ident, $method:ident, $function:ident, [$($ty:ty, $mask_ty:ty => $direct:ident),* $(,)?]) => {
222        pub trait $trait: DataTypeLike + Sized {
223            type Mask: Copy;
224
225            fn $method(
226                stream_context: &StreamContext,
227                source: &ImageView<'_, Self, C1>,
228                source_offset: Point,
229                destination: &mut ImageViewMut<'_, Self, C1>,
230                mask: &[Self::Mask],
231                mask_size: Size,
232                anchor: Point,
233                border_type: BorderType,
234            ) -> Result<()>;
235        }
236
237        pub fn $function<T>(
238            stream_context: &StreamContext,
239            source: &ImageView<'_, T, C1>,
240            source_offset: Point,
241            destination: &mut ImageViewMut<'_, T, C1>,
242            mask: &[T::Mask],
243            mask_size: Size,
244            anchor: Point,
245            border_type: BorderType,
246        ) -> Result<()>
247        where
248            T: $trait,
249        {
250            T::$method(
251                stream_context,
252                source,
253                source_offset,
254                destination,
255                mask,
256                mask_size,
257                anchor,
258                border_type,
259            )
260        }
261
262        $(
263            impl $trait for $ty {
264                type Mask = $mask_ty;
265
266                fn $method(
267                    stream_context: &StreamContext,
268                    source: &ImageView<'_, Self, C1>,
269                    source_offset: Point,
270                    destination: &mut ImageViewMut<'_, Self, C1>,
271                    mask: &[Self::Mask],
272                    mask_size: Size,
273                    anchor: Point,
274                    border_type: BorderType,
275                ) -> Result<()> {
276                    $direct(
277                        stream_context,
278                        source,
279                        source_offset,
280                        destination,
281                        mask,
282                        mask_size,
283                        anchor,
284                        border_type,
285                    )
286                }
287            }
288        )*
289    };
290}
291
292impl_gray_morphology_mask_border!(
293    gray_dilate_border_u8_c1,
294    u8,
295    i32,
296    nppiGrayDilateBorder_8u_C1R_Ctx
297);
298impl_gray_morphology_mask_border!(
299    gray_dilate_border_f32_c1,
300    f32,
301    f32,
302    nppiGrayDilateBorder_32f_C1R_Ctx
303);
304impl_gray_morphology_mask_border!(
305    gray_erode_border_u8_c1,
306    u8,
307    i32,
308    nppiGrayErodeBorder_8u_C1R_Ctx
309);
310impl_gray_morphology_mask_border!(
311    gray_erode_border_f32_c1,
312    f32,
313    f32,
314    nppiGrayErodeBorder_32f_C1R_Ctx
315);
316
317impl_generic_gray_morphology_mask_border!(GrayDilateBorderC1, gray_dilate_border, gray_dilate_border_c1, [
318    u8, i32 => gray_dilate_border_u8_c1,
319    f32, f32 => gray_dilate_border_f32_c1,
320]);
321impl_generic_gray_morphology_mask_border!(GrayErodeBorderC1, gray_erode_border, gray_erode_border_c1, [
322    u8, i32 => gray_erode_border_u8_c1,
323    f32, f32 => gray_erode_border_f32_c1,
324]);