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, C3, C4, ImageView, ImageViewMut},
    try_ffi,
    types::{BorderType, DataTypeLike, Point, Size},
    utility::to_usize,
    workspace::ScratchBuffer,
};

#[path = "morphology_composite.rs"]
mod composite;
pub use composite::*;

#[path = "morphology_mask.rs"]
mod mask;
pub use mask::*;

#[path = "morphology_border.rs"]
mod border;
pub use border::*;

#[path = "morphology_3x3.rs"]
mod three_by_three;
pub use three_by_three::*;

#[path = "morphology_3x3_border.rs"]
mod three_by_three_border;
pub use three_by_three_border::*;

fn validate_positive_size(size: Size, name: &str) -> Result<()> {
    if size.width > 0 && size.height > 0 {
        return Ok(());
    }
    Err(Error::OutOfRange { name: name.into() })
}

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,
    })
}

fn validate_mask(mask: &[u8], mask_size: Size, anchor: Point) -> Result<()> {
    validate_mask_shape(mask, mask_size, anchor)
}

fn validate_mask_shape<T>(mask: &[T], mask_size: Size, anchor: Point) -> Result<()> {
    if mask_size.width <= 0 || mask_size.height <= 0 {
        return Err(Error::OutOfRange {
            name: "mask size".into(),
        });
    }

    if anchor.x < 0 || anchor.y < 0 || anchor.x >= mask_size.width || anchor.y >= mask_size.height {
        return Err(Error::OutOfRange {
            name: "anchor".into(),
        });
    }

    let expected = (mask_size.width as usize)
        .checked_mul(mask_size.height as usize)
        .ok_or_else(|| Error::OutOfRange {
            name: "mask size".into(),
        })?;

    if mask.len() == expected {
        return Ok(());
    }

    Err(Error::LengthMismatch {
        name: "mask".into(),
        expected,
        actual: mask.len(),
    })
}

fn validate_border_roi(source: Size, source_offset: Point, roi: Size) -> Result<()> {
    if source_offset.x < 0 || source_offset.y < 0 {
        return Err(Error::OutOfRange {
            name: "source offset".into(),
        });
    }

    let right = source_offset
        .x
        .checked_add(roi.width)
        .ok_or_else(|| Error::OutOfRange {
            name: "source offset".into(),
        })?;
    let bottom = source_offset
        .y
        .checked_add(roi.height)
        .ok_or_else(|| Error::OutOfRange {
            name: "source offset".into(),
        })?;

    if right <= source.width && bottom <= source.height {
        return Ok(());
    }

    Err(Error::SizeMismatch {
        name: "border roi".into(),
        expected: source,
        actual: roi,
    })
}