use alloc::vec::Vec;
use imgref::ImgRef;
use rgb::alt::BGRA;
use rgb::{Gray, Rgb, Rgba};
use crate::api::{EncodeError, LosslessConfig, LossyConfig, PixelLayout};
pub fn encode_rgb8(img: ImgRef<Rgb<u8>>, config: &LossyConfig) -> Result<Vec<u8>, EncodeError> {
let (buf, w, h) = img.to_contiguous_buf();
let bytes: &[u8] = bytemuck::cast_slice(&buf);
config
.encode(bytes, w as u32, h as u32, PixelLayout::Rgb8)
.map_err(|e| e.decompose().0)
}
pub fn encode_rgba8(img: ImgRef<Rgba<u8>>, config: &LossyConfig) -> Result<Vec<u8>, EncodeError> {
let (buf, w, h) = img.to_contiguous_buf();
let bytes: &[u8] = bytemuck::cast_slice(&buf);
config
.encode(bytes, w as u32, h as u32, PixelLayout::Rgba8)
.map_err(|e| e.decompose().0)
}
pub fn encode_gray8(img: ImgRef<Gray<u8>>, config: &LossyConfig) -> Result<Vec<u8>, EncodeError> {
let (buf, w, h) = img.to_contiguous_buf();
let bytes = gray_to_rgb_bytes(&buf);
config
.encode(&bytes, w as u32, h as u32, PixelLayout::Rgb8)
.map_err(|e| e.decompose().0)
}
pub fn encode_bgra8(img: ImgRef<BGRA<u8>>, config: &LossyConfig) -> Result<Vec<u8>, EncodeError> {
let (buf, w, h) = img.to_contiguous_buf();
let bytes: &[u8] = bytemuck::cast_slice(&buf);
config
.encode(bytes, w as u32, h as u32, PixelLayout::Bgra8)
.map_err(|e| e.decompose().0)
}
pub fn encode_rgb8_lossless(
img: ImgRef<Rgb<u8>>,
config: &LosslessConfig,
) -> Result<Vec<u8>, EncodeError> {
let (buf, w, h) = img.to_contiguous_buf();
let bytes: &[u8] = bytemuck::cast_slice(&buf);
config
.encode(bytes, w as u32, h as u32, PixelLayout::Rgb8)
.map_err(|e| e.decompose().0)
}
pub fn encode_rgba8_lossless(
img: ImgRef<Rgba<u8>>,
config: &LosslessConfig,
) -> Result<Vec<u8>, EncodeError> {
let (buf, w, h) = img.to_contiguous_buf();
let bytes: &[u8] = bytemuck::cast_slice(&buf);
config
.encode(bytes, w as u32, h as u32, PixelLayout::Rgba8)
.map_err(|e| e.decompose().0)
}
pub fn encode_bgra8_lossless(
img: ImgRef<BGRA<u8>>,
config: &LosslessConfig,
) -> Result<Vec<u8>, EncodeError> {
let (buf, w, h) = img.to_contiguous_buf();
let bytes: &[u8] = bytemuck::cast_slice(&buf);
config
.encode(bytes, w as u32, h as u32, PixelLayout::Bgra8)
.map_err(|e| e.decompose().0)
}
pub fn encode_gray8_lossless(
img: ImgRef<Gray<u8>>,
config: &LosslessConfig,
) -> Result<Vec<u8>, EncodeError> {
let (buf, w, h) = img.to_contiguous_buf();
let bytes: &[u8] = bytemuck::cast_slice(&buf);
config
.encode(bytes, w as u32, h as u32, PixelLayout::Gray8)
.map_err(|e| e.decompose().0)
}
pub(crate) fn gray_to_rgb_bytes(pixels: &[Gray<u8>]) -> Vec<u8> {
let mut bytes = Vec::with_capacity(pixels.len() * 3);
for g in pixels {
let v = g.value();
bytes.push(v);
bytes.push(v);
bytes.push(v);
}
bytes
}