use super::{
GeometryOverflow, InsufficientPlane, InsufficientStride, WidthAlignment, 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 Yuyv422FrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
WidthAlignment(WidthAlignment),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct Yuyv422Frame<'a> {
yuyv: &'a [u8],
width: u32,
height: u32,
stride: u32,
}
impl<'a> Yuyv422Frame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
yuyv: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, Yuyv422FrameError> {
if width == 0 || height == 0 {
return Err(Yuyv422FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
if width & 1 != 0 {
return Err(Yuyv422FrameError::WidthAlignment(WidthAlignment::odd(
width as usize,
)));
}
let min_stride = match width.checked_mul(2) {
Some(v) => v,
None => return Err(Yuyv422FrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(Yuyv422FrameError::InsufficientStride(
InsufficientStride::new(stride, min_stride),
));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Yuyv422FrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if yuyv.len() < plane_min {
return Err(Yuyv422FrameError::InsufficientPlane(
InsufficientPlane::new(plane_min, yuyv.len()),
));
}
Ok(Self {
yuyv,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(yuyv: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(yuyv, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid Yuyv422Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn yuyv(&self) -> &'a [u8] {
self.yuyv
}
#[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 Uyvy422FrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
WidthAlignment(WidthAlignment),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct Uyvy422Frame<'a> {
uyvy: &'a [u8],
width: u32,
height: u32,
stride: u32,
}
impl<'a> Uyvy422Frame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
uyvy: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, Uyvy422FrameError> {
if width == 0 || height == 0 {
return Err(Uyvy422FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
if width & 1 != 0 {
return Err(Uyvy422FrameError::WidthAlignment(WidthAlignment::odd(
width as usize,
)));
}
let min_stride = match width.checked_mul(2) {
Some(v) => v,
None => return Err(Uyvy422FrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(Uyvy422FrameError::InsufficientStride(
InsufficientStride::new(stride, min_stride),
));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Uyvy422FrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if uyvy.len() < plane_min {
return Err(Uyvy422FrameError::InsufficientPlane(
InsufficientPlane::new(plane_min, uyvy.len()),
));
}
Ok(Self {
uyvy,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(uyvy: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(uyvy, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid Uyvy422Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn uyvy(&self) -> &'a [u8] {
self.uyvy
}
#[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 Yvyu422FrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
WidthAlignment(WidthAlignment),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct Yvyu422Frame<'a> {
yvyu: &'a [u8],
width: u32,
height: u32,
stride: u32,
}
impl<'a> Yvyu422Frame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
yvyu: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, Yvyu422FrameError> {
if width == 0 || height == 0 {
return Err(Yvyu422FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
if width & 1 != 0 {
return Err(Yvyu422FrameError::WidthAlignment(WidthAlignment::odd(
width as usize,
)));
}
let min_stride = match width.checked_mul(2) {
Some(v) => v,
None => return Err(Yvyu422FrameError::WidthOverflow(WidthOverflow::new(width))),
};
if stride < min_stride {
return Err(Yvyu422FrameError::InsufficientStride(
InsufficientStride::new(stride, min_stride),
));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Yvyu422FrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if yvyu.len() < plane_min {
return Err(Yvyu422FrameError::InsufficientPlane(
InsufficientPlane::new(plane_min, yvyu.len()),
));
}
Ok(Self {
yvyu,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(yvyu: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(yvyu, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid Yvyu422Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn yvyu(&self) -> &'a [u8] {
self.yvyu
}
#[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
}
}