1use imgref::Img;
4
5use crate::iter::{
6 Iter,
7 IterMut,
8 IterPtr,
9 IterPtrMut,
10 IterWindows,
11 IterWindowsMut,
12 IterWindowsPtr,
13 IterWindowsPtrMut
14};
15
16#[cfg(any(doc, feature = "simd"))]
17use crate::iter::{
18 SimdIter,
19 SimdIterMut,
20 SimdIterPtr,
21 SimdIterPtrMut,
22 SimdIterWindows,
23 SimdIterWindowsMut,
24 SimdIterWindowsPtr,
25 SimdIterWindowsPtrMut,
26};
27
28#[cfg(doc)]
29use crate::iter::{
30 SimdIterWindow,
31 SimdIterWindowMut,
32 SimdIterWindowPtr,
33 SimdIterWindowPtrMut
34};
35
36mod sealed {
37 pub trait SealedAsPtr {}
38
39 pub trait SealedAsMutPtr {}
40
41 pub trait SealedPtr {}
42
43 pub trait SealedPtrMut {}
44
45 pub trait Sealed {}
46
47 pub trait SealedMut {}
48
49 #[cfg(any(doc, feature = "simd"))]
50 pub trait SealedSimdPtr {}
51
52 #[cfg(any(doc, feature = "simd"))]
53 pub trait SealedSimdPtrMut {}
54
55 #[cfg(any(doc, feature = "simd"))]
56 pub trait SealedSimd {}
57
58 #[cfg(any(doc, feature = "simd"))]
59 pub trait SealedSimdMut {}
60}
61
62pub trait ImgAsPtr: sealed::SealedAsPtr {
64 type Item;
65
66 #[cfg(not(any(doc, feature = "simd")))]
67 type AsPtr: ImgIterPtr<Item = Self::Item>;
68
69 #[cfg(any(doc, feature = "simd"))]
70 type AsPtr: ImgIterPtr<Item = Self::Item> + ImgSimdIterPtr;
71
72 fn as_ptr(&self) -> Self::AsPtr;
74}
75
76pub trait ImgAsMutPtr: sealed::SealedAsMutPtr + ImgAsPtr {
81 #[cfg(not(any(doc, feature = "simd")))]
82 type AsMutPtr: ImgIterPtrMut<Item = Self::Item>;
83
84 #[cfg(any(doc, feature = "simd"))]
85 type AsMutPtr: ImgIterPtrMut<Item = Self::Item> + ImgSimdIterPtrMut;
86
87 fn as_mut_ptr(&self) -> Self::AsMutPtr;
89}
90
91pub trait ImgIterPtr: sealed::SealedPtr + ImgAsPtr {
96 #[inline]
109 unsafe fn iter_row_ptr(&self, row: usize) -> IterPtr<Self::Item> {
110 self.as_ptr().iter_row_ptr(row)
111 }
112
113 #[inline]
121 unsafe fn iter_rows_ptr(&self) -> IterWindowsPtr<Self::Item> {
122 self.as_ptr().iter_rows_ptr()
123 }
124
125 #[inline]
137 unsafe fn iter_col_ptr(&self, col: usize) -> IterPtr<Self::Item> {
138 self.as_ptr().iter_col_ptr(col)
139 }
140
141 #[inline]
149 unsafe fn iter_cols_ptr(&self) -> IterWindowsPtr<Self::Item> {
150 self.as_ptr().iter_cols_ptr()
151 }
152}
153
154pub trait ImgIterPtrMut: sealed::SealedPtrMut + ImgAsMutPtr + ImgIterPtr {
158 #[inline]
171 unsafe fn iter_row_ptr_mut(&self, row: usize) -> IterPtrMut<Self::Item> {
172 self.as_mut_ptr().iter_row_ptr_mut(row)
173 }
174
175 #[inline]
183 unsafe fn iter_rows_ptr_mut(&self) -> IterWindowsPtrMut<Self::Item> {
184 self.as_mut_ptr().iter_rows_ptr_mut()
185 }
186
187 #[inline]
200 unsafe fn iter_col_ptr_mut(&self, col: usize) -> IterPtrMut<Self::Item> {
201 self.as_mut_ptr().iter_col_ptr_mut(col)
202 }
203
204 #[inline]
212 unsafe fn iter_cols_ptr_mut(&self) -> IterWindowsPtrMut<Self::Item> {
213 self.as_mut_ptr().iter_cols_ptr_mut()
214 }
215}
216
217pub trait ImgIter: sealed::Sealed + ImgAsPtr {
222 fn iter_row(&self, row: usize) -> Iter<Self::Item>;
228
229 fn iter_rows(&self) -> IterWindows<Self::Item>;
231
232 fn iter_col(&self, col: usize) -> Iter<Self::Item>;
238
239 fn iter_cols(&self) -> IterWindows<Self::Item>;
241}
242
243pub trait ImgIterMut: sealed::SealedMut + ImgIter {
248 type AsMutPtr: ImgIterPtrMut<Item = Self::Item>;
249
250 fn as_mut_ptr(&mut self) -> Self::AsMutPtr;
252
253 fn iter_row_mut(&mut self, row: usize) -> IterMut<Self::Item>;
259
260 fn iter_rows_mut(&mut self) -> IterWindowsMut<Self::Item>;
262
263 fn iter_col_mut(&mut self, col: usize) -> IterMut<Self::Item>;
269
270 fn iter_cols_mut(&mut self) -> IterWindowsMut<Self::Item>;
272}
273
274#[cfg(any(doc, feature = "simd"))]
279pub trait ImgSimdIterPtr: sealed::SealedSimdPtr + ImgIterPtr {
280 #[inline]
293 unsafe fn simd_iter_row_ptr<const LANES: usize>(&self, row: usize) -> SimdIterPtr<Self::Item, LANES> {
294 self.as_ptr().simd_iter_row_ptr::<LANES>(row)
295 }
296
297 #[inline]
305 unsafe fn simd_iter_rows_ptr<const LANES: usize>(&self) -> SimdIterWindowsPtr<Self::Item, LANES> {
306 self.as_ptr().simd_iter_rows_ptr()
307 }
308
309 #[inline]
321 unsafe fn simd_iter_col_ptr<const LANES: usize>(&self, col: usize) -> SimdIterPtr<Self::Item, LANES> {
322 self.as_ptr().simd_iter_col_ptr::<LANES>(col)
323 }
324
325 #[inline]
333 unsafe fn simd_iter_cols_ptr<const LANES: usize>(&self) -> SimdIterWindowsPtr<Self::Item, LANES> {
334 self.as_ptr().simd_iter_cols_ptr()
335 }
336}
337
338#[cfg(any(doc, feature = "simd"))]
342pub trait ImgSimdIterPtrMut: sealed::SealedSimdPtrMut + ImgSimdIterPtr + ImgIterPtrMut {
343 #[inline]
356 unsafe fn simd_iter_row_ptr_mut<const LANES: usize>(&self, row: usize) -> SimdIterPtrMut<Self::Item, LANES> {
357 self.as_mut_ptr().simd_iter_row_ptr_mut::<LANES>(row)
358 }
359
360 #[inline]
368 unsafe fn simd_iter_rows_ptr_mut<const LANES: usize>(&self) -> SimdIterWindowsPtrMut<Self::Item, LANES> {
369 self.as_mut_ptr().simd_iter_rows_ptr_mut()
370 }
371
372 #[inline]
384 unsafe fn simd_iter_col_ptr_mut<const LANES: usize>(&self, col: usize) -> SimdIterPtrMut<Self::Item, LANES> {
385 self.as_mut_ptr().simd_iter_col_ptr_mut::<LANES>(col)
386 }
387
388 #[inline]
396 unsafe fn simd_iter_cols_ptr_mut<const LANES: usize>(&self) -> SimdIterWindowsPtrMut<Self::Item, LANES> {
397 self.as_mut_ptr().simd_iter_cols_ptr_mut()
398 }
399}
400
401#[cfg(any(doc, feature = "simd"))]
406pub trait ImgSimdIter: sealed::SealedSimd + ImgIter {
407 fn simd_iter_row<const LANES: usize>(&self, row: usize) -> SimdIter<Self::Item, LANES>;
413
414 fn simd_iter_rows<const LANES: usize>(&self) -> SimdIterWindows<Self::Item, LANES>;
416
417 fn simd_iter_col<const LANES: usize>(&self, col: usize) -> SimdIter<Self::Item, LANES>;
423
424 fn simd_iter_cols<const LANES: usize>(&self) -> SimdIterWindows<Self::Item, LANES>;
426}
427
428#[cfg(any(doc, feature = "simd"))]
433pub trait ImgSimdIterMut: sealed::SealedSimdMut + ImgIterMut {
434 fn simd_iter_row_mut<const LANES: usize>(&mut self, row: usize) -> SimdIterMut<Self::Item, LANES>;
440
441 fn simd_iter_rows_mut<const LANES: usize>(&mut self) -> SimdIterWindowsMut<Self::Item, LANES>;
443
444 fn simd_iter_col_mut<const LANES: usize>(&mut self, col: usize) -> SimdIterMut<Self::Item, LANES>;
450
451 fn simd_iter_cols_mut<const LANES: usize>(&mut self) -> SimdIterWindowsMut<Self::Item, LANES>;
453}
454
455impl<T> sealed::SealedAsPtr for Img<*const [T]> {}
457impl<T> sealed::SealedPtr for Img<*const [T]> {}
458
459impl<T> sealed::SealedAsPtr for Img<*mut [T]> {}
460impl<T> sealed::SealedAsMutPtr for Img<*mut [T]> {}
461impl<T> sealed::SealedPtr for Img<*mut [T]> {}
462impl<T> sealed::SealedPtrMut for Img<*mut [T]> {}
463
464impl<T> sealed::SealedAsPtr for Img<&[T]> {}
465impl<T> sealed::SealedPtr for Img<&[T]> {}
466impl<T> sealed::Sealed for Img<&[T]> {}
467
468impl<T> sealed::SealedAsPtr for Img<&mut [T]> {}
469impl<T> sealed::SealedAsMutPtr for Img<&mut [T]> {}
470impl<T> sealed::SealedPtr for Img<&mut [T]> {}
471impl<T> sealed::Sealed for Img<&mut [T]> {}
472impl<T> sealed::SealedMut for Img<&mut [T]> {}
473
474#[cfg(any(doc, feature = "simd"))] impl<T> sealed::SealedSimdPtr for Img<*const [T]> {}
475
476#[cfg(any(doc, feature = "simd"))] impl<T> sealed::SealedSimdPtr for Img<*mut [T]> {}
477#[cfg(any(doc, feature = "simd"))] impl<T> sealed::SealedSimdPtrMut for Img<*mut [T]> {}
478
479#[cfg(any(doc, feature = "simd"))] impl<T> sealed::SealedSimdPtr for Img<&[T]> {}
480#[cfg(any(doc, feature = "simd"))] impl<T> sealed::SealedSimd for Img<&[T]> {}
481
482#[cfg(any(doc, feature = "simd"))] impl<T> sealed::SealedSimdPtr for Img<&mut [T]> {}
483#[cfg(any(doc, feature = "simd"))] impl<T> sealed::SealedSimd for Img<&mut [T]> {}
484#[cfg(any(doc, feature = "simd"))] impl<T> sealed::SealedSimdMut for Img<&mut [T]> {}
485#[inline]
488unsafe fn copy_buf_unchecked<T, U>(img: &Img<T>, map: impl FnOnce(&T) -> U) -> Img<U> {
489 let (width, height, stride) = (img.width(), img.height(), img.stride());
490 Img::new_stride(map(img.buf()), width, height, stride)
491}
492
493#[inline]
494unsafe fn copy_buf_unchecked_mut<T, U>(img: &mut Img<T>, map: impl FnOnce(&mut T) -> U) -> Img<U> {
495 let (width, height, stride) = (img.width(), img.height(), img.stride());
496 Img::new_stride(map(img.buf_mut()), width, height, stride)
497}
498
499impl<T> ImgAsPtr for Img<*const [T]> {
500 type Item = T;
501 type AsPtr = Self;
502
503 #[inline]
504 fn as_ptr(&self) -> Self::AsPtr {
505 *self
506 }
507}
508
509impl<T> ImgAsPtr for Img<*mut [T]> {
510 type Item = T;
511 type AsPtr = Img<*const [T]>;
512
513 #[inline]
514 fn as_ptr(&self) -> Self::AsPtr {
515 unsafe { copy_buf_unchecked(self, |buf| *buf as *const [T]) }
516 }
517}
518
519impl<T> ImgAsPtr for Img<&[T]> {
520 type Item = T;
521 type AsPtr = Img<*const [T]>;
522
523 #[inline]
524 fn as_ptr(&self) -> Self::AsPtr {
525 unsafe { copy_buf_unchecked(self, |buf| *buf as *const [T]) }
526 }
527}
528
529impl<T> ImgAsPtr for Img<&mut [T]> {
530 type Item = T;
531 type AsPtr = Img<*const [T]>;
532
533 #[inline]
534 fn as_ptr(&self) -> Self::AsPtr {
535 unsafe { copy_buf_unchecked(self, |buf| *buf as *const [T]) }
536 }
537}
538
539impl<T> ImgAsMutPtr for Img<*mut [T]> {
540 type AsMutPtr = Img<*mut [T]>;
541
542 #[inline]
543 fn as_mut_ptr(&self) -> Self::AsMutPtr {
544 *self
545 }
546}
547
548impl<T> ImgIterPtr for Img<*const [T]> {
549 #[inline]
550 unsafe fn iter_row_ptr(&self, row: usize) -> IterPtr<Self::Item> {
551 IterPtr::row_ptr(*self, row)
552 }
553
554 #[inline]
555 unsafe fn iter_rows_ptr(&self) -> IterWindowsPtr<Self::Item> {
556 IterWindowsPtr::rows_ptr(*self)
557 }
558
559 #[inline]
560 unsafe fn iter_col_ptr(&self, col: usize) -> IterPtr<Self::Item> {
561 IterPtr::col_ptr(*self, col)
562 }
563
564 #[inline]
565 unsafe fn iter_cols_ptr(&self) -> IterWindowsPtr<Self::Item> {
566 IterWindowsPtr::cols_ptr(*self)
567 }
568}
569
570impl<T> ImgIterPtr for Img<*mut [T]> {}
571
572impl<T> ImgIterPtr for Img<&[T]> {}
573
574impl<T> ImgIterPtr for Img<&mut [T]> {}
575
576impl<T> ImgIterPtrMut for Img<*mut [T]> {
577 #[inline]
578 unsafe fn iter_row_ptr_mut(&self, row: usize) -> IterPtrMut<Self::Item> {
579 IterPtrMut::row_ptr(*self, row)
580 }
581
582 #[inline]
583 unsafe fn iter_rows_ptr_mut(&self) -> IterWindowsPtrMut<Self::Item> {
584 IterWindowsPtrMut::rows_ptr(*self)
585 }
586
587 #[inline]
588 unsafe fn iter_col_ptr_mut(&self, col: usize) -> IterPtrMut<Self::Item> {
589 IterPtrMut::col_ptr(*self, col)
590 }
591
592 #[inline]
593 unsafe fn iter_cols_ptr_mut(&self) -> IterWindowsPtrMut<Self::Item> {
594 IterWindowsPtrMut::cols_ptr(*self)
595 }
596}
597
598impl<T> ImgIter for Img<&[T]> {
599 #[inline]
600 fn iter_row(&self, row: usize) -> Iter<Self::Item> {
601 Iter::row(self, row)
602 }
603
604 #[inline]
605 fn iter_rows(&self) -> IterWindows<Self::Item> {
606 IterWindows::rows(self)
607 }
608
609 #[inline]
610 fn iter_col(&self, col: usize) -> Iter<Self::Item> {
611 Iter::col(self, col)
612 }
613
614 #[inline]
615 fn iter_cols(&self) -> IterWindows<Self::Item> {
616 IterWindows::cols(self)
617 }
618}
619
620impl<T> ImgIter for Img<&mut [T]> {
621 #[inline]
622 fn iter_row(&self, row: usize) -> Iter<Self::Item> {
623 Iter::row(self, row)
624 }
625
626 #[inline]
627 fn iter_rows(&self) -> IterWindows<Self::Item> {
628 IterWindows::rows(self)
629 }
630
631 #[inline]
632 fn iter_col(&self, col: usize) -> Iter<Self::Item> {
633 Iter::col(self, col)
634 }
635
636 #[inline]
637 fn iter_cols(&self) -> IterWindows<Self::Item> {
638 IterWindows::cols(self)
639 }
640}
641
642impl<T> ImgIterMut for Img<&mut [T]> {
643 type AsMutPtr = Img<*mut [T]>;
644
645 #[inline]
646 fn as_mut_ptr(&mut self) -> Self::AsMutPtr {
647 unsafe { copy_buf_unchecked_mut(self, |buf| *buf as *mut [T]) }
648 }
649
650 #[inline]
651 fn iter_row_mut(&mut self, row: usize) -> IterMut<Self::Item> {
652 IterMut::row(self, row)
653 }
654
655 #[inline]
656 fn iter_rows_mut(&mut self) -> IterWindowsMut<Self::Item> {
657 IterWindowsMut::rows(self)
658 }
659
660 #[inline]
661 fn iter_col_mut(&mut self, col: usize) -> IterMut<Self::Item> {
662 IterMut::col(self, col)
663 }
664
665 #[inline]
666 fn iter_cols_mut(&mut self) -> IterWindowsMut<Self::Item> {
667 IterWindowsMut::cols(self)
668 }
669}
670
671#[cfg(any(doc, feature = "simd"))]
672impl<T> ImgSimdIterPtr for Img<*const [T]> {
673 #[inline]
674 unsafe fn simd_iter_row_ptr<const LANES: usize>(&self, row: usize) -> SimdIterPtr<Self::Item, LANES> {
675 SimdIterPtr::rows_ptr(*self, row)
676 }
677
678 #[inline]
679 unsafe fn simd_iter_rows_ptr<const LANES: usize>(&self) -> SimdIterWindowsPtr<Self::Item, LANES> {
680 SimdIterWindowsPtr::rows_ptr(*self)
681 }
682
683 #[inline]
684 unsafe fn simd_iter_col_ptr<const LANES: usize>(&self, col: usize) -> SimdIterPtr<Self::Item, LANES> {
685 SimdIterPtr::cols_ptr(*self, col)
686 }
687
688 #[inline]
689 unsafe fn simd_iter_cols_ptr<const LANES: usize>(&self) -> SimdIterWindowsPtr<Self::Item, LANES> {
690 SimdIterWindowsPtr::cols_ptr(*self)
691 }
692}
693
694#[cfg(any(doc, feature = "simd"))]
695impl<T> ImgSimdIterPtr for Img<*mut [T]> {}
696
697#[cfg(any(doc, feature = "simd"))]
698impl<T> ImgSimdIterPtr for Img<&[T]> {}
699
700#[cfg(any(doc, feature = "simd"))]
701impl<T> ImgSimdIterPtr for Img<&mut [T]> {}
702
703#[cfg(any(doc, feature = "simd"))]
704impl<T> ImgSimdIterPtrMut for Img<*mut [T]> {
705 #[inline]
706 unsafe fn simd_iter_row_ptr_mut<const LANES: usize>(&self, row: usize) -> SimdIterPtrMut<Self::Item, LANES> {
707 SimdIterPtrMut::rows_ptr(*self, row)
708 }
709
710 #[inline]
711 unsafe fn simd_iter_rows_ptr_mut<const LANES: usize>(&self) -> SimdIterWindowsPtrMut<Self::Item, LANES> {
712 SimdIterWindowsPtrMut::rows_ptr(*self)
713 }
714
715 #[inline]
716 unsafe fn simd_iter_col_ptr_mut<const LANES: usize>(&self, col: usize) -> SimdIterPtrMut<Self::Item, LANES> {
717 SimdIterPtrMut::cols_ptr(*self, col)
718 }
719
720 #[inline]
721 unsafe fn simd_iter_cols_ptr_mut<const LANES: usize>(&self) -> SimdIterWindowsPtrMut<Self::Item, LANES> {
722 SimdIterWindowsPtrMut::cols_ptr(*self)
723 }
724}
725
726#[cfg(any(doc, feature = "simd"))]
727impl<T> ImgSimdIter for Img<&[T]> {
728 #[inline]
729 fn simd_iter_row<const LANES: usize>(&self, row: usize) -> SimdIter<Self::Item, LANES> {
730 SimdIter::rows(self, row)
731 }
732
733 #[inline]
734 fn simd_iter_rows<const LANES: usize>(&self) -> SimdIterWindows<Self::Item, LANES> {
735 SimdIterWindows::rows(self)
736 }
737
738 #[inline]
739 fn simd_iter_col<const LANES: usize>(&self, col: usize) -> SimdIter<Self::Item, LANES> {
740 SimdIter::cols(self, col)
741 }
742
743 #[inline]
744 fn simd_iter_cols<const LANES: usize>(&self) -> SimdIterWindows<Self::Item, LANES> {
745 SimdIterWindows::cols(self)
746 }
747}
748
749#[cfg(any(doc, feature = "simd"))]
750impl<T> ImgSimdIter for Img<&mut [T]> {
751 #[inline]
752 fn simd_iter_row<const LANES: usize>(&self, row: usize) -> SimdIter<Self::Item, LANES> {
753 SimdIter::rows(self, row)
754 }
755
756 #[inline]
757 fn simd_iter_rows<const LANES: usize>(&self) -> SimdIterWindows<Self::Item, LANES> {
758 SimdIterWindows::rows(self)
759 }
760
761 #[inline]
762 fn simd_iter_col<const LANES: usize>(&self, col: usize) -> SimdIter<Self::Item, LANES> {
763 SimdIter::cols(self, col)
764 }
765
766 #[inline]
767 fn simd_iter_cols<const LANES: usize>(&self) -> SimdIterWindows<Self::Item, LANES> {
768 SimdIterWindows::cols(self)
769 }
770}
771
772#[cfg(any(doc, feature = "simd"))]
773impl<T> ImgSimdIterMut for Img<&mut [T]> {
774 #[inline]
775 fn simd_iter_row_mut<const LANES: usize>(&mut self, row: usize) -> SimdIterMut<Self::Item, LANES> {
776 SimdIterMut::rows(self, row)
777 }
778
779 #[inline]
780 fn simd_iter_rows_mut<const LANES: usize>(&mut self) -> SimdIterWindowsMut<Self::Item, LANES> {
781 SimdIterWindowsMut::rows(self)
782 }
783
784 #[inline]
785 fn simd_iter_col_mut<const LANES: usize>(&mut self, col: usize) -> SimdIterMut<Self::Item, LANES> {
786 SimdIterMut::cols(self, col)
787 }
788
789 #[inline]
790 fn simd_iter_cols_mut<const LANES: usize>(&mut self) -> SimdIterWindowsMut<Self::Item, LANES> {
791 SimdIterWindowsMut::cols(self)
792 }
793}