fast image operations
Diffstat (limited to 'src/uninit.rs')
| -rw-r--r-- | src/uninit.rs | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/src/uninit.rs b/src/uninit.rs index 3555beb..c4c341b 100644 --- a/src/uninit.rs +++ b/src/uninit.rs @@ -1,9 +1,14 @@ //! the houser of uninitialized memory. €$@!0В!℡ //! //! contains [`Image`], an uninitialized image. -use std::{mem::MaybeUninit, num::NonZeroU32}; +use std::{ + hint::assert_unchecked, + mem::MaybeUninit, + num::NonZeroU32, + ops::{Index, IndexMut}, +}; -use crate::CopyWithinUnchecked; +use crate::{span::Span, CopyWithinUnchecked}; /// A uninitialized image. Be sure to initialize it! pub struct Image<T: Copy, const CHANNELS: usize> { @@ -13,6 +18,14 @@ pub struct Image<T: Copy, const CHANNELS: usize> { height: NonZeroU32, } +impl<I: Span, T: Copy, const C: usize> Index<I> for Image<T, C> { + type Output = [T]; + + fn index(&self, index: I) -> &Self::Output { + &self.buffer()[index.range::<C>((self.width(), self.height()))] + } +} + impl<T: Copy, const CHANNELS: usize> Image<T, CHANNELS> { /// Create a new uninit image. This is not init. pub fn new(width: NonZeroU32, height: NonZeroU32) -> Self { @@ -27,19 +40,31 @@ impl<T: Copy, const CHANNELS: usize> Image<T, CHANNELS> { /// /// # Safety /// index must be in bounds. - pub unsafe fn write(&mut self, data: &[T], i: impl crate::span::Span) { - let range = i.range::<CHANNELS>((self.width(), self.height())); - // SAFETY: write - let dat = unsafe { self.buf().get_unchecked_mut(range) }; + /// data and indexed range must have same len. + pub unsafe fn write(&mut self, data: &[T], i: impl Span) { + // SAFETY: caller + let dat = unsafe { self.slice(i) }; + // SAFETY: caller + unsafe { assert_unchecked(dat.len() == data.len()) }; MaybeUninit::write_slice(dat, data); } + /// Slice the image. + /// + /// # Safety + /// index must be in bounds. + pub unsafe fn slice(&mut self, i: impl Span) -> &mut [MaybeUninit<T>] { + let range = i.range::<CHANNELS>((self.width(), self.height())); + // SAFETY: assured + unsafe { self.buf().get_unchecked_mut(range) } + } + /// Copy a range to a position. /// /// # Safety /// /// both parts must be in bounds. - pub unsafe fn copy_within(&mut self, i: impl crate::span::Span, to: usize) { + pub unsafe fn copy_within(&mut self, i: impl Span, to: usize) { let range = i.range::<CHANNELS>((self.width(), self.height())); // SAFETY: copy! unsafe { self.buf().copy_within_unchecked(range, to) }; |