fast image operations
Diffstat (limited to 'src/affine.rs')
| -rw-r--r-- | src/affine.rs | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/src/affine.rs b/src/affine.rs index f4c311e..b03dbba 100644 --- a/src/affine.rs +++ b/src/affine.rs @@ -107,9 +107,18 @@ impl<const CHANNELS: usize> ImageCloner<'_, CHANNELS> { /// UB if the image is not square #[must_use = "function does not modify the original image"] pub unsafe fn rot_90(&self) -> Image<Vec<u8>, CHANNELS> { - let mut out = self.flip_v(); + let mut out = self.alloc(); + // SAFETY: yep + unsafe { + mattr::transpose( + self.flatten(), + out.flatten_mut(), + self.height() as usize, + self.width() as usize, + ) + }; // SAFETY: sqar - unsafe { transpose(&mut out.as_mut()) }; + unsafe { crev(out.as_mut()) }; out } @@ -157,6 +166,26 @@ impl<const CHANNELS: usize, T: DerefMut<Target = [u8]>> Image<T, CHANNELS> { } } +/// Reverse columns of square image +/// # Safety +/// +/// UB if supplied image not square +unsafe fn crev<const CHANNELS: usize, T: DerefMut<Target = [u8]>>(mut img: Image<T, CHANNELS>) { + debug_assert_eq!(img.width(), img.height()); + let size = img.width() as usize; + let b = img.flatten_mut(); + for i in 0..size { + let mut start = 0; + let mut end = size - 1; + while start < end { + // SAFETY: hmm + unsafe { b.swap_unchecked(i * size + start, i * size + end) }; + start += 1; + end -= 1; + } + } +} + /// Transpose a square image /// # Safety /// |