image/
buffer.rs

1//! Contains the generic `ImageBuffer` struct.
2use num_traits::Zero;
3use std::fmt;
4use std::marker::PhantomData;
5use std::ops::{Deref, DerefMut, Index, IndexMut, Range};
6use std::path::Path;
7use std::slice::{ChunksExact, ChunksExactMut};
8
9use crate::color::{FromColor, Luma, LumaA, Rgb, Rgba};
10use crate::dynimage::{save_buffer, save_buffer_with_format, write_buffer_with_format};
11use crate::error::ImageResult;
12use crate::flat::{FlatSamples, SampleLayout};
13use crate::image::{GenericImage, GenericImageView, ImageEncoder, ImageFormat};
14use crate::math::Rect;
15use crate::traits::{EncodableLayout, Pixel, PixelWithColorType};
16use crate::utils::expand_packed;
17use crate::DynamicImage;
18
19/// Iterate over pixel refs.
20pub struct Pixels<'a, P: Pixel + 'a>
21where
22    P::Subpixel: 'a,
23{
24    chunks: ChunksExact<'a, P::Subpixel>,
25}
26
27impl<'a, P: Pixel + 'a> Iterator for Pixels<'a, P>
28where
29    P::Subpixel: 'a,
30{
31    type Item = &'a P;
32
33    #[inline(always)]
34    fn next(&mut self) -> Option<&'a P> {
35        self.chunks.next().map(|v| <P as Pixel>::from_slice(v))
36    }
37
38    #[inline(always)]
39    fn size_hint(&self) -> (usize, Option<usize>) {
40        let len = self.len();
41        (len, Some(len))
42    }
43}
44
45impl<'a, P: Pixel + 'a> ExactSizeIterator for Pixels<'a, P>
46where
47    P::Subpixel: 'a,
48{
49    fn len(&self) -> usize {
50        self.chunks.len()
51    }
52}
53
54impl<'a, P: Pixel + 'a> DoubleEndedIterator for Pixels<'a, P>
55where
56    P::Subpixel: 'a,
57{
58    #[inline(always)]
59    fn next_back(&mut self) -> Option<&'a P> {
60        self.chunks.next_back().map(|v| <P as Pixel>::from_slice(v))
61    }
62}
63
64impl<P: Pixel> Clone for Pixels<'_, P> {
65    fn clone(&self) -> Self {
66        Pixels {
67            chunks: self.chunks.clone(),
68        }
69    }
70}
71
72impl<P: Pixel> fmt::Debug for Pixels<'_, P>
73where
74    P::Subpixel: fmt::Debug,
75{
76    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
77        f.debug_struct("Pixels")
78            .field("chunks", &self.chunks)
79            .finish()
80    }
81}
82
83/// Iterate over mutable pixel refs.
84pub struct PixelsMut<'a, P: Pixel + 'a>
85where
86    P::Subpixel: 'a,
87{
88    chunks: ChunksExactMut<'a, P::Subpixel>,
89}
90
91impl<'a, P: Pixel + 'a> Iterator for PixelsMut<'a, P>
92where
93    P::Subpixel: 'a,
94{
95    type Item = &'a mut P;
96
97    #[inline(always)]
98    fn next(&mut self) -> Option<&'a mut P> {
99        self.chunks.next().map(|v| <P as Pixel>::from_slice_mut(v))
100    }
101
102    #[inline(always)]
103    fn size_hint(&self) -> (usize, Option<usize>) {
104        let len = self.len();
105        (len, Some(len))
106    }
107}
108
109impl<'a, P: Pixel + 'a> ExactSizeIterator for PixelsMut<'a, P>
110where
111    P::Subpixel: 'a,
112{
113    fn len(&self) -> usize {
114        self.chunks.len()
115    }
116}
117
118impl<'a, P: Pixel + 'a> DoubleEndedIterator for PixelsMut<'a, P>
119where
120    P::Subpixel: 'a,
121{
122    #[inline(always)]
123    fn next_back(&mut self) -> Option<&'a mut P> {
124        self.chunks
125            .next_back()
126            .map(|v| <P as Pixel>::from_slice_mut(v))
127    }
128}
129
130impl<P: Pixel> fmt::Debug for PixelsMut<'_, P>
131where
132    P::Subpixel: fmt::Debug,
133{
134    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
135        f.debug_struct("PixelsMut")
136            .field("chunks", &self.chunks)
137            .finish()
138    }
139}
140
141/// Iterate over rows of an image
142///
143/// This iterator is created with [`ImageBuffer::rows`]. See its document for details.
144///
145/// [`ImageBuffer::rows`]: ../struct.ImageBuffer.html#method.rows
146pub struct Rows<'a, P: Pixel + 'a>
147where
148    <P as Pixel>::Subpixel: 'a,
149{
150    pixels: ChunksExact<'a, P::Subpixel>,
151}
152
153impl<'a, P: Pixel + 'a> Rows<'a, P> {
154    /// Construct the iterator from image pixels. This is not public since it has a (hidden) panic
155    /// condition. The `pixels` slice must be large enough so that all pixels are addressable.
156    fn with_image(pixels: &'a [P::Subpixel], width: u32, height: u32) -> Self {
157        let row_len = (width as usize) * usize::from(<P as Pixel>::CHANNEL_COUNT);
158        if row_len == 0 {
159            Rows {
160                pixels: [].chunks_exact(1),
161            }
162        } else {
163            let pixels = pixels
164                .get(..row_len * height as usize)
165                .expect("Pixel buffer has too few subpixels");
166            // Rows are physically present. In particular, height is smaller than `usize::MAX` as
167            // all subpixels can be indexed.
168            Rows {
169                pixels: pixels.chunks_exact(row_len),
170            }
171        }
172    }
173}
174
175impl<'a, P: Pixel + 'a> Iterator for Rows<'a, P>
176where
177    P::Subpixel: 'a,
178{
179    type Item = Pixels<'a, P>;
180
181    #[inline(always)]
182    fn next(&mut self) -> Option<Pixels<'a, P>> {
183        let row = self.pixels.next()?;
184        Some(Pixels {
185            // Note: this is not reached when CHANNEL_COUNT is 0.
186            chunks: row.chunks_exact(<P as Pixel>::CHANNEL_COUNT as usize),
187        })
188    }
189
190    #[inline(always)]
191    fn size_hint(&self) -> (usize, Option<usize>) {
192        let len = self.len();
193        (len, Some(len))
194    }
195}
196
197impl<'a, P: Pixel + 'a> ExactSizeIterator for Rows<'a, P>
198where
199    P::Subpixel: 'a,
200{
201    fn len(&self) -> usize {
202        self.pixels.len()
203    }
204}
205
206impl<'a, P: Pixel + 'a> DoubleEndedIterator for Rows<'a, P>
207where
208    P::Subpixel: 'a,
209{
210    #[inline(always)]
211    fn next_back(&mut self) -> Option<Pixels<'a, P>> {
212        let row = self.pixels.next_back()?;
213        Some(Pixels {
214            // Note: this is not reached when CHANNEL_COUNT is 0.
215            chunks: row.chunks_exact(<P as Pixel>::CHANNEL_COUNT as usize),
216        })
217    }
218}
219
220impl<P: Pixel> Clone for Rows<'_, P> {
221    fn clone(&self) -> Self {
222        Rows {
223            pixels: self.pixels.clone(),
224        }
225    }
226}
227
228impl<P: Pixel> fmt::Debug for Rows<'_, P>
229where
230    P::Subpixel: fmt::Debug,
231{
232    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
233        f.debug_struct("Rows")
234            .field("pixels", &self.pixels)
235            .finish()
236    }
237}
238
239/// Iterate over mutable rows of an image
240///
241/// This iterator is created with [`ImageBuffer::rows_mut`]. See its document for details.
242///
243/// [`ImageBuffer::rows_mut`]: ../struct.ImageBuffer.html#method.rows_mut
244pub struct RowsMut<'a, P: Pixel + 'a>
245where
246    <P as Pixel>::Subpixel: 'a,
247{
248    pixels: ChunksExactMut<'a, P::Subpixel>,
249}
250
251impl<'a, P: Pixel + 'a> RowsMut<'a, P> {
252    /// Construct the iterator from image pixels. This is not public since it has a (hidden) panic
253    /// condition. The `pixels` slice must be large enough so that all pixels are addressable.
254    fn with_image(pixels: &'a mut [P::Subpixel], width: u32, height: u32) -> Self {
255        let row_len = (width as usize) * usize::from(<P as Pixel>::CHANNEL_COUNT);
256        if row_len == 0 {
257            RowsMut {
258                pixels: [].chunks_exact_mut(1),
259            }
260        } else {
261            let pixels = pixels
262                .get_mut(..row_len * height as usize)
263                .expect("Pixel buffer has too few subpixels");
264            // Rows are physically present. In particular, height is smaller than `usize::MAX` as
265            // all subpixels can be indexed.
266            RowsMut {
267                pixels: pixels.chunks_exact_mut(row_len),
268            }
269        }
270    }
271}
272
273impl<'a, P: Pixel + 'a> Iterator for RowsMut<'a, P>
274where
275    P::Subpixel: 'a,
276{
277    type Item = PixelsMut<'a, P>;
278
279    #[inline(always)]
280    fn next(&mut self) -> Option<PixelsMut<'a, P>> {
281        let row = self.pixels.next()?;
282        Some(PixelsMut {
283            // Note: this is not reached when CHANNEL_COUNT is 0.
284            chunks: row.chunks_exact_mut(<P as Pixel>::CHANNEL_COUNT as usize),
285        })
286    }
287
288    #[inline(always)]
289    fn size_hint(&self) -> (usize, Option<usize>) {
290        let len = self.len();
291        (len, Some(len))
292    }
293}
294
295impl<'a, P: Pixel + 'a> ExactSizeIterator for RowsMut<'a, P>
296where
297    P::Subpixel: 'a,
298{
299    fn len(&self) -> usize {
300        self.pixels.len()
301    }
302}
303
304impl<'a, P: Pixel + 'a> DoubleEndedIterator for RowsMut<'a, P>
305where
306    P::Subpixel: 'a,
307{
308    #[inline(always)]
309    fn next_back(&mut self) -> Option<PixelsMut<'a, P>> {
310        let row = self.pixels.next_back()?;
311        Some(PixelsMut {
312            // Note: this is not reached when CHANNEL_COUNT is 0.
313            chunks: row.chunks_exact_mut(<P as Pixel>::CHANNEL_COUNT as usize),
314        })
315    }
316}
317
318impl<P: Pixel> fmt::Debug for RowsMut<'_, P>
319where
320    P::Subpixel: fmt::Debug,
321{
322    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
323        f.debug_struct("RowsMut")
324            .field("pixels", &self.pixels)
325            .finish()
326    }
327}
328
329/// Enumerate the pixels of an image.
330pub struct EnumeratePixels<'a, P: Pixel + 'a>
331where
332    <P as Pixel>::Subpixel: 'a,
333{
334    pixels: Pixels<'a, P>,
335    x: u32,
336    y: u32,
337    width: u32,
338}
339
340impl<'a, P: Pixel + 'a> Iterator for EnumeratePixels<'a, P>
341where
342    P::Subpixel: 'a,
343{
344    type Item = (u32, u32, &'a P);
345
346    #[inline(always)]
347    fn next(&mut self) -> Option<(u32, u32, &'a P)> {
348        if self.x >= self.width {
349            self.x = 0;
350            self.y += 1;
351        }
352        let (x, y) = (self.x, self.y);
353        self.x += 1;
354        self.pixels.next().map(|p| (x, y, p))
355    }
356
357    #[inline(always)]
358    fn size_hint(&self) -> (usize, Option<usize>) {
359        let len = self.len();
360        (len, Some(len))
361    }
362}
363
364impl<'a, P: Pixel + 'a> ExactSizeIterator for EnumeratePixels<'a, P>
365where
366    P::Subpixel: 'a,
367{
368    fn len(&self) -> usize {
369        self.pixels.len()
370    }
371}
372
373impl<P: Pixel> Clone for EnumeratePixels<'_, P> {
374    fn clone(&self) -> Self {
375        EnumeratePixels {
376            pixels: self.pixels.clone(),
377            ..*self
378        }
379    }
380}
381
382impl<P: Pixel> fmt::Debug for EnumeratePixels<'_, P>
383where
384    P::Subpixel: fmt::Debug,
385{
386    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
387        f.debug_struct("EnumeratePixels")
388            .field("pixels", &self.pixels)
389            .field("x", &self.x)
390            .field("y", &self.y)
391            .field("width", &self.width)
392            .finish()
393    }
394}
395
396/// Enumerate the rows of an image.
397pub struct EnumerateRows<'a, P: Pixel + 'a>
398where
399    <P as Pixel>::Subpixel: 'a,
400{
401    rows: Rows<'a, P>,
402    y: u32,
403    width: u32,
404}
405
406impl<'a, P: Pixel + 'a> Iterator for EnumerateRows<'a, P>
407where
408    P::Subpixel: 'a,
409{
410    type Item = (u32, EnumeratePixels<'a, P>);
411
412    #[inline(always)]
413    fn next(&mut self) -> Option<(u32, EnumeratePixels<'a, P>)> {
414        let y = self.y;
415        self.y += 1;
416        self.rows.next().map(|r| {
417            (
418                y,
419                EnumeratePixels {
420                    x: 0,
421                    y,
422                    width: self.width,
423                    pixels: r,
424                },
425            )
426        })
427    }
428
429    #[inline(always)]
430    fn size_hint(&self) -> (usize, Option<usize>) {
431        let len = self.len();
432        (len, Some(len))
433    }
434}
435
436impl<'a, P: Pixel + 'a> ExactSizeIterator for EnumerateRows<'a, P>
437where
438    P::Subpixel: 'a,
439{
440    fn len(&self) -> usize {
441        self.rows.len()
442    }
443}
444
445impl<P: Pixel> Clone for EnumerateRows<'_, P> {
446    fn clone(&self) -> Self {
447        EnumerateRows {
448            rows: self.rows.clone(),
449            ..*self
450        }
451    }
452}
453
454impl<P: Pixel> fmt::Debug for EnumerateRows<'_, P>
455where
456    P::Subpixel: fmt::Debug,
457{
458    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
459        f.debug_struct("EnumerateRows")
460            .field("rows", &self.rows)
461            .field("y", &self.y)
462            .field("width", &self.width)
463            .finish()
464    }
465}
466
467/// Enumerate the pixels of an image.
468pub struct EnumeratePixelsMut<'a, P: Pixel + 'a>
469where
470    <P as Pixel>::Subpixel: 'a,
471{
472    pixels: PixelsMut<'a, P>,
473    x: u32,
474    y: u32,
475    width: u32,
476}
477
478impl<'a, P: Pixel + 'a> Iterator for EnumeratePixelsMut<'a, P>
479where
480    P::Subpixel: 'a,
481{
482    type Item = (u32, u32, &'a mut P);
483
484    #[inline(always)]
485    fn next(&mut self) -> Option<(u32, u32, &'a mut P)> {
486        if self.x >= self.width {
487            self.x = 0;
488            self.y += 1;
489        }
490        let (x, y) = (self.x, self.y);
491        self.x += 1;
492        self.pixels.next().map(|p| (x, y, p))
493    }
494
495    #[inline(always)]
496    fn size_hint(&self) -> (usize, Option<usize>) {
497        let len = self.len();
498        (len, Some(len))
499    }
500}
501
502impl<'a, P: Pixel + 'a> ExactSizeIterator for EnumeratePixelsMut<'a, P>
503where
504    P::Subpixel: 'a,
505{
506    fn len(&self) -> usize {
507        self.pixels.len()
508    }
509}
510
511impl<P: Pixel> fmt::Debug for EnumeratePixelsMut<'_, P>
512where
513    P::Subpixel: fmt::Debug,
514{
515    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
516        f.debug_struct("EnumeratePixelsMut")
517            .field("pixels", &self.pixels)
518            .field("x", &self.x)
519            .field("y", &self.y)
520            .field("width", &self.width)
521            .finish()
522    }
523}
524
525/// Enumerate the rows of an image.
526pub struct EnumerateRowsMut<'a, P: Pixel + 'a>
527where
528    <P as Pixel>::Subpixel: 'a,
529{
530    rows: RowsMut<'a, P>,
531    y: u32,
532    width: u32,
533}
534
535impl<'a, P: Pixel + 'a> Iterator for EnumerateRowsMut<'a, P>
536where
537    P::Subpixel: 'a,
538{
539    type Item = (u32, EnumeratePixelsMut<'a, P>);
540
541    #[inline(always)]
542    fn next(&mut self) -> Option<(u32, EnumeratePixelsMut<'a, P>)> {
543        let y = self.y;
544        self.y += 1;
545        self.rows.next().map(|r| {
546            (
547                y,
548                EnumeratePixelsMut {
549                    x: 0,
550                    y,
551                    width: self.width,
552                    pixels: r,
553                },
554            )
555        })
556    }
557
558    #[inline(always)]
559    fn size_hint(&self) -> (usize, Option<usize>) {
560        let len = self.len();
561        (len, Some(len))
562    }
563}
564
565impl<'a, P: Pixel + 'a> ExactSizeIterator for EnumerateRowsMut<'a, P>
566where
567    P::Subpixel: 'a,
568{
569    fn len(&self) -> usize {
570        self.rows.len()
571    }
572}
573
574impl<P: Pixel> fmt::Debug for EnumerateRowsMut<'_, P>
575where
576    P::Subpixel: fmt::Debug,
577{
578    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
579        f.debug_struct("EnumerateRowsMut")
580            .field("rows", &self.rows)
581            .field("y", &self.y)
582            .field("width", &self.width)
583            .finish()
584    }
585}
586
587/// Generic image buffer
588///
589/// This is an image parameterised by its Pixel types, represented by a width and height and a
590/// container of channel data. It provides direct access to its pixels and implements the
591/// [`GenericImageView`] and [`GenericImage`] traits. In many ways, this is the standard buffer
592/// implementing those traits. Using this concrete type instead of a generic type parameter has
593/// been shown to improve performance.
594///
595/// The crate defines a few type aliases with regularly used pixel types for your convenience, such
596/// as [`RgbImage`], [`GrayImage`] etc.
597///
598/// [`GenericImage`]: trait.GenericImage.html
599/// [`GenericImageView`]: trait.GenericImageView.html
600/// [`RgbImage`]: type.RgbImage.html
601/// [`GrayImage`]: type.GrayImage.html
602///
603/// To convert between images of different Pixel types use [`DynamicImage`].
604///
605/// You can retrieve a complete description of the buffer's layout and contents through
606/// [`as_flat_samples`] and [`as_flat_samples_mut`]. This can be handy to also use the contents in
607/// a foreign language, map it as a GPU host buffer or other similar tasks.
608///
609/// [`DynamicImage`]: enum.DynamicImage.html
610/// [`as_flat_samples`]: #method.as_flat_samples
611/// [`as_flat_samples_mut`]: #method.as_flat_samples_mut
612///
613/// ## Examples
614///
615/// Create a simple canvas and paint a small cross.
616///
617/// ```
618/// use image::{RgbImage, Rgb};
619///
620/// let mut img = RgbImage::new(32, 32);
621///
622/// for x in 15..=17 {
623///     for y in 8..24 {
624///         img.put_pixel(x, y, Rgb([255, 0, 0]));
625///         img.put_pixel(y, x, Rgb([255, 0, 0]));
626///     }
627/// }
628/// ```
629///
630/// Overlays an image on top of a larger background raster.
631///
632/// ```no_run
633/// use image::{GenericImage, GenericImageView, ImageBuffer, open};
634///
635/// let on_top = open("path/to/some.png").unwrap().into_rgb8();
636/// let mut img = ImageBuffer::from_fn(512, 512, |x, y| {
637///     if (x + y) % 2 == 0 {
638///         image::Rgb([0, 0, 0])
639///     } else {
640///         image::Rgb([255, 255, 255])
641///     }
642/// });
643///
644/// image::imageops::overlay(&mut img, &on_top, 128, 128);
645/// ```
646///
647/// Convert an `RgbaImage` to a `GrayImage`.
648///
649/// ```no_run
650/// use image::{open, DynamicImage};
651///
652/// let rgba = open("path/to/some.png").unwrap().into_rgba8();
653/// let gray = DynamicImage::ImageRgba8(rgba).into_luma8();
654/// ```
655#[derive(Debug, Hash, PartialEq, Eq)]
656pub struct ImageBuffer<P: Pixel, Container> {
657    width: u32,
658    height: u32,
659    _phantom: PhantomData<P>,
660    data: Container,
661}
662
663// generic implementation, shared along all image buffers
664impl<P, Container> ImageBuffer<P, Container>
665where
666    P: Pixel,
667    Container: Deref<Target = [P::Subpixel]>,
668{
669    /// Constructs a buffer from a generic container
670    /// (for example a `Vec` or a slice)
671    ///
672    /// Returns `None` if the container is not big enough (including when the image dimensions
673    /// necessitate an allocation of more bytes than supported by the container).
674    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
675        if Self::check_image_fits(width, height, buf.len()) {
676            Some(ImageBuffer {
677                data: buf,
678                width,
679                height,
680                _phantom: PhantomData,
681            })
682        } else {
683            None
684        }
685    }
686
687    /// Returns the underlying raw buffer
688    pub fn into_raw(self) -> Container {
689        self.data
690    }
691
692    /// Returns the underlying raw buffer
693    pub fn as_raw(&self) -> &Container {
694        &self.data
695    }
696
697    /// The width and height of this image.
698    pub fn dimensions(&self) -> (u32, u32) {
699        (self.width, self.height)
700    }
701
702    /// The width of this image.
703    pub fn width(&self) -> u32 {
704        self.width
705    }
706
707    /// The height of this image.
708    pub fn height(&self) -> u32 {
709        self.height
710    }
711
712    // TODO: choose name under which to expose.
713    pub(crate) fn inner_pixels(&self) -> &[P::Subpixel] {
714        let len = Self::image_buffer_len(self.width, self.height).unwrap();
715        &self.data[..len]
716    }
717
718    /// Returns an iterator over the pixels of this image.
719    /// The iteration order is x = 0 to width then y = 0 to height
720    pub fn pixels(&self) -> Pixels<P> {
721        Pixels {
722            chunks: self
723                .inner_pixels()
724                .chunks_exact(<P as Pixel>::CHANNEL_COUNT as usize),
725        }
726    }
727
728    /// Returns an iterator over the rows of this image.
729    ///
730    /// Only non-empty rows can be iterated in this manner. In particular the iterator will not
731    /// yield any item when the width of the image is `0` or a pixel type without any channels is
732    /// used. This ensures that its length can always be represented by `usize`.
733    pub fn rows(&self) -> Rows<P> {
734        Rows::with_image(&self.data, self.width, self.height)
735    }
736
737    /// Enumerates over the pixels of the image.
738    /// The iterator yields the coordinates of each pixel
739    /// along with a reference to them.
740    /// The iteration order is x = 0 to width then y = 0 to height
741    /// Starting from the top left.
742    pub fn enumerate_pixels(&self) -> EnumeratePixels<P> {
743        EnumeratePixels {
744            pixels: self.pixels(),
745            x: 0,
746            y: 0,
747            width: self.width,
748        }
749    }
750
751    /// Enumerates over the rows of the image.
752    /// The iterator yields the y-coordinate of each row
753    /// along with a reference to them.
754    pub fn enumerate_rows(&self) -> EnumerateRows<P> {
755        EnumerateRows {
756            rows: self.rows(),
757            y: 0,
758            width: self.width,
759        }
760    }
761
762    /// Gets a reference to the pixel at location `(x, y)`
763    ///
764    /// # Panics
765    ///
766    /// Panics if `(x, y)` is out of the bounds `(width, height)`.
767    #[inline]
768    #[track_caller]
769    pub fn get_pixel(&self, x: u32, y: u32) -> &P {
770        match self.pixel_indices(x, y) {
771            None => panic!(
772                "Image index {:?} out of bounds {:?}",
773                (x, y),
774                (self.width, self.height)
775            ),
776            Some(pixel_indices) => <P as Pixel>::from_slice(&self.data[pixel_indices]),
777        }
778    }
779
780    /// Gets a reference to the pixel at location `(x, y)` or returns `None` if
781    /// the index is out of the bounds `(width, height)`.
782    pub fn get_pixel_checked(&self, x: u32, y: u32) -> Option<&P> {
783        if x >= self.width {
784            return None;
785        }
786        let num_channels = <P as Pixel>::CHANNEL_COUNT as usize;
787        let i = (y as usize)
788            .saturating_mul(self.width as usize)
789            .saturating_add(x as usize)
790            .saturating_mul(num_channels);
791
792        self.data
793            .get(i..i.checked_add(num_channels)?)
794            .map(|pixel_indices| <P as Pixel>::from_slice(pixel_indices))
795    }
796
797    /// Test that the image fits inside the buffer.
798    ///
799    /// Verifies that the maximum image of pixels inside the bounds is smaller than the provided
800    /// length. Note that as a corrolary we also have that the index calculation of pixels inside
801    /// the bounds will not overflow.
802    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
803        let checked_len = Self::image_buffer_len(width, height);
804        checked_len.map_or(false, |min_len| min_len <= len)
805    }
806
807    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
808        Some(<P as Pixel>::CHANNEL_COUNT as usize)
809            .and_then(|size| size.checked_mul(width as usize))
810            .and_then(|size| size.checked_mul(height as usize))
811    }
812
813    #[inline(always)]
814    fn pixel_indices(&self, x: u32, y: u32) -> Option<Range<usize>> {
815        if x >= self.width || y >= self.height {
816            return None;
817        }
818
819        Some(self.pixel_indices_unchecked(x, y))
820    }
821
822    #[inline(always)]
823    fn pixel_indices_unchecked(&self, x: u32, y: u32) -> Range<usize> {
824        let no_channels = <P as Pixel>::CHANNEL_COUNT as usize;
825        // If in bounds, this can't overflow as we have tested that at construction!
826        let min_index = (y as usize * self.width as usize + x as usize) * no_channels;
827        min_index..min_index + no_channels
828    }
829
830    /// Get the format of the buffer when viewed as a matrix of samples.
831    pub fn sample_layout(&self) -> SampleLayout {
832        // None of these can overflow, as all our memory is addressable.
833        SampleLayout::row_major_packed(<P as Pixel>::CHANNEL_COUNT, self.width, self.height)
834    }
835
836    /// Return the raw sample buffer with its stride an dimension information.
837    ///
838    /// The returned buffer is guaranteed to be well formed in all cases. It is laid out by
839    /// colors, width then height, meaning `channel_stride <= width_stride <= height_stride`. All
840    /// strides are in numbers of elements but those are mostly `u8` in which case the strides are
841    /// also byte strides.
842    pub fn into_flat_samples(self) -> FlatSamples<Container>
843    where
844        Container: AsRef<[P::Subpixel]>,
845    {
846        // None of these can overflow, as all our memory is addressable.
847        let layout = self.sample_layout();
848        FlatSamples {
849            samples: self.data,
850            layout,
851            color_hint: None, // TODO: the pixel type might contain P::COLOR_TYPE if it satisfies PixelWithColorType
852        }
853    }
854
855    /// Return a view on the raw sample buffer.
856    ///
857    /// See [`into_flat_samples`](#method.into_flat_samples) for more details.
858    pub fn as_flat_samples(&self) -> FlatSamples<&[P::Subpixel]>
859    where
860        Container: AsRef<[P::Subpixel]>,
861    {
862        let layout = self.sample_layout();
863        FlatSamples {
864            samples: self.data.as_ref(),
865            layout,
866            color_hint: None, // TODO: the pixel type might contain P::COLOR_TYPE if it satisfies PixelWithColorType
867        }
868    }
869
870    /// Return a mutable view on the raw sample buffer.
871    ///
872    /// See [`into_flat_samples`](#method.into_flat_samples) for more details.
873    pub fn as_flat_samples_mut(&mut self) -> FlatSamples<&mut [P::Subpixel]>
874    where
875        Container: AsMut<[P::Subpixel]>,
876    {
877        let layout = self.sample_layout();
878        FlatSamples {
879            samples: self.data.as_mut(),
880            layout,
881            color_hint: None, // TODO: the pixel type might contain P::COLOR_TYPE if it satisfies PixelWithColorType
882        }
883    }
884}
885
886impl<P, Container> ImageBuffer<P, Container>
887where
888    P: Pixel,
889    Container: Deref<Target = [P::Subpixel]> + DerefMut,
890{
891    // TODO: choose name under which to expose.
892    pub(crate) fn inner_pixels_mut(&mut self) -> &mut [P::Subpixel] {
893        let len = Self::image_buffer_len(self.width, self.height).unwrap();
894        &mut self.data[..len]
895    }
896
897    /// Returns an iterator over the mutable pixels of this image.
898    pub fn pixels_mut(&mut self) -> PixelsMut<P> {
899        PixelsMut {
900            chunks: self
901                .inner_pixels_mut()
902                .chunks_exact_mut(<P as Pixel>::CHANNEL_COUNT as usize),
903        }
904    }
905
906    /// Returns an iterator over the mutable rows of this image.
907    ///
908    /// Only non-empty rows can be iterated in this manner. In particular the iterator will not
909    /// yield any item when the width of the image is `0` or a pixel type without any channels is
910    /// used. This ensures that its length can always be represented by `usize`.
911    pub fn rows_mut(&mut self) -> RowsMut<P> {
912        RowsMut::with_image(&mut self.data, self.width, self.height)
913    }
914
915    /// Enumerates over the pixels of the image.
916    /// The iterator yields the coordinates of each pixel
917    /// along with a mutable reference to them.
918    pub fn enumerate_pixels_mut(&mut self) -> EnumeratePixelsMut<P> {
919        let width = self.width;
920        EnumeratePixelsMut {
921            pixels: self.pixels_mut(),
922            x: 0,
923            y: 0,
924            width,
925        }
926    }
927
928    /// Enumerates over the rows of the image.
929    /// The iterator yields the y-coordinate of each row
930    /// along with a mutable reference to them.
931    pub fn enumerate_rows_mut(&mut self) -> EnumerateRowsMut<P> {
932        let width = self.width;
933        EnumerateRowsMut {
934            rows: self.rows_mut(),
935            y: 0,
936            width,
937        }
938    }
939
940    /// Gets a reference to the mutable pixel at location `(x, y)`
941    ///
942    /// # Panics
943    ///
944    /// Panics if `(x, y)` is out of the bounds `(width, height)`.
945    #[inline]
946    #[track_caller]
947    pub fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut P {
948        match self.pixel_indices(x, y) {
949            None => panic!(
950                "Image index {:?} out of bounds {:?}",
951                (x, y),
952                (self.width, self.height)
953            ),
954            Some(pixel_indices) => <P as Pixel>::from_slice_mut(&mut self.data[pixel_indices]),
955        }
956    }
957
958    /// Gets a reference to the mutable pixel at location `(x, y)` or returns
959    /// `None` if the index is out of the bounds `(width, height)`.
960    pub fn get_pixel_mut_checked(&mut self, x: u32, y: u32) -> Option<&mut P> {
961        if x >= self.width {
962            return None;
963        }
964        let num_channels = <P as Pixel>::CHANNEL_COUNT as usize;
965        let i = (y as usize)
966            .saturating_mul(self.width as usize)
967            .saturating_add(x as usize)
968            .saturating_mul(num_channels);
969
970        self.data
971            .get_mut(i..i.checked_add(num_channels)?)
972            .map(|pixel_indices| <P as Pixel>::from_slice_mut(pixel_indices))
973    }
974
975    /// Puts a pixel at location `(x, y)`
976    ///
977    /// # Panics
978    ///
979    /// Panics if `(x, y)` is out of the bounds `(width, height)`.
980    #[inline]
981    #[track_caller]
982    pub fn put_pixel(&mut self, x: u32, y: u32, pixel: P) {
983        *self.get_pixel_mut(x, y) = pixel;
984    }
985}
986
987impl<P, Container> ImageBuffer<P, Container>
988where
989    P: Pixel,
990    [P::Subpixel]: EncodableLayout,
991    Container: Deref<Target = [P::Subpixel]>,
992{
993    /// Saves the buffer to a file at the path specified.
994    ///
995    /// The image format is derived from the file extension.
996    pub fn save<Q>(&self, path: Q) -> ImageResult<()>
997    where
998        Q: AsRef<Path>,
999        P: PixelWithColorType,
1000    {
1001        save_buffer(
1002            path,
1003            self.inner_pixels().as_bytes(),
1004            self.width(),
1005            self.height(),
1006            <P as PixelWithColorType>::COLOR_TYPE,
1007        )
1008    }
1009}
1010
1011impl<P, Container> ImageBuffer<P, Container>
1012where
1013    P: Pixel,
1014    [P::Subpixel]: EncodableLayout,
1015    Container: Deref<Target = [P::Subpixel]>,
1016{
1017    /// Saves the buffer to a file at the specified path in
1018    /// the specified format.
1019    ///
1020    /// See [`save_buffer_with_format`](fn.save_buffer_with_format.html) for
1021    /// supported types.
1022    pub fn save_with_format<Q>(&self, path: Q, format: ImageFormat) -> ImageResult<()>
1023    where
1024        Q: AsRef<Path>,
1025        P: PixelWithColorType,
1026    {
1027        // This is valid as the subpixel is u8.
1028        save_buffer_with_format(
1029            path,
1030            self.inner_pixels().as_bytes(),
1031            self.width(),
1032            self.height(),
1033            <P as PixelWithColorType>::COLOR_TYPE,
1034            format,
1035        )
1036    }
1037}
1038
1039impl<P, Container> ImageBuffer<P, Container>
1040where
1041    P: Pixel,
1042    [P::Subpixel]: EncodableLayout,
1043    Container: Deref<Target = [P::Subpixel]>,
1044{
1045    /// Writes the buffer to a writer in the specified format.
1046    ///
1047    /// Assumes the writer is buffered. In most cases, you should wrap your writer in a `BufWriter`
1048    /// for best performance.
1049    pub fn write_to<W>(&self, writer: &mut W, format: ImageFormat) -> ImageResult<()>
1050    where
1051        W: std::io::Write + std::io::Seek,
1052        P: PixelWithColorType,
1053    {
1054        // This is valid as the subpixel is u8.
1055        write_buffer_with_format(
1056            writer,
1057            self.inner_pixels().as_bytes(),
1058            self.width(),
1059            self.height(),
1060            <P as PixelWithColorType>::COLOR_TYPE,
1061            format,
1062        )
1063    }
1064}
1065
1066impl<P, Container> ImageBuffer<P, Container>
1067where
1068    P: Pixel,
1069    [P::Subpixel]: EncodableLayout,
1070    Container: Deref<Target = [P::Subpixel]>,
1071{
1072    /// Writes the buffer with the given encoder.
1073    pub fn write_with_encoder<E>(&self, encoder: E) -> ImageResult<()>
1074    where
1075        E: ImageEncoder,
1076        P: PixelWithColorType,
1077    {
1078        // This is valid as the subpixel is u8.
1079        encoder.write_image(
1080            self.inner_pixels().as_bytes(),
1081            self.width(),
1082            self.height(),
1083            <P as PixelWithColorType>::COLOR_TYPE,
1084        )
1085    }
1086}
1087
1088impl<P, Container> Default for ImageBuffer<P, Container>
1089where
1090    P: Pixel,
1091    Container: Default,
1092{
1093    fn default() -> Self {
1094        Self {
1095            width: 0,
1096            height: 0,
1097            _phantom: PhantomData,
1098            data: Default::default(),
1099        }
1100    }
1101}
1102
1103impl<P, Container> Deref for ImageBuffer<P, Container>
1104where
1105    P: Pixel,
1106    Container: Deref<Target = [P::Subpixel]>,
1107{
1108    type Target = [P::Subpixel];
1109
1110    fn deref(&self) -> &<Self as Deref>::Target {
1111        &self.data
1112    }
1113}
1114
1115impl<P, Container> DerefMut for ImageBuffer<P, Container>
1116where
1117    P: Pixel,
1118    Container: Deref<Target = [P::Subpixel]> + DerefMut,
1119{
1120    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
1121        &mut self.data
1122    }
1123}
1124
1125impl<P, Container> Index<(u32, u32)> for ImageBuffer<P, Container>
1126where
1127    P: Pixel,
1128    Container: Deref<Target = [P::Subpixel]>,
1129{
1130    type Output = P;
1131
1132    fn index(&self, (x, y): (u32, u32)) -> &P {
1133        self.get_pixel(x, y)
1134    }
1135}
1136
1137impl<P, Container> IndexMut<(u32, u32)> for ImageBuffer<P, Container>
1138where
1139    P: Pixel,
1140    Container: Deref<Target = [P::Subpixel]> + DerefMut,
1141{
1142    fn index_mut(&mut self, (x, y): (u32, u32)) -> &mut P {
1143        self.get_pixel_mut(x, y)
1144    }
1145}
1146
1147impl<P, Container> Clone for ImageBuffer<P, Container>
1148where
1149    P: Pixel,
1150    Container: Deref<Target = [P::Subpixel]> + Clone,
1151{
1152    fn clone(&self) -> ImageBuffer<P, Container> {
1153        ImageBuffer {
1154            data: self.data.clone(),
1155            width: self.width,
1156            height: self.height,
1157            _phantom: PhantomData,
1158        }
1159    }
1160
1161    fn clone_from(&mut self, source: &Self) {
1162        self.data.clone_from(&source.data);
1163        self.width = source.width;
1164        self.height = source.height;
1165    }
1166}
1167
1168impl<P, Container> GenericImageView for ImageBuffer<P, Container>
1169where
1170    P: Pixel,
1171    Container: Deref<Target = [P::Subpixel]> + Deref,
1172{
1173    type Pixel = P;
1174
1175    fn dimensions(&self) -> (u32, u32) {
1176        self.dimensions()
1177    }
1178
1179    fn get_pixel(&self, x: u32, y: u32) -> P {
1180        *self.get_pixel(x, y)
1181    }
1182
1183    /// Returns the pixel located at (x, y), ignoring bounds checking.
1184    #[inline(always)]
1185    unsafe fn unsafe_get_pixel(&self, x: u32, y: u32) -> P {
1186        let indices = self.pixel_indices_unchecked(x, y);
1187        *<P as Pixel>::from_slice(self.data.get_unchecked(indices))
1188    }
1189}
1190
1191impl<P, Container> GenericImage for ImageBuffer<P, Container>
1192where
1193    P: Pixel,
1194    Container: Deref<Target = [P::Subpixel]> + DerefMut,
1195{
1196    fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut P {
1197        self.get_pixel_mut(x, y)
1198    }
1199
1200    fn put_pixel(&mut self, x: u32, y: u32, pixel: P) {
1201        *self.get_pixel_mut(x, y) = pixel;
1202    }
1203
1204    /// Puts a pixel at location (x, y), ignoring bounds checking.
1205    #[inline(always)]
1206    unsafe fn unsafe_put_pixel(&mut self, x: u32, y: u32, pixel: P) {
1207        let indices = self.pixel_indices_unchecked(x, y);
1208        let p = <P as Pixel>::from_slice_mut(self.data.get_unchecked_mut(indices));
1209        *p = pixel;
1210    }
1211
1212    /// Put a pixel at location (x, y), taking into account alpha channels
1213    ///
1214    /// DEPRECATED: This method will be removed. Blend the pixel directly instead.
1215    fn blend_pixel(&mut self, x: u32, y: u32, p: P) {
1216        self.get_pixel_mut(x, y).blend(&p);
1217    }
1218
1219    fn copy_within(&mut self, source: Rect, x: u32, y: u32) -> bool {
1220        let Rect {
1221            x: sx,
1222            y: sy,
1223            width,
1224            height,
1225        } = source;
1226        let dx = x;
1227        let dy = y;
1228        assert!(sx < self.width() && dx < self.width());
1229        assert!(sy < self.height() && dy < self.height());
1230        if self.width() - dx.max(sx) < width || self.height() - dy.max(sy) < height {
1231            return false;
1232        }
1233
1234        if sy < dy {
1235            for y in (0..height).rev() {
1236                let sy = sy + y;
1237                let dy = dy + y;
1238                let Range { start, .. } = self.pixel_indices_unchecked(sx, sy);
1239                let Range { end, .. } = self.pixel_indices_unchecked(sx + width - 1, sy);
1240                let dst = self.pixel_indices_unchecked(dx, dy).start;
1241                self.data.copy_within(start..end, dst);
1242            }
1243        } else {
1244            for y in 0..height {
1245                let sy = sy + y;
1246                let dy = dy + y;
1247                let Range { start, .. } = self.pixel_indices_unchecked(sx, sy);
1248                let Range { end, .. } = self.pixel_indices_unchecked(sx + width - 1, sy);
1249                let dst = self.pixel_indices_unchecked(dx, dy).start;
1250                self.data.copy_within(start..end, dst);
1251            }
1252        }
1253        true
1254    }
1255}
1256
1257// concrete implementation for `Vec`-backed buffers
1258// TODO: I think that rustc does not "see" this impl any more: the impl with
1259// Container meets the same requirements. At least, I got compile errors that
1260// there is no such function as `into_vec`, whereas `into_raw` did work, and
1261// `into_vec` is redundant anyway, because `into_raw` will give you the vector,
1262// and it is more generic.
1263impl<P: Pixel> ImageBuffer<P, Vec<P::Subpixel>> {
1264    /// Creates a new image buffer based on a `Vec<P::Subpixel>`.
1265    ///
1266    /// all the pixels of this image have a value of zero, regardless of the data type or number of channels.
1267    ///
1268    /// # Panics
1269    ///
1270    /// Panics when the resulting image is larger than the maximum size of a vector.
1271    #[must_use]
1272    pub fn new(width: u32, height: u32) -> ImageBuffer<P, Vec<P::Subpixel>> {
1273        let size = Self::image_buffer_len(width, height)
1274            .expect("Buffer length in `ImageBuffer::new` overflows usize");
1275        ImageBuffer {
1276            data: vec![Zero::zero(); size],
1277            width,
1278            height,
1279            _phantom: PhantomData,
1280        }
1281    }
1282
1283    /// Constructs a new `ImageBuffer` by copying a pixel
1284    ///
1285    /// # Panics
1286    ///
1287    /// Panics when the resulting image is larger the the maximum size of a vector.
1288    pub fn from_pixel(width: u32, height: u32, pixel: P) -> ImageBuffer<P, Vec<P::Subpixel>> {
1289        let mut buf = ImageBuffer::new(width, height);
1290        for p in buf.pixels_mut() {
1291            *p = pixel;
1292        }
1293        buf
1294    }
1295
1296    /// Constructs a new `ImageBuffer` by repeated application of the supplied function.
1297    ///
1298    /// The arguments to the function are the pixel's x and y coordinates.
1299    ///
1300    /// # Panics
1301    ///
1302    /// Panics when the resulting image is larger the the maximum size of a vector.
1303    pub fn from_fn<F>(width: u32, height: u32, mut f: F) -> ImageBuffer<P, Vec<P::Subpixel>>
1304    where
1305        F: FnMut(u32, u32) -> P,
1306    {
1307        let mut buf = ImageBuffer::new(width, height);
1308        for (x, y, p) in buf.enumerate_pixels_mut() {
1309            *p = f(x, y);
1310        }
1311        buf
1312    }
1313
1314    /// Creates an image buffer out of an existing buffer.
1315    /// Returns None if the buffer is not big enough.
1316    #[must_use]
1317    pub fn from_vec(
1318        width: u32,
1319        height: u32,
1320        buf: Vec<P::Subpixel>,
1321    ) -> Option<ImageBuffer<P, Vec<P::Subpixel>>> {
1322        ImageBuffer::from_raw(width, height, buf)
1323    }
1324
1325    /// Consumes the image buffer and returns the underlying data
1326    /// as an owned buffer
1327    #[must_use]
1328    pub fn into_vec(self) -> Vec<P::Subpixel> {
1329        self.into_raw()
1330    }
1331}
1332
1333/// Provides color conversions for whole image buffers.
1334pub trait ConvertBuffer<T> {
1335    /// Converts `self` to a buffer of type T
1336    ///
1337    /// A generic implementation is provided to convert any image buffer to a image buffer
1338    /// based on a `Vec<T>`.
1339    fn convert(&self) -> T;
1340}
1341
1342// concrete implementation Luma -> Rgba
1343impl GrayImage {
1344    /// Expands a color palette by re-using the existing buffer.
1345    /// Assumes 8 bit per pixel. Uses an optionally transparent index to
1346    /// adjust it's alpha value accordingly.
1347    #[must_use]
1348    pub fn expand_palette(
1349        self,
1350        palette: &[(u8, u8, u8)],
1351        transparent_idx: Option<u8>,
1352    ) -> RgbaImage {
1353        let (width, height) = self.dimensions();
1354        let mut data = self.into_raw();
1355        let entries = data.len();
1356        data.resize(entries.checked_mul(4).unwrap(), 0);
1357        let mut buffer = ImageBuffer::from_vec(width, height, data).unwrap();
1358        expand_packed(&mut buffer, 4, 8, |idx, pixel| {
1359            let (r, g, b) = palette[idx as usize];
1360            let a = if let Some(t_idx) = transparent_idx {
1361                if t_idx == idx {
1362                    0
1363                } else {
1364                    255
1365                }
1366            } else {
1367                255
1368            };
1369            pixel[0] = r;
1370            pixel[1] = g;
1371            pixel[2] = b;
1372            pixel[3] = a;
1373        });
1374        buffer
1375    }
1376}
1377
1378// TODO: Equality constraints are not yet supported in where clauses, when they
1379// are, the T parameter should be removed in favor of ToType::Subpixel, which
1380// will then be FromType::Subpixel.
1381impl<Container, FromType: Pixel, ToType: Pixel>
1382    ConvertBuffer<ImageBuffer<ToType, Vec<ToType::Subpixel>>> for ImageBuffer<FromType, Container>
1383where
1384    Container: Deref<Target = [FromType::Subpixel]>,
1385    ToType: FromColor<FromType>,
1386{
1387    /// # Examples
1388    /// Convert RGB image to gray image.
1389    /// ```no_run
1390    /// use image::buffer::ConvertBuffer;
1391    /// use image::GrayImage;
1392    ///
1393    /// let image_path = "examples/fractal.png";
1394    /// let image = image::open(&image_path)
1395    ///     .expect("Open file failed")
1396    ///     .to_rgba8();
1397    ///
1398    /// let gray_image: GrayImage = image.convert();
1399    /// ```
1400    fn convert(&self) -> ImageBuffer<ToType, Vec<ToType::Subpixel>> {
1401        let mut buffer: ImageBuffer<ToType, Vec<ToType::Subpixel>> =
1402            ImageBuffer::new(self.width, self.height);
1403        for (to, from) in buffer.pixels_mut().zip(self.pixels()) {
1404            to.from_color(from);
1405        }
1406        buffer
1407    }
1408}
1409
1410/// Sendable Rgb image buffer
1411pub type RgbImage = ImageBuffer<Rgb<u8>, Vec<u8>>;
1412/// Sendable Rgb + alpha channel image buffer
1413pub type RgbaImage = ImageBuffer<Rgba<u8>, Vec<u8>>;
1414/// Sendable grayscale image buffer
1415pub type GrayImage = ImageBuffer<Luma<u8>, Vec<u8>>;
1416/// Sendable grayscale + alpha channel image buffer
1417pub type GrayAlphaImage = ImageBuffer<LumaA<u8>, Vec<u8>>;
1418/// Sendable 16-bit Rgb image buffer
1419pub(crate) type Rgb16Image = ImageBuffer<Rgb<u16>, Vec<u16>>;
1420/// Sendable 16-bit Rgb + alpha channel image buffer
1421pub(crate) type Rgba16Image = ImageBuffer<Rgba<u16>, Vec<u16>>;
1422/// Sendable 16-bit grayscale image buffer
1423pub(crate) type Gray16Image = ImageBuffer<Luma<u16>, Vec<u16>>;
1424/// Sendable 16-bit grayscale + alpha channel image buffer
1425pub(crate) type GrayAlpha16Image = ImageBuffer<LumaA<u16>, Vec<u16>>;
1426
1427/// An image buffer for 32-bit float RGB pixels,
1428/// where the backing container is a flattened vector of floats.
1429pub type Rgb32FImage = ImageBuffer<Rgb<f32>, Vec<f32>>;
1430
1431/// An image buffer for 32-bit float RGBA pixels,
1432/// where the backing container is a flattened vector of floats.
1433pub type Rgba32FImage = ImageBuffer<Rgba<f32>, Vec<f32>>;
1434
1435impl From<DynamicImage> for RgbImage {
1436    fn from(value: DynamicImage) -> Self {
1437        value.into_rgb8()
1438    }
1439}
1440
1441impl From<DynamicImage> for RgbaImage {
1442    fn from(value: DynamicImage) -> Self {
1443        value.into_rgba8()
1444    }
1445}
1446
1447impl From<DynamicImage> for GrayImage {
1448    fn from(value: DynamicImage) -> Self {
1449        value.into_luma8()
1450    }
1451}
1452
1453impl From<DynamicImage> for GrayAlphaImage {
1454    fn from(value: DynamicImage) -> Self {
1455        value.into_luma_alpha8()
1456    }
1457}
1458
1459impl From<DynamicImage> for Rgb16Image {
1460    fn from(value: DynamicImage) -> Self {
1461        value.into_rgb16()
1462    }
1463}
1464
1465impl From<DynamicImage> for Rgba16Image {
1466    fn from(value: DynamicImage) -> Self {
1467        value.into_rgba16()
1468    }
1469}
1470
1471impl From<DynamicImage> for Gray16Image {
1472    fn from(value: DynamicImage) -> Self {
1473        value.into_luma16()
1474    }
1475}
1476
1477impl From<DynamicImage> for GrayAlpha16Image {
1478    fn from(value: DynamicImage) -> Self {
1479        value.into_luma_alpha16()
1480    }
1481}
1482
1483impl From<DynamicImage> for Rgba32FImage {
1484    fn from(value: DynamicImage) -> Self {
1485        value.into_rgba32f()
1486    }
1487}
1488
1489#[cfg(test)]
1490mod test {
1491    use super::{GrayImage, ImageBuffer, RgbImage};
1492    use crate::math::Rect;
1493    use crate::GenericImage as _;
1494    use crate::ImageFormat;
1495    use crate::{Luma, LumaA, Pixel, Rgb, Rgba};
1496    use num_traits::Zero;
1497
1498    #[test]
1499    /// Tests if image buffers from slices work
1500    fn slice_buffer() {
1501        let data = [0; 9];
1502        let buf: ImageBuffer<Luma<u8>, _> = ImageBuffer::from_raw(3, 3, &data[..]).unwrap();
1503        assert_eq!(&*buf, &data[..])
1504    }
1505
1506    macro_rules! new_buffer_zero_test {
1507        ($test_name:ident, $pxt:ty) => {
1508            #[test]
1509            fn $test_name() {
1510                let buffer = ImageBuffer::<$pxt, Vec<<$pxt as Pixel>::Subpixel>>::new(2, 2);
1511                assert!(buffer
1512                    .iter()
1513                    .all(|p| *p == <$pxt as Pixel>::Subpixel::zero()));
1514            }
1515        };
1516    }
1517
1518    new_buffer_zero_test!(luma_u8_zero_test, Luma<u8>);
1519    new_buffer_zero_test!(luma_u16_zero_test, Luma<u16>);
1520    new_buffer_zero_test!(luma_f32_zero_test, Luma<f32>);
1521    new_buffer_zero_test!(luma_a_u8_zero_test, LumaA<u8>);
1522    new_buffer_zero_test!(luma_a_u16_zero_test, LumaA<u16>);
1523    new_buffer_zero_test!(luma_a_f32_zero_test, LumaA<f32>);
1524    new_buffer_zero_test!(rgb_u8_zero_test, Rgb<u8>);
1525    new_buffer_zero_test!(rgb_u16_zero_test, Rgb<u16>);
1526    new_buffer_zero_test!(rgb_f32_zero_test, Rgb<f32>);
1527    new_buffer_zero_test!(rgb_a_u8_zero_test, Rgba<u8>);
1528    new_buffer_zero_test!(rgb_a_u16_zero_test, Rgba<u16>);
1529    new_buffer_zero_test!(rgb_a_f32_zero_test, Rgba<f32>);
1530
1531    #[test]
1532    fn get_pixel() {
1533        let mut a: RgbImage = ImageBuffer::new(10, 10);
1534        {
1535            let b = a.get_mut(3 * 10).unwrap();
1536            *b = 255;
1537        }
1538        assert_eq!(a.get_pixel(0, 1)[0], 255)
1539    }
1540
1541    #[test]
1542    fn get_pixel_checked() {
1543        let mut a: RgbImage = ImageBuffer::new(10, 10);
1544        a.get_pixel_mut_checked(0, 1).unwrap()[0] = 255;
1545
1546        assert_eq!(a.get_pixel_checked(0, 1), Some(&Rgb([255, 0, 0])));
1547        assert_eq!(a.get_pixel_checked(0, 1).unwrap(), a.get_pixel(0, 1));
1548        assert_eq!(a.get_pixel_checked(10, 0), None);
1549        assert_eq!(a.get_pixel_checked(0, 10), None);
1550        assert_eq!(a.get_pixel_mut_checked(10, 0), None);
1551        assert_eq!(a.get_pixel_mut_checked(0, 10), None);
1552
1553        // From image/issues/1672
1554        const WHITE: Rgb<u8> = Rgb([255_u8, 255, 255]);
1555        let mut a = RgbImage::new(2, 1);
1556        a.put_pixel(1, 0, WHITE);
1557
1558        assert_eq!(a.get_pixel_checked(1, 0), Some(&WHITE));
1559        assert_eq!(a.get_pixel_checked(1, 0).unwrap(), a.get_pixel(1, 0));
1560    }
1561
1562    #[test]
1563    fn mut_iter() {
1564        let mut a: RgbImage = ImageBuffer::new(10, 10);
1565        {
1566            let val = a.pixels_mut().next().unwrap();
1567            *val = Rgb([42, 0, 0]);
1568        }
1569        assert_eq!(a.data[0], 42);
1570    }
1571
1572    #[test]
1573    fn zero_width_zero_height() {
1574        let mut image = RgbImage::new(0, 0);
1575
1576        assert_eq!(image.rows_mut().count(), 0);
1577        assert_eq!(image.pixels_mut().count(), 0);
1578        assert_eq!(image.rows().count(), 0);
1579        assert_eq!(image.pixels().count(), 0);
1580    }
1581
1582    #[test]
1583    fn zero_width_nonzero_height() {
1584        let mut image = RgbImage::new(0, 2);
1585
1586        assert_eq!(image.rows_mut().count(), 0);
1587        assert_eq!(image.pixels_mut().count(), 0);
1588        assert_eq!(image.rows().count(), 0);
1589        assert_eq!(image.pixels().count(), 0);
1590    }
1591
1592    #[test]
1593    fn nonzero_width_zero_height() {
1594        let mut image = RgbImage::new(2, 0);
1595
1596        assert_eq!(image.rows_mut().count(), 0);
1597        assert_eq!(image.pixels_mut().count(), 0);
1598        assert_eq!(image.rows().count(), 0);
1599        assert_eq!(image.pixels().count(), 0);
1600    }
1601
1602    #[test]
1603    fn pixels_on_large_buffer() {
1604        let mut image = RgbImage::from_raw(1, 1, vec![0; 6]).unwrap();
1605
1606        assert_eq!(image.pixels().count(), 1);
1607        assert_eq!(image.enumerate_pixels().count(), 1);
1608        assert_eq!(image.pixels_mut().count(), 1);
1609        assert_eq!(image.enumerate_pixels_mut().count(), 1);
1610
1611        assert_eq!(image.rows().count(), 1);
1612        assert_eq!(image.rows_mut().count(), 1);
1613    }
1614
1615    #[test]
1616    fn default() {
1617        let image = ImageBuffer::<Rgb<u8>, Vec<u8>>::default();
1618        assert_eq!(image.dimensions(), (0, 0));
1619    }
1620
1621    #[test]
1622    #[rustfmt::skip]
1623    fn test_image_buffer_copy_within_oob() {
1624        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, vec![0u8; 16]).unwrap();
1625        assert!(!image.copy_within(Rect { x: 0, y: 0, width: 5, height: 4 }, 0, 0));
1626        assert!(!image.copy_within(Rect { x: 0, y: 0, width: 4, height: 5 }, 0, 0));
1627        assert!(!image.copy_within(Rect { x: 1, y: 0, width: 4, height: 4 }, 0, 0));
1628        assert!(!image.copy_within(Rect { x: 0, y: 0, width: 4, height: 4 }, 1, 0));
1629        assert!(!image.copy_within(Rect { x: 0, y: 1, width: 4, height: 4 }, 0, 0));
1630        assert!(!image.copy_within(Rect { x: 0, y: 0, width: 4, height: 4 }, 0, 1));
1631        assert!(!image.copy_within(Rect { x: 1, y: 1, width: 4, height: 4 }, 0, 0));
1632    }
1633
1634    #[test]
1635    fn test_image_buffer_copy_within_tl() {
1636        let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1637        let expected = [0, 1, 2, 3, 4, 0, 1, 2, 8, 4, 5, 6, 12, 8, 9, 10];
1638        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1639        assert!(image.copy_within(
1640            Rect {
1641                x: 0,
1642                y: 0,
1643                width: 3,
1644                height: 3
1645            },
1646            1,
1647            1
1648        ));
1649        assert_eq!(&image.into_raw(), &expected);
1650    }
1651
1652    #[test]
1653    fn test_image_buffer_copy_within_tr() {
1654        let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1655        let expected = [0, 1, 2, 3, 1, 2, 3, 7, 5, 6, 7, 11, 9, 10, 11, 15];
1656        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1657        assert!(image.copy_within(
1658            Rect {
1659                x: 1,
1660                y: 0,
1661                width: 3,
1662                height: 3
1663            },
1664            0,
1665            1
1666        ));
1667        assert_eq!(&image.into_raw(), &expected);
1668    }
1669
1670    #[test]
1671    fn test_image_buffer_copy_within_bl() {
1672        let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1673        let expected = [0, 4, 5, 6, 4, 8, 9, 10, 8, 12, 13, 14, 12, 13, 14, 15];
1674        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1675        assert!(image.copy_within(
1676            Rect {
1677                x: 0,
1678                y: 1,
1679                width: 3,
1680                height: 3
1681            },
1682            1,
1683            0
1684        ));
1685        assert_eq!(&image.into_raw(), &expected);
1686    }
1687
1688    #[test]
1689    fn test_image_buffer_copy_within_br() {
1690        let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1691        let expected = [5, 6, 7, 3, 9, 10, 11, 7, 13, 14, 15, 11, 12, 13, 14, 15];
1692        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1693        assert!(image.copy_within(
1694            Rect {
1695                x: 1,
1696                y: 1,
1697                width: 3,
1698                height: 3
1699            },
1700            0,
1701            0
1702        ));
1703        assert_eq!(&image.into_raw(), &expected);
1704    }
1705
1706    #[test]
1707    #[cfg(feature = "png")]
1708    fn write_to_with_large_buffer() {
1709        // A buffer of 1 pixel, padded to 4 bytes as would be common in, e.g. BMP.
1710
1711        let img: GrayImage = ImageBuffer::from_raw(1, 1, vec![0u8; 4]).unwrap();
1712        let mut buffer = std::io::Cursor::new(vec![]);
1713        assert!(img.write_to(&mut buffer, ImageFormat::Png).is_ok());
1714    }
1715
1716    #[test]
1717    fn exact_size_iter_size_hint() {
1718        // The docs for `std::iter::ExactSizeIterator` requires that the implementation of
1719        // `size_hint` on the iterator returns the same value as the `len` implementation.
1720
1721        // This test should work for any size image.
1722        const N: u32 = 10;
1723
1724        let mut image = RgbImage::from_raw(N, N, vec![0; (N * N * 3) as usize]).unwrap();
1725
1726        let iter = image.pixels();
1727        let exact_len = ExactSizeIterator::len(&iter);
1728        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1729
1730        let iter = image.pixels_mut();
1731        let exact_len = ExactSizeIterator::len(&iter);
1732        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1733
1734        let iter = image.rows();
1735        let exact_len = ExactSizeIterator::len(&iter);
1736        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1737
1738        let iter = image.rows_mut();
1739        let exact_len = ExactSizeIterator::len(&iter);
1740        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1741
1742        let iter = image.enumerate_pixels();
1743        let exact_len = ExactSizeIterator::len(&iter);
1744        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1745
1746        let iter = image.enumerate_rows();
1747        let exact_len = ExactSizeIterator::len(&iter);
1748        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1749
1750        let iter = image.enumerate_pixels_mut();
1751        let exact_len = ExactSizeIterator::len(&iter);
1752        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1753
1754        let iter = image.enumerate_rows_mut();
1755        let exact_len = ExactSizeIterator::len(&iter);
1756        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1757    }
1758}
1759
1760#[cfg(test)]
1761#[cfg(feature = "benchmarks")]
1762mod benchmarks {
1763    use super::{ConvertBuffer, GrayImage, ImageBuffer, Pixel, RgbImage};
1764
1765    #[bench]
1766    fn conversion(b: &mut test::Bencher) {
1767        let mut a: RgbImage = ImageBuffer::new(1000, 1000);
1768        for p in a.pixels_mut() {
1769            let rgb = p.channels_mut();
1770            rgb[0] = 255;
1771            rgb[1] = 23;
1772            rgb[2] = 42;
1773        }
1774        assert!(a.data[0] != 0);
1775        b.iter(|| {
1776            let b: GrayImage = a.convert();
1777            assert!(0 != b.data[0]);
1778            assert!(a.data[0] != b.data[0]);
1779            test::black_box(b);
1780        });
1781        b.bytes = 1000 * 1000 * 3
1782    }
1783
1784    #[bench]
1785    fn image_access_row_by_row(b: &mut test::Bencher) {
1786        let mut a: RgbImage = ImageBuffer::new(1000, 1000);
1787        for p in a.pixels_mut() {
1788            let rgb = p.channels_mut();
1789            rgb[0] = 255;
1790            rgb[1] = 23;
1791            rgb[2] = 42;
1792        }
1793
1794        b.iter(move || {
1795            let image: &RgbImage = test::black_box(&a);
1796            let mut sum: usize = 0;
1797            for y in 0..1000 {
1798                for x in 0..1000 {
1799                    let pixel = image.get_pixel(x, y);
1800                    sum = sum.wrapping_add(pixel[0] as usize);
1801                    sum = sum.wrapping_add(pixel[1] as usize);
1802                    sum = sum.wrapping_add(pixel[2] as usize);
1803                }
1804            }
1805            test::black_box(sum)
1806        });
1807
1808        b.bytes = 1000 * 1000 * 3;
1809    }
1810
1811    #[bench]
1812    fn image_access_col_by_col(b: &mut test::Bencher) {
1813        let mut a: RgbImage = ImageBuffer::new(1000, 1000);
1814        for p in a.pixels_mut() {
1815            let rgb = p.channels_mut();
1816            rgb[0] = 255;
1817            rgb[1] = 23;
1818            rgb[2] = 42;
1819        }
1820
1821        b.iter(move || {
1822            let image: &RgbImage = test::black_box(&a);
1823            let mut sum: usize = 0;
1824            for x in 0..1000 {
1825                for y in 0..1000 {
1826                    let pixel = image.get_pixel(x, y);
1827                    sum = sum.wrapping_add(pixel[0] as usize);
1828                    sum = sum.wrapping_add(pixel[1] as usize);
1829                    sum = sum.wrapping_add(pixel[2] as usize);
1830                }
1831            }
1832            test::black_box(sum)
1833        });
1834
1835        b.bytes = 1000 * 1000 * 3;
1836    }
1837}