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.is_some_and(|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 than 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 than 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}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy