Skip to main content

singe_npp/image/
threshold.rs

1use 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}