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 Rgb48FrameError {
#[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 Rgb48Frame<'a, const BE: bool = false> {
rgb48: &'a [u16],
width: u32,
height: u32,
stride: u32,
}
pub type Rgb48LeFrame<'a> = Rgb48Frame<'a, false>;
pub type Rgb48BeFrame<'a> = Rgb48Frame<'a, true>;
impl<'a, const BE: bool> Rgb48Frame<'a, BE> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
rgb48: &'a [u16],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, Rgb48FrameError> {
if width == 0 || height == 0 {
return Err(Rgb48FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(3) {
Some(v) => v,
None => return Err(Rgb48FrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(Rgb48FrameError::InsufficientStride(
InsufficientStride::new(stride, min_stride),
));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Rgb48FrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if rgb48.len() < plane_min {
return Err(Rgb48FrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
rgb48.len(),
)));
}
Ok(Self {
rgb48,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(rgb48: &'a [u16], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(rgb48, width, height, stride) {
Ok(f) => f,
Err(_) => panic!("invalid Rgb48Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn rgb48(&self) -> &'a [u16] {
self.rgb48
}
#[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
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn is_be(&self) -> bool {
BE
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum Bgr48FrameError {
#[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 Bgr48Frame<'a, const BE: bool = false> {
bgr48: &'a [u16],
width: u32,
height: u32,
stride: u32,
}
pub type Bgr48LeFrame<'a> = Bgr48Frame<'a, false>;
pub type Bgr48BeFrame<'a> = Bgr48Frame<'a, true>;
impl<'a, const BE: bool> Bgr48Frame<'a, BE> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
bgr48: &'a [u16],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, Bgr48FrameError> {
if width == 0 || height == 0 {
return Err(Bgr48FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(3) {
Some(v) => v,
None => return Err(Bgr48FrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(Bgr48FrameError::InsufficientStride(
InsufficientStride::new(stride, min_stride),
));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Bgr48FrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if bgr48.len() < plane_min {
return Err(Bgr48FrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
bgr48.len(),
)));
}
Ok(Self {
bgr48,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(bgr48: &'a [u16], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(bgr48, width, height, stride) {
Ok(f) => f,
Err(_) => panic!("invalid Bgr48Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn bgr48(&self) -> &'a [u16] {
self.bgr48
}
#[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
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn is_be(&self) -> bool {
BE
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum Rgba64FrameError {
#[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 Rgba64Frame<'a, const BE: bool = false> {
rgba64: &'a [u16],
width: u32,
height: u32,
stride: u32,
}
pub type Rgba64LeFrame<'a> = Rgba64Frame<'a, false>;
pub type Rgba64BeFrame<'a> = Rgba64Frame<'a, true>;
impl<'a, const BE: bool> Rgba64Frame<'a, BE> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
rgba64: &'a [u16],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, Rgba64FrameError> {
if width == 0 || height == 0 {
return Err(Rgba64FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(4) {
Some(v) => v,
None => return Err(Rgba64FrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(Rgba64FrameError::InsufficientStride(
InsufficientStride::new(stride, min_stride),
));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Rgba64FrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if rgba64.len() < plane_min {
return Err(Rgba64FrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
rgba64.len(),
)));
}
Ok(Self {
rgba64,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(rgba64: &'a [u16], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(rgba64, width, height, stride) {
Ok(f) => f,
Err(_) => panic!("invalid Rgba64Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn rgba64(&self) -> &'a [u16] {
self.rgba64
}
#[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
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn is_be(&self) -> bool {
BE
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum Bgra64FrameError {
#[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 Bgra64Frame<'a, const BE: bool = false> {
bgra64: &'a [u16],
width: u32,
height: u32,
stride: u32,
}
pub type Bgra64LeFrame<'a> = Bgra64Frame<'a, false>;
pub type Bgra64BeFrame<'a> = Bgra64Frame<'a, true>;
impl<'a, const BE: bool> Bgra64Frame<'a, BE> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
bgra64: &'a [u16],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, Bgra64FrameError> {
if width == 0 || height == 0 {
return Err(Bgra64FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(4) {
Some(v) => v,
None => return Err(Bgra64FrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(Bgra64FrameError::InsufficientStride(
InsufficientStride::new(stride, min_stride),
));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Bgra64FrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if bgra64.len() < plane_min {
return Err(Bgra64FrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
bgra64.len(),
)));
}
Ok(Self {
bgra64,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(bgra64: &'a [u16], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(bgra64, width, height, stride) {
Ok(f) => f,
Err(_) => panic!("invalid Bgra64Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn bgra64(&self) -> &'a [u16] {
self.bgra64
}
#[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
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn is_be(&self) -> bool {
BE
}
}