use crate::*;
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(feature = "alloc")]
use alloc::vec;
#[cfg(feature = "alloc")]
pub struct CanvasBuf {
pub(crate) raw: Box<[u8]>,
}
#[cfg(feature = "alloc")]
impl CanvasBuf {
#[must_use]
#[expect(clippy::cast_sign_loss)]
pub fn new(s: Size) -> Self {
const HEADER_SIZE: usize = 4;
let body_size = s.width * s.height / 2;
let mut raw = vec![0; HEADER_SIZE + body_size as usize];
prepare_slice(&mut raw, s.width);
Self {
raw: raw.into_boxed_slice(),
}
}
#[must_use]
pub fn into_image(self) -> ImageBuf {
self.into()
}
}
#[cfg(feature = "alloc")]
impl Canvas for CanvasBuf {
unsafe fn as_bytes(&self) -> &[u8] {
&self.raw
}
}
pub struct CanvasRef<'a> {
pub(crate) raw: &'a [u8],
}
impl<'a> CanvasRef<'a> {
#[must_use]
#[expect(clippy::cast_sign_loss)]
pub fn new(s: Size, raw: &'a mut [u8]) -> Option<Self> {
const HEADER_SIZE: usize = 4;
let body_size = s.width * s.height / 2;
let exp_size = HEADER_SIZE + body_size as usize;
if raw.len() < exp_size {
return None;
}
prepare_slice(raw, s.width);
Some(Self {
raw: &raw[..exp_size],
})
}
#[must_use]
pub fn into_image(self) -> ImageRef<'a> {
self.into()
}
}
impl Canvas for CanvasRef<'_> {
unsafe fn as_bytes(&self) -> &[u8] {
self.raw
}
}
pub trait Canvas {
unsafe fn as_bytes(&self) -> &[u8];
}
#[expect(clippy::cast_sign_loss)]
const fn prepare_slice(raw: &mut [u8], width: i32) {
raw[0] = 0x22; raw[1] = width as u8; raw[2] = (width >> 8) as u8; raw[3] = 255; }
impl<T: Canvas> Image for T {
unsafe fn as_bytes(&self) -> &[u8] {
unsafe { Canvas::as_bytes(self) }
}
}