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]);