dimensions operator impls, pad image if it's too small

This commit is contained in:
Breval Ferrari 2025-03-14 23:54:22 -04:00
parent f4e8f7c276
commit 07f2a9fa38
No known key found for this signature in database
GPG key ID: F71E304D6400AB8E

View file

@ -1,6 +1,7 @@
use std::{
convert::Infallible,
ops::{Deref, DerefMut},
iter::once,
ops::{Add, Deref, DerefMut, Div, Mul, Sub},
};
pub use image::*;
@ -25,15 +26,96 @@ where
}
}
#[cfg_attr(debug_assertions, derive(Debug))]
pub struct Dimensions {
pub width: u32,
pub height: u32,
}
impl Div<Dimensions> for Dimensions {
type Output = Dimensions;
fn div(self, rhs: Dimensions) -> Self::Output {
Dimensions {
width: self.width / rhs.width,
height: self.height / rhs.height,
}
}
}
impl Div<u32> for Dimensions {
type Output = Dimensions;
fn div(self, rhs: u32) -> Self::Output {
Dimensions {
width: self.width / rhs,
height: self.height / rhs,
}
}
}
impl Mul<Dimensions> for Dimensions {
type Output = Dimensions;
fn mul(self, rhs: Dimensions) -> Self::Output {
Dimensions {
width: self.width * rhs.width,
height: self.height * rhs.height,
}
}
}
impl Mul<u32> for Dimensions {
type Output = Dimensions;
fn mul(self, rhs: u32) -> Self::Output {
Dimensions {
width: self.width * rhs,
height: self.height * rhs,
}
}
}
impl Add<Dimensions> for Dimensions {
type Output = Dimensions;
fn add(self, rhs: Dimensions) -> Self::Output {
Dimensions {
width: self.width + rhs.width,
height: self.height + rhs.height,
}
}
}
impl Add<u32> for Dimensions {
type Output = Dimensions;
fn add(self, rhs: u32) -> Self::Output {
Dimensions {
width: self.width + rhs,
height: self.height + rhs,
}
}
}
impl Sub<Dimensions> for Dimensions {
type Output = Dimensions;
fn sub(self, rhs: Dimensions) -> Self::Output {
Dimensions {
width: self.width - rhs.width,
height: self.height - rhs.height,
}
}
}
impl Sub<u32> for Dimensions {
type Output = Dimensions;
fn sub(self, rhs: u32) -> Self::Output {
Dimensions {
width: self.width - rhs,
height: self.height - rhs,
}
}
}
impl<P: Pixel> TryFromDataBytes for ImageBuffer<P, Vec<P::Subpixel>>
where
Vec<P::Subpixel>: Deref<Target = [P::Subpixel]>,
P::Subpixel: ToBytes + FromBytes,
P::Subpixel: ToBytes + FromBytes + Zero,
<P::Subpixel as FromBytes>::Bytes: for<'a> TryFrom<&'a [u8]>,
{
type Error = Infallible;
@ -50,6 +132,7 @@ where
format.width,
format.height,
match crop {
// TODO: separate outer crop from inner crop
crate::Crop::End => bytes
.chunks_exact(P::Subpixel::zero().to_ne_bytes().as_ref().len())
.map(|p| {
@ -60,6 +143,10 @@ where
},
)
})
.chain(once(P::Subpixel::zero()).cycle())
.take(
format.width as usize * format.height as usize * P::CHANNEL_COUNT as usize,
)
.collect::<Vec<P::Subpixel>>(),
crate::Crop::Start => bytes
.rchunks_exact(P::Subpixel::zero().to_ne_bytes().as_ref().len())
@ -71,6 +158,10 @@ where
},
)
})
.chain(once(P::Subpixel::zero()).cycle())
.take(
format.width as usize * format.height as usize * P::CHANNEL_COUNT as usize,
)
.collect::<Vec<P::Subpixel>>(),
},
)