use crate::{
image_ref::ImageRef, owned::OImage, ImageBuffer, ImageBufferRef, ImageData, PixelFormat, Stride,
};
pub enum CowImage<'a, F: PixelFormat> {
Borrowed(ImageRef<'a, F>),
Owned(OImage<F>),
}
impl<'a, F: PixelFormat> CowImage<'a, F> {
pub fn owned(self) -> OImage<F> {
match self {
CowImage::Borrowed(im) => {
let w = im.width();
let h = im.height();
let s = im.stride();
let buf = im.buffer();
crate::owned::OImage::new(w, h, s, buf.data).unwrap()
}
CowImage::Owned(im) => im,
}
}
}
impl<'a, F: PixelFormat> From<ImageRef<'a, F>> for CowImage<'a, F> {
fn from(frame: ImageRef<'a, F>) -> CowImage<'a, F> {
CowImage::Borrowed(frame)
}
}
impl<'a, F: PixelFormat> From<OImage<F>> for CowImage<'a, F> {
fn from(frame: OImage<F>) -> CowImage<'a, F> {
CowImage::Owned(frame)
}
}
impl<F: PixelFormat> Stride for CowImage<'_, F> {
fn stride(&self) -> usize {
match self {
CowImage::Borrowed(im) => im.stride(),
CowImage::Owned(im) => im.stride(),
}
}
}
impl<F: PixelFormat> ImageData<F> for CowImage<'_, F> {
fn width(&self) -> u32 {
match self {
CowImage::Borrowed(im) => im.width(),
CowImage::Owned(im) => im.width(),
}
}
fn height(&self) -> u32 {
match self {
CowImage::Borrowed(im) => im.height(),
CowImage::Owned(im) => im.height(),
}
}
fn buffer_ref(&self) -> ImageBufferRef<'_, F> {
let image_data = match self {
CowImage::Borrowed(im) => im.image_data(),
CowImage::Owned(im) => im.image_data(),
};
ImageBufferRef::new(image_data)
}
fn buffer(self) -> ImageBuffer<F> {
match self {
CowImage::Borrowed(im) => ImageBuffer::new(im.image_data().to_vec()),
CowImage::Owned(im) => ImageBuffer::new(im.into()),
}
}
}