use super::{
GeometryOverflow, InsufficientPlane, InsufficientStride, WidthOverflow, ZeroDimension,
};
use derive_more::{IsVariant, TryUnwrap, Unwrap};
use thiserror::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum Rgb24FrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct Rgb24Frame<'a> {
rgb: &'a [u8],
width: u32,
height: u32,
stride: u32,
}
impl<'a> Rgb24Frame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
rgb: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, Rgb24FrameError> {
if width == 0 || height == 0 {
return Err(Rgb24FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(3) {
Some(v) => v,
None => return Err(Rgb24FrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(Rgb24FrameError::InsufficientStride(
InsufficientStride::new(stride, min_stride),
));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Rgb24FrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if rgb.len() < plane_min {
return Err(Rgb24FrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
rgb.len(),
)));
}
Ok(Self {
rgb,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(rgb: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(rgb, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid Rgb24Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn rgb(&self) -> &'a [u8] {
self.rgb
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn width(&self) -> u32 {
self.width
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn height(&self) -> u32 {
self.height
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn stride(&self) -> u32 {
self.stride
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum Bgr24FrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct Bgr24Frame<'a> {
bgr: &'a [u8],
width: u32,
height: u32,
stride: u32,
}
impl<'a> Bgr24Frame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
bgr: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, Bgr24FrameError> {
if width == 0 || height == 0 {
return Err(Bgr24FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(3) {
Some(v) => v,
None => return Err(Bgr24FrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(Bgr24FrameError::InsufficientStride(
InsufficientStride::new(stride, min_stride),
));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Bgr24FrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if bgr.len() < plane_min {
return Err(Bgr24FrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
bgr.len(),
)));
}
Ok(Self {
bgr,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(bgr: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(bgr, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid Bgr24Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn bgr(&self) -> &'a [u8] {
self.bgr
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn width(&self) -> u32 {
self.width
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn height(&self) -> u32 {
self.height
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn stride(&self) -> u32 {
self.stride
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum RgbaFrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct RgbaFrame<'a> {
rgba: &'a [u8],
width: u32,
height: u32,
stride: u32,
}
impl<'a> RgbaFrame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
rgba: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, RgbaFrameError> {
if width == 0 || height == 0 {
return Err(RgbaFrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(4) {
Some(v) => v,
None => return Err(RgbaFrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(RgbaFrameError::InsufficientStride(InsufficientStride::new(
stride, min_stride,
)));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(RgbaFrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if rgba.len() < plane_min {
return Err(RgbaFrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
rgba.len(),
)));
}
Ok(Self {
rgba,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(rgba: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(rgba, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid RgbaFrame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn rgba(&self) -> &'a [u8] {
self.rgba
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn width(&self) -> u32 {
self.width
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn height(&self) -> u32 {
self.height
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn stride(&self) -> u32 {
self.stride
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum BgraFrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct BgraFrame<'a> {
bgra: &'a [u8],
width: u32,
height: u32,
stride: u32,
}
impl<'a> BgraFrame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
bgra: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, BgraFrameError> {
if width == 0 || height == 0 {
return Err(BgraFrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(4) {
Some(v) => v,
None => return Err(BgraFrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(BgraFrameError::InsufficientStride(InsufficientStride::new(
stride, min_stride,
)));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(BgraFrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if bgra.len() < plane_min {
return Err(BgraFrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
bgra.len(),
)));
}
Ok(Self {
bgra,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(bgra: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(bgra, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid BgraFrame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn bgra(&self) -> &'a [u8] {
self.bgra
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn width(&self) -> u32 {
self.width
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn height(&self) -> u32 {
self.height
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn stride(&self) -> u32 {
self.stride
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum ArgbFrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct ArgbFrame<'a> {
argb: &'a [u8],
width: u32,
height: u32,
stride: u32,
}
impl<'a> ArgbFrame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
argb: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, ArgbFrameError> {
if width == 0 || height == 0 {
return Err(ArgbFrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(4) {
Some(v) => v,
None => return Err(ArgbFrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(ArgbFrameError::InsufficientStride(InsufficientStride::new(
stride, min_stride,
)));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(ArgbFrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if argb.len() < plane_min {
return Err(ArgbFrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
argb.len(),
)));
}
Ok(Self {
argb,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(argb: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(argb, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid ArgbFrame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn argb(&self) -> &'a [u8] {
self.argb
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn width(&self) -> u32 {
self.width
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn height(&self) -> u32 {
self.height
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn stride(&self) -> u32 {
self.stride
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum AbgrFrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct AbgrFrame<'a> {
abgr: &'a [u8],
width: u32,
height: u32,
stride: u32,
}
impl<'a> AbgrFrame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
abgr: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, AbgrFrameError> {
if width == 0 || height == 0 {
return Err(AbgrFrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(4) {
Some(v) => v,
None => return Err(AbgrFrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(AbgrFrameError::InsufficientStride(InsufficientStride::new(
stride, min_stride,
)));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(AbgrFrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if abgr.len() < plane_min {
return Err(AbgrFrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
abgr.len(),
)));
}
Ok(Self {
abgr,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(abgr: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(abgr, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid AbgrFrame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn abgr(&self) -> &'a [u8] {
self.abgr
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn width(&self) -> u32 {
self.width
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn height(&self) -> u32 {
self.height
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn stride(&self) -> u32 {
self.stride
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum XrgbFrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct XrgbFrame<'a> {
xrgb: &'a [u8],
width: u32,
height: u32,
stride: u32,
}
impl<'a> XrgbFrame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
xrgb: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, XrgbFrameError> {
if width == 0 || height == 0 {
return Err(XrgbFrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(4) {
Some(v) => v,
None => return Err(XrgbFrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(XrgbFrameError::InsufficientStride(InsufficientStride::new(
stride, min_stride,
)));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(XrgbFrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if xrgb.len() < plane_min {
return Err(XrgbFrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
xrgb.len(),
)));
}
Ok(Self {
xrgb,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(xrgb: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(xrgb, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid XrgbFrame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn xrgb(&self) -> &'a [u8] {
self.xrgb
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn width(&self) -> u32 {
self.width
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn height(&self) -> u32 {
self.height
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn stride(&self) -> u32 {
self.stride
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum RgbxFrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct RgbxFrame<'a> {
rgbx: &'a [u8],
width: u32,
height: u32,
stride: u32,
}
impl<'a> RgbxFrame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
rgbx: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, RgbxFrameError> {
if width == 0 || height == 0 {
return Err(RgbxFrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(4) {
Some(v) => v,
None => return Err(RgbxFrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(RgbxFrameError::InsufficientStride(InsufficientStride::new(
stride, min_stride,
)));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(RgbxFrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if rgbx.len() < plane_min {
return Err(RgbxFrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
rgbx.len(),
)));
}
Ok(Self {
rgbx,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(rgbx: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(rgbx, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid RgbxFrame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn rgbx(&self) -> &'a [u8] {
self.rgbx
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn width(&self) -> u32 {
self.width
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn height(&self) -> u32 {
self.height
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn stride(&self) -> u32 {
self.stride
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum XbgrFrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct XbgrFrame<'a> {
xbgr: &'a [u8],
width: u32,
height: u32,
stride: u32,
}
impl<'a> XbgrFrame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
xbgr: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, XbgrFrameError> {
if width == 0 || height == 0 {
return Err(XbgrFrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(4) {
Some(v) => v,
None => return Err(XbgrFrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(XbgrFrameError::InsufficientStride(InsufficientStride::new(
stride, min_stride,
)));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(XbgrFrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if xbgr.len() < plane_min {
return Err(XbgrFrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
xbgr.len(),
)));
}
Ok(Self {
xbgr,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(xbgr: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(xbgr, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid XbgrFrame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn xbgr(&self) -> &'a [u8] {
self.xbgr
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn width(&self) -> u32 {
self.width
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn height(&self) -> u32 {
self.height
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn stride(&self) -> u32 {
self.stride
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum BgrxFrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct BgrxFrame<'a> {
bgrx: &'a [u8],
width: u32,
height: u32,
stride: u32,
}
impl<'a> BgrxFrame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
bgrx: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, BgrxFrameError> {
if width == 0 || height == 0 {
return Err(BgrxFrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(4) {
Some(v) => v,
None => return Err(BgrxFrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(BgrxFrameError::InsufficientStride(InsufficientStride::new(
stride, min_stride,
)));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(BgrxFrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if bgrx.len() < plane_min {
return Err(BgrxFrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
bgrx.len(),
)));
}
Ok(Self {
bgrx,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(bgrx: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(bgrx, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid BgrxFrame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn bgrx(&self) -> &'a [u8] {
self.bgrx
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn width(&self) -> u32 {
self.width
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn height(&self) -> u32 {
self.height
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn stride(&self) -> u32 {
self.stride
}
}