1 //! In graphics code it's very common to pass `width` and `height` along with a `Vec` of pixels,
2 //! all as separate arguments. This is tedious, and can lead to errors.
3 //!
4 //! This crate is a simple struct that adds dimensions to the underlying buffer. This makes it easier to correctly keep track
5 //! of the image size and allows passing images with just one function argument instead three or four.
6 //!
7 //! Additionally, it has a concept of a `stride`, which allows defining sub-regions of images without copying,
8 //! as well as handling padding (e.g. buffers for video frames may require to be a multiple of 8, regardless of logical image size).
9 //!
10 //! For convenience, there are iterators over rows or all pixels of a (sub)image and
11 //! pixel-based indexing directly with `img[(x,y)]` (where `x`/`y` can be `u32` as well as `usize`).
12 //!
13 //! `Img<Container>` type has aliases for common uses:
14 //!
15 //! * Owned: `ImgVec<T>` → `Img<Vec<T>>`  (use it in `struct`s and return types)
16 //! * Reference: `ImgRef<T>` → `Img<&[T]>` (use it in function arguments)
17 //! * Mutable reference: `ImgRefMut<T>` → `Img<&mut [T]>`
18 //!
19 //! It is assumed that the container is [one element per pixel](https://crates.io/crates/rgb/), e.g. `Vec<RGBA>`,
20 //! and _not_ a `Vec<u8>` where 4 `u8` elements are interpreted as one pixel.
21 //!
22 //!
23 //!  ```rust
24 //!  use imgref::*;
25 //!  # fn some_image_processing_function(img: ImgRef<u8>) -> ImgVec<u8> { img.new_buf(img.buf().to_vec()) }
26 //!
27 //!  fn main() {
28 //!      let img = Img::new(vec![0; 1000], 50, 20); // 1000 pixels of a 50×20 image
29 //!
30 //!      let new_image = some_image_processing_function(img.as_ref()); // Use imgvec.as_ref() instead of &imgvec for better efficiency
31 //!
32 //!      println!("New size is {}×{}", new_image.width(), new_image.height());
33 //!      println!("And the top left pixel is {:?}", new_image[(0u32,0u32)]);
34 //!
35 //!      let first_row_slice = &new_image[0];
36 //!
37 //!      for row in new_image.rows() {
38 //!          // …
39 //!      }
40 //!      for px in new_image.pixels() {
41 //!          // …
42 //!      }
43 //!
44 //!      // slice (x, y, width, height) by reference - no copy!
45 //!      let fragment = img.sub_image(5, 5, 15, 15);
46 //!
47 //!      //
48 //!      let (vec, width, height) = fragment.to_contiguous_buf();
49 //!  }
50 //!  ```
51 
52 use std::borrow::Cow;
53 use std::slice;
54 
55 mod traits;
56 
57 mod ops;
58 pub use ops::*;
59 
60 mod iter;
61 pub use iter::*;
62 
63 /// Image owning its pixels.
64 ///
65 /// A 2D array of pixels. The pixels are oriented top-left first and rows are `stride` pixels wide.
66 ///
67 /// If size of the `buf` is larger than `width`*`height`, then any excess space is a padding (see `width_padded()`/`height_padded()`).
68 pub type ImgVec<Pixel> = Img<Vec<Pixel>>;
69 
70 /// Reference to pixels inside another image.
71 /// Pass this structure by value (i.e. `ImgRef`, not `&ImgRef`).
72 ///
73 /// Only `width` of pixels of every `stride` can be modified. The `buf` may be longer than `height`*`stride`, but the extra space should be ignored.
74 pub type ImgRef<'a, Pixel> = Img<&'a [Pixel]>;
75 
76 /// Same as `ImgRef`, but mutable
77 /// Pass this structure by value (i.e. `ImgRef`, not `&ImgRef`).
78 ///
79 pub type ImgRefMut<'a, Pixel> = Img<&'a mut [Pixel]>;
80 
81 /// Additional methods that depend on buffer size
82 ///
83 /// To use these methods you need:
84 ///
85 /// ```rust
86 /// use imgref::*;
87 /// ```
88 pub trait ImgExt<Pixel> {
89     /// Maximum possible width of the data, including the stride.
90     ///
91     /// # Panics
92     ///
93     /// This method may panic if the underlying buffer is not at least `height()*stride()` pixels large.
width_padded(&self) -> usize94     fn width_padded(&self) -> usize;
95 
96     /// Height in number of full strides.
97     /// If the underlying buffer is not an even multiple of strides, the last row is ignored.
98     ///
99     /// # Panics
100     ///
101     /// This method may panic if the underlying buffer is not at least `height()*stride()` pixels large.
height_padded(&self) -> usize102     fn height_padded(&self) -> usize;
103 
104     /// Iterate over the entire buffer as rows, including all padding
105     ///
106     /// Rows will have up to `stride` width, but the last row may be shorter.
rows_padded(&self) -> slice::Chunks<'_, Pixel>107     fn rows_padded(&self) -> slice::Chunks<'_, Pixel>;
108 
109     /// Borrow the container
as_ref(&self) -> ImgRef<Pixel>110     fn as_ref(&self) -> ImgRef<Pixel>;
111 }
112 
113 /// Additional methods that depend on buffer size
114 ///
115 /// To use these methods you need:
116 ///
117 /// ```rust
118 /// use imgref::*;
119 /// ```
120 pub trait ImgExtMut<Pixel> {
121     /// Iterate over the entire buffer as rows, including all padding
122     ///
123     /// Rows will have up to `stride` width, but the last row may be shorter.
rows_padded_mut(&mut self) -> slice::ChunksMut<'_, Pixel>124     fn rows_padded_mut(&mut self) -> slice::ChunksMut<'_, Pixel>;
125 
126     /// Borrow the container mutably
as_mut(&mut self) -> ImgRefMut<Pixel>127     fn as_mut(&mut self) -> ImgRefMut<Pixel>;
128 }
129 
130 /// Basic struct used for both owned (alias `ImgVec`) and borrowed (alias `ImgRef`) image fragments.
131 ///
132 /// Note: the fields are `pub` only because of borrow checker limitations. Please consider them as read-only.
133 #[derive(Debug, Copy, Clone)]
134 pub struct Img<Container> {
135     /// Storage for the pixels. Usually `Vec<Pixel>` or `&[Pixel]`. See `ImgVec` and `ImgRef`.
136     ///
137     /// Note that future version will make this field private. Use `.rows()` and `.pixels()` iterators where possible, or `buf()`/`buf_mut()`/`into_buf()`.
138     #[deprecated(note = "Don't access struct fields directly. Use buf(), buf_mut() or into_buf()")]
139     pub buf: Container,
140 
141     /// Number of pixels to skip in the container to advance to the next row.
142     ///
143     /// Note: pixels between `width` and `stride` may not be usable, and may not even exist in the last row.
144     #[deprecated(note = "Don't access struct fields directly. Use stride()")]
145     pub stride: usize,
146     /// Width of the image in pixels.
147     ///
148     /// Note that this isn't same as the width of the row in the `buf`, see `stride`
149     #[deprecated(note = "Don't access struct fields directly. Use width()")]
150     pub width: u32,
151     /// Height of the image in pixels.
152     #[deprecated(note = "Don't access struct fields directly. Use height()")]
153     pub height: u32,
154 }
155 
156 impl<Container> Img<Container> {
157     /// Width of the image in pixels.
158     ///
159     /// Note that this isn't same as the width of the row in image data, see `stride()`
160     #[inline(always)]
161     #[allow(deprecated)]
width(&self) -> usize162     pub fn width(&self) -> usize {self.width as usize}
163 
164     /// Height of the image in pixels.
165     #[inline(always)]
166     #[allow(deprecated)]
height(&self) -> usize167     pub fn height(&self) -> usize {self.height as usize}
168 
169     /// Number of _pixels_ to skip in the container to advance to the next row.
170     ///
171     /// Note the last row may have fewer pixels than the stride.
172     /// Some APIs use number of *bytes* for a stride. You may need to multiply this one by number of pixels.
173     #[inline(always)]
174     #[allow(deprecated)]
stride(&self) -> usize175     pub fn stride(&self) -> usize {self.stride}
176 
177     /// Immutable reference to the pixel storage. Warning: exposes stride. Use `pixels()` or `rows()` insetad.
178     ///
179     /// See also `into_contiguous_buf()`.
180     #[inline(always)]
181     #[allow(deprecated)]
buf(&self) -> &Container182     pub fn buf(&self) -> &Container {&self.buf}
183 
184     /// Mutable reference to the pixel storage. Warning: exposes stride. Use `pixels_mut()` or `rows_mut()` insetad.
185     ///
186     /// See also `into_contiguous_buf()`.
187     #[inline(always)]
188     #[allow(deprecated)]
buf_mut(&mut self) -> &mut Container189     pub fn buf_mut(&mut self) -> &mut Container {&mut self.buf}
190 
191     /// Get the pixel storage by consuming the image. Be careful about stride — see `into_contiguous_buf()` for a safe version.
192     #[inline(always)]
193     #[allow(deprecated)]
into_buf(self) -> Container194     pub fn into_buf(self) -> Container {self.buf}
195 
196     #[deprecated(note = "this was meant to be private, use new_buf() and/or rows()")]
rows_buf<'a, T: 'a>(&self, buf: &'a [T]) -> RowsIter<'a, T>197     pub fn rows_buf<'a, T: 'a>(&self, buf: &'a [T]) -> RowsIter<'a, T> {
198         self.rows_buf_internal(buf)
199     }
200 
201     #[inline]
rows_buf_internal<'a, T: 'a>(&self, buf: &'a [T]) -> RowsIter<'a, T>202     fn rows_buf_internal<'a, T: 'a>(&self, buf: &'a [T]) -> RowsIter<'a, T> {
203         let stride = self.stride();
204         debug_assert!(self.width() <= self.stride());
205         debug_assert!(buf.len() >= self.width() * self.height());
206         assert!(stride > 0);
207         let non_padded = &buf[0..stride * self.height() + self.width() - stride];
208         RowsIter {
209             width: self.width(),
210             inner: non_padded.chunks(stride),
211         }
212     }
213 }
214 
215 impl<Pixel,Container> ImgExt<Pixel> for Img<Container> where Container: AsRef<[Pixel]> {
216     #[inline(always)]
width_padded(&self) -> usize217     fn width_padded(&self) -> usize {
218         self.stride()
219     }
220 
221     #[inline(always)]
height_padded(&self) -> usize222     fn height_padded(&self) -> usize {
223         let len = self.buf().as_ref().len();
224         assert_eq!(0, len % self.stride());
225         len / self.stride()
226     }
227 
228     /// Iterate over the entire buffer as rows, including all padding
229     ///
230     /// Rows will have up to `stride` width, but the last row may be shorter.
231     #[inline(always)]
rows_padded(&self) -> slice::Chunks<'_, Pixel>232     fn rows_padded(&self) -> slice::Chunks<'_, Pixel> {
233         self.buf().as_ref().chunks(self.stride())
234     }
235 
236     #[inline(always)]
237     #[allow(deprecated)]
as_ref(&self) -> ImgRef<Pixel>238     fn as_ref(&self) -> ImgRef<Pixel> {
239         Img {
240             buf: self.buf.as_ref(),
241             width: self.width,
242             height: self.height,
243             stride: self.stride,
244         }
245     }
246 }
247 
248 impl<Pixel,Container> ImgExtMut<Pixel> for Img<Container> where Container: AsMut<[Pixel]> {
249     /// Iterate over the entire buffer as rows, including all padding
250     ///
251     /// Rows will have up to `stride` width, but the last row may be shorter.
252     ///
253     /// # Panics
254     ///
255     /// If stride is 0
256     #[inline]
257     #[must_use]
rows_padded_mut(&mut self) -> slice::ChunksMut<'_, Pixel>258     fn rows_padded_mut(&mut self) -> slice::ChunksMut<'_, Pixel> {
259         let stride = self.stride();
260         self.buf_mut().as_mut().chunks_mut(stride)
261     }
262 
263     #[inline(always)]
264     #[allow(deprecated)]
as_mut(&mut self) -> ImgRefMut<Pixel>265     fn as_mut(&mut self) -> ImgRefMut<Pixel> {
266         Img {
267             buf: self.buf.as_mut(),
268             width: self.width,
269             height: self.height,
270             stride: self.stride,
271         }
272     }
273 }
274 
275 #[inline]
sub_image(left: usize, top: usize, width: usize, height: usize, stride: usize, buf_len: usize) -> (usize, usize, usize)276 fn sub_image(left: usize, top: usize, width: usize, height: usize, stride: usize, buf_len: usize) -> (usize, usize, usize) {
277     let start = stride * top + left;
278     let full_strides_end = start + stride * height;
279     // when left > 0 and height is full, the last line is shorter than the stride
280     let end = if buf_len >= full_strides_end {
281         full_strides_end
282     } else {
283         debug_assert!(height > 0);
284         let min_strides_len = full_strides_end + width - stride;
285         debug_assert!(buf_len >= min_strides_len, "the buffer is too small to fit the subimage");
286         // if can't use full buffer, then shrink to min required (last line having exact width)
287         min_strides_len
288     };
289     (start, end, stride)
290 }
291 
292 impl<'a, T> ImgRef<'a, T> {
293     /// Make a reference for a part of the image, without copying any pixels.
294     ///
295     /// # Panics
296     ///
297     /// It will panic if sub_image is outside of the image area
298     /// (left + width must be <= container width, etc.)
299     #[inline]
300     #[must_use]
sub_image(&self, left: usize, top: usize, width: usize, height: usize) -> Self301     pub fn sub_image(&self, left: usize, top: usize, width: usize, height: usize) -> Self {
302         assert!(top + height <= self.height());
303         assert!(left + width <= self.width());
304         let (start, end, stride) = sub_image(left, top, width, height, self.stride(), self.buf().len());
305         let buf = &self.buf()[start..end];
306         Self::new_stride(buf, width, height, stride)
307     }
308 
309     #[inline]
310     /// Iterate over whole rows of pixels as slices
311     ///
312     /// # Panics
313     ///
314     /// If stride is 0
315     ///
316     /// See also `pixels()`
rows(&self) -> RowsIter<'_, T>317     pub fn rows(&self) -> RowsIter<'_, T> {
318         self.rows_buf_internal(self.buf())
319     }
320 
321     /// Deprecated
322     ///
323     /// Note: it iterates **all** pixels in the underlying buffer, not just limited by width/height.
324     #[deprecated(note = "Size of this buffer is unpredictable. Use .rows() instead")]
iter(&self) -> std::slice::Iter<'_, T>325     pub fn iter(&self) -> std::slice::Iter<'_, T> {
326         self.buf().iter()
327     }
328 }
329 
330 impl<'a, T: Clone> ImgRef<'a, T> {
331     /// Returns a reference to the buffer, width, height. Guarantees that the buffer is contiguous,
332     /// i.e. it's `width*height` elements long, and `[x + y*width]` addresses each pixel.
333     ///
334     /// It will create a copy if the buffer isn't contiguous (width != stride).
335     /// For a more efficient version, see `into_contiguous_buf()`
336     #[allow(deprecated)]
337     #[must_use]
to_contiguous_buf(&self) -> (Cow<[T]>, usize, usize)338     pub fn to_contiguous_buf(&self) -> (Cow<[T]>, usize, usize) {
339         let width = self.width();
340         let height = self.height();
341         let stride = self.stride();
342         if width == stride {
343             return (Cow::Borrowed(self.buf), width, height)
344         }
345         let mut buf = Vec::with_capacity(width*height);
346         for row in self.rows() {
347             buf.extend_from_slice(row);
348         }
349         (Cow::Owned(buf), width, height)
350     }
351 }
352 
353 impl<'a, T> ImgRefMut<'a, T> {
354     /// Turn this into immutable reference, and slice a subregion of it
355     #[inline]
356     #[allow(deprecated)]
357     #[must_use]
sub_image(&'a mut self, left: usize, top: usize, width: usize, height: usize) -> ImgRef<'a, T>358     pub fn sub_image(&'a mut self, left: usize, top: usize, width: usize, height: usize) -> ImgRef<'a, T> {
359         self.as_ref().sub_image(left, top, width, height)
360     }
361 
362     /// Trim this image without copying.
363     /// Note that mutable borrows are exclusive, so it's not possible to have more than
364     /// one mutable subimage at a time.
365     #[inline]
366     #[allow(deprecated)]
367     #[must_use]
sub_image_mut(&mut self, left: usize, top: usize, width: usize, height: usize) -> ImgRefMut<'_, T>368     pub fn sub_image_mut(&mut self, left: usize, top: usize, width: usize, height: usize) -> ImgRefMut<'_, T> {
369         assert!(top+height <= self.height());
370         assert!(left+width <= self.width());
371         let (start, end, stride) = sub_image(left, top, width, height, self.stride(), self.buf.len());
372         let buf = &mut self.buf[start..end];
373         ImgRefMut::new_stride(buf, width, height, stride)
374     }
375 
376     /// Make mutable reference immutable
377     #[inline]
378     #[must_use]
as_ref(&self) -> ImgRef<'_, T>379     pub fn as_ref(&self) -> ImgRef<'_, T> {
380         self.new_buf(self.buf().as_ref())
381     }
382 }
383 
384 impl<'a, T: Copy> ImgRef<'a, T> {
385     /// Iterate `width*height` pixels in the `Img`, ignoring padding area
386     ///
387     /// # Panics
388     ///
389     /// if width is 0
390     #[inline]
pixels(&self) -> PixelsIter<'_, T>391     pub fn pixels(&self) -> PixelsIter<'_, T> {
392         PixelsIter::new(*self)
393     }
394 }
395 
396 impl<'a, T> ImgRef<'a, T> {
397     /// Iterate `width*height` pixels in the `Img`, by reference, ignoring padding area
398     ///
399     /// # Panics
400     ///
401     /// if width is 0
402     #[inline]
pixels_ref(&self) -> PixelsRefIter<'_, T>403     pub fn pixels_ref(&self) -> PixelsRefIter<'_, T> {
404         PixelsRefIter::new(*self)
405     }
406 }
407 
408 impl<'a, T: Copy> ImgRefMut<'a, T> {
409     /// # Panics
410     ///
411     /// if width is 0
412     #[inline]
pixels(&self) -> PixelsIter<'_, T>413     pub fn pixels(&self) -> PixelsIter<'_, T> {
414         PixelsIter::new(self.as_ref())
415     }
416 
417     /// # Panics
418     ///
419     /// if width is 0
420     #[inline]
pixels_mut(&mut self) -> PixelsIterMut<'_, T>421     pub fn pixels_mut(&mut self) -> PixelsIterMut<'_, T> {
422         PixelsIterMut::new(self)
423     }
424 }
425 
426 impl<'a, T: Copy> ImgVec<T> {
427     /// # Panics
428     ///
429     /// if width is 0
430     #[inline]
pixels(&self) -> PixelsIter<'_, T>431     pub fn pixels(&self) -> PixelsIter<'_, T> {
432         PixelsIter::new(self.as_ref())
433     }
434 
435     /// # Panics
436     ///
437     /// if width is 0
438     #[inline]
pixels_mut(&mut self) -> PixelsIterMut<'_, T>439     pub fn pixels_mut(&mut self) -> PixelsIterMut<'_, T> {
440         PixelsIterMut::new(&mut self.as_mut())
441     }
442 }
443 
444 impl<'a, T> ImgRefMut<'a, T> {
445     /// # Panics
446     ///
447     /// if stride is 0
448     #[inline]
rows(&self) -> RowsIter<'_, T>449     pub fn rows(&self) -> RowsIter<'_, T> {
450         self.rows_buf_internal(&self.buf()[..])
451     }
452 
453     /// # Panics
454     ///
455     /// if stride is 0
456     #[inline]
457     #[allow(deprecated)]
rows_mut(&mut self) -> RowsIterMut<'_, T>458     pub fn rows_mut(&mut self) -> RowsIterMut<'_, T> {
459         let stride = self.stride();
460         let width = self.width();
461         let height = self.height();
462         let non_padded = &mut self.buf[0..stride * height + width - stride];
463         RowsIterMut {
464             width,
465             inner: non_padded.chunks_mut(stride),
466         }
467     }
468 }
469 
470 /// Deprecated. Use .rows() or .pixels() iterators which are more predictable
471 impl<Container> IntoIterator for Img<Container> where Container: IntoIterator {
472     type Item = Container::Item;
473     type IntoIter = Container::IntoIter;
474     /// Deprecated. Use .rows() or .pixels() iterators which are more predictable
into_iter(self) -> Container::IntoIter475     fn into_iter(self) -> Container::IntoIter {
476         self.into_buf().into_iter()
477     }
478 }
479 
480 impl<T> ImgVec<T> {
481     /// Create a mutable view into a region within the image. See `sub_image()` for read-only views.
482     #[allow(deprecated)]
483     #[must_use]
sub_image_mut(&mut self, left: usize, top: usize, width: usize, height: usize) -> ImgRefMut<'_, T>484     pub fn sub_image_mut(&mut self, left: usize, top: usize, width: usize, height: usize) -> ImgRefMut<'_, T> {
485         assert!(top+height <= self.height());
486         assert!(left+width <= self.width());
487         let start = self.stride * top + left;
488         let min_buf_size = if self.height > 0 {self.stride * height + width - self.stride} else {0};
489         let buf = &mut self.buf[start .. start + min_buf_size];
490         Img::new_stride(buf, width, height, self.stride)
491     }
492 
493     #[inline]
494     #[must_use]
495     /// Make a reference for a part of the image, without copying any pixels.
sub_image(&self, left: usize, top: usize, width: usize, height: usize) -> ImgRef<'_, T>496     pub fn sub_image(&self, left: usize, top: usize, width: usize, height: usize) -> ImgRef<'_, T> {
497         self.as_ref().sub_image(left, top, width, height)
498     }
499 
500     /// Make a reference to this image to pass it to functions without giving up ownership
501     ///
502     /// The reference should be passed by value (`ImgRef`, not `&ImgRef`).
503     ///
504     /// If you need a mutable reference, see `as_mut()` and `sub_image_mut()`
505     #[inline]
506     #[must_use]
as_ref(&self) -> ImgRef<'_, T>507     pub fn as_ref(&self) -> ImgRef<'_, T> {
508         self.new_buf(self.buf().as_ref())
509     }
510 
511     /// Make a mutable reference to the entire image
512     ///
513     /// The reference should be passed by value (`ImgRefMut`, not `&mut ImgRefMut`).
514     ///
515     /// See also `sub_image_mut()` and `rows_mut()`
516     #[inline]
as_mut(&mut self) -> ImgRefMut<'_, T>517     pub fn as_mut(&mut self) -> ImgRefMut<'_, T> {
518         let width = self.width();
519         let height = self.height();
520         let stride = self.stride();
521         Img::new_stride(self.buf_mut().as_mut(), width, height, stride)
522     }
523 
524     #[deprecated(note = "Size of this buffer may be unpredictable. Use .rows() instead")]
iter(&self) -> std::slice::Iter<'_, T>525     pub fn iter(&self) -> std::slice::Iter<'_, T> {
526         self.buf().iter()
527     }
528 
529     /// Iterate over rows of the image as slices
530     ///
531     /// Each slice is guaranteed to be exactly `width` pixels wide.
532     #[inline]
rows(&self) -> RowsIter<'_, T>533     pub fn rows(&self) -> RowsIter<'_, T> {
534         self.rows_buf_internal(self.buf())
535     }
536 
537     /// Iterate over rows of the image as mutable slices
538     ///
539     /// Each slice is guaranteed to be exactly `width` pixels wide.
540     #[inline]
541     #[allow(deprecated)]
rows_mut(&mut self) -> RowsIterMut<'_, T>542     pub fn rows_mut(&mut self) -> RowsIterMut<'_, T> {
543         let stride = self.stride();
544         let width = self.width();
545         let height = self.height();
546         let non_padded = &mut self.buf[0..stride * height + width - stride];
547         RowsIterMut {
548             width,
549             inner: non_padded.chunks_mut(stride),
550         }
551     }
552 }
553 
554 impl<Container> Img<Container> {
555     /// Same as `new()`, except each row is located `stride` number of pixels after the previous one.
556     ///
557     /// Stride can be equal to `width` or larger. If it's larger, then pixels between end of previous row and start of the next are considered a padding, and may be ignored.
558     ///
559     /// The `Container` is usually a `Vec` or a slice.
560     #[inline]
561     #[allow(deprecated)]
new_stride(buf: Container, width: usize, height: usize, stride: usize) -> Self562     pub fn new_stride(buf: Container, width: usize, height: usize, stride: usize) -> Self {
563         assert!(stride > 0);
564         assert!(stride >= width as usize);
565         debug_assert!(height < <u32>::max_value() as usize);
566         debug_assert!(width < <u32>::max_value() as usize);
567         Img {
568             buf,
569             width: width as u32,
570             height: height as u32,
571             stride,
572         }
573     }
574 
575     /// Create new image with `Container` (which can be `Vec`, `&[]` or something else) with given `width` and `height` in pixels.
576     ///
577     /// Assumes the pixels in container are contiguous, layed out row by row with `width` pixels per row and at least `height` rows.
578     ///
579     /// If the container is larger than `width`×`height` pixels, the extra rows are a considered a padding and may be ignored.
580     #[inline]
new(buf: Container, width: usize, height: usize) -> Self581     pub fn new(buf: Container, width: usize, height: usize) -> Self {
582         Self::new_stride(buf, width, height, width)
583     }
584 }
585 
586 impl<T: Copy> Img<Vec<T>> {
587     /// Returns the buffer, width, height. Guarantees that the buffer is contiguous,
588     /// i.e. it's `width*height` elements long, and `[x + y*width]` addresses each pixel.
589     ///
590     /// Efficiently performs operation in-place. For other containers use `pixels().collect()`.
591     #[allow(deprecated)]
592     #[must_use]
into_contiguous_buf(mut self) -> (Vec<T>, usize, usize)593     pub fn into_contiguous_buf(mut self) -> (Vec<T>, usize, usize) {
594         let (_, w, h) = self.as_contiguous_buf();
595         (self.buf, w, h)
596     }
597 
598     /// Returns a reference to the buffer, width, height. Guarantees that the buffer is contiguous,
599     /// i.e. it's `width*height` elements long, and `[x + y*width]` addresses each pixel.
600     ///
601     /// Efficiently performs operation in-place. For other containers use `pixels().collect()`.
602     #[allow(deprecated)]
603     #[must_use]
as_contiguous_buf(&mut self) -> (&[T], usize, usize)604     pub fn as_contiguous_buf(&mut self) -> (&[T], usize, usize) {
605         let width = self.width();
606         let height = self.height();
607         let stride = self.stride();
608         if width != stride {
609             unsafe {
610                 let buf = self.buf.as_mut_ptr();
611                 for row in 1..height {
612                     std::ptr::copy(buf.add(row * stride), buf.add(row * width), width);
613                 }
614             }
615         }
616         self.buf.truncate(width * height);
617         (&mut self.buf, width, height)
618     }
619 }
620 
621 impl<OldContainer> Img<OldContainer> {
622     /// A convenience method for creating an image of the same size and stride, but with a new buffer.
623     #[inline]
new_buf<NewContainer, OldPixel, NewPixel>(&self, new_buf: NewContainer) -> Img<NewContainer> where NewContainer: AsRef<[NewPixel]>, OldContainer: AsRef<[OldPixel]>624     pub fn new_buf<NewContainer, OldPixel, NewPixel>(&self, new_buf: NewContainer) -> Img<NewContainer>
625         where NewContainer: AsRef<[NewPixel]>, OldContainer: AsRef<[OldPixel]> {
626         assert_eq!(self.buf().as_ref().len(), new_buf.as_ref().len());
627         Img::new_stride(new_buf, self.width(), self.height(), self.stride())
628     }
629 }
630 
631 impl<T: Clone> From<Img<Cow<'_, [T]>>> for Img<Vec<T>> {
632     #[allow(deprecated)]
from(img: Img<Cow<'_, [T]>>) -> Self633     fn from(img: Img<Cow<'_, [T]>>) -> Self {
634         Img {
635             width: img.width,
636             height: img.height,
637             stride: img.stride,
638             buf: img.buf.into_owned(),
639         }
640     }
641 }
642 
643 impl<T: Clone> From<ImgVec<T>> for Img<Cow<'static, [T]>> {
644     #[allow(deprecated)]
from(img: ImgVec<T>) -> Self645     fn from(img: ImgVec<T>) -> Self {
646         Img {
647             width: img.width,
648             height: img.height,
649             stride: img.stride,
650             buf: img.buf.into(),
651         }
652     }
653 }
654 
655 impl<'a, T: Clone> From<ImgRef<'a, T>> for Img<Cow<'a, [T]>> {
656     #[allow(deprecated)]
from(img: ImgRef<'a, T>) -> Self657     fn from(img: ImgRef<'a, T>) -> Self {
658         Img {
659             buf: img.buf.into(),
660             width: img.width,
661             height: img.height,
662             stride: img.stride,
663         }
664     }
665 }
666 
667 impl<T: Clone> Img<Cow<'_, [T]>> {
668     /// Convert underlying buffer to owned (e.g. slice to vec)
669     ///
670     /// See also `to_contiguous_buf().0.into_owned()`
671     #[allow(deprecated)]
into_owned(self) -> ImgVec<T>672     pub fn into_owned(self) -> ImgVec<T> {
673         match self.buf {
674             Cow::Borrowed(_) => {
675                 let tmp = self.as_ref();
676                 let (buf, w, h) = tmp.to_contiguous_buf();
677                 ImgVec::new(buf.into_owned(), w, h)
678             },
679             Cow::Owned(buf) => Img {
680                 buf,
681                 width: self.width,
682                 height: self.height,
683                 stride: self.stride,
684             },
685         }
686     }
687 }
688 
689 impl<T> Img<T> where T: ToOwned {
690     /// Convert underlying buffer to owned (e.g. slice to vec)
691     ///
692     /// See also `to_contiguous_buf().0.into_owned()`
693     #[allow(deprecated)]
to_owned(&self) -> Img<T::Owned>694     pub fn to_owned(&self) -> Img<T::Owned> {
695         Img {
696             buf: self.buf.to_owned(),
697             width: self.width,
698             height: self.height,
699             stride: self.stride,
700         }
701     }
702 }
703 
704 #[cfg(test)]
705 mod tests {
706     use super::*;
707 
708     mod with_opinionated_container {
709         use super::*;
710 
711         struct IDontDeriveAnything;
712 
713         #[test]
compiles()714         fn compiles() {
715             let _ = Img::new(IDontDeriveAnything, 1, 1);
716         }
717     }
718 
719     #[test]
with_vec()720     fn with_vec() {
721         let bytes = vec![0u8;20];
722         let old = Img::new_stride(bytes, 10,2,10);
723         let _ = old.new_buf(vec![6u16;20]);
724     }
725 
726     #[test]
zero()727     fn zero() {
728         let bytes = vec![0u8];
729         let mut img = Img::new_stride(bytes,0,0,1);
730         let _ = img.sub_image(0,0,0,0);
731         let _ = img.sub_image_mut(0,0,0,0);
732         let _ = img.as_ref();
733     }
734 
735     #[test]
zero_width()736     fn zero_width() {
737         let bytes = vec![0u8];
738         let mut img = Img::new_stride(bytes,0,1,1);
739         let _ = img.sub_image(0,1,0,0);
740         let _ = img.sub_image_mut(0,0,0,1);
741     }
742 
743     #[test]
zero_height()744     fn zero_height() {
745         let bytes = vec![0u8];
746         let mut img = Img::new_stride(bytes,1,0,1);
747         assert_eq!(0, img.rows().count());
748         let _ = img.sub_image(1,0,0,0);
749         let _ = img.sub_image_mut(0,0,1,0);
750     }
751 
752     #[test]
753     #[allow(deprecated)]
with_slice()754     fn with_slice() {
755         let bytes = vec![0u8;20];
756         let _ = Img::new_stride(bytes.as_slice(), 10,2,10);
757         let vec = ImgVec::new_stride(bytes, 10,2,10);
758         for _ in vec.iter() {}
759         assert_eq!(2, vec.rows().count());
760         for _ in vec.as_ref().buf().iter() {}
761         for _ in vec {}
762     }
763 
764     #[test]
sub()765     fn sub() {
766         let img = Img::new_stride(vec![1,2,3,4,
767                        5,6,7,8,
768                        9], 3, 2, 4);
769         assert_eq!(img.buf()[img.stride()], 5);
770         assert_eq!(img.buf()[img.stride() + img.width()-1], 7);
771 
772         assert_eq!(img.pixels().count(), img.width() * img.height());
773         assert_eq!(img.pixels().sum::<i32>(), 24);
774 
775         {
776         let refimg = img.as_ref();
777         let refimg2 = refimg; // Test is Copy
778 
779         // sub-image with stride hits end of the buffer
780         let s1 = refimg.sub_image(1, 0, refimg.width()-1, refimg.height());
781         let _ = s1.sub_image(1, 0, s1.width()-1, s1.height());
782 
783         let subimg = refimg.sub_image(1, 1, 2, 1);
784         assert_eq!(subimg.pixels().count(), subimg.width() * subimg.height());
785 
786         assert_eq!(subimg.buf()[0], 6);
787         assert_eq!(subimg.stride(), refimg2.stride());
788         assert!(subimg.stride() * subimg.height() + subimg.width() - subimg.stride() <= subimg.buf().len());
789         assert_eq!(refimg.buf()[0], 1);
790         assert_eq!(1, subimg.rows().count());
791         }
792 
793         let mut img = img;
794         let mut subimg = img.sub_image_mut(1, 1, 2, 1);
795         assert_eq!(1, subimg.rows().count());
796         assert_eq!(1, subimg.rows_mut().count());
797         assert_eq!(1, subimg.rows_mut().rev().count());
798         assert_eq!(1, subimg.rows_mut().fuse().rev().count());
799         assert_eq!(subimg.buf()[0], 6);
800     }
801 
802     #[test]
rows()803     fn rows() {
804         let img = ImgVec::new_stride(vec![0u8; 10000], 10, 15, 100);
805         assert_eq!(img.height(), img.rows().count());
806         assert_eq!(img.height(), img.rows().rev().count());
807         assert_eq!(img.height(), img.rows().fuse().rev().count());
808     }
809 
810     #[test]
mut_pixels()811     fn mut_pixels() {
812         for y in 1..15 {
813             for x in 1..10 {
814                 let mut img = ImgVec::new_stride(vec![0u8; 10000], x, y, 100);
815                 assert_eq!(x*y, img.pixels_mut().count());
816                 assert_eq!(x*y, img.as_mut().pixels().count());
817                 assert_eq!(x*y, img.as_mut().pixels_mut().count());
818                 assert_eq!(x*y, img.as_mut().as_ref().pixels().count());
819             }
820         }
821     }
822 
823     #[test]
into_contiguous_buf()824     fn into_contiguous_buf() {
825         for in_h in [1, 2, 3, 38, 39, 40, 41].iter().copied() {
826             for in_w in [1, 2, 3, 120, 121].iter().copied() {
827                 for stride in [in_w, 121, 122, 166, 242, 243].iter().copied() {
828                     let img = ImgVec::new_stride((0..10000).map(|x| x as u8).collect(), in_w, in_h, stride);
829                     let pixels: Vec<_> = img.pixels().collect();
830                     let (buf, w, h) = img.into_contiguous_buf();
831                     assert_eq!(pixels, buf);
832                     assert_eq!(in_w*in_h, buf.len());
833                     assert_eq!(10000, buf.capacity());
834                     assert_eq!(in_w, w);
835                     assert_eq!(in_h, h);
836                 }
837             }
838         }
839 
840         let img = ImgVec::new((0..55*33).map(|x| x as u8).collect(), 55, 33);
841         let pixels: Vec<_> = img.pixels().collect();
842         let tmp = img.as_ref();
843         let (buf, ..) = tmp.to_contiguous_buf();
844         assert_eq!(&pixels[..], &buf[..]);
845         let (buf, ..) = img.into_contiguous_buf();
846         assert_eq!(pixels, buf);
847     }
848 }
849