fast image operations
Diffstat (limited to 'src/dyn/mod.rs')
| -rw-r--r-- | src/dyn/mod.rs | 198 |
1 files changed, 0 insertions, 198 deletions
diff --git a/src/dyn/mod.rs b/src/dyn/mod.rs deleted file mode 100644 index c36a7c1..0000000 --- a/src/dyn/mod.rs +++ /dev/null @@ -1,198 +0,0 @@ -use crate::{Image, pixels::convert::PFrom}; -mod affine; -mod convert; -#[cfg(feature = "scale")] -mod scale; - -#[derive(Clone, Debug, PartialEq, Hash)] -/// Dynamic image. -/// Can be any of {`Y8`, `YA8`, `RGB8`, `RGB16`}. -pub enum DynImage<T> { - /// Y image - Y(Image<T, 1>), - /// YA image - Ya(Image<T, 2>), - /// RGB image - Rgb(Image<T, 3>), - /// RGBA image - Rgba(Image<T, 4>), -} - -impl Copy for DynImage<&[u8]> {} - -impl<T> const From<Image<T, 1>> for DynImage<T> { - fn from(x: Image<T, 1>) -> Self { - Self::Y(x) - } -} - -impl<T> const From<Image<T, 2>> for DynImage<T> { - fn from(x: Image<T, 2>) -> Self { - Self::Ya(x) - } -} - -impl<T> const From<Image<T, 3>> for DynImage<T> { - fn from(x: Image<T, 3>) -> Self { - Self::Rgb(x) - } -} - -impl<T> const From<Image<T, 4>> for DynImage<T> { - fn from(x: Image<T, 4>) -> Self { - Self::Rgba(x) - } -} - -macro_rules! e { - ($dyn:expr => |$image: pat_param| $do:expr) => { - match $dyn { - DynImage::Y($image) => DynImage::Y($do), - DynImage::Ya($image) => DynImage::Ya($do), - DynImage::Rgb($image) => DynImage::Rgb($do), - DynImage::Rgba($image) => DynImage::Rgba($do), - } - }; - ($dyn:expr, |$image: pat_param| $do:expr) => { - match $dyn { - DynImage::Y($image) => $do, - DynImage::Ya($image) => $do, - DynImage::Rgb($image) => $do, - DynImage::Rgba($image) => $do, - } - }; -} -pub(crate) use e; - -#[cfg(feature = "term")] -impl<T: AsRef<[u8]>> std::fmt::Display for crate::term::Display<DynImage<T>> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - e!(&self.0, |x| crate::term::Display(x.as_ref()).write(f)) - } -} - -#[cfg(feature = "term")] -impl<T: AsRef<[u8]>> std::fmt::Debug for crate::term::Display<DynImage<T>> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - e!(&self.0, |x| crate::term::Display(x.as_ref()).write(f)) - } -} - -#[cfg(feature = "term")] -impl<T: AsRef<[u8]>> std::fmt::Display for DynImage<T> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - e!(&self, |x| crate::term::Display(x.as_ref()).write(f)) - } -} - -impl<T> DynImage<T> { - /// Get the width of this image. - pub const fn width(&self) -> u32 { - e!(self, |i| i.width()) - } - - /// Get the height of this image. - pub const fn height(&self) -> u32 { - e!(self, |i| i.height()) - } - - #[doc(hidden)] - pub unsafe fn mapped<U, F: FnOnce(T) -> U>(self, f: F) -> DynImage<U> { - // SAFETY: we dont change anything, why check - unsafe { e!(self => |i| i.mapped(f)) } - } - - /// Get the image buffer. - pub const fn buffer(&self) -> &T { - e!(self, |i| i.buffer()) - } - - /// Take the image buffer. - pub fn take_buffer(self) -> T { - e!(self, |i| i.take_buffer()) - } -} - -impl DynImage<&[u8]> { - /// Copy this ref image - pub fn copy(&self) -> Self { - e!(self => |i| i.copy()) - } -} - -impl<T: AsRef<[u8]>> DynImage<T> { - /// Reference this image. - pub fn as_ref(&self) -> DynImage<&[u8]> { - e!(self => |i| i.as_ref()) - } - - /// Get a pixel, of a type. - /// ``` - /// # use fimg::{Image, DynImage}; - /// let i = DynImage::Rgb(Image::alloc(50, 50)); - /// assert_eq!(unsafe { i.pixel::<4>(25, 25) }, [0, 0, 0, 255]); - /// ``` - /// # Safety - /// - /// undefined behaviour if pixel is out of bounds. - pub unsafe fn pixel<const P: usize>(&self, x: u32, y: u32) -> [u8; P] - where - [u8; P]: PFrom<1>, - [u8; P]: PFrom<2>, - [u8; P]: PFrom<3>, - [u8; P]: PFrom<4>, - { - e!(self, |i| PFrom::pfrom(unsafe { *i.pixel(x, y) })) - } - - /// Bytes of this image. - pub fn bytes(&self) -> &[u8] { - e!(self, |i| i.bytes()) - } -} - -impl DynImage<Box<[u8]>> { - #[cfg(feature = "save")] - /// Open a PNG image - pub fn open(f: impl AsRef<std::path::Path>) -> Self { - use png::Transformations as T; - let p = std::fs::File::open(f).unwrap(); - let r = std::io::BufReader::new(p); - let mut dec = png::Decoder::new(r); - dec.set_transformations(T::STRIP_16 | T::EXPAND); - let mut reader = dec.read_info().unwrap(); - let mut buf = vec![0; reader.output_buffer_size().unwrap()].into_boxed_slice(); - let info = reader.next_frame(&mut buf).unwrap(); - use png::ColorType::*; - match info.color_type { - Indexed | Grayscale => Self::Y(Image::build(info.width, info.height).buf(buf)), - Rgb => Self::Rgb(Image::build(info.width, info.height).buf(buf)), - Rgba => Self::Rgba(Image::build(info.width, info.height).buf(buf)), - GrayscaleAlpha => Self::Ya(Image::build(info.width, info.height).buf(buf)), - } - } - - #[cfg(feature = "save")] - /// Save this image to a PNG. - pub fn save(&self, f: impl AsRef<std::path::Path>) { - let p = std::fs::File::create(f).unwrap(); - let w = &mut std::io::BufWriter::new(p); - let mut enc = png::Encoder::new(w, self.width(), self.height()); - enc.set_depth(png::BitDepth::Eight); - enc.set_color(match self { - Self::Y(_) => png::ColorType::Grayscale, - Self::Ya(_) => png::ColorType::GrayscaleAlpha, - Self::Rgb(_) => png::ColorType::Rgb, - Self::Rgba(_) => png::ColorType::Rgba, - }); - enc.set_source_gamma(png::ScaledFloat::new(1.0 / 2.2)); - enc.set_source_chromaticities(png::SourceChromaticities::new( - (0.31270, 0.32900), - (0.64000, 0.33000), - (0.30000, 0.60000), - (0.15000, 0.06000), - )); - let mut writer = enc.write_header().unwrap(); - writer.write_image_data(self.bytes()).unwrap(); - } -} |