1#![no_std]
50
51extern crate alloc;
52#[cfg(test)]
53extern crate std;
54
55use alloc::borrow::{Cow, ToOwned};
56use alloc::vec::Vec;
57use core::slice;
58
59mod traits;
60
61mod iter;
62mod ops;
63pub use iter::*;
64
65pub type ImgVec<Pixel> = Img<Vec<Pixel>>;
71
72pub type ImgRef<'slice, Pixel> = Img<&'slice [Pixel]>;
77
78pub type ImgRefMut<'slice, Pixel> = Img<&'slice mut [Pixel]>;
82
83pub trait ImgExt<Pixel> {
91 #[cfg(feature = "deprecated")]
97 fn width_padded(&self) -> usize;
98
99 #[cfg(feature = "deprecated")]
106 fn height_padded(&self) -> usize;
107
108 #[cfg(feature = "deprecated")]
112 fn rows_padded(&self) -> slice::Chunks<'_, Pixel>;
113
114 fn as_ref(&self) -> ImgRef<'_, Pixel>;
116}
117
118pub trait ImgExtMut<Pixel> {
126 #[cfg(feature = "deprecated")]
130 fn rows_padded_mut(&mut self) -> slice::ChunksMut<'_, Pixel>;
131
132 fn as_mut(&mut self) -> ImgRefMut<'_, Pixel>;
134}
135
136#[derive(Debug, Copy, Clone)]
140pub struct Img<Container> {
141 #[deprecated(note = "Don't access struct fields directly. Use buf(), buf_mut() or into_buf()")]
145 #[cfg(feature = "deprecated")]
146 pub buf: Container,
147
148 #[cfg(not(feature = "deprecated"))]
149 buf: Container,
150
151 #[deprecated(note = "Don't access struct fields directly. Use stride()")]
155 #[cfg(feature = "deprecated")]
156 pub stride: usize,
157
158 #[cfg(not(feature = "deprecated"))]
159 stride: usize,
160
161 #[deprecated(note = "Don't access struct fields directly. Use width()")]
165 #[cfg(feature = "deprecated")]
166 pub width: u32,
167
168 #[cfg(not(feature = "deprecated"))]
169 width: u32,
170
171 #[deprecated(note = "Don't access struct fields directly. Use height()")]
173 #[cfg(feature = "deprecated")]
174 pub height: u32,
175
176 #[cfg(not(feature = "deprecated"))]
177 height: u32,
178}
179
180impl<Container> Img<Container> {
181 #[inline(always)]
185 #[allow(deprecated)]
186 pub const fn width(&self) -> usize { self.width as usize }
187
188 #[inline(always)]
190 #[allow(deprecated)]
191 pub const fn height(&self) -> usize { self.height as usize }
192
193 #[inline(always)]
201 #[allow(deprecated)]
202 pub const fn stride(&self) -> usize { self.stride }
203
204 #[inline(always)]
208 #[allow(deprecated)]
209 pub const fn buf(&self) -> &Container { &self.buf }
210
211 #[inline(always)]
215 #[allow(deprecated)]
216 pub fn buf_mut(&mut self) -> &mut Container { &mut self.buf }
217
218 #[inline(always)]
220 #[allow(deprecated)]
221 pub fn into_buf(self) -> Container { self.buf }
222}
223
224impl<Pixel,Container> ImgExt<Pixel> for Img<Container> where Container: AsRef<[Pixel]> {
225 #[inline(always)]
226 #[cfg(feature = "deprecated")]
227 fn width_padded(&self) -> usize {
228 self.stride()
229 }
230
231 #[inline(always)]
232 #[cfg(feature = "deprecated")]
233 fn height_padded(&self) -> usize {
234 let len = self.buf().as_ref().len();
235 assert_eq!(0, len % self.stride());
236 len / self.stride()
237 }
238
239 #[inline(always)]
243 #[cfg(feature = "deprecated")]
244 fn rows_padded(&self) -> slice::Chunks<'_, Pixel> {
245 self.buf().as_ref().chunks(self.stride())
246 }
247
248 #[inline(always)]
249 #[allow(deprecated)]
250 fn as_ref(&self) -> ImgRef<'_, Pixel> {
251 Img {
252 buf: self.buf.as_ref(),
253 width: self.width,
254 height: self.height,
255 stride: self.stride,
256 }
257 }
258}
259
260impl<Pixel,Container> ImgExtMut<Pixel> for Img<Container> where Container: AsMut<[Pixel]> {
261 #[cfg(feature = "deprecated")]
269 fn rows_padded_mut(&mut self) -> slice::ChunksMut<'_, Pixel> {
270 let stride = self.stride();
271 self.buf_mut().as_mut().chunks_mut(stride)
272 }
273
274 #[inline(always)]
275 #[allow(deprecated)]
276 fn as_mut(&mut self) -> ImgRefMut<'_, Pixel> {
277 Img {
278 buf: self.buf.as_mut(),
279 width: self.width,
280 height: self.height,
281 stride: self.stride,
282 }
283 }
284}
285
286#[inline]
287fn sub_image(left: usize, top: usize, width: usize, height: usize, stride: usize, buf_len: usize) -> (usize, usize, usize) {
288 let start = stride * top + left;
289 let full_strides_end = start + stride * height;
290 let end = if buf_len >= full_strides_end {
292 full_strides_end
293 } else {
294 debug_assert!(height > 0);
295 let min_strides_len = full_strides_end + width - stride;
296 debug_assert!(buf_len >= min_strides_len, "the buffer is too small to fit the subimage");
297 min_strides_len
299 };
300 (start, end, stride)
301}
302
303impl<'slice, T> ImgRef<'slice, T> {
304 #[inline]
311 #[must_use]
312 #[track_caller]
313 pub fn sub_image(&self, left: usize, top: usize, width: usize, height: usize) -> Self {
314 assert!(top + height <= self.height());
315 assert!(left + width <= self.width());
316 let (start, end, stride) = sub_image(left, top, width, height, self.stride(), self.buf().len());
317 let buf = &self.buf()[start..end];
318 Self::new_stride(buf, width, height, stride)
319 }
320
321 #[inline]
322 #[cfg_attr(debug_assertions, track_caller)]
330 pub fn rows(&self) -> RowsIter<'slice, T> {
331 RowsIter {
332 inner: self.valid_buf().chunks(self.stride()),
333 width: self.width(),
334 }
335 }
336
337 #[deprecated(note = "Size of this buffer is unpredictable. Use .rows() instead")]
341 #[cfg(feature = "deprecated")]
342 #[doc(hidden)]
343 pub fn iter(&self) -> slice::Iter<'slice, T> {
344 self.buf().iter()
345 }
346}
347
348impl<'a, T: Clone> ImgRef<'a, T> {
349 #[allow(deprecated)]
355 #[must_use]
356 pub fn to_contiguous_buf(&self) -> (Cow<'a, [T]>, usize, usize) {
357 let width = self.width();
358 let height = self.height();
359 let stride = self.stride();
360 if width == stride {
361 return (Cow::Borrowed(self.buf), width, height);
362 }
363 let mut buf = Vec::with_capacity(width * height);
364 for row in self.rows() {
365 buf.extend_from_slice(row);
366 }
367 (Cow::Owned(buf), width, height)
368 }
369}
370
371impl<'slice, T> ImgRefMut<'slice, T> {
372 #[inline]
374 #[allow(deprecated)]
375 #[must_use]
376 pub fn sub_image(&'slice self, left: usize, top: usize, width: usize, height: usize) -> ImgRef<'slice, T> {
377 self.as_ref().sub_image(left, top, width, height)
378 }
379
380 #[inline]
389 #[allow(deprecated)]
390 #[must_use]
391 #[track_caller]
392 pub fn sub_image_mut(&mut self, left: usize, top: usize, width: usize, height: usize) -> ImgRefMut<'_, T> {
393 assert!(top + height <= self.height());
394 assert!(left + width <= self.width());
395 let (start, end, stride) = sub_image(left, top, width, height, self.stride(), self.buf.len());
396 let buf = &mut self.buf[start..end];
397 ImgRefMut::new_stride(buf, width, height, stride)
398 }
399
400 #[allow(deprecated)]
409 #[must_use]
410 #[track_caller]
411 pub fn into_sub_image_mut(self, left: usize, top: usize, width: usize, height: usize) -> Self {
412 assert!(top + height <= self.height());
413 assert!(left + width <= self.width());
414 let (start, end, stride) = sub_image(left, top, width, height, self.stride(), self.buf.len());
415 let buf = &mut self.buf[start..end];
416 ImgRefMut::new_stride(buf, width, height, stride)
417 }
418
419 #[inline]
421 #[must_use]
422 pub fn as_ref(&self) -> ImgRef<'_, T> {
423 self.new_buf(self.buf().as_ref())
424 }
425}
426
427impl<'slice, T: Copy> ImgRef<'slice, T> {
428 #[inline]
436 #[track_caller]
437 pub fn pixels(&self) -> PixelsIter<'slice, T> {
438 PixelsIter::new(*self)
439 }
440}
441
442impl<'slice, T> ImgRef<'slice, T> {
443 #[inline]
451 pub fn pixels_ref(&self) -> PixelsRefIter<'slice, T> {
452 PixelsRefIter::new(*self)
453 }
454}
455
456impl<T: Copy> ImgRefMut<'_, T> {
457 #[inline]
463 pub fn pixels(&self) -> PixelsIter<'_, T> {
464 PixelsIter::new(self.as_ref())
465 }
466}
467
468impl<T> ImgRefMut<'_, T> {
469 #[inline]
474 pub fn pixels_mut(&mut self) -> PixelsIterMut<'_, T> {
475 PixelsIterMut::new(self.as_mut())
476 }
477}
478
479impl<T: Copy> ImgVec<T> {
480 #[inline]
485 #[cfg_attr(debug_assertions, track_caller)]
486 pub fn pixels(&self) -> PixelsIter<'_, T> {
487 PixelsIter::new(self.as_ref())
488 }
489}
490
491impl<T> ImgVec<T> {
492 #[inline]
497 #[cfg_attr(debug_assertions, track_caller)]
498 pub fn pixels_mut(&mut self) -> PixelsIterMut<'_, T> {
499 PixelsIterMut::new(self.as_mut())
500 }
501}
502
503impl<T> ImgRefMut<'_, T> {
504 #[inline]
510 pub fn rows(&self) -> RowsIter<'_, T> {
511 self.as_ref().rows()
512 }
513
514 #[inline]
520 #[allow(deprecated)]
521 pub fn rows_mut(&mut self) -> RowsIterMut<'_, T> {
522 let stride = self.stride();
523 let width = self.width();
524 let height = self.height();
525 let non_padded = &mut self.buf[0..stride * height + width - stride];
526 RowsIterMut {
527 width,
528 inner: non_padded.chunks_mut(stride),
529 }
530 }
531}
532
533#[cfg(feature = "deprecated")]
535impl<Container> IntoIterator for Img<Container> where Container: IntoIterator {
536 type Item = Container::Item;
537 type IntoIter = Container::IntoIter;
538 fn into_iter(self) -> Container::IntoIter {
540 self.into_buf().into_iter()
541 }
542}
543
544impl<T> ImgVec<T> {
545 #[allow(deprecated)]
551 #[must_use]
552 #[track_caller]
553 pub fn sub_image_mut(&mut self, left: usize, top: usize, width: usize, height: usize) -> ImgRefMut<'_, T> {
554 assert!(top + height <= self.height());
555 assert!(left + width <= self.width());
556 let start = self.stride * top + left;
557 let min_buf_size = if self.height > 0 { self.stride * height + width - self.stride } else {0};
558 let buf = &mut self.buf[start .. start + min_buf_size];
559 Img::new_stride(buf, width, height, self.stride)
560 }
561
562 #[inline]
563 #[must_use]
564 pub fn sub_image(&self, left: usize, top: usize, width: usize, height: usize) -> ImgRef<'_, T> {
566 self.as_ref().sub_image(left, top, width, height)
567 }
568
569 #[inline]
575 #[must_use]
576 pub fn as_ref(&self) -> ImgRef<'_, T> {
577 self.new_buf(self.buf().as_ref())
578 }
579
580 #[inline]
586 pub fn as_mut(&mut self) -> ImgRefMut<'_, T> {
587 let width = self.width();
588 let height = self.height();
589 let stride = self.stride();
590 Img::new_stride(self.buf_mut().as_mut(), width, height, stride)
591 }
592
593 #[deprecated(note = "Size of this buffer may be unpredictable. Use .rows() instead")]
594 #[cfg(feature = "deprecated")]
595 #[doc(hidden)]
596 pub fn iter(&self) -> slice::Iter<'_, T> {
597 self.buf().iter()
598 }
599
600 #[inline]
606 #[cfg_attr(debug_assertions, track_caller)]
607 pub fn rows(&self) -> RowsIter<'_, T> {
608 self.as_ref().rows()
609 }
610
611 #[inline]
617 #[allow(deprecated)]
618 pub fn rows_mut(&mut self) -> RowsIterMut<'_, T> {
619 let stride = self.stride();
620 let width = self.width();
621 let height = self.height();
622 let non_padded = &mut self.buf[0..stride * height + width - stride];
623 RowsIterMut {
624 width,
625 inner: non_padded.chunks_mut(stride),
626 }
627 }
628}
629
630impl<Container> Img<Container> {
631 #[inline]
647 #[allow(deprecated)]
648 #[track_caller]
649 pub fn new_stride(buf: Container, width: usize, height: usize, stride: usize) -> Self {
650 assert!(stride > 0);
651 assert!(stride >= width);
652 debug_assert!(height < u32::MAX as usize);
653 debug_assert!(width < u32::MAX as usize);
654 Self {
655 buf,
656 width: width as u32,
657 height: height as u32,
658 stride,
659 }
660 }
661
662 #[inline]
676 pub fn new(buf: Container, width: usize, height: usize) -> Self {
677 Self::new_stride(buf, width, height, width)
678 }
679}
680
681#[cold]
682#[inline(never)]
683#[cfg_attr(debug_assertions, track_caller)]
684fn imgref_invalid_size(width: u32, height: u32, stride: usize, min_size: usize, len: usize) -> ! {
685 panic!("Invalid ImgRef params. Got stride={stride} for {width}×{height}; len={len} (needed {min_size})");
686}
687
688impl<T> ImgRefMut<'_, T> {
689 #[cfg_attr(debug_assertions, track_caller)]
690 fn valid_buf_mut(&mut self) -> &mut [T] {
691 let len = self.as_ref().valid_min_len();
692 &mut self.buf_mut()[..len]
693 }
694}
695
696impl<'buf, T> ImgRef<'buf, T> {
697 #[cfg_attr(debug_assertions, track_caller)]
698 fn valid_buf(&self) -> &'buf [T] {
699 &self.buf()[..self.valid_min_len()]
700 }
701
702 #[cfg_attr(debug_assertions, track_caller)]
703 #[inline(always)]
704 fn valid_min_len(&self) -> usize {
705 let stride = self.stride();
706 let width = self.width();
707 let height = self.height();
708 let buf = self.buf();
709 #[allow(deprecated)]
710 if stride == 0 || stride < width {
711 imgref_invalid_size(self.width, self.height, stride, 0, buf.len());
712 }
713 #[allow(deprecated)]
714 let min_size = if height == 0 || width == 0 {
715 0
716 } else {
717 stride
718 .checked_mul(height - 1)
719 .and_then(|len| len.checked_add(width))
720 .unwrap_or_else(|| {
721 imgref_invalid_size(self.width, self.height, stride, usize::MAX, buf.len())
722 })
723 };
724 #[allow(deprecated)]
725 if buf.len() < min_size {
726 imgref_invalid_size(self.width, self.height, stride, min_size, buf.len());
727 }
728 min_size
729 }
730}
731
732impl<T: Copy> Img<Vec<T>> {
733 #[allow(deprecated)]
738 #[must_use]
739 #[cfg_attr(debug_assertions, track_caller)]
740 pub fn into_contiguous_buf(mut self) -> (Vec<T>, usize, usize) {
741 let (_, w, h) = self.as_contiguous_buf();
742 (self.buf, w, h)
743 }
744
745 #[allow(deprecated)]
750 #[must_use]
751 #[cfg_attr(debug_assertions, track_caller)]
752 pub fn as_contiguous_buf(&mut self) -> (&[T], usize, usize) {
753 let width = self.width();
754 let height = self.height();
755 let stride = self.stride();
756 if width != stride {
757 let mut ref_mut = self.as_mut();
758 let buf = ref_mut.valid_buf_mut();
759 for row in 1..height {
760 buf.copy_within(row * stride .. row * stride + width, row * width);
761 }
762 }
763 self.buf.truncate(width * height);
764 (&mut self.buf, width, height)
765 }
766}
767
768impl<OldContainer> Img<OldContainer> {
769 #[inline]
775 #[track_caller]
776 pub fn map_buf<NewContainer, OldPixel, NewPixel, F>(self, callback: F) -> Img<NewContainer>
777 where NewContainer: AsRef<[NewPixel]>, OldContainer: AsRef<[OldPixel]>, F: FnOnce(OldContainer) -> NewContainer {
778 let width = self.width();
779 let height = self.height();
780 let stride = self.stride();
781 let old_buf_len = self.buf().as_ref().len();
782 #[allow(deprecated)]
783 let new_buf = callback(self.buf);
784 assert_eq!(old_buf_len, new_buf.as_ref().len());
785 Img::new_stride(new_buf, width, height, stride)
786 }
787
788 #[inline]
794 #[track_caller]
795 pub fn new_buf<NewContainer, OldPixel, NewPixel>(&self, new_buf: NewContainer) -> Img<NewContainer>
796 where NewContainer: AsRef<[NewPixel]>, OldContainer: AsRef<[OldPixel]> {
797 assert_eq!(self.buf().as_ref().len(), new_buf.as_ref().len());
798 Img::new_stride(new_buf, self.width(), self.height(), self.stride())
799 }
800}
801
802impl<T: Clone> From<Img<Cow<'_, [T]>>> for Img<Vec<T>> {
803 #[allow(deprecated)]
804 fn from(img: Img<Cow<'_, [T]>>) -> Self {
805 Self {
806 width: img.width,
807 height: img.height,
808 stride: img.stride,
809 buf: img.buf.into_owned(),
810 }
811 }
812}
813
814impl<T: Clone> From<ImgVec<T>> for Img<Cow<'static, [T]>> {
815 #[allow(deprecated)]
816 fn from(img: ImgVec<T>) -> Self {
817 Img {
818 width: img.width,
819 height: img.height,
820 stride: img.stride,
821 buf: img.buf.into(),
822 }
823 }
824}
825
826impl<'a, T: Clone> From<ImgRef<'a, T>> for Img<Cow<'a, [T]>> {
827 #[allow(deprecated)]
828 fn from(img: ImgRef<'a, T>) -> Self {
829 Img {
830 buf: img.buf.into(),
831 width: img.width,
832 height: img.height,
833 stride: img.stride,
834 }
835 }
836}
837
838impl<T: Clone> Img<Cow<'_, [T]>> {
839 #[allow(deprecated)]
843 #[must_use]
844 pub fn into_owned(self) -> ImgVec<T> {
845 match self.buf {
846 Cow::Borrowed(_) => {
847 let tmp = self.as_ref();
848 let (buf, w, h) = tmp.to_contiguous_buf();
849 ImgVec::new(buf.into_owned(), w, h)
850 },
851 Cow::Owned(buf) => Img {
852 buf,
853 width: self.width,
854 height: self.height,
855 stride: self.stride,
856 },
857 }
858 }
859}
860
861impl<T> Img<T> where T: ToOwned {
862 #[allow(deprecated)]
866 pub fn to_owned(&self) -> Img<T::Owned> {
867 Img {
868 buf: self.buf.to_owned(),
869 width: self.width,
870 height: self.height,
871 stride: self.stride,
872 }
873 }
874}
875
876#[cfg(test)]
877mod tests {
878 use super::*;
879 use alloc::vec;
880
881 mod with_opinionated_container {
882 use super::*;
883
884 struct IDontDeriveAnything;
885
886 #[test]
887 fn compiles() {
888 let _ = Img::new(IDontDeriveAnything, 1, 1);
889 }
890 }
891
892 #[test]
893 fn with_vec() {
894 let bytes = vec![0u8;20];
895 let old = Img::new_stride(bytes, 10,2,10);
896 let _ = old.new_buf(vec![6u16;20]);
897 }
898
899 #[test]
900 fn zero() {
901 let bytes = vec![0u8];
902 let mut img = Img::new_stride(bytes,0,0,1);
903 let _ = img.sub_image(0,0,0,0);
904 let _ = img.sub_image_mut(0,0,0,0);
905 let _ = img.as_ref();
906 }
907
908 #[test]
909 fn zero_width() {
910 let bytes = vec![0u8];
911 let mut img = Img::new_stride(bytes,0,1,1);
912 let _ = img.sub_image(0,1,0,0);
913 let _ = img.sub_image_mut(0,0,0,1);
914 }
915
916 #[test]
917 fn zero_height() {
918 let bytes = vec![0u8];
919 let mut img = Img::new_stride(bytes,1,0,1);
920 assert_eq!(0, img.rows().count());
921 let _ = img.sub_image(1,0,0,0);
922 let _ = img.sub_image_mut(0,0,1,0);
923 }
924
925 #[test]
926 #[allow(deprecated)]
927 fn with_slice() {
928 let bytes = vec![0u8;20];
929 let _ = Img::new_stride(bytes.as_slice(), 10,2,10);
930 let vec = ImgVec::new_stride(bytes, 10,2,10);
931
932 #[cfg(feature = "deprecated")]
933 for _ in vec.iter() {}
934
935 assert_eq!(2, vec.rows().count());
936 for _ in *vec.as_ref().buf() {}
937
938 #[cfg(feature = "deprecated")]
939 for _ in vec {}
940 }
941
942 #[test]
943 fn sub() {
944 let img = Img::new_stride(vec![1,2,3,4,
945 5,6,7,8,
946 9], 3, 2, 4);
947 assert_eq!(img.buf()[img.stride()], 5);
948 assert_eq!(img.buf()[img.stride() + img.width()-1], 7);
949
950 assert_eq!(img.pixels().count(), img.width() * img.height());
951 assert_eq!(img.pixels().sum::<i32>(), 24);
952
953 {
954 let refimg = img.as_ref();
955 let refimg2 = refimg; let s1 = refimg.sub_image(1, 0, refimg.width()-1, refimg.height());
959 let _ = s1.sub_image(1, 0, s1.width()-1, s1.height());
960
961 let subimg = refimg.sub_image(1, 1, 2, 1);
962 assert_eq!(subimg.pixels().count(), subimg.width() * subimg.height());
963
964 assert_eq!(subimg.buf()[0], 6);
965 assert_eq!(subimg.stride(), refimg2.stride());
966 assert!(subimg.stride() * subimg.height() + subimg.width() - subimg.stride() <= subimg.buf().len());
967 assert_eq!(refimg.buf()[0], 1);
968 assert_eq!(1, subimg.rows().count());
969 }
970
971 let mut img_for_mut_1 = img.clone();
973 let mut img_for_mut_2 = img.clone();
974 let mut img_for_mut_3 = img;
975 for mut subimg in [
976 img_for_mut_1.sub_image_mut(1, 1, 2, 1),
977 img_for_mut_2.as_mut().sub_image_mut(1, 1, 2, 1),
978 img_for_mut_3.as_mut().into_sub_image_mut(1, 1, 2, 1),
979 ] {
980 assert_eq!(1, subimg.rows().count());
981 assert_eq!(1, subimg.rows_mut().count());
982 assert_eq!(1, subimg.rows_mut().rev().count());
983 assert_eq!(1, subimg.rows_mut().fuse().rev().count());
984 assert_eq!(subimg.buf()[0], 6);
985 }
986 }
987
988 #[test]
989 fn rows() {
990 let img = ImgVec::new_stride(vec![0u8; 10000], 10, 15, 100);
991 assert_eq!(img.height(), img.rows().count());
992 assert_eq!(img.height(), img.rows().rev().count());
993 assert_eq!(img.height(), img.rows().fuse().rev().count());
994 }
995
996 #[test]
997 fn mut_pixels() {
998 for y in 1..15 {
999 for x in 1..10 {
1000 let mut img = ImgVec::new_stride(vec![0u8; 10000], x, y, 100);
1001 assert_eq!(x*y, img.pixels_mut().count());
1002 assert_eq!(x*y, img.as_mut().pixels().count());
1003 assert_eq!(x*y, img.as_mut().pixels_mut().count());
1004 assert_eq!(x*y, img.as_mut().as_ref().pixels().count());
1005 }
1006 }
1007 }
1008
1009 #[test]
1010 fn into_contiguous_buf() {
1011 for in_h in [1, 2, 3, 38, 39, 40, 41].iter().copied() {
1012 for in_w in [1, 2, 3, 120, 121].iter().copied() {
1013 for stride in [in_w, 121, 122, 166, 242, 243].iter().copied() {
1014 let img = ImgVec::new_stride((0..10000).map(|x| x as u8).collect(), in_w, in_h, stride)
1015 .map_buf(|x| x);
1016 let pixels: Vec<_> = img.pixels().collect();
1017 let (buf, w, h) = img.into_contiguous_buf();
1018 assert_eq!(pixels, buf);
1019 assert_eq!(in_w*in_h, buf.len());
1020 assert_eq!(10000, buf.capacity());
1021 assert_eq!(in_w, w);
1022 assert_eq!(in_h, h);
1023 }
1024 }
1025 }
1026
1027 let img = ImgVec::new((0..55*33).map(|x| x as u8).collect(), 55, 33);
1028 let pixels: Vec<_> = img.pixels().collect();
1029 let tmp = img.as_ref();
1030 let (buf, ..) = tmp.to_contiguous_buf();
1031 assert_eq!(&pixels[..], &buf[..]);
1032 let (buf, ..) = img.into_contiguous_buf();
1033 assert_eq!(pixels, buf);
1034 }
1035}