float subpixel format support, more tests

This commit is contained in:
Breval Ferrari 2025-01-17 18:50:06 -05:00
parent 0d5532ab08
commit 1508a03717
No known key found for this signature in database
GPG key ID: CEAB625B75A836B2

View file

@ -1,7 +1,10 @@
use std::ops::{BitOr, Deref, DerefMut, Shl}; use std::ops::{Deref, DerefMut};
pub use image::*; pub use image::*;
use num::{traits::ToBytes, Zero}; use num::{
traits::{FromBytes, ToBytes},
Zero,
};
use rayon::iter::ParallelIterator; use rayon::iter::ParallelIterator;
use crate::{Bendable, IntoDataBytes, TryFromDataBytes}; use crate::{Bendable, IntoDataBytes, TryFromDataBytes};
@ -12,7 +15,7 @@ where
P::Subpixel: ToBytes, P::Subpixel: ToBytes,
{ {
fn into_bytes(self) -> crate::Bytes { fn into_bytes(self) -> crate::Bytes {
self.into_iter() self.iter()
.flat_map(|subpixel| subpixel.to_be_bytes().as_ref().to_vec()) .flat_map(|subpixel| subpixel.to_be_bytes().as_ref().to_vec())
.collect() .collect()
} }
@ -26,8 +29,8 @@ pub struct Dimensions {
impl<P: Pixel> TryFromDataBytes for ImageBuffer<P, Vec<P::Subpixel>> impl<P: Pixel> TryFromDataBytes for ImageBuffer<P, Vec<P::Subpixel>>
where where
Vec<P::Subpixel>: Deref<Target = [P::Subpixel]>, Vec<P::Subpixel>: Deref<Target = [P::Subpixel]>,
P::Subpixel: P::Subpixel: ToBytes + FromBytes,
ToBytes + Zero + Shl<u8, Output = P::Subpixel> + BitOr<P::Subpixel, Output = P::Subpixel>, <P::Subpixel as FromBytes>::Bytes: for<'a> TryFrom<&'a [u8]>,
{ {
type Error = (); type Error = ();
type Format = Dimensions; type Format = Dimensions;
@ -41,11 +44,12 @@ where
bytes bytes
.chunks_exact(P::Subpixel::zero().to_be_bytes().as_ref().len()) .chunks_exact(P::Subpixel::zero().to_be_bytes().as_ref().len())
.map(|p| { .map(|p| {
p.iter() P::Subpixel::from_be_bytes(
.copied() &match <P::Subpixel as FromBytes>::Bytes::try_from(p) {
.flat_map(num::traits::cast::<u8, P::Subpixel>) Ok(v) => v,
.reduce(|acc, b| (acc << 8u8) | b) Err(_) => unreachable!("you messed up chunk size!"),
.unwrap() },
)
}) })
.collect::<Vec<P::Subpixel>>(), .collect::<Vec<P::Subpixel>>(),
) )
@ -56,13 +60,9 @@ where
impl<P: Pixel> Bendable for ImageBuffer<P, Vec<P::Subpixel>> impl<P: Pixel> Bendable for ImageBuffer<P, Vec<P::Subpixel>>
where where
Vec<P::Subpixel>: Deref<Target = [P::Subpixel]> + DerefMut, Vec<P::Subpixel>: Deref<Target = [P::Subpixel]> + DerefMut,
P::Subpixel: ToBytes P::Subpixel: ToBytes + FromBytes + Send + Sync,
+ Zero <P::Subpixel as FromBytes>::Bytes: for<'a> TryFrom<&'a [u8]>,
+ Shl<u8, Output = P::Subpixel> P: Send + Sync,
+ BitOr<P::Subpixel, Output = P::Subpixel>
+ Send
+ Sync,
P: Pixel + Send + Sync,
{ {
type Unit = P; type Unit = P;
fn apply<F: Fn(&Self::Unit) -> Self::Unit + Sync>(mut self, f: F) -> Self { fn apply<F: Fn(&Self::Unit) -> Self::Unit + Sync>(mut self, f: F) -> Self {
@ -75,7 +75,10 @@ where
mod tests { mod tests {
#[cfg(test)] #[cfg(test)]
mod ser_de { mod ser_de {
use super::super::{Dimensions, IntoDataBytes, RgbImage, TryFromDataBytes}; use super::super::{
Dimensions, ImageBuffer, IntoDataBytes, Rgb, Rgb32FImage, RgbImage, RgbaImage,
TryFromDataBytes,
};
#[test] #[test]
fn empty() { fn empty() {
@ -106,5 +109,81 @@ mod tests {
) )
) )
} }
#[test]
fn rgba() {
let image =
RgbaImage::from_raw(3, 1, vec![1, 2, 3, 0, 4, 5, 6, 1, 7, 8, 9, 2]).unwrap();
assert_eq!(
Ok(image.clone()),
RgbaImage::try_from_bytes(
image.into_bytes(),
Dimensions {
width: 3,
height: 1
}
)
)
}
#[test]
fn rgb_u16() {
let image = ImageBuffer::<Rgb<u16>, Vec<u16>>::from_raw(
3,
1,
vec![1, 2, 3, 254, 255, 256, 307, 308, 309],
)
.unwrap();
assert_eq!(
Ok(image.clone()),
ImageBuffer::<Rgb<u16>, Vec<u16>>::try_from_bytes(
image.into_bytes(),
Dimensions {
width: 3,
height: 1
}
)
)
}
#[test]
fn rgb_signed() {
let image = ImageBuffer::<Rgb<i16>, Vec<i16>>::from_raw(
3,
1,
vec![1, 2, 3, 254, 255, 256, -307, 308, 309],
)
.unwrap();
assert_eq!(
Ok(image.clone()),
ImageBuffer::<Rgb<i16>, Vec<i16>>::try_from_bytes(
image.into_bytes(),
Dimensions {
width: 3,
height: 1
}
)
)
}
#[test]
fn rgb_f32() {
let image = Rgb32FImage::from_raw(
3,
1,
vec![1.0, 2.0, 3.0, 254.0, 255.0, 256.1, 307.0, 308.0, 309.0],
)
.unwrap();
assert_eq!(
Ok(image.clone()),
Rgb32FImage::try_from_bytes(
image.into_bytes(),
Dimensions {
width: 3,
height: 1
}
)
)
}
} }
} }