use crate::{Boundary1d, Extent2};
#[doc = crate::_tags!(image layout)]
#[doc = crate::_doc_meta!{location("media/visual/image/raster")}]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct RasterLayout {
pub extent: Extent2<u32>,
pub row_start: Boundary1d,
pub bytes_per_pixel: u8,
pub bytes_per_line: usize,
}
impl RasterLayout {
pub const fn interleaved(
extent: Extent2<u32>,
bytes_per_pixel: u8,
bytes_per_line: usize,
row_start: Boundary1d,
) -> Self {
Self { extent, row_start, bytes_per_pixel, bytes_per_line }
}
pub const fn dense_interleaved(extent: Extent2<u32>, bytes_per_pixel: u8) -> Option<Self> {
let [w, _h] = extent.dim;
match (w as usize).checked_mul(bytes_per_pixel as usize) {
Some(bytes_per_line) => Some(Self {
extent,
row_start: Boundary1d::Upper,
bytes_per_pixel,
bytes_per_line,
}),
None => None,
}
}
pub const fn is_dense(self) -> bool {
let [w, _h] = self.extent.dim;
self.bytes_per_line == w as usize * self.bytes_per_pixel as usize
}
pub const fn bytes_per_line(self) -> Option<usize> {
Some(self.bytes_per_line)
}
pub const fn min_len_bytes(self) -> Option<usize> {
let [w, h] = self.extent.dim;
if h == 0 {
return Some(0);
}
let Some(row_used) = (w as usize).checked_mul(self.bytes_per_pixel as usize) else {
return None;
};
let Some(prior_rows) = (h as usize - 1).checked_mul(self.bytes_per_line) else {
return None;
};
prior_rows.checked_add(row_used)
}
}