fast image operations
Diffstat (limited to 'src/overlay.rs')
| -rw-r--r-- | src/overlay.rs | 120 |
1 files changed, 119 insertions, 1 deletions
diff --git a/src/overlay.rs b/src/overlay.rs index 08f3caf..3027808 100644 --- a/src/overlay.rs +++ b/src/overlay.rs @@ -1,6 +1,6 @@ //! Handles image overlay // TODO Y/YA -use crate::{cloner::ImageCloner, uninit}; +use crate::{DynImage, cloner::ImageCloner, uninit}; use super::{Image, assert_unchecked}; use crate::pixels::Blend; @@ -278,6 +278,95 @@ impl<U: AsRef<[u8]>> OverlayAt<Image<U, 3>> for uninit::Image<u8, 3> { } } +impl<T: AsMut<[u8]> + AsRef<[u8]>, U: AsRef<[u8]>> OverlayAt<Image<U, 1>> for Image<T, 3> { + #[inline] + #[cfg_attr(debug_assertions, track_caller)] + /// this impl doesnt make much sense without a color. + unsafe fn overlay_at(&mut self, with: &Image<U, 1>, x: u32, y: u32) -> &mut Self { + for j in 0..with.height() { + for i in 0..with.width() { + // SAFETY: i, j is in bounds. + let &[their_px] = unsafe { &with.pixel(i, j) }; + let our_px = unsafe { self.pixel_mut(i + x, j + y) }; + our_px.copy_from_slice(&[their_px; 3]); + } + } + self + } +} + +impl<T: AsMut<[u8]> + AsRef<[u8]>, U: AsRef<[u8]>> OverlayAt<Image<U, 2>> for Image<T, 3> { + #[inline] + #[cfg_attr(debug_assertions, track_caller)] + /// this impl doesnt make much sense without a color. + unsafe fn overlay_at(&mut self, with: &Image<U, 2>, x: u32, y: u32) -> &mut Self { + for j in 0..with.height() { + for i in 0..with.width() { + // SAFETY: i, j is in bounds. + let &[their_px, a] = unsafe { &with.pixel(i, j) }; + if a >= 128 { + let our_px = unsafe { self.pixel_mut(i + x, j + y) }; + our_px.copy_from_slice(&[their_px; 3]); + } + } + } + self + } +} + +impl<T: AsMut<[u8]> + AsRef<[u8]>, U: AsRef<[u8]>> OverlayAt<Image<U, 1>> for Image<T, 4> { + #[inline] + #[cfg_attr(debug_assertions, track_caller)] + /// this impl doesnt make much sense without a color. + unsafe fn overlay_at(&mut self, with: &Image<U, 1>, x: u32, y: u32) -> &mut Self { + for j in 0..with.height() { + for i in 0..with.width() { + // SAFETY: i, j is in bounds. + let &[their_px] = unsafe { &with.pixel(i, j) }; + let our_px = unsafe { self.pixel_mut(i + x, j + y) }; + our_px.copy_from_slice(&[their_px; 4]); + } + } + self + } +} + +impl<T: AsMut<[u8]> + AsRef<[u8]>, U: AsRef<[u8]>> OverlayAt<Image<U, 2>> for Image<T, 4> { + #[inline] + #[cfg_attr(debug_assertions, track_caller)] + /// this impl doesnt make much sense without a color. + unsafe fn overlay_at(&mut self, with: &Image<U, 2>, x: u32, y: u32) -> &mut Self { + for j in 0..with.height() { + for i in 0..with.width() { + // SAFETY: i, j is in bounds. + let &[their_px, a] = unsafe { &with.pixel(i, j) }; + if a >= 128 { + let our_px = unsafe { self.pixel_mut(i + x, j + y) }; + our_px.copy_from_slice(&[their_px; 4]); + } + } + } + self + } +} + +impl<T: AsMut<[u8]> + AsRef<[u8]>, U: AsRef<[u8]>> OverlayAt<Image<U, 3>> for Image<T, 4> { + #[inline] + #[cfg_attr(debug_assertions, track_caller)] + /// its not a optimized impl + unsafe fn overlay_at(&mut self, with: &Image<U, 3>, x: u32, y: u32) -> &mut Self { + for j in 0..with.height() { + for i in 0..with.width() { + // SAFETY: i, j is in bounds. + let their_px = unsafe { &with.pixel(i, j) }; + let our_px = unsafe { self.pixel_mut(i + x, j + y) }; + our_px.copy_from_slice(their_px); + } + } + self + } +} + impl<T: AsMut<[u8]> + AsRef<[u8]>, U: AsRef<[u8]>> OverlayAt<Image<U, 3>> for Image<T, 3> { /// Overlay a RGB image(with) => self at coordinates x, y. /// As this is a `RGBxRGB` operation, blending is unnecessary, @@ -398,3 +487,32 @@ impl ClonerOverlayAt<4, 4> for ImageCloner<'_, 4> { out } } + +impl<T: AsMut<[u8]> + AsRef<[u8]>, U: AsRef<[u8]>> OverlayAt<DynImage<U>> for Image<T, 3> { + unsafe fn overlay_at(&mut self, with: &DynImage<U>, x: u32, y: u32) -> &mut Self { + crate::r#dyn::e!(with, |with| unsafe { + self.overlay_at(with, x, y); + }); + self + } +} + +impl<T: AsMut<[u8]> + AsRef<[u8]>, U: AsRef<[u8]>> OverlayAt<DynImage<U>> for Image<T, 4> { + unsafe fn overlay_at(&mut self, with: &DynImage<U>, x: u32, y: u32) -> &mut Self { + crate::r#dyn::e!(with, |with| unsafe { + self.overlay_at(with, x, y); + }); + self + } +} + +impl<U: AsRef<[u8]>> OverlayAt<DynImage<U>> for uninit::Image<u8, 3> { + unsafe fn overlay_at(&mut self, with: &DynImage<U>, x: u32, y: u32) -> &mut Self { + match with { + DynImage::Rgb(with) => unsafe { self.overlay_at(with, x, y) }, + DynImage::Rgba(with) => unsafe { self.overlay_at(with, x, y) }, + _ => unimplemented!(), + }; + self + } +} |