fast image operations
Diffstat (limited to 'src/overlay.rs')
| -rw-r--r-- | src/overlay.rs | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/overlay.rs b/src/overlay.rs index 3dbc45e..eb7ac29 100644 --- a/src/overlay.rs +++ b/src/overlay.rs @@ -1,4 +1,6 @@ //! Handles image overlay +use crate::cloner::ImageCloner; + use super::{assert_unchecked, really_unsafe_index, Image}; use std::simd::SimdInt; use std::simd::SimdPartialOrd; @@ -12,6 +14,16 @@ pub trait OverlayAt<W> { /// UB if x, y is out of bounds unsafe fn overlay_at(&mut self, with: &W, x: u32, y: u32) -> &mut Self; } + +/// [`OverlayAt`] but owned +pub trait ClonerOverlayAt<const W: usize, const C: usize> { + /// Overlay with => self at coordinates x, y, without blending, and returning a new image. + /// # Safety + /// + /// UB if x, y is out of bounds + unsafe fn overlay_at(&self, with: &Image<&[u8], W>, x: u32, y: u32) -> Image<Vec<u8>, C>; +} + /// Trait for layering images ontop of each other. /// Think `magick a b -layers flatten a` pub trait Overlay<W> { @@ -22,6 +34,15 @@ pub trait Overlay<W> { unsafe fn overlay(&mut self, with: &W) -> &mut Self; } +/// [`Overlay`] but owned +pub trait ClonerOverlay<const W: usize, const C: usize> { + /// Overlay with => self (does not blend) + /// # Safety + /// + /// UB if a.width != b.width || a.height != b.height + unsafe fn overlay(&self, with: &Image<&[u8], W>) -> Image<Vec<u8>, C>; +} + #[inline] /// SIMD accelerated rgba => rgb overlay. /// @@ -88,6 +109,16 @@ impl Overlay<Image<&[u8], 4>> for Image<&mut [u8], 4> { } } +impl ClonerOverlay<4, 4> for ImageCloner<'_, 4> { + #[inline] + unsafe fn overlay(&self, with: &Image<&[u8], 4>) -> Image<Vec<u8>, 4> { + let mut out = self.dup(); + // SAFETY: same + unsafe { out.as_mut().overlay(with) }; + out + } +} + impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 3> { #[inline] unsafe fn overlay_at(&mut self, with: &Image<&[u8], 4>, x: u32, y: u32) -> &mut Self { @@ -113,6 +144,15 @@ impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 3> { } } +impl ClonerOverlayAt<4, 3> for ImageCloner<'_, 3> { + unsafe fn overlay_at(&self, with: &Image<&[u8], 4>, x: u32, y: u32) -> Image<Vec<u8>, 3> { + let mut new = self.dup(); + // SAFETY: same + unsafe { new.as_mut().overlay_at(with, x, y) }; + new + } +} + impl OverlayAt<Image<&[u8], 3>> for Image<&mut [u8], 3> { /// Overlay a RGB image(with) => self at coordinates x, y. /// As this is a `RGBxRGB` operation, blending is unnecessary, @@ -175,6 +215,16 @@ impl Overlay<Image<&[u8], 4>> for Image<&mut [u8], 3> { } } +impl ClonerOverlay<4, 3> for ImageCloner<'_, 3> { + #[inline] + unsafe fn overlay(&self, with: &Image<&[u8], 4>) -> Image<Vec<u8>, 3> { + let mut out = self.dup(); + // SAFETY: same + unsafe { out.as_mut().overlay(with) }; + out + } +} + impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 4> { #[inline] /// Overlay with => self at coordinates x, y, without blending @@ -210,3 +260,19 @@ impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 4> { self } } + +impl ClonerOverlayAt<4, 4> for ImageCloner<'_, 4> { + #[inline] + /// Overlay with => self at coordinates x, y, without blending, returning a new Image + /// + /// # Safety + /// - UB if x, y is out of bounds + /// - UB if x + with.width() > [`u32::MAX`] + /// - UB if y + with.height() > [`u32::MAX`] + unsafe fn overlay_at(&self, with: &Image<&[u8], 4>, x: u32, y: u32) -> Image<Vec<u8>, 4> { + let mut out = self.dup(); + // SAFETY: same + unsafe { out.as_mut().overlay_at(with, x, y) }; + out + } +} |