webp_encoder 0.6.0

WebPEncodeLosslessRGBA
Documentation
use std::ffi::{c_int, c_void};

use anyhow::{ensure, Result};

#[link(name = "webp", kind = "dylib")]
extern "C" {
    fn WebPEncodeLosslessRGBA(
        rgba: *const u8,
        width: c_int,
        height: c_int,
        stride: c_int,
        output: *mut *mut u8,
    ) -> usize;

    fn WebPFree(ptr: *mut c_void);
}

pub fn webp_encode_lossless_rgba(rgba: &[u8], width: usize, height: usize) -> Result<EncodedImage> {
    unsafe {
        ensure!(width < 16384 && height < 16384);
        ensure!(width > 0 && height > 0);
        ensure!(rgba.len() == width * height * 4);
        let mut ptr = std::ptr::null_mut();
        let len = WebPEncodeLosslessRGBA(
            rgba.as_ptr(),
            width as c_int,
            height as c_int,
            (width * 4) as c_int,
            &mut ptr,
        );
        ensure!(len != 0);
        ensure!(!ptr.is_null());
        Ok(EncodedImage { ptr, len })
    }
}

pub struct EncodedImage {
    ptr: *mut u8,
    len: usize,
}

impl EncodedImage {
    pub fn webp_file(&self) -> &[u8] {
        unsafe { std::slice::from_raw_parts(self.ptr, self.len) }
    }
}

impl Drop for EncodedImage {
    fn drop(&mut self) {
        unsafe {
            WebPFree(self.ptr as *mut c_void);
        }
    }
}

unsafe impl Send for EncodedImage {}
unsafe impl Sync for EncodedImage {}