singe_npp/image/
threshold.rs1use singe_npp_sys as sys;
2
3use crate::{
4 context::StreamContext,
5 error::{Error, Result},
6 image::view::{AC4, C1, C2, C3, C4, ChannelLayout, ImageView, ImageViewMut},
7 try_ffi,
8 types::{ComparisonOperation, DataType, DataTypeLike, ImageChannels, Size},
9};
10
11pub trait FusedAbsDiffElement: Copy {
12 const DATA_TYPE: DataType;
13}
14
15impl FusedAbsDiffElement for u8 {
16 const DATA_TYPE: DataType = DataType::U8;
17}
18
19impl FusedAbsDiffElement for i8 {
20 const DATA_TYPE: DataType = DataType::I8;
21}
22
23impl FusedAbsDiffElement for u16 {
24 const DATA_TYPE: DataType = DataType::U16;
25}
26
27impl FusedAbsDiffElement for i16 {
28 const DATA_TYPE: DataType = DataType::I16;
29}
30
31impl FusedAbsDiffElement for u32 {
32 const DATA_TYPE: DataType = DataType::U32;
33}
34
35impl FusedAbsDiffElement for i32 {
36 const DATA_TYPE: DataType = DataType::I32;
37}
38
39impl FusedAbsDiffElement for u64 {
40 const DATA_TYPE: DataType = DataType::U64;
41}
42
43impl FusedAbsDiffElement for i64 {
44 const DATA_TYPE: DataType = DataType::I64;
45}
46
47impl FusedAbsDiffElement for f32 {
48 const DATA_TYPE: DataType = DataType::F32;
49}
50
51impl FusedAbsDiffElement for f64 {
52 const DATA_TYPE: DataType = DataType::F64;
53}
54
55pub trait FusedAbsDiffChannels: ChannelLayout {
56 const CHANNELS: ImageChannels;
57}
58
59impl FusedAbsDiffChannels for C1 {
60 const CHANNELS: ImageChannels = ImageChannels::C1;
61}
62
63impl FusedAbsDiffChannels for C2 {
64 const CHANNELS: ImageChannels = ImageChannels::C2;
65}
66
67impl FusedAbsDiffChannels for C3 {
68 const CHANNELS: ImageChannels = ImageChannels::C3;
69}
70
71impl FusedAbsDiffChannels for C4 {
72 const CHANNELS: ImageChannels = ImageChannels::C4;
73}
74
75impl FusedAbsDiffChannels for AC4 {
76 const CHANNELS: ImageChannels = ImageChannels::AC4;
77}
78
79pub fn fused_absolute_difference_threshold_greater_value<T, L>(
80 stream_context: &StreamContext,
81 source1: &ImageView<'_, T, L>,
82 source2: &ImageView<'_, T, L>,
83 destination: &mut ImageViewMut<'_, T, L>,
84 threshold: T,
85 value: T,
86) -> Result<()>
87where
88 T: FusedAbsDiffElement,
89 L: FusedAbsDiffChannels,
90{
91 validate_same_size(source1.size(), source2.size())?;
92 validate_same_size(source1.size(), destination.size())?;
93
94 unsafe {
95 try_ffi!(sys::nppiFusedAbsDiff_Threshold_GTVal_Ctx(
96 T::DATA_TYPE.into(),
97 <L as FusedAbsDiffChannels>::CHANNELS.into(),
98 source1.as_ptr().cast(),
99 source1.step(),
100 source2.as_ptr().cast(),
101 source2.step(),
102 destination.as_mut_ptr().cast(),
103 destination.step(),
104 source1.size().into(),
105 (&raw const threshold).cast(),
106 (&raw const value).cast(),
107 stream_context.as_raw(),
108 ))?;
109 }
110 Ok(())
111}
112
113pub fn fused_absolute_difference_threshold_greater_value_in_place<T, L>(
114 stream_context: &StreamContext,
115 source_destination: &mut ImageViewMut<'_, T, L>,
116 source2: &ImageView<'_, T, L>,
117 threshold: T,
118 value: T,
119) -> Result<()>
120where
121 T: FusedAbsDiffElement,
122 L: FusedAbsDiffChannels,
123{
124 validate_same_size(source_destination.size(), source2.size())?;
125
126 unsafe {
127 try_ffi!(sys::nppiFusedAbsDiff_Threshold_GTVal_I_Ctx(
128 T::DATA_TYPE.into(),
129 <L as FusedAbsDiffChannels>::CHANNELS.into(),
130 source_destination.as_mut_ptr().cast(),
131 source_destination.step(),
132 source2.as_ptr().cast(),
133 source2.step(),
134 source_destination.size().into(),
135 (&raw const threshold).cast(),
136 (&raw const value).cast(),
137 stream_context.as_raw(),
138 ))?;
139 }
140 Ok(())
141}
142
143#[macro_use]
144#[path = "threshold_direct_macros.rs"]
145mod direct_macros;
146
147#[macro_use]
148#[path = "threshold_generic_macros.rs"]
149mod generic_macros;
150
151#[path = "threshold_basic.rs"]
152mod basic;
153pub use basic::*;
154
155#[path = "threshold_fixed.rs"]
156mod fixed;
157pub use fixed::*;
158
159#[path = "threshold_value.rs"]
160mod value;
161pub use value::*;
162
163#[path = "threshold_fixed_value.rs"]
164mod fixed_value;
165pub use fixed_value::*;
166
167#[path = "threshold_range_value.rs"]
168mod range_value;
169pub use range_value::*;
170
171fn validate_same_size(source: Size, destination: Size) -> Result<()> {
172 if source == destination {
173 return Ok(());
174 }
175 Err(Error::SizeMismatch {
176 name: "image size".into(),
177 expected: source,
178 actual: destination,
179 })
180}