#[cfg(feature = "img")]
use image::DynamicImage;
use libwebp_sys::*;
use crate::shared::*;
pub struct Encoder<'a> {
image: &'a [u8],
layout: PixelLayout,
width: u32,
height: u32,
}
impl<'a> Encoder<'a> {
pub fn new(image: &'a [u8], layout: PixelLayout, width: u32, height: u32) -> Self {
Self { image, layout, width, height }
}
#[cfg(feature = "img")]
pub fn from_image(image: &'a DynamicImage) -> Self {
match image {
DynamicImage::ImageLuma8(_) => { unreachable!() }
DynamicImage::ImageLumaA8(_) => { unreachable!() }
DynamicImage::ImageRgb8(image) => {
Self::from_rgb(image.as_ref(), image.width(), image.height())
}
DynamicImage::ImageRgba8(image) => {
Self::from_rgba(image.as_ref(), image.width(), image.height())
}
DynamicImage::ImageBgr8(_) => { unreachable!() }
DynamicImage::ImageBgra8(_) => { unreachable!() }
}
}
pub fn from_rgb(image: &'a [u8], width: u32, height: u32) -> Self {
Self { image, layout: PixelLayout::Rgb, width, height }
}
pub fn from_rgba(image: &'a [u8], width: u32, height: u32) -> Self {
Self { image, layout: PixelLayout::Rgba, width, height }
}
pub fn encode(&self, quality: f32) -> WebPMemory {
unsafe { encode(self.image, self.layout, self.width, self.height, quality) }
}
pub fn encode_lossless(&self) -> WebPMemory {
unsafe { encode(self.image, self.layout, self.width, self.height, -1.0) }
}
}
unsafe fn encode(image: &[u8], color: PixelLayout, width: u32, height: u32, quality: f32) -> WebPMemory {
let width = width as _;
let height = height as _;
let mut buffer = std::ptr::null_mut::<u8>();
let len = match color {
PixelLayout::Rgb if quality < 0.0 => {
let stride = width * 3;
WebPEncodeLosslessRGB(image.as_ptr(), width, height, stride, &mut buffer as *mut _)
}
PixelLayout::Rgb => {
let stride = width * 3;
WebPEncodeRGB(image.as_ptr(), width, height, stride, quality, &mut buffer as *mut _)
}
PixelLayout::Rgba if quality < 0.0 => {
let stride = width * 4;
WebPEncodeLosslessRGBA(image.as_ptr(), width, height, stride, &mut buffer as *mut _)
}
PixelLayout::Rgba => {
let stride = width * 4;
WebPEncodeRGBA(image.as_ptr(), width, height, stride, quality, &mut buffer as *mut _)
}
};
WebPMemory(buffer, len)
}