libwebp 0.1.0

A binding to libwebp
Documentation
use std::fmt;
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::os::raw::*;
use std::ptr::NonNull;

pub struct WebpBox<T: ?Sized> {
    ptr: NonNull<T>,
    _marker: PhantomData<T>,
}

impl<T: ?Sized> WebpBox<T> {
    pub unsafe fn from_raw(raw: *mut T) -> WebpBox<T> {
        Self {
            ptr: NonNull::new_unchecked(raw),
            _marker: PhantomData,
        }
    }

    pub fn into_raw(b: WebpBox<T>) -> *mut T {
        let ptr = b.ptr;
        mem::forget(b);
        ptr.as_ptr()
    }
}

impl<T: ?Sized> Deref for WebpBox<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        unsafe { self.ptr.as_ref() }
    }
}

impl<T: ?Sized> DerefMut for WebpBox<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { self.ptr.as_mut() }
    }
}

impl<T: ?Sized> Drop for WebpBox<T> {
    fn drop(&mut self) {
        unsafe {
            WebPFree(self.ptr.as_ptr() as *mut c_void);
        }
    }
}

#[cfg(feature = "0.5")]
use libwebp_sys::WebPFree;

#[cfg(not(feature = "0.5"))]
#[allow(non_snake_case)]
unsafe fn WebPFree(ptr: *mut c_void) {
    extern "C" {
        fn free(ptr: *mut c_void);
    }
    free(ptr);
}

impl<T: fmt::Debug + ?Sized> fmt::Debug for WebpBox<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(self as &T, f)
    }
}

pub struct WebpYuvBox {
    y: NonNull<[u8]>,
    u: NonNull<[u8]>,
    v: NonNull<[u8]>,
}

impl WebpYuvBox {
    pub unsafe fn from_raw_yuv(y: *mut [u8], u: *mut [u8], v: *mut [u8]) -> WebpYuvBox {
        Self {
            y: NonNull::new_unchecked(y),
            u: NonNull::new_unchecked(u),
            v: NonNull::new_unchecked(v),
        }
    }

    pub fn into_raw_yuv(self) -> (*mut [u8], *mut [u8], *mut [u8]) {
        let y = self.y.as_ptr();
        let u = self.u.as_ptr();
        let v = self.v.as_ptr();
        mem::forget(self);
        (y, u, v)
    }

    pub fn y(&self) -> &[u8] {
        unsafe { self.y.as_ref() }
    }
    pub fn y_mut(&mut self) -> &mut [u8] {
        unsafe { self.y.as_mut() }
    }

    pub fn u(&self) -> &[u8] {
        unsafe { self.u.as_ref() }
    }
    pub fn u_mut(&mut self) -> &mut [u8] {
        unsafe { self.u.as_mut() }
    }

    pub fn v(&self) -> &[u8] {
        unsafe { self.v.as_ref() }
    }
    pub fn v_mut(&mut self) -> &mut [u8] {
        unsafe { self.v.as_mut() }
    }

    pub fn yuv(&self) -> (&[u8], &[u8], &[u8]) {
        let y = unsafe { self.y.as_ref() };
        let u = unsafe { self.u.as_ref() };
        let v = unsafe { self.v.as_ref() };
        (y, u, v)
    }
    pub fn yuv_mut(&mut self) -> (&mut [u8], &mut [u8], &mut [u8]) {
        let y = unsafe { self.y.as_mut() };
        let u = unsafe { self.u.as_mut() };
        let v = unsafe { self.v.as_mut() };
        (y, u, v)
    }

    pub fn into_y(self) -> WebpBox<[u8]> {
        let y = self.y;
        mem::forget(self);
        WebpBox {
            ptr: y,
            _marker: PhantomData,
        }
    }
}

impl Drop for WebpYuvBox {
    fn drop(&mut self) {
        unsafe {
            WebPFree(self.y.as_ptr() as *mut c_void);
        }
    }
}

impl fmt::Debug for WebpYuvBox {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("WebpYuvBox")
            .field("y", &self.y())
            .field("u", &self.u())
            .field("v", &self.v())
            .finish()
    }
}