use crate::{ImageBufferMutRef, ImageBufferRef, ImageData, ImageMutData, PixelFormat, Stride};
pub struct ImageRef<'a, FMT: PixelFormat> {
buf: &'a [u8],
width: u32,
height: u32,
stride: usize,
fmt: std::marker::PhantomData<FMT>,
}
impl<'a, FMT: PixelFormat> ImageRef<'a, FMT> {
pub fn new(width: u32, height: u32, stride: usize, buf: &'a [u8]) -> Option<Self> {
let fmt = crate::pixel_format::pixfmt::<FMT>().unwrap();
let min_stride = fmt.bits_per_pixel() as usize * width as usize / 8;
if height == 0 {
return None;
}
let sz = stride * (height as usize - 1) + min_stride;
if buf.len() < sz {
return None;
}
Some(Self {
width,
height,
stride,
buf,
fmt: std::marker::PhantomData,
})
}
}
impl<F: PixelFormat> std::fmt::Debug for ImageRef<'_, F> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_struct("ImageRef")
.field("fmt", &self.fmt)
.field("width", &self.width)
.field("height", &self.height)
.field("stride", &self.stride)
.finish_non_exhaustive()
}
}
impl<FMT: PixelFormat> ImageData<FMT> for ImageRef<'_, FMT> {
fn width(&self) -> u32 {
self.width
}
fn height(&self) -> u32 {
self.height
}
fn buffer_ref(&self) -> ImageBufferRef<'_, FMT> {
ImageBufferRef::new(self.buf)
}
#[cfg(any(feature = "std", feature = "alloc"))]
fn buffer(self) -> crate::ImageBuffer<FMT> {
self.buffer_ref().to_buffer()
}
}
impl<FMT: PixelFormat> Stride for ImageRef<'_, FMT> {
fn stride(&self) -> usize {
self.stride
}
}
pub struct ImageRefMut<'a, FMT: PixelFormat> {
buf: &'a mut [u8],
width: u32,
height: u32,
stride: usize,
fmt: std::marker::PhantomData<FMT>,
}
impl<'a, FMT: PixelFormat> ImageRefMut<'a, FMT> {
pub fn new(width: u32, height: u32, stride: usize, buf: &'a mut [u8]) -> Option<Self> {
let fmt = crate::pixel_format::pixfmt::<FMT>().unwrap();
let min_stride = fmt.bits_per_pixel() as usize * width as usize / 8;
if height == 0 {
return None;
}
let sz = stride * (height as usize - 1) + min_stride;
if buf.len() < sz {
return None;
}
Some(Self {
width,
height,
stride,
buf,
fmt: std::marker::PhantomData,
})
}
}
impl<F: PixelFormat> std::fmt::Debug for ImageRefMut<'_, F> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_struct("ImageRefMut")
.field("fmt", &self.fmt)
.field("width", &self.width)
.field("height", &self.height)
.field("stride", &self.stride)
.finish_non_exhaustive()
}
}
impl<FMT: PixelFormat> ImageData<FMT> for ImageRefMut<'_, FMT> {
fn width(&self) -> u32 {
self.width
}
fn height(&self) -> u32 {
self.height
}
fn buffer_ref(&self) -> ImageBufferRef<'_, FMT> {
ImageBufferRef::new(self.buf)
}
#[cfg(any(feature = "std", feature = "alloc"))]
fn buffer(self) -> crate::ImageBuffer<FMT> {
self.buffer_ref().to_buffer()
}
}
impl<FMT: PixelFormat> ImageMutData<FMT> for ImageRefMut<'_, FMT> {
fn buffer_mut_ref(&mut self) -> ImageBufferMutRef<'_, FMT> {
ImageBufferMutRef::new(self.buf)
}
}
impl<FMT: PixelFormat> Stride for ImageRefMut<'_, FMT> {
fn stride(&self) -> usize {
self.stride
}
}