singe-npp 0.1.0-alpha.8

Safe Rust wrappers for NVIDIA Performance Primitives library (NPP).
Documentation
use crate::{
    context::StreamContext,
    error::{Error, Result},
    image::{
        memory::Image,
        view::{C1, ImageView, ImageViewMut},
    },
    pipeline::{ImageAllocator, Workspace},
    types::Size,
};

use super::{ImageBacking, ImagePipeline};

#[path = "statistics_integral_concrete_methods.rs"]
mod concrete_methods;
#[path = "statistics_integral_dispatch.rs"]
mod integral_dispatch;
#[path = "statistics_integral_squared_methods.rs"]
mod squared_methods;

use integral_dispatch::{IntegralImage, SquaredIntegralImage};

impl<'a> ImagePipeline<'a, u8, C1> {
    pub fn integral_to_into<T>(
        stream_context: &StreamContext,
        source: &ImageView<'_, u8, C1>,
        destination: &mut ImageViewMut<'_, T, C1>,
        value: T,
    ) -> Result<()>
    where
        T: Copy,
        Self: IntegralImage<T>,
    {
        <Self as IntegralImage<T>>::integral_image(stream_context, source, destination, value)
    }

    pub fn integral_to<T>(self, value: T) -> Result<ImagePipeline<'a, T, C1>>
    where
        T: Copy,
        Workspace: ImageAllocator<T, C1>,
        Self: IntegralImage<T>,
    {
        let size = integral_size(self.size())?;
        let mut destination = self.workspace.image::<T, C1>(size)?;
        {
            let source = self.view()?;
            let mut destination_view = destination.view_mut()?;
            <Self as IntegralImage<T>>::integral_image(
                self.stream_context,
                &source,
                &mut destination_view,
                value,
            )?;
        }

        Ok(ImagePipeline {
            stream_context: self.stream_context,
            workspace: self.workspace,
            backing: ImageBacking::Owned(destination),
        })
    }

    pub(super) fn integral<T>(
        &mut self,
        value: T,
        operation: fn(
            &StreamContext,
            &ImageView<'_, u8, C1>,
            &mut ImageViewMut<'_, T, C1>,
            T,
        ) -> Result<()>,
    ) -> Result<Image<T, C1>>
    where
        T: Copy,
        Workspace: ImageAllocator<T, C1>,
    {
        let size = integral_size(self.size())?;
        let mut destination = self.workspace.image::<T, C1>(size)?;

        {
            let source = self.view()?;
            let mut destination_view = destination.view_mut()?;
            operation(self.stream_context, &source, &mut destination_view, value)?;
        }

        Ok(destination)
    }
}

pub(super) fn integral_size(source: Size) -> Result<Size> {
    Ok(Size {
        width: source
            .width
            .checked_add(1)
            .ok_or_else(|| Error::OutOfRange {
                name: "integral destination width".into(),
            })?,
        height: source
            .height
            .checked_add(1)
            .ok_or_else(|| Error::OutOfRange {
                name: "integral destination height".into(),
            })?,
    })
}