use super::{
GeometryOverflow, InsufficientPlane, InsufficientStride, UnsupportedBits, WidthOverflow,
ZeroDimension,
};
use derive_more::{IsVariant, TryUnwrap, Unwrap};
use thiserror::Error;
#[derive(Debug, Clone, Copy)]
pub struct Gray8Frame<'a> {
y: &'a [u8],
width: u32,
height: u32,
y_stride: u32,
}
impl<'a> Gray8Frame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
y: &'a [u8],
width: u32,
height: u32,
y_stride: u32,
) -> Result<Self, Gray8FrameError> {
if width == 0 || height == 0 {
return Err(Gray8FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
if y_stride < width {
return Err(Gray8FrameError::InsufficientYStride(
InsufficientStride::new(y_stride, width),
));
}
let y_min = match (y_stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Gray8FrameError::GeometryOverflow(GeometryOverflow::new(
y_stride, height,
)));
}
};
if y.len() < y_min {
return Err(Gray8FrameError::InsufficientYPlane(InsufficientPlane::new(
y_min,
y.len(),
)));
}
Ok(Self {
y,
width,
height,
y_stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(y: &'a [u8], width: u32, height: u32, y_stride: u32) -> Self {
match Self::try_new(y, width, height, y_stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid Gray8Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn y(&self) -> &'a [u8] {
self.y
}
#[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 y_stride(&self) -> u32 {
self.y_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 Gray8FrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientYStride(InsufficientStride),
#[error(transparent)]
InsufficientYPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct GrayNFrame<'a, const BITS: u32, const BE: bool = false> {
y: &'a [u16],
width: u32,
height: u32,
y_stride: u32,
}
impl<'a, const BITS: u32, const BE: bool> GrayNFrame<'a, BITS, BE> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
y: &'a [u16],
width: u32,
height: u32,
y_stride: u32,
) -> Result<Self, GrayNFrameError> {
if BITS != 9 && BITS != 10 && BITS != 12 && BITS != 14 {
return Err(GrayNFrameError::UnsupportedBits(UnsupportedBits::new(BITS)));
}
if width == 0 || height == 0 {
return Err(GrayNFrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
if y_stride < width {
return Err(GrayNFrameError::InsufficientYStride(
InsufficientStride::new(y_stride, width),
));
}
let y_min = match (y_stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(GrayNFrameError::GeometryOverflow(GeometryOverflow::new(
y_stride, height,
)));
}
};
if y.len() < y_min {
return Err(GrayNFrameError::InsufficientYPlane(InsufficientPlane::new(
y_min,
y.len(),
)));
}
Ok(Self {
y,
width,
height,
y_stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(y: &'a [u16], width: u32, height: u32, y_stride: u32) -> Self {
match Self::try_new(y, width, height, y_stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid GrayNFrame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn y(&self) -> &'a [u16] {
self.y
}
#[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 y_stride(&self) -> u32 {
self.y_stride
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn is_be(&self) -> bool {
BE
}
}
pub type Gray9Frame<'a, const BE: bool = false> = GrayNFrame<'a, 9, BE>;
pub type Gray10Frame<'a, const BE: bool = false> = GrayNFrame<'a, 10, BE>;
pub type Gray12Frame<'a, const BE: bool = false> = GrayNFrame<'a, 12, BE>;
pub type Gray14Frame<'a, const BE: bool = false> = GrayNFrame<'a, 14, BE>;
pub type Gray9LeFrame<'a> = GrayNFrame<'a, 9, false>;
pub type Gray9BeFrame<'a> = GrayNFrame<'a, 9, true>;
pub type Gray10LeFrame<'a> = GrayNFrame<'a, 10, false>;
pub type Gray10BeFrame<'a> = GrayNFrame<'a, 10, true>;
pub type Gray12LeFrame<'a> = GrayNFrame<'a, 12, false>;
pub type Gray12BeFrame<'a> = GrayNFrame<'a, 12, true>;
pub type Gray14LeFrame<'a> = GrayNFrame<'a, 14, false>;
pub type Gray14BeFrame<'a> = GrayNFrame<'a, 14, true>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, TryUnwrap, Unwrap, Error)]
#[non_exhaustive]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum GrayNFrameError {
#[error(transparent)]
UnsupportedBits(UnsupportedBits),
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientYStride(InsufficientStride),
#[error(transparent)]
InsufficientYPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct Gray16Frame<'a, const BE: bool = false> {
y: &'a [u16],
width: u32,
height: u32,
y_stride: u32,
}
pub type Gray16LeFrame<'a> = Gray16Frame<'a, false>;
pub type Gray16BeFrame<'a> = Gray16Frame<'a, true>;
impl<'a, const BE: bool> Gray16Frame<'a, BE> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
y: &'a [u16],
width: u32,
height: u32,
y_stride: u32,
) -> Result<Self, Gray16FrameError> {
if width == 0 || height == 0 {
return Err(Gray16FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
if y_stride < width {
return Err(Gray16FrameError::InsufficientYStride(
InsufficientStride::new(y_stride, width),
));
}
let y_min = match (y_stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Gray16FrameError::GeometryOverflow(GeometryOverflow::new(
y_stride, height,
)));
}
};
if y.len() < y_min {
return Err(Gray16FrameError::InsufficientYPlane(
InsufficientPlane::new(y_min, y.len()),
));
}
Ok(Self {
y,
width,
height,
y_stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(y: &'a [u16], width: u32, height: u32, y_stride: u32) -> Self {
match Self::try_new(y, width, height, y_stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid Gray16Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn y(&self) -> &'a [u16] {
self.y
}
#[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 y_stride(&self) -> u32 {
self.y_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 Gray16FrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientYStride(InsufficientStride),
#[error(transparent)]
InsufficientYPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct Grayf32Frame<'a, const BE: bool = false> {
y: &'a [f32],
width: u32,
height: u32,
y_stride: u32, }
pub type Grayf32LeFrame<'a> = Grayf32Frame<'a, false>;
pub type Grayf32BeFrame<'a> = Grayf32Frame<'a, true>;
impl<'a, const BE: bool> Grayf32Frame<'a, BE> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
y: &'a [f32],
width: u32,
height: u32,
y_stride: u32,
) -> Result<Self, Grayf32FrameError> {
if width == 0 || height == 0 {
return Err(Grayf32FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
if y_stride < width {
return Err(Grayf32FrameError::InsufficientYStride(
InsufficientStride::new(y_stride, width),
));
}
let y_min = match (y_stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Grayf32FrameError::GeometryOverflow(GeometryOverflow::new(
y_stride, height,
)));
}
};
if y.len() < y_min {
return Err(Grayf32FrameError::InsufficientYPlane(
InsufficientPlane::new(y_min, y.len()),
));
}
Ok(Self {
y,
width,
height,
y_stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(y: &'a [f32], width: u32, height: u32, y_stride: u32) -> Self {
match Self::try_new(y, width, height, y_stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid Grayf32Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn y(&self) -> &'a [f32] {
self.y
}
#[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 y_stride(&self) -> u32 {
self.y_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 Grayf32FrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientYStride(InsufficientStride),
#[error(transparent)]
InsufficientYPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
}
#[derive(Debug, Clone, Copy)]
pub struct Ya8Frame<'a> {
packed: &'a [u8],
width: u32,
height: u32,
stride: u32, }
impl<'a> Ya8Frame<'a> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
packed: &'a [u8],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, Ya8FrameError> {
if width == 0 || height == 0 {
return Err(Ya8FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(2) {
Some(v) => v,
None => {
return Err(Ya8FrameError::WidthOverflow(WidthOverflow::new(width)));
}
};
if stride < min_stride {
return Err(Ya8FrameError::InsufficientStride(InsufficientStride::new(
stride, min_stride,
)));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Ya8FrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if packed.len() < plane_min {
return Err(Ya8FrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
packed.len(),
)));
}
Ok(Self {
packed,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(packed: &'a [u8], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(packed, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid Ya8Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn packed(&self) -> &'a [u8] {
self.packed
}
#[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 Ya8FrameError {
#[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 Ya16Frame<'a, const BE: bool = false> {
packed: &'a [u16],
width: u32,
height: u32,
stride: u32, }
pub type Ya16LeFrame<'a> = Ya16Frame<'a, false>;
pub type Ya16BeFrame<'a> = Ya16Frame<'a, true>;
impl<'a, const BE: bool> Ya16Frame<'a, BE> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn try_new(
packed: &'a [u16],
width: u32,
height: u32,
stride: u32,
) -> Result<Self, Ya16FrameError> {
if width == 0 || height == 0 {
return Err(Ya16FrameError::ZeroDimension(ZeroDimension::new(
width, height,
)));
}
let min_stride = match width.checked_mul(2) {
Some(v) => v,
None => {
return Err(Ya16FrameError::WidthOverflow(WidthOverflow::new(width)));
}
};
if stride < min_stride {
return Err(Ya16FrameError::InsufficientStride(InsufficientStride::new(
stride, min_stride,
)));
}
let plane_min = match (stride as usize).checked_mul(height as usize) {
Some(v) => v,
None => {
return Err(Ya16FrameError::GeometryOverflow(GeometryOverflow::new(
stride, height,
)));
}
};
if packed.len() < plane_min {
return Err(Ya16FrameError::InsufficientPlane(InsufficientPlane::new(
plane_min,
packed.len(),
)));
}
Ok(Self {
packed,
width,
height,
stride,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(packed: &'a [u16], width: u32, height: u32, stride: u32) -> Self {
match Self::try_new(packed, width, height, stride) {
Ok(frame) => frame,
Err(_) => panic!("invalid Ya16Frame dimensions or plane length"),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn packed(&self) -> &'a [u16] {
self.packed
}
#[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 Ya16FrameError {
#[error(transparent)]
ZeroDimension(ZeroDimension),
#[error(transparent)]
InsufficientStride(InsufficientStride),
#[error(transparent)]
InsufficientPlane(InsufficientPlane),
#[error(transparent)]
GeometryOverflow(GeometryOverflow),
#[error(transparent)]
WidthOverflow(WidthOverflow),
}