#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
#[repr(u8)]
#[allow(
clippy::exhaustive_enums,
reason = "a closed set: there is no further variant to add"
)]
pub enum MapAccess {
Read = 0,
Write = 1,
#[default]
ReadWrite = 2,
}
#[derive(Debug)]
pub struct Mapping<'a> {
pixels: &'a mut [u8],
stride: u32,
width: u32,
height: u32,
access: MapAccess,
}
impl<'a> Mapping<'a> {
pub(crate) fn new(
pixels: &'a mut [u8],
stride: u32,
width: u32,
height: u32,
access: MapAccess,
) -> Self {
Self {
pixels,
stride,
width,
height,
access,
}
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.pixels.is_empty()
}
#[must_use]
pub const fn pixels(&self) -> &[u8] {
self.pixels
}
#[must_use]
pub const fn pixels_mut(&mut self) -> &mut [u8] {
self.pixels
}
#[must_use]
pub const fn stride(&self) -> u32 {
self.stride
}
#[must_use]
pub const fn width(&self) -> u32 {
self.width
}
#[must_use]
pub const fn height(&self) -> u32 {
self.height
}
#[must_use]
pub const fn access(&self) -> MapAccess {
self.access
}
#[must_use]
pub fn row(&self, row: u32) -> Option<&[u8]> {
let (start, end) = self.row_range(row)?;
self.pixels.get(start..end)
}
#[must_use]
pub fn row_mut(&mut self, row: u32) -> Option<&mut [u8]> {
let (start, end) = self.row_range(row)?;
self.pixels.get_mut(start..end)
}
fn row_range(&self, row: u32) -> Option<(usize, usize)> {
if row >= self.height {
return None;
}
let stride = self.stride as usize;
let start = (row as usize).checked_mul(stride)?;
Some((start, start.checked_add(stride)?))
}
}