use crate::Size;
use std::mem;
pub fn from_rgba(
rgba: Vec<u8>,
width: u32,
height: u32,
) -> Result<Icon, Error> {
const PIXEL_SIZE: usize = mem::size_of::<u8>() * 4;
if rgba.len() % PIXEL_SIZE != 0 {
return Err(Error::ByteCountNotDivisibleBy4 {
byte_count: rgba.len(),
});
}
let pixel_count = rgba.len() / PIXEL_SIZE;
if pixel_count != (width * height) as usize {
return Err(Error::DimensionsVsPixelCount {
width,
height,
width_x_height: (width * height) as usize,
pixel_count,
});
}
Ok(Icon {
rgba,
size: Size::new(width, height),
})
}
#[derive(Debug, Clone)]
pub struct Icon {
rgba: Vec<u8>,
size: Size<u32>,
}
impl Icon {
pub fn into_raw(self) -> (Vec<u8>, Size<u32>) {
(self.rgba, self.size)
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(
"The provided RGBA data (with length {byte_count}) isn't divisible \
by 4. Therefore, it cannot be safely interpreted as 32bpp RGBA pixels"
)]
ByteCountNotDivisibleBy4 {
byte_count: usize,
},
#[error(
"The number of RGBA pixels ({pixel_count}) does not match the \
provided dimensions ({width}x{height})."
)]
DimensionsVsPixelCount {
width: u32,
height: u32,
width_x_height: usize,
pixel_count: usize,
},
}