imgref_iter/iter/windows/
ptr.rs1use std::iter::FusedIterator;
2use std::ops::Range;
3use std::ptr::{slice_from_raw_parts, slice_from_raw_parts_mut};
4use imgref::Img;
5use crate::iter::{IterPtr, IterPtrMut};
6use crate::{slice_ptr_len, slice_ptr_len_mut};
7
8#[derive(Clone, Eq, PartialEq, Debug)]
9pub struct IterWindowsPtr<T>(*const [T], usize, usize, Range<usize>);
10
11unsafe impl<T: Sync> Send for IterWindowsPtr<T> {}
12
13unsafe impl<T> Sync for IterWindowsPtr<T> {}
14
15impl<T> IterWindowsPtr<T> {
16 #[inline]
47 pub unsafe fn new(slice: *const [T], slice_stride: usize, iter_stride: usize, len: usize) -> Self {
48 assert!(IterPtr::is_slice_perfect(slice_ptr_len(slice), slice_stride));
49 Self::new_unchecked(slice, slice_stride, iter_stride, len)
50 }
51
52 #[inline]
59 pub unsafe fn new_unchecked(slice: *const [T], slice_stride: usize, iter_stride: usize, len: usize) -> Self {
60 Self(slice, slice_stride, iter_stride, 0..len)
61 }
62
63 #[inline]
74 pub unsafe fn rows<S: AsRef<[T]>>(buf: &Img<S>) -> Self {
75 let (width, height, stride) = (buf.width(), buf.height(), buf.stride());
76 let buf = buf.buf().as_ref() as *const [T];
77 Self::rows_ptr(Img::new_stride(buf, width, height, stride))
78 }
79
80 #[inline]
91 pub unsafe fn rows_ptr(buf: Img<*const [T]>) -> Self {
92 IterPtr::assert_slice_enough(buf);
93 let (width, height, stride) = (buf.width(), buf.height(), buf.stride());
94 let first_row = slice_from_raw_parts(buf.buf().cast::<T>(), width);
95 Self::new_unchecked(first_row, 1, stride, height)
96 }
97
98 #[inline]
109 pub unsafe fn cols<S: AsRef<[T]>>(buf: &Img<S>) -> Self {
110 let (width, height, stride) = (buf.width(), buf.height(), buf.stride());
111 let buf = buf.buf().as_ref() as *const [T];
112 Self::cols_ptr(Img::new_stride(buf, width, height, stride))
113 }
114
115 #[inline]
126 pub unsafe fn cols_ptr(buf: Img<*const [T]>) -> Self {
127 IterPtr::assert_slice_enough(buf);
128 let (width, height, stride) = (buf.width(), buf.height(), buf.stride());
129 let first_col = slice_from_raw_parts(buf.buf().cast::<T>(), stride * (height - 1) + 1);
130 Self::new_unchecked(first_col, buf.stride(), 1, width)
131 }
132
133 #[inline]
134 unsafe fn window(&self, offset: usize) -> *const [T] {
135 let data = self.0.cast::<T>().add(offset);
136 let len = slice_ptr_len(self.0);
137 slice_from_raw_parts(data, len)
138 }
139}
140
141impl<T> Iterator for IterWindowsPtr<T> {
142 type Item = IterPtr<T>;
143
144 #[inline]
145 fn next(&mut self) -> Option<Self::Item> {
146 self.3.next().map(|index| unsafe { IterPtr::new(self.window(index * self.2), self.1) })
147 }
148
149 #[inline]
150 fn size_hint(&self) -> (usize, Option<usize>) {
151 let len = self.len();
152 (len, Some(len))
153 }
154}
155
156impl<T> DoubleEndedIterator for IterWindowsPtr<T> {
157 #[inline]
158 fn next_back(&mut self) -> Option<Self::Item> {
159 self.3.next_back().map(|index| unsafe { IterPtr::new(self.window(index * self.2), self.1) })
160 }
161}
162
163impl<T> ExactSizeIterator for IterWindowsPtr<T> {
164 #[inline]
165 fn len(&self) -> usize {
166 self.3.len()
167 }
168}
169
170impl<T> FusedIterator for IterWindowsPtr<T> {}
171
172#[derive(Clone, Eq, PartialEq, Debug)]
173pub struct IterWindowsPtrMut<T>(*mut [T], usize, usize, Range<usize>);
174
175unsafe impl<T: Send> Send for IterWindowsPtrMut<T> {}
176
177unsafe impl<T> Sync for IterWindowsPtrMut<T> {}
178
179impl<T> IterWindowsPtrMut<T> {
180 #[inline]
211 pub unsafe fn new(slice: *mut [T], slice_stride: usize, iter_stride: usize, len: usize) -> Self {
212 assert!(IterPtr::is_slice_perfect(slice_ptr_len_mut(slice), slice_stride));
213 Self::new_unchecked(slice, slice_stride, iter_stride, len)
214 }
215
216 #[inline]
223 pub unsafe fn new_unchecked(slice: *mut [T], slice_stride: usize, iter_stride: usize, len: usize) -> Self {
224 Self(slice, slice_stride, iter_stride, 0..len)
225 }
226
227 #[inline]
238 pub unsafe fn rows<S: AsMut<[T]>>(buf: &mut Img<S>) -> Self {
239 let (width, height, stride) = (buf.width(), buf.height(), buf.stride());
240 let buf = buf.buf_mut().as_mut() as *mut [T];
241 Self::rows_ptr(Img::new_stride(buf, width, height, stride))
242 }
243
244 #[inline]
255 pub unsafe fn rows_ptr(buf: Img<*mut [T]>) -> Self {
256 IterPtrMut::assert_slice_enough(buf);
257 let (width, height, stride) = (buf.width(), buf.height(), buf.stride());
258 let first_row = slice_from_raw_parts_mut(buf.buf().cast::<T>(), width);
259 Self::new_unchecked(first_row, 1, stride, height)
260 }
261
262 #[inline]
273 pub unsafe fn cols<S: AsMut<[T]>>(buf: &mut Img<S>) -> Self {
274 let (width, height, stride) = (buf.width(), buf.height(), buf.stride());
275 let buf = buf.buf_mut().as_mut() as *mut [T];
276 Self::cols_ptr(Img::new_stride(buf, width, height, stride))
277 }
278
279 #[inline]
290 pub unsafe fn cols_ptr(buf: Img<*mut [T]>) -> Self {
291 IterPtrMut::assert_slice_enough(buf);
292 let (width, height, stride) = (buf.width(), buf.height(), buf.stride());
293 let first_col = slice_from_raw_parts_mut(buf.buf().cast::<T>(), stride * (height - 1) + 1);
294 Self::new_unchecked(first_col, buf.stride(), 1, width)
295 }
296
297 #[inline]
298 unsafe fn window(&self, offset: usize) -> *mut [T] {
299 let data = self.0.cast::<T>().add(offset);
300 let len = slice_ptr_len_mut(self.0);
301 slice_from_raw_parts_mut(data, len)
302 }
303}
304
305impl<T> Iterator for IterWindowsPtrMut<T> {
306 type Item = IterPtrMut<T>;
307
308 #[inline]
309 fn next(&mut self) -> Option<Self::Item> {
310 self.3.next().map(|index| unsafe { IterPtrMut::new(self.window(index * self.2), self.1) })
311 }
312
313 #[inline]
314 fn size_hint(&self) -> (usize, Option<usize>) {
315 let len = self.len();
316 (len, Some(len))
317 }
318}
319
320impl<T> DoubleEndedIterator for IterWindowsPtrMut<T> {
321 #[inline]
322 fn next_back(&mut self) -> Option<Self::Item> {
323 self.3.next_back().map(|index| unsafe { IterPtrMut::new(self.window(index * self.2), self.1) })
324 }
325}
326
327impl<T> ExactSizeIterator for IterWindowsPtrMut<T> {
328 #[inline]
329 fn len(&self) -> usize {
330 self.3.len()
331 }
332}
333
334impl<T> FusedIterator for IterWindowsPtrMut<T> {}