use crate::{ColorSpace, ImageProps, PixelType};
use super::PipelineError;
#[derive(Debug, Clone, PartialEq)]
pub struct ImageSpec {
pub width: usize,
pub height: usize,
pub cspace: ColorSpace,
pub pixel_type: PixelType,
}
impl ImageSpec {
pub fn new(width: usize, height: usize, cspace: ColorSpace, pixel_type: PixelType) -> Self {
Self {
width,
height,
cspace,
pixel_type,
}
}
pub fn from_dynamic<I: ImageProps + ?Sized>(img: &I) -> Self {
Self {
width: img.width(),
height: img.height(),
cspace: img.color_space(),
pixel_type: img.pixel_type(),
}
}
pub fn elems(&self) -> usize {
self.width * self.height * self.cspace.channels() as usize
}
pub fn bytes(&self) -> Result<usize, PipelineError> {
Ok(self.elems() * pixel_size(self.pixel_type)?)
}
pub(super) fn bpp(&self) -> Result<usize, PipelineError> {
Ok(self.cspace.channels() as usize * pixel_size(self.pixel_type)?)
}
pub(super) fn tile_bytes(&self, rows: usize, cols: usize) -> Result<usize, PipelineError> {
Ok(rows * cols * self.bpp()?)
}
pub(super) fn validate(&self) -> Result<(), PipelineError> {
if self.width == 0 || self.height == 0 || self.width > 65535 || self.height > 65535 {
return Err(PipelineError::BadDimensions);
}
pixel_size(self.pixel_type)?;
Ok(())
}
}
pub(crate) fn pixel_size(pt: PixelType) -> Result<usize, PipelineError> {
match pt.storage() {
PixelType::U8 => Ok(1),
PixelType::U16 => Ok(2),
PixelType::F32 => Ok(4),
other => Err(PipelineError::UnsupportedPixelType(other)),
}
}