use zeroize::Zeroize;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ColorSpace {
Rgb8,
Rgb16,
Rgba8,
Luma8,
}
impl ColorSpace {
pub fn bytes_per_pixel(&self) -> usize {
match self {
ColorSpace::Rgb8 => 3,
ColorSpace::Rgb16 => 6,
ColorSpace::Rgba8 => 4,
ColorSpace::Luma8 => 1,
}
}
pub fn has_explicit_red_channel(&self) -> bool {
match self {
ColorSpace::Rgb8 | ColorSpace::Rgb16 | ColorSpace::Rgba8 => true,
ColorSpace::Luma8 => false,
}
}
}
pub trait CoverSource {
fn dimensions(&self) -> (u32, u32);
fn pixels(&self) -> &[u8];
fn pixels_mut(&mut self) -> &mut [u8];
fn color_space(&self) -> ColorSpace;
fn pixel_count(&self) -> usize {
let (width, height) = self.dimensions();
width as usize * height as usize
}
fn pixel_offset(&self, x: u32, y: u32) -> usize {
let (width, _) = self.dimensions();
(y as usize * width as usize + x as usize) * self.color_space().bytes_per_pixel()
}
}
#[derive(Debug)]
pub struct ImageBuffer {
pixels: Vec<u8>,
width: u32,
height: u32,
color_space: ColorSpace,
}
impl ImageBuffer {
pub(crate) fn new(pixels: Vec<u8>, width: u32, height: u32, color_space: ColorSpace) -> Self {
Self {
pixels,
width,
height,
color_space,
}
}
}
impl CoverSource for ImageBuffer {
fn dimensions(&self) -> (u32, u32) {
(self.width, self.height)
}
fn pixels(&self) -> &[u8] {
&self.pixels
}
fn pixels_mut(&mut self) -> &mut [u8] {
&mut self.pixels
}
fn color_space(&self) -> ColorSpace {
self.color_space
}
}
impl Zeroize for ImageBuffer {
fn zeroize(&mut self) {
self.pixels.zeroize();
}
}