diff --git a/bingus/src/img/image.rs b/bingus/src/img/image.rs index 4496cd5..bfcbe95 100644 --- a/bingus/src/img/image.rs +++ b/bingus/src/img/image.rs @@ -1,7 +1,10 @@ -use std::ops::{BitOr, Deref, DerefMut, Shl}; +use std::ops::{Deref, DerefMut}; pub use image::*; -use num::{traits::ToBytes, Zero}; +use num::{ + traits::{FromBytes, ToBytes}, + Zero, +}; use rayon::iter::ParallelIterator; use crate::{Bendable, IntoDataBytes, TryFromDataBytes}; @@ -12,7 +15,7 @@ where P::Subpixel: ToBytes, { fn into_bytes(self) -> crate::Bytes { - self.into_iter() + self.iter() .flat_map(|subpixel| subpixel.to_be_bytes().as_ref().to_vec()) .collect() } @@ -26,8 +29,8 @@ pub struct Dimensions { impl TryFromDataBytes for ImageBuffer> where Vec: Deref, - P::Subpixel: - ToBytes + Zero + Shl + BitOr, + P::Subpixel: ToBytes + FromBytes, + ::Bytes: for<'a> TryFrom<&'a [u8]>, { type Error = (); type Format = Dimensions; @@ -41,11 +44,12 @@ where bytes .chunks_exact(P::Subpixel::zero().to_be_bytes().as_ref().len()) .map(|p| { - p.iter() - .copied() - .flat_map(num::traits::cast::) - .reduce(|acc, b| (acc << 8u8) | b) - .unwrap() + P::Subpixel::from_be_bytes( + &match ::Bytes::try_from(p) { + Ok(v) => v, + Err(_) => unreachable!("you messed up chunk size!"), + }, + ) }) .collect::>(), ) @@ -56,13 +60,9 @@ where impl Bendable for ImageBuffer> where Vec: Deref + DerefMut, - P::Subpixel: ToBytes - + Zero - + Shl - + BitOr - + Send - + Sync, - P: Pixel + Send + Sync, + P::Subpixel: ToBytes + FromBytes + Send + Sync, + ::Bytes: for<'a> TryFrom<&'a [u8]>, + P: Send + Sync, { type Unit = P; fn apply Self::Unit + Sync>(mut self, f: F) -> Self { @@ -75,7 +75,10 @@ where mod tests { #[cfg(test)] mod ser_de { - use super::super::{Dimensions, IntoDataBytes, RgbImage, TryFromDataBytes}; + use super::super::{ + Dimensions, ImageBuffer, IntoDataBytes, Rgb, Rgb32FImage, RgbImage, RgbaImage, + TryFromDataBytes, + }; #[test] 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::, Vec>::from_raw( + 3, + 1, + vec![1, 2, 3, 254, 255, 256, 307, 308, 309], + ) + .unwrap(); + assert_eq!( + Ok(image.clone()), + ImageBuffer::, Vec>::try_from_bytes( + image.into_bytes(), + Dimensions { + width: 3, + height: 1 + } + ) + ) + } + + #[test] + fn rgb_signed() { + let image = ImageBuffer::, Vec>::from_raw( + 3, + 1, + vec![1, 2, 3, 254, 255, 256, -307, 308, 309], + ) + .unwrap(); + assert_eq!( + Ok(image.clone()), + ImageBuffer::, Vec>::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 + } + ) + ) + } } }