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, ImageOutputFormat};
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: &[

::Subpixel]| <P as Pixel>::from_slice(v))

36 }
37
38 #[inline(always)]
39 fn size_hint(&self) -> (usize, Option<usize>) {
40 let len: usize = 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: &[

::Subpixel]| <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&mut DebugStruct<'_, '_>.debug_struct("Pixels")
78 .field(name:"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: &mut [

::Subpixel]| <P as Pixel>::from_slice_mut(slice:v))

100 }
101
102 #[inline(always)]
103 fn size_hint(&self) -> (usize, Option<usize>) {
104 let len: usize = 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: &mut [

::Subpixel]| <P as Pixel>::from_slice_mut(slice: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&mut DebugStruct<'_, '_>.debug_struct("PixelsMut")
136 .field(name:"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: usize = (width as usize) * usize::from(<P as Pixel>::CHANNEL_COUNT);
158 if row_len == 0 {
159 Rows {
160 pixels: [].chunks_exact(chunk_size:1),
161 }
162 } else {
163 let pixels: &[

::Subpixel] = pixels

164 .get(..row_len * height as usize)
165 .expect(msg:"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(chunk_size: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: &[

::Subpixel] = 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: usize = 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: &[

::Subpixel] = 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&mut DebugStruct<'_, '_>.debug_struct("Rows")
234 .field(name:"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: usize = (width as usize) * usize::from(<P as Pixel>::CHANNEL_COUNT);
256 if row_len == 0 {
257 RowsMut {
258 pixels: [].chunks_exact_mut(chunk_size:1),
259 }
260 } else {
261 let pixels: &mut [

::Subpixel] = pixels

262 .get_mut(..row_len * height as usize)
263 .expect(msg:"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(chunk_size: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: &mut [

::Subpixel] = 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: usize = 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: &mut [

::Subpixel] = 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&mut DebugStruct<'_, '_>.debug_struct("RowsMut")
324 .field(name:"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: u32, y: u32) = (self.x, self.y);
353 self.x += 1;
354 self.pixels.next().map(|p: &P| (x, y, p))
355 }
356
357 #[inline(always)]
358 fn size_hint(&self) -> (usize, Option<usize>) {
359 let len: usize = 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&mut DebugStruct<'_, '_>.debug_struct("EnumeratePixels")
388 .field("pixels", &self.pixels)
389 .field("x", &self.x)
390 .field("y", &self.y)
391 .field(name:"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&mut DebugStruct<'_, '_>.debug_struct("EnumerateRows")
460 .field("rows", &self.rows)
461 .field("y", &self.y)
462 .field(name:"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: u32, y: u32) = (self.x, self.y);
491 self.x += 1;
492 self.pixels.next().map(|p: &mut P| (x, y, p))
493 }
494
495 #[inline(always)]
496 fn size_hint(&self) -> (usize, Option<usize>) {
497 let len: usize = 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&mut DebugStruct<'_, '_>.debug_struct("EnumeratePixelsMut")
517 .field("pixels", &self.pixels)
518 .field("x", &self.x)
519 .field("y", &self.y)
520 .field(name:"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&mut DebugStruct<'_, '_>.debug_struct("EnumerateRowsMut")
580 .field("rows", &self.rows)
581 .field("y", &self.y)
582 .field(name:"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(|min_len| min_len <= len).unwrap_or(false)
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,
1048 /// you should wrap your writer in a `BufWriter` for best performance.
1049 ///
1050 /// See [`ImageOutputFormat`](enum.ImageOutputFormat.html) for
1051 /// supported types.
1052 pub fn write_to<W, F>(&self, writer: &mut W, format: F) -> ImageResult<()>
1053 where
1054 W: std::io::Write + std::io::Seek,
1055 F: Into<ImageOutputFormat>,
1056 P: PixelWithColorType,
1057 {
1058 // This is valid as the subpixel is u8.
1059 write_buffer_with_format(
1060 writer,
1061 self.inner_pixels().as_bytes(),
1062 self.width(),
1063 self.height(),
1064 <P as PixelWithColorType>::COLOR_TYPE,
1065 format,
1066 )
1067 }
1068}
1069
1070impl<P, Container> ImageBuffer<P, Container>
1071where
1072 P: Pixel,
1073 [P::Subpixel]: EncodableLayout,
1074 Container: Deref<Target = [P::Subpixel]>,
1075{
1076 /// Writes the buffer with the given encoder.
1077 pub fn write_with_encoder<E>(&self, encoder: E) -> ImageResult<()>
1078 where
1079 E: ImageEncoder,
1080 P: PixelWithColorType,
1081 {
1082 // This is valid as the subpixel is u8.
1083 encoder.write_image(
1084 self.inner_pixels().as_bytes(),
1085 self.width(),
1086 self.height(),
1087 <P as PixelWithColorType>::COLOR_TYPE,
1088 )
1089 }
1090}
1091
1092impl<P, Container> Default for ImageBuffer<P, Container>
1093where
1094 P: Pixel,
1095 Container: Default,
1096{
1097 fn default() -> Self {
1098 Self {
1099 width: 0,
1100 height: 0,
1101 _phantom: PhantomData,
1102 data: Default::default(),
1103 }
1104 }
1105}
1106
1107impl<P, Container> Deref for ImageBuffer<P, Container>
1108where
1109 P: Pixel,
1110 Container: Deref<Target = [P::Subpixel]>,
1111{
1112 type Target = [P::Subpixel];
1113
1114 fn deref(&self) -> &<Self as Deref>::Target {
1115 &self.data
1116 }
1117}
1118
1119impl<P, Container> DerefMut for ImageBuffer<P, Container>
1120where
1121 P: Pixel,
1122 Container: Deref<Target = [P::Subpixel]> + DerefMut,
1123{
1124 fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
1125 &mut self.data
1126 }
1127}
1128
1129impl<P, Container> Index<(u32, u32)> for ImageBuffer<P, Container>
1130where
1131 P: Pixel,
1132 Container: Deref<Target = [P::Subpixel]>,
1133{
1134 type Output = P;
1135
1136 fn index(&self, (x: u32, y: u32): (u32, u32)) -> &P {
1137 self.get_pixel(x, y)
1138 }
1139}
1140
1141impl<P, Container> IndexMut<(u32, u32)> for ImageBuffer<P, Container>
1142where
1143 P: Pixel,
1144 Container: Deref<Target = [P::Subpixel]> + DerefMut,
1145{
1146 fn index_mut(&mut self, (x: u32, y: u32): (u32, u32)) -> &mut P {
1147 self.get_pixel_mut(x, y)
1148 }
1149}
1150
1151impl<P, Container> Clone for ImageBuffer<P, Container>
1152where
1153 P: Pixel,
1154 Container: Deref<Target = [P::Subpixel]> + Clone,
1155{
1156 fn clone(&self) -> ImageBuffer<P, Container> {
1157 ImageBuffer {
1158 data: self.data.clone(),
1159 width: self.width,
1160 height: self.height,
1161 _phantom: PhantomData,
1162 }
1163 }
1164}
1165
1166impl<P, Container> GenericImageView for ImageBuffer<P, Container>
1167where
1168 P: Pixel,
1169 Container: Deref<Target = [P::Subpixel]> + Deref,
1170{
1171 type Pixel = P;
1172
1173 fn dimensions(&self) -> (u32, u32) {
1174 self.dimensions()
1175 }
1176
1177 fn bounds(&self) -> (u32, u32, u32, u32) {
1178 (0, 0, self.width, self.height)
1179 }
1180
1181 fn get_pixel(&self, x: u32, y: u32) -> P {
1182 *self.get_pixel(x, y)
1183 }
1184
1185 /// Returns the pixel located at (x, y), ignoring bounds checking.
1186 #[inline(always)]
1187 unsafe fn unsafe_get_pixel(&self, x: u32, y: u32) -> P {
1188 let indices: Range = self.pixel_indices_unchecked(x, y);
1189 *<P as Pixel>::from_slice(self.data.get_unchecked(index:indices))
1190 }
1191}
1192
1193impl<P, Container> GenericImage for ImageBuffer<P, Container>
1194where
1195 P: Pixel,
1196 Container: Deref<Target = [P::Subpixel]> + DerefMut,
1197{
1198 fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut P {
1199 self.get_pixel_mut(x, y)
1200 }
1201
1202 fn put_pixel(&mut self, x: u32, y: u32, pixel: P) {
1203 *self.get_pixel_mut(x, y) = pixel
1204 }
1205
1206 /// Puts a pixel at location (x, y), ignoring bounds checking.
1207 #[inline(always)]
1208 unsafe fn unsafe_put_pixel(&mut self, x: u32, y: u32, pixel: P) {
1209 let indices = self.pixel_indices_unchecked(x, y);
1210 let p = <P as Pixel>::from_slice_mut(self.data.get_unchecked_mut(indices));
1211 *p = pixel
1212 }
1213
1214 /// Put a pixel at location (x, y), taking into account alpha channels
1215 ///
1216 /// DEPRECATED: This method will be removed. Blend the pixel directly instead.
1217 fn blend_pixel(&mut self, x: u32, y: u32, p: P) {
1218 self.get_pixel_mut(x, y).blend(&p)
1219 }
1220
1221 fn copy_within(&mut self, source: Rect, x: u32, y: u32) -> bool {
1222 let Rect {
1223 x: sx,
1224 y: sy,
1225 width,
1226 height,
1227 } = source;
1228 let dx = x;
1229 let dy = y;
1230 assert!(sx < self.width() && dx < self.width());
1231 assert!(sy < self.height() && dy < self.height());
1232 if self.width() - dx.max(sx) < width || self.height() - dy.max(sy) < height {
1233 return false;
1234 }
1235
1236 if sy < dy {
1237 for y in (0..height).rev() {
1238 let sy = sy + y;
1239 let dy = dy + y;
1240 let Range { start, .. } = self.pixel_indices_unchecked(sx, sy);
1241 let Range { end, .. } = self.pixel_indices_unchecked(sx + width - 1, sy);
1242 let dst = self.pixel_indices_unchecked(dx, dy).start;
1243 self.data.copy_within(start..end, dst);
1244 }
1245 } else {
1246 for y in 0..height {
1247 let sy = sy + y;
1248 let dy = dy + y;
1249 let Range { start, .. } = self.pixel_indices_unchecked(sx, sy);
1250 let Range { end, .. } = self.pixel_indices_unchecked(sx + width - 1, sy);
1251 let dst = self.pixel_indices_unchecked(dx, dy).start;
1252 self.data.copy_within(start..end, dst);
1253 }
1254 }
1255 true
1256 }
1257}
1258
1259// concrete implementation for `Vec`-backed buffers
1260// TODO: I think that rustc does not "see" this impl any more: the impl with
1261// Container meets the same requirements. At least, I got compile errors that
1262// there is no such function as `into_vec`, whereas `into_raw` did work, and
1263// `into_vec` is redundant anyway, because `into_raw` will give you the vector,
1264// and it is more generic.
1265impl<P: Pixel> ImageBuffer<P, Vec<P::Subpixel>> {
1266 /// Creates a new image buffer based on a `Vec<P::Subpixel>`.
1267 ///
1268 /// # Panics
1269 ///
1270 /// Panics when the resulting image is larger than the maximum size of a vector.
1271 pub fn new(width: u32, height: u32) -> ImageBuffer<P, Vec<P::Subpixel>> {
1272 let size = Self::image_buffer_len(width, height)
1273 .expect("Buffer length in `ImageBuffer::new` overflows usize");
1274 ImageBuffer {
1275 data: vec![Zero::zero(); size],
1276 width,
1277 height,
1278 _phantom: PhantomData,
1279 }
1280 }
1281
1282 /// Constructs a new ImageBuffer by copying a pixel
1283 ///
1284 /// # Panics
1285 ///
1286 /// Panics when the resulting image is larger the the maximum size of a vector.
1287 pub fn from_pixel(width: u32, height: u32, pixel: P) -> ImageBuffer<P, Vec<P::Subpixel>> {
1288 let mut buf = ImageBuffer::new(width, height);
1289 for p in buf.pixels_mut() {
1290 *p = pixel
1291 }
1292 buf
1293 }
1294
1295 /// Constructs a new ImageBuffer by repeated application of the supplied function.
1296 ///
1297 /// The arguments to the function are the pixel's x and y coordinates.
1298 ///
1299 /// # Panics
1300 ///
1301 /// Panics when the resulting image is larger the the maximum size of a vector.
1302 pub fn from_fn<F>(width: u32, height: u32, mut f: F) -> ImageBuffer<P, Vec<P::Subpixel>>
1303 where
1304 F: FnMut(u32, u32) -> P,
1305 {
1306 let mut buf = ImageBuffer::new(width, height);
1307 for (x, y, p) in buf.enumerate_pixels_mut() {
1308 *p = f(x, y)
1309 }
1310 buf
1311 }
1312
1313 /// Creates an image buffer out of an existing buffer.
1314 /// Returns None if the buffer is not big enough.
1315 pub fn from_vec(
1316 width: u32,
1317 height: u32,
1318 buf: Vec<P::Subpixel>,
1319 ) -> Option<ImageBuffer<P, Vec<P::Subpixel>>> {
1320 ImageBuffer::from_raw(width, height, buf)
1321 }
1322
1323 /// Consumes the image buffer and returns the underlying data
1324 /// as an owned buffer
1325 pub fn into_vec(self) -> Vec<P::Subpixel> {
1326 self.into_raw()
1327 }
1328}
1329
1330/// Provides color conversions for whole image buffers.
1331pub trait ConvertBuffer<T> {
1332 /// Converts `self` to a buffer of type T
1333 ///
1334 /// A generic implementation is provided to convert any image buffer to a image buffer
1335 /// based on a `Vec<T>`.
1336 fn convert(&self) -> T;
1337}
1338
1339// concrete implementation Luma -> Rgba
1340impl GrayImage {
1341 /// Expands a color palette by re-using the existing buffer.
1342 /// Assumes 8 bit per pixel. Uses an optionally transparent index to
1343 /// adjust it's alpha value accordingly.
1344 pub fn expand_palette(
1345 self,
1346 palette: &[(u8, u8, u8)],
1347 transparent_idx: Option<u8>,
1348 ) -> RgbaImage {
1349 let (width, height) = self.dimensions();
1350 let mut data = self.into_raw();
1351 let entries = data.len();
1352 data.resize(entries.checked_mul(4).unwrap(), 0);
1353 let mut buffer = ImageBuffer::from_vec(width, height, data).unwrap();
1354 expand_packed(&mut buffer, 4, 8, |idx, pixel| {
1355 let (r, g, b) = palette[idx as usize];
1356 let a = if let Some(t_idx) = transparent_idx {
1357 if t_idx == idx {
1358 0
1359 } else {
1360 255
1361 }
1362 } else {
1363 255
1364 };
1365 pixel[0] = r;
1366 pixel[1] = g;
1367 pixel[2] = b;
1368 pixel[3] = a;
1369 });
1370 buffer
1371 }
1372}
1373
1374// TODO: Equality constraints are not yet supported in where clauses, when they
1375// are, the T parameter should be removed in favor of ToType::Subpixel, which
1376// will then be FromType::Subpixel.
1377impl<Container, FromType: Pixel, ToType: Pixel>
1378 ConvertBuffer<ImageBuffer<ToType, Vec<ToType::Subpixel>>> for ImageBuffer<FromType, Container>
1379where
1380 Container: Deref<Target = [FromType::Subpixel]>,
1381 ToType: FromColor<FromType>,
1382{
1383 /// # Examples
1384 /// Convert RGB image to gray image.
1385 /// ```no_run
1386 /// use image::buffer::ConvertBuffer;
1387 /// use image::GrayImage;
1388 ///
1389 /// let image_path = "examples/fractal.png";
1390 /// let image = image::open(&image_path)
1391 /// .expect("Open file failed")
1392 /// .to_rgba8();
1393 ///
1394 /// let gray_image: GrayImage = image.convert();
1395 /// ```
1396 fn convert(&self) -> ImageBuffer<ToType, Vec<ToType::Subpixel>> {
1397 let mut buffer: ImageBuffer<ToType, Vec<ToType::Subpixel>> =
1398 ImageBuffer::new(self.width, self.height);
1399 for (to: &mut ToType, from: &FromType) in buffer.pixels_mut().zip(self.pixels()) {
1400 to.from_color(from)
1401 }
1402 buffer
1403 }
1404}
1405
1406/// Sendable Rgb image buffer
1407pub type RgbImage = ImageBuffer<Rgb<u8>, Vec<u8>>;
1408/// Sendable Rgb + alpha channel image buffer
1409pub type RgbaImage = ImageBuffer<Rgba<u8>, Vec<u8>>;
1410/// Sendable grayscale image buffer
1411pub type GrayImage = ImageBuffer<Luma<u8>, Vec<u8>>;
1412/// Sendable grayscale + alpha channel image buffer
1413pub type GrayAlphaImage = ImageBuffer<LumaA<u8>, Vec<u8>>;
1414/// Sendable 16-bit Rgb image buffer
1415pub(crate) type Rgb16Image = ImageBuffer<Rgb<u16>, Vec<u16>>;
1416/// Sendable 16-bit Rgb + alpha channel image buffer
1417pub(crate) type Rgba16Image = ImageBuffer<Rgba<u16>, Vec<u16>>;
1418/// Sendable 16-bit grayscale image buffer
1419pub(crate) type Gray16Image = ImageBuffer<Luma<u16>, Vec<u16>>;
1420/// Sendable 16-bit grayscale + alpha channel image buffer
1421pub(crate) type GrayAlpha16Image = ImageBuffer<LumaA<u16>, Vec<u16>>;
1422
1423/// An image buffer for 32-bit float RGB pixels,
1424/// where the backing container is a flattened vector of floats.
1425pub type Rgb32FImage = ImageBuffer<Rgb<f32>, Vec<f32>>;
1426
1427/// An image buffer for 32-bit float RGBA pixels,
1428/// where the backing container is a flattened vector of floats.
1429pub type Rgba32FImage = ImageBuffer<Rgba<f32>, Vec<f32>>;
1430
1431impl From<DynamicImage> for RgbImage {
1432 fn from(value: DynamicImage) -> Self {
1433 value.into_rgb8()
1434 }
1435}
1436
1437impl From<DynamicImage> for RgbaImage {
1438 fn from(value: DynamicImage) -> Self {
1439 value.into_rgba8()
1440 }
1441}
1442
1443impl From<DynamicImage> for GrayImage {
1444 fn from(value: DynamicImage) -> Self {
1445 value.into_luma8()
1446 }
1447}
1448
1449impl From<DynamicImage> for GrayAlphaImage {
1450 fn from(value: DynamicImage) -> Self {
1451 value.into_luma_alpha8()
1452 }
1453}
1454
1455impl From<DynamicImage> for Rgb16Image {
1456 fn from(value: DynamicImage) -> Self {
1457 value.into_rgb16()
1458 }
1459}
1460
1461impl From<DynamicImage> for Rgba16Image {
1462 fn from(value: DynamicImage) -> Self {
1463 value.into_rgba16()
1464 }
1465}
1466
1467impl From<DynamicImage> for Gray16Image {
1468 fn from(value: DynamicImage) -> Self {
1469 value.into_luma16()
1470 }
1471}
1472
1473impl From<DynamicImage> for GrayAlpha16Image {
1474 fn from(value: DynamicImage) -> Self {
1475 value.into_luma_alpha16()
1476 }
1477}
1478
1479impl From<DynamicImage> for Rgba32FImage {
1480 fn from(value: DynamicImage) -> Self {
1481 value.into_rgba32f()
1482 }
1483}
1484
1485#[cfg(test)]
1486mod test {
1487 use super::{GrayImage, ImageBuffer, ImageOutputFormat, RgbImage};
1488 use crate::math::Rect;
1489 use crate::GenericImage as _;
1490 use crate::{color, Rgb};
1491
1492 #[test]
1493 /// Tests if image buffers from slices work
1494 fn slice_buffer() {
1495 let data = [0; 9];
1496 let buf: ImageBuffer<color::Luma<u8>, _> = ImageBuffer::from_raw(3, 3, &data[..]).unwrap();
1497 assert_eq!(&*buf, &data[..])
1498 }
1499
1500 #[test]
1501 fn get_pixel() {
1502 let mut a: RgbImage = ImageBuffer::new(10, 10);
1503 {
1504 let b = a.get_mut(3 * 10).unwrap();
1505 *b = 255;
1506 }
1507 assert_eq!(a.get_pixel(0, 1)[0], 255)
1508 }
1509
1510 #[test]
1511 fn get_pixel_checked() {
1512 let mut a: RgbImage = ImageBuffer::new(10, 10);
1513 a.get_pixel_mut_checked(0, 1).unwrap()[0] = 255;
1514
1515 assert_eq!(a.get_pixel_checked(0, 1), Some(&Rgb([255, 0, 0])));
1516 assert_eq!(a.get_pixel_checked(0, 1).unwrap(), a.get_pixel(0, 1));
1517 assert_eq!(a.get_pixel_checked(10, 0), None);
1518 assert_eq!(a.get_pixel_checked(0, 10), None);
1519 assert_eq!(a.get_pixel_mut_checked(10, 0), None);
1520 assert_eq!(a.get_pixel_mut_checked(0, 10), None);
1521
1522 // From image/issues/1672
1523 const WHITE: Rgb<u8> = Rgb([255_u8, 255, 255]);
1524 let mut a = RgbImage::new(2, 1);
1525 a.put_pixel(1, 0, WHITE);
1526
1527 assert_eq!(a.get_pixel_checked(1, 0), Some(&WHITE));
1528 assert_eq!(a.get_pixel_checked(1, 0).unwrap(), a.get_pixel(1, 0));
1529 }
1530
1531 #[test]
1532 fn mut_iter() {
1533 let mut a: RgbImage = ImageBuffer::new(10, 10);
1534 {
1535 let val = a.pixels_mut().next().unwrap();
1536 *val = Rgb([42, 0, 0]);
1537 }
1538 assert_eq!(a.data[0], 42)
1539 }
1540
1541 #[test]
1542 fn zero_width_zero_height() {
1543 let mut image = RgbImage::new(0, 0);
1544
1545 assert_eq!(image.rows_mut().count(), 0);
1546 assert_eq!(image.pixels_mut().count(), 0);
1547 assert_eq!(image.rows().count(), 0);
1548 assert_eq!(image.pixels().count(), 0);
1549 }
1550
1551 #[test]
1552 fn zero_width_nonzero_height() {
1553 let mut image = RgbImage::new(0, 2);
1554
1555 assert_eq!(image.rows_mut().count(), 0);
1556 assert_eq!(image.pixels_mut().count(), 0);
1557 assert_eq!(image.rows().count(), 0);
1558 assert_eq!(image.pixels().count(), 0);
1559 }
1560
1561 #[test]
1562 fn nonzero_width_zero_height() {
1563 let mut image = RgbImage::new(2, 0);
1564
1565 assert_eq!(image.rows_mut().count(), 0);
1566 assert_eq!(image.pixels_mut().count(), 0);
1567 assert_eq!(image.rows().count(), 0);
1568 assert_eq!(image.pixels().count(), 0);
1569 }
1570
1571 #[test]
1572 fn pixels_on_large_buffer() {
1573 let mut image = RgbImage::from_raw(1, 1, vec![0; 6]).unwrap();
1574
1575 assert_eq!(image.pixels().count(), 1);
1576 assert_eq!(image.enumerate_pixels().count(), 1);
1577 assert_eq!(image.pixels_mut().count(), 1);
1578 assert_eq!(image.enumerate_pixels_mut().count(), 1);
1579
1580 assert_eq!(image.rows().count(), 1);
1581 assert_eq!(image.rows_mut().count(), 1);
1582 }
1583
1584 #[test]
1585 fn default() {
1586 let image = ImageBuffer::<Rgb<u8>, Vec<u8>>::default();
1587 assert_eq!(image.dimensions(), (0, 0));
1588 }
1589
1590 #[test]
1591 #[rustfmt::skip]
1592 fn test_image_buffer_copy_within_oob() {
1593 let mut image: GrayImage = ImageBuffer::from_raw(4, 4, vec![0u8; 16]).unwrap();
1594 assert!(!image.copy_within(Rect { x: 0, y: 0, width: 5, height: 4 }, 0, 0));
1595 assert!(!image.copy_within(Rect { x: 0, y: 0, width: 4, height: 5 }, 0, 0));
1596 assert!(!image.copy_within(Rect { x: 1, y: 0, width: 4, height: 4 }, 0, 0));
1597 assert!(!image.copy_within(Rect { x: 0, y: 0, width: 4, height: 4 }, 1, 0));
1598 assert!(!image.copy_within(Rect { x: 0, y: 1, width: 4, height: 4 }, 0, 0));
1599 assert!(!image.copy_within(Rect { x: 0, y: 0, width: 4, height: 4 }, 0, 1));
1600 assert!(!image.copy_within(Rect { x: 1, y: 1, width: 4, height: 4 }, 0, 0));
1601 }
1602
1603 #[test]
1604 fn test_image_buffer_copy_within_tl() {
1605 let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1606 let expected = [0, 1, 2, 3, 4, 0, 1, 2, 8, 4, 5, 6, 12, 8, 9, 10];
1607 let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1608 assert!(image.copy_within(
1609 Rect {
1610 x: 0,
1611 y: 0,
1612 width: 3,
1613 height: 3
1614 },
1615 1,
1616 1
1617 ));
1618 assert_eq!(&image.into_raw(), &expected);
1619 }
1620
1621 #[test]
1622 fn test_image_buffer_copy_within_tr() {
1623 let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1624 let expected = [0, 1, 2, 3, 1, 2, 3, 7, 5, 6, 7, 11, 9, 10, 11, 15];
1625 let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1626 assert!(image.copy_within(
1627 Rect {
1628 x: 1,
1629 y: 0,
1630 width: 3,
1631 height: 3
1632 },
1633 0,
1634 1
1635 ));
1636 assert_eq!(&image.into_raw(), &expected);
1637 }
1638
1639 #[test]
1640 fn test_image_buffer_copy_within_bl() {
1641 let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1642 let expected = [0, 4, 5, 6, 4, 8, 9, 10, 8, 12, 13, 14, 12, 13, 14, 15];
1643 let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1644 assert!(image.copy_within(
1645 Rect {
1646 x: 0,
1647 y: 1,
1648 width: 3,
1649 height: 3
1650 },
1651 1,
1652 0
1653 ));
1654 assert_eq!(&image.into_raw(), &expected);
1655 }
1656
1657 #[test]
1658 fn test_image_buffer_copy_within_br() {
1659 let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1660 let expected = [5, 6, 7, 3, 9, 10, 11, 7, 13, 14, 15, 11, 12, 13, 14, 15];
1661 let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1662 assert!(image.copy_within(
1663 Rect {
1664 x: 1,
1665 y: 1,
1666 width: 3,
1667 height: 3
1668 },
1669 0,
1670 0
1671 ));
1672 assert_eq!(&image.into_raw(), &expected);
1673 }
1674
1675 #[test]
1676 #[cfg(feature = "png")]
1677 fn write_to_with_large_buffer() {
1678 // A buffer of 1 pixel, padded to 4 bytes as would be common in, e.g. BMP.
1679 let img: GrayImage = ImageBuffer::from_raw(1, 1, vec![0u8; 4]).unwrap();
1680 let mut buffer = std::io::Cursor::new(vec![]);
1681 assert!(img.write_to(&mut buffer, ImageOutputFormat::Png).is_ok());
1682 }
1683
1684 #[test]
1685 fn exact_size_iter_size_hint() {
1686 // The docs for `std::iter::ExactSizeIterator` requires that the implementation of
1687 // `size_hint` on the iterator returns the same value as the `len` implementation.
1688
1689 // This test should work for any size image.
1690 const N: u32 = 10;
1691
1692 let mut image = RgbImage::from_raw(N, N, vec![0; (N * N * 3) as usize]).unwrap();
1693
1694 let iter = image.pixels();
1695 let exact_len = ExactSizeIterator::len(&iter);
1696 assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1697
1698 let iter = image.pixels_mut();
1699 let exact_len = ExactSizeIterator::len(&iter);
1700 assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1701
1702 let iter = image.rows();
1703 let exact_len = ExactSizeIterator::len(&iter);
1704 assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1705
1706 let iter = image.rows_mut();
1707 let exact_len = ExactSizeIterator::len(&iter);
1708 assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1709
1710 let iter = image.enumerate_pixels();
1711 let exact_len = ExactSizeIterator::len(&iter);
1712 assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1713
1714 let iter = image.enumerate_rows();
1715 let exact_len = ExactSizeIterator::len(&iter);
1716 assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1717
1718 let iter = image.enumerate_pixels_mut();
1719 let exact_len = ExactSizeIterator::len(&iter);
1720 assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1721
1722 let iter = image.enumerate_rows_mut();
1723 let exact_len = ExactSizeIterator::len(&iter);
1724 assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
1725 }
1726}
1727
1728#[cfg(test)]
1729#[cfg(feature = "benchmarks")]
1730mod benchmarks {
1731 use super::{ConvertBuffer, GrayImage, ImageBuffer, Pixel, RgbImage};
1732
1733 #[bench]
1734 fn conversion(b: &mut test::Bencher) {
1735 let mut a: RgbImage = ImageBuffer::new(1000, 1000);
1736 for p in a.pixels_mut() {
1737 let rgb = p.channels_mut();
1738 rgb[0] = 255;
1739 rgb[1] = 23;
1740 rgb[2] = 42;
1741 }
1742 assert!(a.data[0] != 0);
1743 b.iter(|| {
1744 let b: GrayImage = a.convert();
1745 assert!(0 != b.data[0]);
1746 assert!(a.data[0] != b.data[0]);
1747 test::black_box(b);
1748 });
1749 b.bytes = 1000 * 1000 * 3
1750 }
1751
1752 #[bench]
1753 fn image_access_row_by_row(b: &mut test::Bencher) {
1754 let mut a: RgbImage = ImageBuffer::new(1000, 1000);
1755 for p in a.pixels_mut() {
1756 let rgb = p.channels_mut();
1757 rgb[0] = 255;
1758 rgb[1] = 23;
1759 rgb[2] = 42;
1760 }
1761
1762 b.iter(move || {
1763 let image: &RgbImage = test::black_box(&a);
1764 let mut sum: usize = 0;
1765 for y in 0..1000 {
1766 for x in 0..1000 {
1767 let pixel = image.get_pixel(x, y);
1768 sum = sum.wrapping_add(pixel[0] as usize);
1769 sum = sum.wrapping_add(pixel[1] as usize);
1770 sum = sum.wrapping_add(pixel[2] as usize);
1771 }
1772 }
1773 test::black_box(sum)
1774 });
1775
1776 b.bytes = 1000 * 1000 * 3;
1777 }
1778
1779 #[bench]
1780 fn image_access_col_by_col(b: &mut test::Bencher) {
1781 let mut a: RgbImage = ImageBuffer::new(1000, 1000);
1782 for p in a.pixels_mut() {
1783 let rgb = p.channels_mut();
1784 rgb[0] = 255;
1785 rgb[1] = 23;
1786 rgb[2] = 42;
1787 }
1788
1789 b.iter(move || {
1790 let image: &RgbImage = test::black_box(&a);
1791 let mut sum: usize = 0;
1792 for x in 0..1000 {
1793 for y in 0..1000 {
1794 let pixel = image.get_pixel(x, y);
1795 sum = sum.wrapping_add(pixel[0] as usize);
1796 sum = sum.wrapping_add(pixel[1] as usize);
1797 sum = sum.wrapping_add(pixel[2] as usize);
1798 }
1799 }
1800 test::black_box(sum)
1801 });
1802
1803 b.bytes = 1000 * 1000 * 3;
1804 }
1805}
1806