singe-npp 0.1.0-alpha.8

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

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
pub struct Size {
    pub width: i32,
    pub height: i32,
}

impl Size {
    pub const fn new(width: i32, height: i32) -> Self {
        assert!(width > 0, "width must be greater than 0");
        assert!(height > 0, "height must be greater than 0");
        Self { width, height }
    }

    pub const fn from_raw_parts(width: i32, height: i32) -> Self {
        Self { width, height }
    }

    pub fn create(width: i32, height: i32) -> Result<Self> {
        let size = Self::from_raw_parts(width, height);
        size.validate()?;
        Ok(size)
    }

    pub const fn is_positive(self) -> bool {
        self.width > 0 && self.height > 0
    }

    pub fn validate(self) -> Result<()> {
        if self.width <= 0 {
            return Err(Error::ValueNotPositive {
                name: "width".into(),
            });
        }
        if self.height <= 0 {
            return Err(Error::ValueNotPositive {
                name: "height".into(),
            });
        }
        Ok(())
    }

    pub fn rectangle(self) -> Rectangle {
        Rectangle {
            x: 0,
            y: 0,
            width: self.width,
            height: self.height,
        }
    }

    pub fn centered_rectangle(self) -> Rectangle {
        let side = self.width.min(self.height);
        Rectangle {
            x: ((self.width - side) / 2),
            y: ((self.height - side) / 2),
            width: side,
            height: side,
        }
    }
}

impl From<Size> for sys::NppiSize {
    fn from(value: Size) -> Self {
        Self {
            width: value.width,
            height: value.height,
        }
    }
}

impl From<sys::NppiSize> for Size {
    fn from(value: sys::NppiSize) -> Self {
        Self::from_raw_parts(value.width, value.height)
    }
}

impl Display for Size {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "{}x{}", self.width, self.height)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn size_create_rejects_nonpositive_width() {
        assert!(matches!(
            Size::create(0, 1),
            Err(Error::ValueNotPositive { name }) if name == "width"
        ));
    }

    #[test]
    fn size_create_rejects_nonpositive_height() {
        assert!(matches!(
            Size::create(1, -1),
            Err(Error::ValueNotPositive { name }) if name == "height"
        ));
    }

    #[test]
    fn size_raw_parts_preserves_ffi_values() {
        let size = Size::from_raw_parts(0, -1);
        assert_eq!(size.width, 0);
        assert_eq!(size.height, -1);
        assert!(!size.is_positive());
    }
}

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Default)]
pub struct Rectangle {
    pub x: i32,
    pub y: i32,
    pub width: i32,
    pub height: i32,
}

impl Rectangle {
    pub fn size(self) -> Size {
        Size::from_raw_parts(self.width, self.height)
    }
}

impl From<Rectangle> for sys::NppiRect {
    fn from(value: Rectangle) -> Self {
        Self {
            x: value.x,
            y: value.y,
            width: value.width,
            height: value.height,
        }
    }
}

impl From<sys::NppiRect> for Rectangle {
    fn from(value: sys::NppiRect) -> Self {
        Self {
            x: value.x,
            y: value.y,
            width: value.width,
            height: value.height,
        }
    }
}

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Default)]
pub struct Point {
    pub x: i32,
    pub y: i32,
}

impl Point {
    pub const ZERO: Point = Point::new(0, 0);

    pub const fn new(x: i32, y: i32) -> Self {
        Point { x, y }
    }
}

impl From<Point> for sys::NppiPoint {
    fn from(value: Point) -> Self {
        Self {
            x: value.x,
            y: value.y,
        }
    }
}

impl From<sys::NppiPoint> for Point {
    fn from(value: sys::NppiPoint) -> Self {
        Self {
            x: value.x,
            y: value.y,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialOrd, PartialEq, Default)]
pub struct Point32f {
    pub x: f32,
    pub y: f32,
}

impl From<Point32f> for sys::NppiPoint32f {
    fn from(value: Point32f) -> Self {
        Self {
            x: value.x,
            y: value.y,
        }
    }
}

impl From<sys::NppiPoint32f> for Point32f {
    fn from(value: sys::NppiPoint32f) -> Self {
        Self {
            x: value.x,
            y: value.y,
        }
    }
}

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialOrd, PartialEq, Default)]
pub struct Point64f {
    pub x: f64,
    pub y: f64,
}

impl From<Point64f> for sys::NppiPoint64f {
    fn from(value: Point64f) -> Self {
        Self {
            x: value.x,
            y: value.y,
        }
    }
}

impl From<sys::NppiPoint64f> for Point64f {
    fn from(value: sys::NppiPoint64f) -> Self {
        Self {
            x: value.x,
            y: value.y,
        }
    }
}

impl From<[f64; 2]> for Point64f {
    fn from(value: [f64; 2]) -> Self {
        Self {
            x: value[0],
            y: value[1],
        }
    }
}

impl From<Point64f> for [f64; 2] {
    fn from(value: Point64f) -> Self {
        [value.x, value.y]
    }
}

impl Point64f {
    pub const fn to_array(self) -> [f64; 2] {
        [self.x, self.y]
    }
}

pub type PointF64 = Point64f;

#[derive(Debug, Clone, Copy, PartialOrd, PartialEq, Default)]
pub struct PointPolar {
    pub rho: f32,
    pub theta: f32,
}

impl From<PointPolar> for sys::NppPointPolar {
    fn from(value: PointPolar) -> Self {
        Self {
            rho: value.rho,
            theta: value.theta,
        }
    }
}

impl From<sys::NppPointPolar> for PointPolar {
    fn from(value: sys::NppPointPolar) -> Self {
        Self {
            rho: value.rho,
            theta: value.theta,
        }
    }
}

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct BoundF64 {
    pub lower: PointF64,
    pub upper: PointF64,
}

impl From<[[f64; 2]; 2]> for BoundF64 {
    fn from(value: [[f64; 2]; 2]) -> Self {
        Self {
            lower: value[0].into(),
            upper: value[1].into(),
        }
    }
}

impl From<BoundF64> for [[f64; 2]; 2] {
    fn from(value: BoundF64) -> Self {
        [value.lower.into(), value.upper.into()]
    }
}

impl BoundF64 {
    pub const fn as_ptr(&self) -> *const [f64; 2] {
        (&self.lower as *const PointF64).cast()
    }

    pub const fn as_mut_ptr(&mut self) -> *mut [f64; 2] {
        (&mut self.lower as *mut PointF64).cast()
    }
}

#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct QuadrangleF64 {
    pub points: [PointF64; 4],
}

impl From<[[f64; 2]; 4]> for QuadrangleF64 {
    fn from(value: [[f64; 2]; 4]) -> Self {
        Self {
            points: value.map(PointF64::from),
        }
    }
}

impl From<QuadrangleF64> for [[f64; 2]; 4] {
    fn from(value: QuadrangleF64) -> Self {
        value.points.map(Into::into)
    }
}

impl QuadrangleF64 {
    pub const fn as_ptr(&self) -> *const [f64; 2] {
        self.points.as_ptr().cast()
    }

    pub fn as_mut_ptr(&mut self) -> *mut [f64; 2] {
        self.points.as_mut_ptr().cast()
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct AffineCoefficients {
    pub values: [[f64; 3]; 2],
}

impl From<[[f64; 3]; 2]> for AffineCoefficients {
    fn from(value: [[f64; 3]; 2]) -> Self {
        Self { values: value }
    }
}

impl From<AffineCoefficients> for [[f64; 3]; 2] {
    fn from(value: AffineCoefficients) -> Self {
        value.values
    }
}

impl AffineCoefficients {
    pub const fn as_ptr(&self) -> *const [f64; 3] {
        self.values.as_ptr()
    }

    pub fn as_mut_ptr(&mut self) -> *mut [f64; 3] {
        self.values.as_mut_ptr()
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct PerspectiveCoefficients {
    pub values: [[f64; 3]; 3],
}

impl From<[[f64; 3]; 3]> for PerspectiveCoefficients {
    fn from(value: [[f64; 3]; 3]) -> Self {
        Self { values: value }
    }
}

impl From<PerspectiveCoefficients> for [[f64; 3]; 3] {
    fn from(value: PerspectiveCoefficients) -> Self {
        value.values
    }
}

impl PerspectiveCoefficients {
    pub const fn as_ptr(&self) -> *const [f64; 3] {
        self.values.as_ptr()
    }

    pub fn as_mut_ptr(&mut self) -> *mut [f64; 3] {
        self.values.as_mut_ptr()
    }
}