1use singe_npp_sys as sys;
2
3use crate::{
4 context::StreamContext,
5 error::{Error, Result},
6 image::view::{AC4, C1, C3, C4, ImageView, MaskViewMut},
7 try_ffi,
8 types::{ComparisonOperation, DataTypeLike, Size},
9};
10
11macro_rules! impl_generic_compare {
12 ($trait:ident, $method:ident, $function:ident, $layout:ty, [$($ty:ty => $direct:ident),* $(,)?]) => {
13 pub trait $trait<Layout>: DataTypeLike + Sized {
14 fn $method(
15 stream_context: &StreamContext,
16 source1: &ImageView<'_, Self, Layout>,
17 source2: &ImageView<'_, Self, Layout>,
18 destination: &mut MaskViewMut<'_>,
19 operation: ComparisonOperation,
20 ) -> Result<()>;
21 }
22
23 pub fn $function<T>(
24 stream_context: &StreamContext,
25 source1: &ImageView<'_, T, $layout>,
26 source2: &ImageView<'_, T, $layout>,
27 destination: &mut MaskViewMut<'_>,
28 operation: ComparisonOperation,
29 ) -> Result<()>
30 where
31 T: $trait<$layout>,
32 {
33 T::$method(stream_context, source1, source2, destination, operation)
34 }
35
36 $(
37 impl $trait<$layout> for $ty {
38 fn $method(
39 stream_context: &StreamContext,
40 source1: &ImageView<'_, Self, $layout>,
41 source2: &ImageView<'_, Self, $layout>,
42 destination: &mut MaskViewMut<'_>,
43 operation: ComparisonOperation,
44 ) -> Result<()> {
45 $direct(stream_context, source1, source2, destination, operation)
46 }
47 }
48 )*
49 };
50}
51
52macro_rules! impl_generic_compare_constant_scalar {
53 ($trait:ident, $method:ident, $function:ident, $layout:ty, [$($ty:ty => $direct:ident),* $(,)?]) => {
54 pub trait $trait<Layout>: DataTypeLike + Sized {
55 fn $method(
56 stream_context: &StreamContext,
57 source: &ImageView<'_, Self, Layout>,
58 constant: Self,
59 destination: &mut MaskViewMut<'_>,
60 operation: ComparisonOperation,
61 ) -> Result<()>;
62 }
63
64 pub fn $function<T>(
65 stream_context: &StreamContext,
66 source: &ImageView<'_, T, $layout>,
67 constant: T,
68 destination: &mut MaskViewMut<'_>,
69 operation: ComparisonOperation,
70 ) -> Result<()>
71 where
72 T: $trait<$layout>,
73 {
74 T::$method(stream_context, source, constant, destination, operation)
75 }
76
77 $(
78 impl $trait<$layout> for $ty {
79 fn $method(
80 stream_context: &StreamContext,
81 source: &ImageView<'_, Self, $layout>,
82 constant: Self,
83 destination: &mut MaskViewMut<'_>,
84 operation: ComparisonOperation,
85 ) -> Result<()> {
86 $direct(stream_context, source, constant, destination, operation)
87 }
88 }
89 )*
90 };
91}
92
93macro_rules! impl_generic_compare_constant_array {
94 ($trait:ident, $method:ident, $function:ident, $layout:ty, $channels:literal, [$($ty:ty => $direct:ident),* $(,)?]) => {
95 pub trait $trait<Layout>: DataTypeLike + Sized {
96 fn $method(
97 stream_context: &StreamContext,
98 source: &ImageView<'_, Self, Layout>,
99 constants: [Self; $channels],
100 destination: &mut MaskViewMut<'_>,
101 operation: ComparisonOperation,
102 ) -> Result<()>;
103 }
104
105 pub fn $function<T>(
106 stream_context: &StreamContext,
107 source: &ImageView<'_, T, $layout>,
108 constants: [T; $channels],
109 destination: &mut MaskViewMut<'_>,
110 operation: ComparisonOperation,
111 ) -> Result<()>
112 where
113 T: $trait<$layout>,
114 {
115 T::$method(stream_context, source, constants, destination, operation)
116 }
117
118 $(
119 impl $trait<$layout> for $ty {
120 fn $method(
121 stream_context: &StreamContext,
122 source: &ImageView<'_, Self, $layout>,
123 constants: [Self; $channels],
124 destination: &mut MaskViewMut<'_>,
125 operation: ComparisonOperation,
126 ) -> Result<()> {
127 $direct(stream_context, source, constants, destination, operation)
128 }
129 }
130 )*
131 };
132}
133
134macro_rules! impl_generic_compare_equal_epsilon {
135 ($trait:ident, $method:ident, $function:ident, $layout:ty, [$($ty:ty => $direct:ident),* $(,)?]) => {
136 pub trait $trait<Layout>: DataTypeLike + Sized {
137 fn $method(
138 stream_context: &StreamContext,
139 source1: &ImageView<'_, Self, Layout>,
140 source2: &ImageView<'_, Self, Layout>,
141 destination: &mut MaskViewMut<'_>,
142 epsilon: Self,
143 ) -> Result<()>;
144 }
145
146 pub fn $function<T>(
147 stream_context: &StreamContext,
148 source1: &ImageView<'_, T, $layout>,
149 source2: &ImageView<'_, T, $layout>,
150 destination: &mut MaskViewMut<'_>,
151 epsilon: T,
152 ) -> Result<()>
153 where
154 T: $trait<$layout>,
155 {
156 T::$method(stream_context, source1, source2, destination, epsilon)
157 }
158
159 $(
160 impl $trait<$layout> for $ty {
161 fn $method(
162 stream_context: &StreamContext,
163 source1: &ImageView<'_, Self, $layout>,
164 source2: &ImageView<'_, Self, $layout>,
165 destination: &mut MaskViewMut<'_>,
166 epsilon: Self,
167 ) -> Result<()> {
168 $direct(stream_context, source1, source2, destination, epsilon)
169 }
170 }
171 )*
172 };
173}
174
175macro_rules! impl_generic_compare_equal_epsilon_constant_scalar {
176 ($trait:ident, $method:ident, $function:ident, $layout:ty, [$($ty:ty => $direct:ident),* $(,)?]) => {
177 pub trait $trait<Layout>: DataTypeLike + Sized {
178 fn $method(
179 stream_context: &StreamContext,
180 source: &ImageView<'_, Self, Layout>,
181 constant: Self,
182 destination: &mut MaskViewMut<'_>,
183 epsilon: Self,
184 ) -> Result<()>;
185 }
186
187 pub fn $function<T>(
188 stream_context: &StreamContext,
189 source: &ImageView<'_, T, $layout>,
190 constant: T,
191 destination: &mut MaskViewMut<'_>,
192 epsilon: T,
193 ) -> Result<()>
194 where
195 T: $trait<$layout>,
196 {
197 T::$method(stream_context, source, constant, destination, epsilon)
198 }
199
200 $(
201 impl $trait<$layout> for $ty {
202 fn $method(
203 stream_context: &StreamContext,
204 source: &ImageView<'_, Self, $layout>,
205 constant: Self,
206 destination: &mut MaskViewMut<'_>,
207 epsilon: Self,
208 ) -> Result<()> {
209 $direct(stream_context, source, constant, destination, epsilon)
210 }
211 }
212 )*
213 };
214}
215
216macro_rules! impl_generic_compare_equal_epsilon_constant_array {
217 ($trait:ident, $method:ident, $function:ident, $layout:ty, $channels:literal, [$($ty:ty => $direct:ident),* $(,)?]) => {
218 pub trait $trait<Layout>: DataTypeLike + Sized {
219 fn $method(
220 stream_context: &StreamContext,
221 source: &ImageView<'_, Self, Layout>,
222 constants: [Self; $channels],
223 destination: &mut MaskViewMut<'_>,
224 epsilon: Self,
225 ) -> Result<()>;
226 }
227
228 pub fn $function<T>(
229 stream_context: &StreamContext,
230 source: &ImageView<'_, T, $layout>,
231 constants: [T; $channels],
232 destination: &mut MaskViewMut<'_>,
233 epsilon: T,
234 ) -> Result<()>
235 where
236 T: $trait<$layout>,
237 {
238 T::$method(stream_context, source, constants, destination, epsilon)
239 }
240
241 $(
242 impl $trait<$layout> for $ty {
243 fn $method(
244 stream_context: &StreamContext,
245 source: &ImageView<'_, Self, $layout>,
246 constants: [Self; $channels],
247 destination: &mut MaskViewMut<'_>,
248 epsilon: Self,
249 ) -> Result<()> {
250 $direct(stream_context, source, constants, destination, epsilon)
251 }
252 }
253 )*
254 };
255}
256
257macro_rules! impl_compare_c1 {
258 ($name:ident, $ty:ty, $ffi:ident) => {
259 pub fn $name(
260 stream_context: &StreamContext,
261 source1: &ImageView<'_, $ty, C1>,
262 source2: &ImageView<'_, $ty, C1>,
263 destination: &mut MaskViewMut<'_>,
264 operation: ComparisonOperation,
265 ) -> Result<()> {
266 validate_same_size(source1.size(), source2.size())?;
267 validate_same_size(source1.size(), destination.size())?;
268
269 unsafe {
270 try_ffi!(sys::$ffi(
271 source1.as_ptr().cast(),
272 source1.step(),
273 source2.as_ptr().cast(),
274 source2.step(),
275 destination.as_mut_ptr().cast(),
276 destination.step(),
277 source1.size().into(),
278 operation.into(),
279 stream_context.as_raw(),
280 ))?;
281 }
282 Ok(())
283 }
284 };
285}
286
287impl_compare_c1!(compare_u8_c1, u8, nppiCompare_8u_C1R_Ctx);
288impl_compare_c1!(compare_u16_c1, u16, nppiCompare_16u_C1R_Ctx);
289impl_compare_c1!(compare_i16_c1, i16, nppiCompare_16s_C1R_Ctx);
290impl_compare_c1!(compare_f32_c1, f32, nppiCompare_32f_C1R_Ctx);
291
292macro_rules! impl_compare_packed {
293 ($name:ident, $ty:ty, $layout:ty, $ffi:ident) => {
294 pub fn $name(
295 stream_context: &StreamContext,
296 source1: &ImageView<'_, $ty, $layout>,
297 source2: &ImageView<'_, $ty, $layout>,
298 destination: &mut MaskViewMut<'_>,
299 operation: ComparisonOperation,
300 ) -> Result<()> {
301 validate_same_size(source1.size(), source2.size())?;
302 validate_same_size(source1.size(), destination.size())?;
303
304 unsafe {
305 try_ffi!(sys::$ffi(
306 source1.as_ptr().cast(),
307 source1.step(),
308 source2.as_ptr().cast(),
309 source2.step(),
310 destination.as_mut_ptr().cast(),
311 destination.step(),
312 source1.size().into(),
313 operation.into(),
314 stream_context.as_raw(),
315 ))?;
316 }
317 Ok(())
318 }
319 };
320}
321
322impl_compare_packed!(compare_u8_c3, u8, C3, nppiCompare_8u_C3R_Ctx);
323impl_compare_packed!(compare_u8_c4, u8, C4, nppiCompare_8u_C4R_Ctx);
324impl_compare_packed!(compare_u8_ac4, u8, AC4, nppiCompare_8u_AC4R_Ctx);
325impl_compare_packed!(compare_u16_c3, u16, C3, nppiCompare_16u_C3R_Ctx);
326impl_compare_packed!(compare_u16_c4, u16, C4, nppiCompare_16u_C4R_Ctx);
327impl_compare_packed!(compare_u16_ac4, u16, AC4, nppiCompare_16u_AC4R_Ctx);
328impl_compare_packed!(compare_i16_c3, i16, C3, nppiCompare_16s_C3R_Ctx);
329impl_compare_packed!(compare_i16_c4, i16, C4, nppiCompare_16s_C4R_Ctx);
330impl_compare_packed!(compare_i16_ac4, i16, AC4, nppiCompare_16s_AC4R_Ctx);
331impl_compare_packed!(compare_f32_c3, f32, C3, nppiCompare_32f_C3R_Ctx);
332impl_compare_packed!(compare_f32_c4, f32, C4, nppiCompare_32f_C4R_Ctx);
333impl_compare_packed!(compare_f32_ac4, f32, AC4, nppiCompare_32f_AC4R_Ctx);
334
335impl_generic_compare!(CompareC1, compare, compare_c1, C1, [
336 u8 => compare_u8_c1,
337 u16 => compare_u16_c1,
338 i16 => compare_i16_c1,
339 f32 => compare_f32_c1,
340]);
341impl_generic_compare!(CompareC3, compare, compare_c3, C3, [
342 u8 => compare_u8_c3,
343 u16 => compare_u16_c3,
344 i16 => compare_i16_c3,
345 f32 => compare_f32_c3,
346]);
347impl_generic_compare!(CompareC4, compare, compare_c4, C4, [
348 u8 => compare_u8_c4,
349 u16 => compare_u16_c4,
350 i16 => compare_i16_c4,
351 f32 => compare_f32_c4,
352]);
353impl_generic_compare!(CompareAc4, compare, compare_ac4, AC4, [
354 u8 => compare_u8_ac4,
355 u16 => compare_u16_ac4,
356 i16 => compare_i16_ac4,
357 f32 => compare_f32_ac4,
358]);
359
360macro_rules! impl_compare_constant_c1 {
361 ($name:ident, $ty:ty, $ffi:ident) => {
362 pub fn $name(
363 stream_context: &StreamContext,
364 source: &ImageView<'_, $ty, C1>,
365 constant: $ty,
366 destination: &mut MaskViewMut<'_>,
367 operation: ComparisonOperation,
368 ) -> Result<()> {
369 validate_same_size(source.size(), destination.size())?;
370
371 unsafe {
372 try_ffi!(sys::$ffi(
373 source.as_ptr().cast(),
374 source.step(),
375 constant,
376 destination.as_mut_ptr().cast(),
377 destination.step(),
378 source.size().into(),
379 operation.into(),
380 stream_context.as_raw(),
381 ))?;
382 }
383 Ok(())
384 }
385 };
386}
387
388impl_compare_constant_c1!(compare_constant_u8_c1, u8, nppiCompareC_8u_C1R_Ctx);
389impl_compare_constant_c1!(compare_constant_u16_c1, u16, nppiCompareC_16u_C1R_Ctx);
390impl_compare_constant_c1!(compare_constant_i16_c1, i16, nppiCompareC_16s_C1R_Ctx);
391impl_compare_constant_c1!(compare_constant_f32_c1, f32, nppiCompareC_32f_C1R_Ctx);
392
393macro_rules! impl_compare_constant_packed {
394 ($name:ident, $ty:ty, $layout:ty, $channels:expr, $ffi:ident) => {
395 pub fn $name(
396 stream_context: &StreamContext,
397 source: &ImageView<'_, $ty, $layout>,
398 constants: [$ty; $channels],
399 destination: &mut MaskViewMut<'_>,
400 operation: ComparisonOperation,
401 ) -> Result<()> {
402 validate_same_size(source.size(), destination.size())?;
403
404 unsafe {
405 try_ffi!(sys::$ffi(
406 source.as_ptr().cast(),
407 source.step(),
408 constants.as_ptr().cast(),
409 destination.as_mut_ptr().cast(),
410 destination.step(),
411 source.size().into(),
412 operation.into(),
413 stream_context.as_raw(),
414 ))?;
415 }
416 Ok(())
417 }
418 };
419}
420
421impl_compare_constant_packed!(compare_constant_u8_c3, u8, C3, 3, nppiCompareC_8u_C3R_Ctx);
422impl_compare_constant_packed!(compare_constant_u8_c4, u8, C4, 4, nppiCompareC_8u_C4R_Ctx);
423impl_compare_constant_packed!(
424 compare_constant_u8_ac4,
425 u8,
426 AC4,
427 3,
428 nppiCompareC_8u_AC4R_Ctx
429);
430impl_compare_constant_packed!(
431 compare_constant_u16_c3,
432 u16,
433 C3,
434 3,
435 nppiCompareC_16u_C3R_Ctx
436);
437impl_compare_constant_packed!(
438 compare_constant_u16_c4,
439 u16,
440 C4,
441 4,
442 nppiCompareC_16u_C4R_Ctx
443);
444impl_compare_constant_packed!(
445 compare_constant_u16_ac4,
446 u16,
447 AC4,
448 3,
449 nppiCompareC_16u_AC4R_Ctx
450);
451impl_compare_constant_packed!(
452 compare_constant_i16_c3,
453 i16,
454 C3,
455 3,
456 nppiCompareC_16s_C3R_Ctx
457);
458impl_compare_constant_packed!(
459 compare_constant_i16_c4,
460 i16,
461 C4,
462 4,
463 nppiCompareC_16s_C4R_Ctx
464);
465impl_compare_constant_packed!(
466 compare_constant_i16_ac4,
467 i16,
468 AC4,
469 3,
470 nppiCompareC_16s_AC4R_Ctx
471);
472impl_compare_constant_packed!(
473 compare_constant_f32_c3,
474 f32,
475 C3,
476 3,
477 nppiCompareC_32f_C3R_Ctx
478);
479impl_compare_constant_packed!(
480 compare_constant_f32_c4,
481 f32,
482 C4,
483 4,
484 nppiCompareC_32f_C4R_Ctx
485);
486impl_compare_constant_packed!(
487 compare_constant_f32_ac4,
488 f32,
489 AC4,
490 3,
491 nppiCompareC_32f_AC4R_Ctx
492);
493
494impl_generic_compare_constant_scalar!(
495 CompareConstantC1,
496 compare_constant,
497 compare_constant_c1,
498 C1,
499 [
500 u8 => compare_constant_u8_c1,
501 u16 => compare_constant_u16_c1,
502 i16 => compare_constant_i16_c1,
503 f32 => compare_constant_f32_c1,
504 ]
505);
506impl_generic_compare_constant_array!(
507 CompareConstantC3,
508 compare_constant,
509 compare_constant_c3,
510 C3,
511 3,
512 [
513 u8 => compare_constant_u8_c3,
514 u16 => compare_constant_u16_c3,
515 i16 => compare_constant_i16_c3,
516 f32 => compare_constant_f32_c3,
517 ]
518);
519impl_generic_compare_constant_array!(
520 CompareConstantC4,
521 compare_constant,
522 compare_constant_c4,
523 C4,
524 4,
525 [
526 u8 => compare_constant_u8_c4,
527 u16 => compare_constant_u16_c4,
528 i16 => compare_constant_i16_c4,
529 f32 => compare_constant_f32_c4,
530 ]
531);
532impl_generic_compare_constant_array!(
533 CompareConstantAc4,
534 compare_constant,
535 compare_constant_ac4,
536 AC4,
537 3,
538 [
539 u8 => compare_constant_u8_ac4,
540 u16 => compare_constant_u16_ac4,
541 i16 => compare_constant_i16_ac4,
542 f32 => compare_constant_f32_ac4,
543 ]
544);
545
546macro_rules! impl_compare_equal_epsilon {
547 ($name:ident, $layout:ty, $ffi:ident) => {
548 pub fn $name(
549 stream_context: &StreamContext,
550 source1: &ImageView<'_, f32, $layout>,
551 source2: &ImageView<'_, f32, $layout>,
552 destination: &mut MaskViewMut<'_>,
553 epsilon: f32,
554 ) -> Result<()> {
555 validate_same_size(source1.size(), source2.size())?;
556 validate_same_size(source1.size(), destination.size())?;
557
558 unsafe {
559 try_ffi!(sys::$ffi(
560 source1.as_ptr().cast(),
561 source1.step(),
562 source2.as_ptr().cast(),
563 source2.step(),
564 destination.as_mut_ptr().cast(),
565 destination.step(),
566 source1.size().into(),
567 epsilon,
568 stream_context.as_raw(),
569 ))?;
570 }
571 Ok(())
572 }
573 };
574}
575
576impl_compare_equal_epsilon!(
577 compare_equal_epsilon_f32_c1,
578 C1,
579 nppiCompareEqualEps_32f_C1R_Ctx
580);
581impl_compare_equal_epsilon!(
582 compare_equal_epsilon_f32_c3,
583 C3,
584 nppiCompareEqualEps_32f_C3R_Ctx
585);
586impl_compare_equal_epsilon!(
587 compare_equal_epsilon_f32_c4,
588 C4,
589 nppiCompareEqualEps_32f_C4R_Ctx
590);
591impl_compare_equal_epsilon!(
592 compare_equal_epsilon_f32_ac4,
593 AC4,
594 nppiCompareEqualEps_32f_AC4R_Ctx
595);
596
597impl_generic_compare_equal_epsilon!(
598 CompareEqualEpsilonC1,
599 compare_equal_epsilon,
600 compare_equal_epsilon_c1,
601 C1,
602 [f32 => compare_equal_epsilon_f32_c1]
603);
604impl_generic_compare_equal_epsilon!(
605 CompareEqualEpsilonC3,
606 compare_equal_epsilon,
607 compare_equal_epsilon_c3,
608 C3,
609 [f32 => compare_equal_epsilon_f32_c3]
610);
611impl_generic_compare_equal_epsilon!(
612 CompareEqualEpsilonC4,
613 compare_equal_epsilon,
614 compare_equal_epsilon_c4,
615 C4,
616 [f32 => compare_equal_epsilon_f32_c4]
617);
618impl_generic_compare_equal_epsilon!(
619 CompareEqualEpsilonAc4,
620 compare_equal_epsilon,
621 compare_equal_epsilon_ac4,
622 AC4,
623 [f32 => compare_equal_epsilon_f32_ac4]
624);
625
626macro_rules! impl_compare_equal_epsilon_constant_c1 {
627 ($name:ident, $ffi:ident) => {
628 pub fn $name(
629 stream_context: &StreamContext,
630 source: &ImageView<'_, f32, C1>,
631 constant: f32,
632 destination: &mut MaskViewMut<'_>,
633 epsilon: f32,
634 ) -> Result<()> {
635 validate_same_size(source.size(), destination.size())?;
636
637 unsafe {
638 try_ffi!(sys::$ffi(
639 source.as_ptr().cast(),
640 source.step(),
641 constant,
642 destination.as_mut_ptr().cast(),
643 destination.step(),
644 source.size().into(),
645 epsilon,
646 stream_context.as_raw(),
647 ))?;
648 }
649 Ok(())
650 }
651 };
652}
653
654macro_rules! impl_compare_equal_epsilon_constant_packed {
655 ($name:ident, $layout:ty, $channels:expr, $ffi:ident) => {
656 pub fn $name(
657 stream_context: &StreamContext,
658 source: &ImageView<'_, f32, $layout>,
659 constants: [f32; $channels],
660 destination: &mut MaskViewMut<'_>,
661 epsilon: f32,
662 ) -> Result<()> {
663 validate_same_size(source.size(), destination.size())?;
664
665 unsafe {
666 try_ffi!(sys::$ffi(
667 source.as_ptr().cast(),
668 source.step(),
669 constants.as_ptr().cast(),
670 destination.as_mut_ptr().cast(),
671 destination.step(),
672 source.size().into(),
673 epsilon,
674 stream_context.as_raw(),
675 ))?;
676 }
677 Ok(())
678 }
679 };
680}
681
682impl_compare_equal_epsilon_constant_c1!(
683 compare_equal_epsilon_constant_f32_c1,
684 nppiCompareEqualEpsC_32f_C1R_Ctx
685);
686impl_compare_equal_epsilon_constant_packed!(
687 compare_equal_epsilon_constant_f32_c3,
688 C3,
689 3,
690 nppiCompareEqualEpsC_32f_C3R_Ctx
691);
692impl_compare_equal_epsilon_constant_packed!(
693 compare_equal_epsilon_constant_f32_c4,
694 C4,
695 4,
696 nppiCompareEqualEpsC_32f_C4R_Ctx
697);
698impl_compare_equal_epsilon_constant_packed!(
699 compare_equal_epsilon_constant_f32_ac4,
700 AC4,
701 3,
702 nppiCompareEqualEpsC_32f_AC4R_Ctx
703);
704
705impl_generic_compare_equal_epsilon_constant_scalar!(
706 CompareEqualEpsilonConstantC1,
707 compare_equal_epsilon_constant,
708 compare_equal_epsilon_constant_c1,
709 C1,
710 [f32 => compare_equal_epsilon_constant_f32_c1]
711);
712impl_generic_compare_equal_epsilon_constant_array!(
713 CompareEqualEpsilonConstantC3,
714 compare_equal_epsilon_constant,
715 compare_equal_epsilon_constant_c3,
716 C3,
717 3,
718 [f32 => compare_equal_epsilon_constant_f32_c3]
719);
720impl_generic_compare_equal_epsilon_constant_array!(
721 CompareEqualEpsilonConstantC4,
722 compare_equal_epsilon_constant,
723 compare_equal_epsilon_constant_c4,
724 C4,
725 4,
726 [f32 => compare_equal_epsilon_constant_f32_c4]
727);
728impl_generic_compare_equal_epsilon_constant_array!(
729 CompareEqualEpsilonConstantAc4,
730 compare_equal_epsilon_constant,
731 compare_equal_epsilon_constant_ac4,
732 AC4,
733 3,
734 [f32 => compare_equal_epsilon_constant_f32_ac4]
735);
736
737fn validate_same_size(source: Size, destination: Size) -> Result<()> {
738 if source == destination {
739 return Ok(());
740 }
741 Err(Error::SizeMismatch {
742 name: "image size".into(),
743 expected: source,
744 actual: destination,
745 })
746}