singe-npp 0.1.0-alpha.8

Safe Rust wrappers for NVIDIA Performance Primitives library (NPP).
Documentation
use super::*;

macro_rules! impl_count_in_range {
    (
        $buffer_size_name:ident,
        $name:ident,
        $ty:ty,
        C1,
        $buffer_size_ffi:ident,
        $ffi:ident
    ) => {
        pub fn $buffer_size_name(stream_context: &StreamContext, roi: Size) -> Result<usize> {
            let mut bytes = 0;
            unsafe {
                try_ffi!(sys::$buffer_size_ffi(
                    roi.into(),
                    &raw mut bytes,
                    stream_context.as_raw(),
                ))?;
            }
            to_usize(bytes, "buffer size")
        }

        pub fn $name(
            stream_context: &StreamContext,
            source: &ImageView<'_, $ty, C1>,
            counts: &mut DeviceMemory<i32>,
            lower_bound: $ty,
            upper_bound: $ty,
        ) -> Result<()> {
            validate_index_output(counts, 1)?;
            let required_bytes = $buffer_size_name(stream_context, source.size())?;
            let scratch = DeviceMemory::<u8>::create(required_bytes)?;

            unsafe {
                try_ffi!(sys::$ffi(
                    source.as_ptr().cast(),
                    source.step(),
                    source.size().into(),
                    counts.as_mut_ptr().cast(),
                    lower_bound,
                    upper_bound,
                    scratch.as_mut_ptr().cast(),
                    stream_context.as_raw(),
                ))?;
            }
            Ok(())
        }
    };
    (
        $buffer_size_name:ident,
        $name:ident,
        $ty:ty,
        C3,
        $buffer_size_ffi:ident,
        $ffi:ident
    ) => {
        pub fn $buffer_size_name(stream_context: &StreamContext, roi: Size) -> Result<usize> {
            let mut bytes = 0;
            unsafe {
                try_ffi!(sys::$buffer_size_ffi(
                    roi.into(),
                    &raw mut bytes,
                    stream_context.as_raw(),
                ))?;
            }
            to_usize(bytes, "buffer size")
        }

        pub fn $name(
            stream_context: &StreamContext,
            source: &ImageView<'_, $ty, C3>,
            counts: &mut DeviceMemory<i32>,
            lower_bound: [$ty; 3],
            upper_bound: [$ty; 3],
        ) -> Result<()> {
            validate_index_output(counts, 3)?;
            let required_bytes = $buffer_size_name(stream_context, source.size())?;
            let scratch = DeviceMemory::<u8>::create(required_bytes)?;

            unsafe {
                try_ffi!(sys::$ffi(
                    source.as_ptr().cast(),
                    source.step(),
                    source.size().into(),
                    counts.as_mut_ptr().cast(),
                    lower_bound.as_ptr().cast_mut(),
                    upper_bound.as_ptr().cast_mut(),
                    scratch.as_mut_ptr().cast(),
                    stream_context.as_raw(),
                ))?;
            }
            Ok(())
        }
    };
    (
        $buffer_size_name:ident,
        $name:ident,
        $ty:ty,
        AC4,
        $buffer_size_ffi:ident,
        $ffi:ident
    ) => {
        pub fn $buffer_size_name(stream_context: &StreamContext, roi: Size) -> Result<usize> {
            let mut bytes = 0;
            unsafe {
                try_ffi!(sys::$buffer_size_ffi(
                    roi.into(),
                    &raw mut bytes,
                    stream_context.as_raw(),
                ))?;
            }
            to_usize(bytes, "buffer size")
        }

        pub fn $name(
            stream_context: &StreamContext,
            source: &ImageView<'_, $ty, AC4>,
            counts: &mut DeviceMemory<i32>,
            lower_bound: [$ty; 3],
            upper_bound: [$ty; 3],
        ) -> Result<()> {
            validate_index_output(counts, 3)?;
            let required_bytes = $buffer_size_name(stream_context, source.size())?;
            let scratch = DeviceMemory::<u8>::create(required_bytes)?;

            unsafe {
                try_ffi!(sys::$ffi(
                    source.as_ptr().cast(),
                    source.step(),
                    source.size().into(),
                    counts.as_mut_ptr().cast(),
                    lower_bound.as_ptr().cast_mut(),
                    upper_bound.as_ptr().cast_mut(),
                    scratch.as_mut_ptr().cast(),
                    stream_context.as_raw(),
                ))?;
            }
            Ok(())
        }
    };
}

macro_rules! impl_generic_count_in_range_c1 {
    ($trait_name:ident, $name:ident, $buffer_size_name:ident, [$(($ty:ty, $direct:ident, $direct_buffer_size:ident)),+ $(,)?]) => {
        pub trait $trait_name: DataTypeLike {
            fn buffer_size(stream_context: &StreamContext, roi: Size) -> Result<usize>;

            fn dispatch(
                stream_context: &StreamContext,
                source: &ImageView<'_, Self, C1>,
                counts: &mut DeviceMemory<i32>,
                lower_bound: Self,
                upper_bound: Self,
            ) -> Result<()>
            where
                Self: Sized;
        }

        $(
            impl $trait_name for $ty {
                fn buffer_size(stream_context: &StreamContext, roi: Size) -> Result<usize> {
                    $direct_buffer_size(stream_context, roi)
                }

                fn dispatch(
                    stream_context: &StreamContext,
                    source: &ImageView<'_, Self, C1>,
                    counts: &mut DeviceMemory<i32>,
                    lower_bound: Self,
                    upper_bound: Self,
                ) -> Result<()> {
                    $direct(stream_context, source, counts, lower_bound, upper_bound)
                }
            }
        )+

        pub fn $buffer_size_name<T: $trait_name>(
            stream_context: &StreamContext,
            roi: Size,
        ) -> Result<usize> {
            T::buffer_size(stream_context, roi)
        }

        pub fn $name<T: $trait_name>(
            stream_context: &StreamContext,
            source: &ImageView<'_, T, C1>,
            counts: &mut DeviceMemory<i32>,
            lower_bound: T,
            upper_bound: T,
        ) -> Result<()> {
            T::dispatch(stream_context, source, counts, lower_bound, upper_bound)
        }
    };
}

macro_rules! impl_generic_count_in_range_packed {
    ($trait_name:ident, $name:ident, $buffer_size_name:ident, $layout:ty, [$(($ty:ty, $direct:ident, $direct_buffer_size:ident)),+ $(,)?]) => {
        pub trait $trait_name: DataTypeLike {
            fn buffer_size(stream_context: &StreamContext, roi: Size) -> Result<usize>;

            fn dispatch(
                stream_context: &StreamContext,
                source: &ImageView<'_, Self, $layout>,
                counts: &mut DeviceMemory<i32>,
                lower_bound: [Self; 3],
                upper_bound: [Self; 3],
            ) -> Result<()>
            where
                Self: Sized;
        }

        $(
            impl $trait_name for $ty {
                fn buffer_size(stream_context: &StreamContext, roi: Size) -> Result<usize> {
                    $direct_buffer_size(stream_context, roi)
                }

                fn dispatch(
                    stream_context: &StreamContext,
                    source: &ImageView<'_, Self, $layout>,
                    counts: &mut DeviceMemory<i32>,
                    lower_bound: [Self; 3],
                    upper_bound: [Self; 3],
                ) -> Result<()> {
                    $direct(stream_context, source, counts, lower_bound, upper_bound)
                }
            }
        )+

        pub fn $buffer_size_name<T: $trait_name>(
            stream_context: &StreamContext,
            roi: Size,
        ) -> Result<usize> {
            T::buffer_size(stream_context, roi)
        }

        pub fn $name<T: $trait_name>(
            stream_context: &StreamContext,
            source: &ImageView<'_, T, $layout>,
            counts: &mut DeviceMemory<i32>,
            lower_bound: [T; 3],
            upper_bound: [T; 3],
        ) -> Result<()> {
            T::dispatch(stream_context, source, counts, lower_bound, upper_bound)
        }
    };
}

impl_count_in_range!(
    count_in_range_u8_c1_buffer_size,
    count_in_range_u8_c1,
    u8,
    C1,
    nppiCountInRangeGetBufferHostSize_8u_C1R_Ctx,
    nppiCountInRange_8u_C1R_Ctx
);
impl_count_in_range!(
    count_in_range_f32_c1_buffer_size,
    count_in_range_f32_c1,
    f32,
    C1,
    nppiCountInRangeGetBufferHostSize_32f_C1R_Ctx,
    nppiCountInRange_32f_C1R_Ctx
);
impl_count_in_range!(
    count_in_range_u8_c3_buffer_size,
    count_in_range_u8_c3,
    u8,
    C3,
    nppiCountInRangeGetBufferHostSize_8u_C3R_Ctx,
    nppiCountInRange_8u_C3R_Ctx
);
impl_count_in_range!(
    count_in_range_f32_c3_buffer_size,
    count_in_range_f32_c3,
    f32,
    C3,
    nppiCountInRangeGetBufferHostSize_32f_C3R_Ctx,
    nppiCountInRange_32f_C3R_Ctx
);
impl_count_in_range!(
    count_in_range_u8_ac4_buffer_size,
    count_in_range_u8_ac4,
    u8,
    AC4,
    nppiCountInRangeGetBufferHostSize_8u_AC4R_Ctx,
    nppiCountInRange_8u_AC4R_Ctx
);
impl_count_in_range!(
    count_in_range_f32_ac4_buffer_size,
    count_in_range_f32_ac4,
    f32,
    AC4,
    nppiCountInRangeGetBufferHostSize_32f_AC4R_Ctx,
    nppiCountInRange_32f_AC4R_Ctx
);
impl_generic_count_in_range_c1!(
    CountInRangeC1,
    count_in_range_c1,
    count_in_range_c1_buffer_size,
    [
        (u8, count_in_range_u8_c1, count_in_range_u8_c1_buffer_size),
        (
            f32,
            count_in_range_f32_c1,
            count_in_range_f32_c1_buffer_size
        ),
    ]
);
impl_generic_count_in_range_packed!(
    CountInRangeC3,
    count_in_range_c3,
    count_in_range_c3_buffer_size,
    C3,
    [
        (u8, count_in_range_u8_c3, count_in_range_u8_c3_buffer_size),
        (
            f32,
            count_in_range_f32_c3,
            count_in_range_f32_c3_buffer_size
        ),
    ]
);
impl_generic_count_in_range_packed!(
    CountInRangeAC4,
    count_in_range_ac4,
    count_in_range_ac4_buffer_size,
    AC4,
    [
        (u8, count_in_range_u8_ac4, count_in_range_u8_ac4_buffer_size),
        (
            f32,
            count_in_range_f32_ac4,
            count_in_range_f32_ac4_buffer_size
        ),
    ]
);