singe-npp 0.1.0-alpha.8

Safe Rust wrappers for NVIDIA Performance Primitives library (NPP).
Documentation
use singe_npp_sys as sys;

use crate::{
    context::StreamContext,
    error::{Error, Result},
    image::view::{AC4, C1, C2, C3, C4, ChannelLayout, ImageView, ImageViewMut},
    try_ffi,
    types::{ComparisonOperation, DataType, DataTypeLike, ImageChannels, Size},
};

pub trait FusedAbsDiffElement: Copy {
    const DATA_TYPE: DataType;
}

impl FusedAbsDiffElement for u8 {
    const DATA_TYPE: DataType = DataType::U8;
}

impl FusedAbsDiffElement for i8 {
    const DATA_TYPE: DataType = DataType::I8;
}

impl FusedAbsDiffElement for u16 {
    const DATA_TYPE: DataType = DataType::U16;
}

impl FusedAbsDiffElement for i16 {
    const DATA_TYPE: DataType = DataType::I16;
}

impl FusedAbsDiffElement for u32 {
    const DATA_TYPE: DataType = DataType::U32;
}

impl FusedAbsDiffElement for i32 {
    const DATA_TYPE: DataType = DataType::I32;
}

impl FusedAbsDiffElement for u64 {
    const DATA_TYPE: DataType = DataType::U64;
}

impl FusedAbsDiffElement for i64 {
    const DATA_TYPE: DataType = DataType::I64;
}

impl FusedAbsDiffElement for f32 {
    const DATA_TYPE: DataType = DataType::F32;
}

impl FusedAbsDiffElement for f64 {
    const DATA_TYPE: DataType = DataType::F64;
}

pub trait FusedAbsDiffChannels: ChannelLayout {
    const CHANNELS: ImageChannels;
}

impl FusedAbsDiffChannels for C1 {
    const CHANNELS: ImageChannels = ImageChannels::C1;
}

impl FusedAbsDiffChannels for C2 {
    const CHANNELS: ImageChannels = ImageChannels::C2;
}

impl FusedAbsDiffChannels for C3 {
    const CHANNELS: ImageChannels = ImageChannels::C3;
}

impl FusedAbsDiffChannels for C4 {
    const CHANNELS: ImageChannels = ImageChannels::C4;
}

impl FusedAbsDiffChannels for AC4 {
    const CHANNELS: ImageChannels = ImageChannels::AC4;
}

pub fn fused_absolute_difference_threshold_greater_value<T, L>(
    stream_context: &StreamContext,
    source1: &ImageView<'_, T, L>,
    source2: &ImageView<'_, T, L>,
    destination: &mut ImageViewMut<'_, T, L>,
    threshold: T,
    value: T,
) -> Result<()>
where
    T: FusedAbsDiffElement,
    L: FusedAbsDiffChannels,
{
    validate_same_size(source1.size(), source2.size())?;
    validate_same_size(source1.size(), destination.size())?;

    unsafe {
        try_ffi!(sys::nppiFusedAbsDiff_Threshold_GTVal_Ctx(
            T::DATA_TYPE.into(),
            <L as FusedAbsDiffChannels>::CHANNELS.into(),
            source1.as_ptr().cast(),
            source1.step(),
            source2.as_ptr().cast(),
            source2.step(),
            destination.as_mut_ptr().cast(),
            destination.step(),
            source1.size().into(),
            (&raw const threshold).cast(),
            (&raw const value).cast(),
            stream_context.as_raw(),
        ))?;
    }
    Ok(())
}

pub fn fused_absolute_difference_threshold_greater_value_in_place<T, L>(
    stream_context: &StreamContext,
    source_destination: &mut ImageViewMut<'_, T, L>,
    source2: &ImageView<'_, T, L>,
    threshold: T,
    value: T,
) -> Result<()>
where
    T: FusedAbsDiffElement,
    L: FusedAbsDiffChannels,
{
    validate_same_size(source_destination.size(), source2.size())?;

    unsafe {
        try_ffi!(sys::nppiFusedAbsDiff_Threshold_GTVal_I_Ctx(
            T::DATA_TYPE.into(),
            <L as FusedAbsDiffChannels>::CHANNELS.into(),
            source_destination.as_mut_ptr().cast(),
            source_destination.step(),
            source2.as_ptr().cast(),
            source2.step(),
            source_destination.size().into(),
            (&raw const threshold).cast(),
            (&raw const value).cast(),
            stream_context.as_raw(),
        ))?;
    }
    Ok(())
}

#[macro_use]
#[path = "threshold_direct_macros.rs"]
mod direct_macros;

#[macro_use]
#[path = "threshold_generic_macros.rs"]
mod generic_macros;

#[path = "threshold_basic.rs"]
mod basic;
pub use basic::*;

#[path = "threshold_fixed.rs"]
mod fixed;
pub use fixed::*;

#[path = "threshold_value.rs"]
mod value;
pub use value::*;

#[path = "threshold_fixed_value.rs"]
mod fixed_value;
pub use fixed_value::*;

#[path = "threshold_range_value.rs"]
mod range_value;
pub use range_value::*;

fn validate_same_size(source: Size, destination: Size) -> Result<()> {
    if source == destination {
        return Ok(());
    }
    Err(Error::SizeMismatch {
        name: "image size".into(),
        expected: source,
        actual: destination,
    })
}