firefly_rust/graphics/
image.rsuse crate::*;
pub struct Image<'a> {
pub(crate) raw: &'a [u8],
}
impl<'a> From<File<'a>> for Image<'a> {
fn from(value: File<'a>) -> Self {
Self { raw: value.raw }
}
}
#[cfg(feature = "alloc")]
impl<'a> From<&'a FileBuf> for Image<'a> {
fn from(value: &'a FileBuf) -> Self {
Self { raw: &value.raw }
}
}
impl<'a> From<Canvas<'a>> for Image<'a> {
fn from(value: Canvas<'a>) -> Self {
Self { raw: value.raw }
}
}
#[cfg(feature = "alloc")]
impl<'a> From<&'a CanvasBuf> for Image<'a> {
fn from(value: &'a CanvasBuf) -> Self {
Self { raw: &value.raw }
}
}
impl<'a> Image<'a> {
#[must_use]
pub const fn sub(&self, p: Point, s: Size) -> SubImage<'a> {
SubImage {
point: p,
size: s,
raw: self.raw,
}
}
#[must_use]
pub const fn bpp(&self) -> u8 {
self.raw[1]
}
#[must_use]
pub fn transparency(&self) -> Color {
let c = usize::from(self.raw[4]) + 1;
c.try_into().unwrap_or(Color::None)
}
#[must_use]
pub const fn pixels(&self) -> usize {
self.raw.len() * 8 / self.bpp() as usize
}
#[must_use]
pub fn width(&self) -> u16 {
let big = u16::from(self.raw[2]);
let little = u16::from(self.raw[3]);
big | (little << 8)
}
#[must_use]
pub fn height(&self) -> u16 {
let p = self.pixels();
let w = self.width() as usize;
p.checked_div(w).unwrap_or(0) as u16
}
#[must_use]
pub fn size(&self) -> Size {
Size {
width: i32::from(self.width()),
height: i32::from(self.height()),
}
}
#[must_use]
pub fn get_color(&self, p: u8) -> Color {
if p > 15 {
return Color::None;
}
let byte_idx = usize::from(5 + p / 2);
let mut byte_val = self.raw[byte_idx];
if p % 2 == 0 {
byte_val >>= 4;
}
byte_val &= 0b1111;
let transp = self.raw[4];
if byte_val == transp {
return Color::None;
}
let color_val = usize::from(byte_val + 1);
color_val.try_into().unwrap_or(Color::None)
}
}
#[expect(clippy::module_name_repetitions)]
pub struct SubImage<'a> {
pub(crate) point: Point,
pub(crate) size: Size,
pub(crate) raw: &'a [u8],
}