fast image operations
Diffstat (limited to 'src/uninit.rs')
-rw-r--r--src/uninit.rs39
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) };