1 #![allow(clippy::too_many_arguments)]
2 use std::convert::TryFrom;
3 use std::io;
4 use std::io::Read;
5 use std::ops::{Deref, DerefMut};
6 use std::path::Path;
7 
8 use crate::buffer::{ImageBuffer, Pixel};
9 use crate::color::{ColorType, ExtendedColorType};
10 use crate::error::{ImageError, ImageResult};
11 use crate::math::Rect;
12 
13 use crate::animation::Frames;
14 
15 #[cfg(feature = "pnm")]
16 use crate::pnm::PNMSubtype;
17 
18 /// An enumeration of supported image formats.
19 /// Not all formats support both encoding and decoding.
20 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
21 pub enum ImageFormat {
22     /// An Image in PNG Format
23     Png,
24 
25     /// An Image in JPEG Format
26     Jpeg,
27 
28     /// An Image in GIF Format
29     Gif,
30 
31     /// An Image in WEBP Format
32     WebP,
33 
34     /// An Image in general PNM Format
35     Pnm,
36 
37     /// An Image in TIFF Format
38     Tiff,
39 
40     /// An Image in TGA Format
41     Tga,
42 
43     /// An Image in DDS Format
44     Dds,
45 
46     /// An Image in BMP Format
47     Bmp,
48 
49     /// An Image in ICO Format
50     Ico,
51 
52     /// An Image in Radiance HDR Format
53     Hdr,
54 
55     #[doc(hidden)]
56     __NonExhaustive(crate::utils::NonExhaustiveMarker),
57 }
58 
59 impl ImageFormat {
60     /// Return the image format specified by the path's file extension.
from_path<P>(path: P) -> ImageResult<Self> where P : AsRef<Path>61     pub fn from_path<P>(path: P) -> ImageResult<Self> where P : AsRef<Path> {
62         // thin wrapper function to strip generics before calling from_path_impl
63         crate::io::free_functions::guess_format_from_path_impl(path.as_ref())
64             .map_err(Into::into)
65     }
66 }
67 
68 /// An enumeration of supported image formats for encoding.
69 #[derive(Clone, PartialEq, Eq, Debug)]
70 pub enum ImageOutputFormat {
71     #[cfg(feature = "png")]
72     /// An Image in PNG Format
73     Png,
74 
75     #[cfg(feature = "jpeg")]
76     /// An Image in JPEG Format with specified quality
77     Jpeg(u8),
78 
79     #[cfg(feature = "pnm")]
80     /// An Image in one of the PNM Formats
81     Pnm(PNMSubtype),
82 
83     #[cfg(feature = "gif")]
84     /// An Image in GIF Format
85     Gif,
86 
87     #[cfg(feature = "ico")]
88     /// An Image in ICO Format
89     Ico,
90 
91     #[cfg(feature = "bmp")]
92     /// An Image in BMP Format
93     Bmp,
94 
95     /// A value for signalling an error: An unsupported format was requested
96     // Note: When TryFrom is stabilized, this value should not be needed, and
97     // a TryInto<ImageOutputFormat> should be used instead of an Into<ImageOutputFormat>.
98     Unsupported(String),
99 
100     #[doc(hidden)]
101     __NonExhaustive(crate::utils::NonExhaustiveMarker),
102 }
103 
104 impl From<ImageFormat> for ImageOutputFormat {
from(fmt: ImageFormat) -> Self105     fn from(fmt: ImageFormat) -> Self {
106         match fmt {
107             #[cfg(feature = "png")]
108             ImageFormat::Png => ImageOutputFormat::Png,
109             #[cfg(feature = "jpeg")]
110             ImageFormat::Jpeg => ImageOutputFormat::Jpeg(75),
111             #[cfg(feature = "pnm")]
112             ImageFormat::Pnm => ImageOutputFormat::Pnm(PNMSubtype::ArbitraryMap),
113             #[cfg(feature = "gif")]
114             ImageFormat::Gif => ImageOutputFormat::Gif,
115             #[cfg(feature = "ico")]
116             ImageFormat::Ico => ImageOutputFormat::Ico,
117             #[cfg(feature = "bmp")]
118             ImageFormat::Bmp => ImageOutputFormat::Bmp,
119 
120             f => ImageOutputFormat::Unsupported(format!(
121                 "Image format {:?} not supported for encoding.",
122                 f
123             )),
124         }
125     }
126 }
127 
128 // This struct manages buffering associated with implementing `Read` and `Seek` on decoders that can
129 // must decode ranges of bytes at a time.
130 pub(crate) struct ImageReadBuffer {
131     scanline_bytes: usize,
132     buffer: Vec<u8>,
133     consumed: usize,
134 
135     total_bytes: u64,
136     offset: u64,
137 }
138 impl ImageReadBuffer {
139     /// Create a new ImageReadBuffer.
140     ///
141     /// Panics if scanline_bytes doesn't fit into a usize, because that would mean reading anything
142     /// from the image would take more RAM than the entire virtual address space. In other words,
143     /// actually using this struct would instantly OOM so just get it out of the way now.
new(scanline_bytes: u64, total_bytes: u64) -> Self144     pub(crate) fn new(scanline_bytes: u64, total_bytes: u64) -> Self {
145         Self {
146             scanline_bytes: usize::try_from(scanline_bytes).unwrap(),
147             buffer: Vec::new(),
148             consumed: 0,
149             total_bytes,
150             offset: 0,
151         }
152     }
153 
read<F>(&mut self, buf: &mut [u8], mut read_scanline: F) -> io::Result<usize> where F: FnMut(&mut [u8]) -> io::Result<usize>,154     pub(crate) fn read<F>(&mut self, buf: &mut [u8], mut read_scanline: F) -> io::Result<usize>
155     where
156         F: FnMut(&mut [u8]) -> io::Result<usize>,
157     {
158         if self.buffer.len() == self.consumed {
159             if self.offset == self.total_bytes {
160                 return Ok(0);
161             } else if buf.len() >= self.scanline_bytes {
162                 // If there is nothing buffered and the user requested a full scanline worth of
163                 // data, skip buffering.
164                 let bytes_read = read_scanline(&mut buf[..self.scanline_bytes])?;
165                 self.offset += u64::try_from(bytes_read).unwrap();
166                 return Ok(bytes_read);
167             } else {
168                 // Lazily allocate buffer the first time that read is called with a buffer smaller
169                 // than the scanline size.
170                 if self.buffer.is_empty() {
171                     self.buffer.resize(self.scanline_bytes, 0);
172                 }
173 
174                 self.consumed = 0;
175                 let bytes_read = read_scanline(&mut self.buffer[..])?;
176                 self.buffer.resize(bytes_read, 0);
177                 self.offset += u64::try_from(bytes_read).unwrap();
178 
179                 assert!(bytes_read == self.scanline_bytes || self.offset == self.total_bytes);
180             }
181         }
182 
183         // Finally, copy bytes into output buffer.
184         let bytes_buffered = self.buffer.len() - self.consumed;
185         if bytes_buffered > buf.len() {
186             crate::copy_memory(&self.buffer[self.consumed..][..buf.len()], &mut buf[..]);
187             self.consumed += buf.len();
188             Ok(buf.len())
189         } else {
190             crate::copy_memory(&self.buffer[self.consumed..], &mut buf[..bytes_buffered]);
191             self.consumed = self.buffer.len();
192             Ok(bytes_buffered)
193         }
194     }
195 }
196 
197 /// Decodes a specific region of the image, represented by the rectangle
198 /// starting from ```x``` and ```y``` and having ```length``` and ```width```
load_rect<'a, D, F, F1, F2, E>(x: u32, y: u32, width: u32, height: u32, buf: &mut [u8], progress_callback: F, decoder: &mut D, mut seek_scanline: F1, mut read_scanline: F2) -> ImageResult<()> where D: ImageDecoder<'a>, F: Fn(Progress), F1: FnMut(&mut D, u64) -> io::Result<()>, F2: FnMut(&mut D, &mut [u8]) -> Result<usize, E>, ImageError: From<E>,199 pub(crate) fn load_rect<'a, D, F, F1, F2, E>(x: u32, y: u32, width: u32, height: u32, buf: &mut [u8],
200                                           progress_callback: F,
201                                           decoder: &mut D,
202                                           mut seek_scanline: F1,
203                                           mut read_scanline: F2) -> ImageResult<()>
204     where D: ImageDecoder<'a>,
205           F: Fn(Progress),
206           F1: FnMut(&mut D, u64) -> io::Result<()>,
207           F2: FnMut(&mut D, &mut [u8]) -> Result<usize, E>,
208           ImageError: From<E>,
209 {
210     let (x, y, width, height) = (u64::from(x), u64::from(y), u64::from(width), u64::from(height));
211     let dimensions = decoder.dimensions();
212     let bytes_per_pixel = u64::from(decoder.color_type().bytes_per_pixel());
213     let row_bytes = bytes_per_pixel * u64::from(dimensions.0);
214     let scanline_bytes = decoder.scanline_bytes();
215     let total_bytes = width * height * bytes_per_pixel;
216 
217     let mut bytes_read = 0u64;
218     let mut current_scanline = 0;
219     let mut tmp = Vec::new();
220 
221     {
222         // Read a range of the image starting from byte number `start` and continuing until byte
223         // number `end`. Updates `current_scanline` and `bytes_read` appropiately.
224         let mut read_image_range = |start: u64, end: u64| -> ImageResult<()> {
225             let target_scanline = start / scanline_bytes;
226             if target_scanline != current_scanline {
227                 seek_scanline(decoder, target_scanline)?;
228                 current_scanline = target_scanline;
229             }
230 
231             let mut position = current_scanline * scanline_bytes;
232             while position < end {
233                 if position >= start && end - position >= scanline_bytes {
234                     read_scanline(decoder, &mut buf[(bytes_read as usize)..]
235                                                    [..(scanline_bytes as usize)])?;
236                     bytes_read += scanline_bytes;
237                 } else {
238                     tmp.resize(scanline_bytes as usize, 0u8);
239                     read_scanline(decoder, &mut tmp)?;
240 
241                     let offset = start.saturating_sub(position);
242                     let len = (end - start)
243                         .min(scanline_bytes - offset)
244                         .min(end - position);
245 
246                     buf[(bytes_read as usize)..][..len as usize]
247                         .copy_from_slice(&tmp[offset as usize..][..len as usize]);
248                     bytes_read += len;
249                 }
250 
251                 current_scanline += 1;
252                 position += scanline_bytes;
253                 progress_callback(Progress {current: bytes_read, total: total_bytes});
254             }
255             Ok(())
256         };
257 
258         if x + width > u64::from(dimensions.0) || y + height > u64::from(dimensions.0)
259             || width == 0 || height == 0 {
260                 return Err(ImageError::DimensionError);
261             }
262         if scanline_bytes > usize::max_value() as u64 {
263             return Err(ImageError::InsufficientMemory);
264         }
265 
266         progress_callback(Progress {current: 0, total: total_bytes});
267         if x == 0 && width == u64::from(dimensions.0) {
268             let start = x * bytes_per_pixel + y * row_bytes;
269             let end = (x + width) * bytes_per_pixel + (y + height - 1) * row_bytes;
270             read_image_range(start, end)?;
271         } else {
272             for row in y..(y+height) {
273                 let start = x * bytes_per_pixel + row * row_bytes;
274                 let end = (x + width) * bytes_per_pixel + row * row_bytes;
275                 read_image_range(start, end)?;
276             }
277         }
278     }
279 
280     // Seek back to the start
281     Ok(seek_scanline(decoder, 0)?)
282 }
283 
284 /// Reads all of the bytes of a decoder into a Vec<T>. No particular alignment
285 /// of the output buffer is guaranteed.
286 ///
287 /// Panics if there isn't enough memory to decode the image.
decoder_to_vec<'a, T>(decoder: impl ImageDecoder<'a>) -> ImageResult<Vec<T>> where T: crate::traits::Primitive + bytemuck::Pod,288 pub(crate) fn decoder_to_vec<'a, T>(decoder: impl ImageDecoder<'a>) -> ImageResult<Vec<T>>
289 where
290     T: crate::traits::Primitive + bytemuck::Pod,
291 {
292     let mut buf = vec![num_traits::Zero::zero(); usize::try_from(decoder.total_bytes()).unwrap() / std::mem::size_of::<T>()];
293     decoder.read_image(bytemuck::cast_slice_mut(buf.as_mut_slice()))?;
294     Ok(buf)
295 }
296 
297 /// Represents the progress of an image operation.
298 ///
299 /// Note that this is not necessarily accurate and no change to the values passed to the progress
300 /// function during decoding will be considered breaking. A decoder could in theory report the
301 /// progress `(0, 0)` if progress is unknown, without violating the interface contract of the type.
302 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
303 pub struct Progress {
304     current: u64,
305     total: u64,
306 }
307 
308 impl Progress {
309     /// A measure of completed decoding.
current(self) -> u64310     pub fn current(self) -> u64 {
311         self.current
312     }
313 
314     /// A measure of all necessary decoding work.
315     ///
316     /// This is in general greater or equal than `current`.
total(self) -> u64317     pub fn total(self) -> u64 {
318         self.total
319     }
320 
321     /// Calculate a measure for remaining decoding work.
remaining(self) -> u64322     pub fn remaining(self) -> u64 {
323         self.total.max(self.current) - self.current
324     }
325 }
326 
327 /// The trait that all decoders implement
328 pub trait ImageDecoder<'a>: Sized {
329     /// The type of reader produced by `into_reader`.
330     type Reader: Read + 'a;
331 
332     /// Returns a tuple containing the width and height of the image
dimensions(&self) -> (u32, u32)333     fn dimensions(&self) -> (u32, u32);
334 
335     /// Returns the color type of the image data produced by this decoder
color_type(&self) -> ColorType336     fn color_type(&self) -> ColorType;
337 
338     /// Retuns the color type of the image file before decoding
original_color_type(&self) -> ExtendedColorType339     fn original_color_type(&self) -> ExtendedColorType {
340         self.color_type().into()
341     }
342 
343     /// Returns a reader that can be used to obtain the bytes of the image. For the best
344     /// performance, always try to read at least `scanline_bytes` from the reader at a time. Reading
345     /// fewer bytes will cause the reader to perform internal buffering.
into_reader(self) -> ImageResult<Self::Reader>346     fn into_reader(self) -> ImageResult<Self::Reader>;
347 
348     /// Returns the total number of bytes in the decoded image.
349     ///
350     /// This is the size of the buffer that must be passed to `read_image` or
351     /// `read_image_with_progress`. The returned value may exceed usize::MAX, in
352     /// which case it isn't actually possible to construct a buffer to decode all the image data
353     /// into.
total_bytes(&self) -> u64354     fn total_bytes(&self) -> u64 {
355         let dimensions = self.dimensions();
356         u64::from(dimensions.0) * u64::from(dimensions.1) * u64::from(self.color_type().bytes_per_pixel())
357     }
358 
359     /// Returns the minimum number of bytes that can be efficiently read from this decoder. This may
360     /// be as few as 1 or as many as `total_bytes()`.
scanline_bytes(&self) -> u64361     fn scanline_bytes(&self) -> u64 {
362         self.total_bytes()
363     }
364 
365     /// Returns all the bytes in the image.
366     ///
367     /// This function takes a slice of bytes and writes the pixel data of the image into it.
368     /// Although not required, for certain color types callers may want to pass buffers which are
369     /// aligned to 2 or 4 byte boundaries to the slice can be cast to a [u16] or [u32]. To accommodate
370     /// such casts, the returned contents will always be in native endian.
371     ///
372     /// # Panics
373     ///
374     /// This function panics if buf.len() != self.total_bytes().
375     ///
376     /// # Examples
377     ///
378     /// ```no_build
379     /// use zerocopy::{AsBytes, FromBytes};
380     /// fn read_16bit_image(decoder: impl ImageDecoder) -> Vec<16> {
381     ///     let mut buf: Vec<u16> = vec![0; decoder.total_bytes()/2];
382     ///     decoder.read_image(buf.as_bytes());
383     ///     buf
384     /// }
read_image(self, buf: &mut [u8]) -> ImageResult<()>385     fn read_image(self, buf: &mut [u8]) -> ImageResult<()> {
386         self.read_image_with_progress(buf, |_| {})
387     }
388 
389     /// Same as `read_image` but periodically calls the provided callback to give updates on loading
390     /// progress.
read_image_with_progress<F: Fn(Progress)>( self, buf: &mut [u8], progress_callback: F, ) -> ImageResult<()>391     fn read_image_with_progress<F: Fn(Progress)>(
392         self,
393         buf: &mut [u8],
394         progress_callback: F,
395     ) -> ImageResult<()> {
396         assert_eq!(u64::try_from(buf.len()), Ok(self.total_bytes()));
397 
398         let total_bytes = self.total_bytes() as usize;
399         let scanline_bytes = self.scanline_bytes() as usize;
400         let target_read_size = if scanline_bytes < 4096 {
401             (4096 / scanline_bytes) * scanline_bytes
402         } else {
403             scanline_bytes
404         };
405 
406         let mut reader = self.into_reader()?;
407 
408         let mut bytes_read = 0;
409         while bytes_read < total_bytes {
410             let read_size = target_read_size.min(total_bytes - bytes_read);
411             reader.read_exact(&mut buf[bytes_read..][..read_size])?;
412             bytes_read += read_size;
413 
414             progress_callback(Progress {
415                 current: bytes_read as u64,
416                 total: total_bytes as u64,
417             });
418         }
419 
420         Ok(())
421     }
422 }
423 
424 /// ImageDecoderExt trait
425 pub trait ImageDecoderExt<'a>: ImageDecoder<'a> + Sized {
426     /// Read a rectangular section of the image.
read_rect( &mut self, x: u32, y: u32, width: u32, height: u32, buf: &mut [u8], ) -> ImageResult<()>427     fn read_rect(
428         &mut self,
429         x: u32,
430         y: u32,
431         width: u32,
432         height: u32,
433         buf: &mut [u8],
434     ) -> ImageResult<()> {
435         self.read_rect_with_progress(x, y, width, height, buf, |_|{})
436     }
437 
438     /// Read a rectangular section of the image, periodically reporting progress.
read_rect_with_progress<F: Fn(Progress)>( &mut self, x: u32, y: u32, width: u32, height: u32, buf: &mut [u8], progress_callback: F, ) -> ImageResult<()>439     fn read_rect_with_progress<F: Fn(Progress)>(
440         &mut self,
441         x: u32,
442         y: u32,
443         width: u32,
444         height: u32,
445         buf: &mut [u8],
446         progress_callback: F,
447     ) -> ImageResult<()>;
448 }
449 
450 /// AnimationDecoder trait
451 pub trait AnimationDecoder<'a> {
452     /// Consume the decoder producing a series of frames.
into_frames(self) -> Frames<'a>453     fn into_frames(self) -> Frames<'a>;
454 }
455 
456 /// The trait all encoders implement
457 pub trait ImageEncoder {
458     /// Writes all the bytes in an image to the encoder.
459     ///
460     /// This function takes a slice of bytes of the pixel data of the image
461     /// and encodes them. Unlike particular format encoders inherent impl encode
462     /// methods where endianness is not specified, here image data bytes should
463     /// always be in native endian. The implementor will reorder the endianess
464     /// as necessary for the target encoding format.
465     ///
466     /// See also `ImageDecoder::read_image` which reads byte buffers into
467     /// native endian.
write_image( self, buf: &[u8], width: u32, height: u32, color_type: ColorType, ) -> ImageResult<()>468     fn write_image(
469         self,
470         buf: &[u8],
471         width: u32,
472         height: u32,
473         color_type: ColorType,
474     ) -> ImageResult<()>;
475 }
476 
477 /// Immutable pixel iterator
478 pub struct Pixels<'a, I: ?Sized + 'a> {
479     image: &'a I,
480     x: u32,
481     y: u32,
482     width: u32,
483     height: u32,
484 }
485 
486 impl<'a, I: GenericImageView> Iterator for Pixels<'a, I> {
487     type Item = (u32, u32, I::Pixel);
488 
next(&mut self) -> Option<(u32, u32, I::Pixel)>489     fn next(&mut self) -> Option<(u32, u32, I::Pixel)> {
490         if self.x >= self.width {
491             self.x = 0;
492             self.y += 1;
493         }
494 
495         if self.y >= self.height {
496             None
497         } else {
498             let pixel = self.image.get_pixel(self.x, self.y);
499             let p = (self.x, self.y, pixel);
500 
501             self.x += 1;
502 
503             Some(p)
504         }
505     }
506 }
507 
508 /// Trait to inspect an image.
509 pub trait GenericImageView {
510     /// The type of pixel.
511     type Pixel: Pixel;
512 
513     /// Underlying image type. This is mainly used by SubImages in order to
514     /// always have a reference to the original image. This allows for less
515     /// indirections and it eases the use of nested SubImages.
516     type InnerImageView: GenericImageView<Pixel = Self::Pixel>;
517 
518     /// The width and height of this image.
dimensions(&self) -> (u32, u32)519     fn dimensions(&self) -> (u32, u32);
520 
521     /// The width of this image.
width(&self) -> u32522     fn width(&self) -> u32 {
523         let (w, _) = self.dimensions();
524         w
525     }
526 
527     /// The height of this image.
height(&self) -> u32528     fn height(&self) -> u32 {
529         let (_, h) = self.dimensions();
530         h
531     }
532 
533     /// The bounding rectangle of this image.
bounds(&self) -> (u32, u32, u32, u32)534     fn bounds(&self) -> (u32, u32, u32, u32);
535 
536     /// Returns true if this x, y coordinate is contained inside the image.
in_bounds(&self, x: u32, y: u32) -> bool537     fn in_bounds(&self, x: u32, y: u32) -> bool {
538         let (ix, iy, iw, ih) = self.bounds();
539         x >= ix && x < ix + iw && y >= iy && y < iy + ih
540     }
541 
542     /// Returns the pixel located at (x, y)
543     ///
544     /// # Panics
545     ///
546     /// Panics if `(x, y)` is out of bounds.
547     ///
548     /// TODO: change this signature to &P
get_pixel(&self, x: u32, y: u32) -> Self::Pixel549     fn get_pixel(&self, x: u32, y: u32) -> Self::Pixel;
550 
551     /// Returns the pixel located at (x, y)
552     ///
553     /// This function can be implemented in a way that ignores bounds checking.
unsafe_get_pixel(&self, x: u32, y: u32) -> Self::Pixel554     unsafe fn unsafe_get_pixel(&self, x: u32, y: u32) -> Self::Pixel {
555         self.get_pixel(x, y)
556     }
557 
558     /// Returns an Iterator over the pixels of this image.
559     /// The iterator yields the coordinates of each pixel
560     /// along with their value
pixels(&self) -> Pixels<Self>561     fn pixels(&self) -> Pixels<Self> {
562         let (width, height) = self.dimensions();
563 
564         Pixels {
565             image: self,
566             x: 0,
567             y: 0,
568             width,
569             height,
570         }
571     }
572 
573     /// Returns a reference to the underlying image.
inner(&self) -> &Self::InnerImageView574     fn inner(&self) -> &Self::InnerImageView;
575 
576     /// Returns an subimage that is an immutable view into this image.
577     /// You can use [`GenericImage::sub_image`] if you need a mutable view instead.
view(&self, x: u32, y: u32, width: u32, height: u32) -> SubImage<&Self::InnerImageView>578     fn view(&self, x: u32, y: u32, width: u32, height: u32) -> SubImage<&Self::InnerImageView> {
579         SubImage::new(self.inner(), x, y, width, height)
580     }
581 }
582 
583 /// A trait for manipulating images.
584 pub trait GenericImage: GenericImageView {
585     /// Underlying image type. This is mainly used by SubImages in order to
586     /// always have a reference to the original image. This allows for less
587     /// indirections and it eases the use of nested SubImages.
588     type InnerImage: GenericImage<Pixel = Self::Pixel>;
589 
590     /// Gets a reference to the mutable pixel at location `(x, y)`
591     ///
592     /// # Panics
593     ///
594     /// Panics if `(x, y)` is out of bounds.
get_pixel_mut(&mut self, x: u32, y: u32) -> &mut Self::Pixel595     fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut Self::Pixel;
596 
597     /// Put a pixel at location (x, y)
598     ///
599     /// # Panics
600     ///
601     /// Panics if `(x, y)` is out of bounds.
put_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel)602     fn put_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel);
603 
604     /// Puts a pixel at location (x, y)
605     ///
606     /// This function can be implemented in a way that ignores bounds checking.
unsafe_put_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel)607     unsafe fn unsafe_put_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel) {
608         self.put_pixel(x, y, pixel);
609     }
610 
611     /// Put a pixel at location (x, y), taking into account alpha channels
612     ///
613     /// DEPRECATED: This method will be removed. Blend the pixel directly instead.
blend_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel)614     fn blend_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel);
615 
616     /// Copies all of the pixels from another image into this image.
617     ///
618     /// The other image is copied with the top-left corner of the
619     /// other image placed at (x, y).
620     ///
621     /// In order to copy only a piece of the other image, use [`GenericImageView::view`].
622     ///
623     /// # Returns
624     /// Returns an error if the image is too large to be copied at the given position
copy_from<O>(&mut self, other: &O, x: u32, y: u32) -> ImageResult<()> where O: GenericImageView<Pixel = Self::Pixel>,625     fn copy_from<O>(&mut self, other: &O, x: u32, y: u32) -> ImageResult<()>
626     where
627         O: GenericImageView<Pixel = Self::Pixel>,
628     {
629         // Do bounds checking here so we can use the non-bounds-checking
630         // functions to copy pixels.
631         if self.width() < other.width() + x || self.height() < other.height() + y {
632             return Err(ImageError::DimensionError);
633         }
634 
635         for i in 0..other.width() {
636             for k in 0..other.height() {
637                 let p = other.get_pixel(i, k);
638                 self.put_pixel(i + x, k + y, p);
639             }
640         }
641         Ok(())
642     }
643 
644     /// Copies all of the pixels from one part of this image to another part of this image.
645     ///
646     /// The destination rectangle of the copy is specified with the top-left corner placed at (x, y).
647     ///
648     /// # Returns
649     /// `true` if the copy was successful, `false` if the image could not
650     /// be copied due to size constraints.
copy_within(&mut self, source: Rect, x: u32, y: u32) -> bool651     fn copy_within(&mut self, source: Rect, x: u32, y: u32) -> bool {
652         let Rect { x: sx, y: sy, width, height } = source;
653         let dx = x;
654         let dy = y;
655         assert!(sx < self.width() && dx < self.width());
656         assert!(sy < self.height() && dy < self.height());
657         if self.width() - dx.max(sx) < width || self.height() - dy.max(sy) < height {
658             return false;
659         }
660         // since `.rev()` creates a new dype we would either have to go with dynamic dispatch for the ranges
661         // or have quite a lot of code bloat. A macro gives us static dispatch with less visible bloat.
662         macro_rules! copy_within_impl_ {
663             ($xiter:expr, $yiter:expr) => {
664                 for y in $yiter {
665                     let sy = sy + y;
666                     let dy = dy + y;
667                     for x in $xiter {
668                         let sx = sx + x;
669                         let dx = dx + x;
670                         let pixel = self.get_pixel(sx, sy);
671                         self.put_pixel(dx, dy, pixel);
672                     }
673                 }
674             };
675         }
676         // check how target and source rectangles relate to each other so we dont overwrite data before we copied it.
677         match (sx < dx, sy < dy) {
678             (true, true) => copy_within_impl_!((0..width).rev(), (0..height).rev()),
679             (true, false) => copy_within_impl_!((0..width).rev(), 0..height),
680             (false, true) => copy_within_impl_!(0..width, (0..height).rev()),
681             (false, false) => copy_within_impl_!(0..width, 0..height),
682         }
683         true
684     }
685 
686     /// Returns a mutable reference to the underlying image.
inner_mut(&mut self) -> &mut Self::InnerImage687     fn inner_mut(&mut self) -> &mut Self::InnerImage;
688 
689     /// Returns a mutable subimage that is a view into this image.
690     /// If you want an immutable subimage instead, use [`GenericImageView::view`]
sub_image( &mut self, x: u32, y: u32, width: u32, height: u32, ) -> SubImage<&mut Self::InnerImage>691     fn sub_image(
692         &mut self,
693         x: u32,
694         y: u32,
695         width: u32,
696         height: u32,
697     ) -> SubImage<&mut Self::InnerImage> {
698         SubImage::new(self.inner_mut(), x, y, width, height)
699     }
700 }
701 
702 /// A View into another image
703 ///
704 /// Instances of this struct can be created using:
705 ///   - [`GenericImage::sub_image`] to create a mutable view,
706 ///   - [`GenericImageView::view`] to create an immutable view,
707 ///   - [`SubImage::new`] to instantiate the struct directly.
708 pub struct SubImage<I> {
709     image: I,
710     xoffset: u32,
711     yoffset: u32,
712     xstride: u32,
713     ystride: u32,
714 }
715 
716 /// Alias to access Pixel behind a reference
717 type DerefPixel<I> = <<I as Deref>::Target as GenericImageView>::Pixel;
718 
719 /// Alias to access Subpixel behind a reference
720 type DerefSubpixel<I> = <DerefPixel<I> as Pixel>::Subpixel;
721 
722 impl<I> SubImage<I> {
723     /// Construct a new subimage
new(image: I, x: u32, y: u32, width: u32, height: u32) -> SubImage<I>724     pub fn new(image: I, x: u32, y: u32, width: u32, height: u32) -> SubImage<I> {
725         SubImage {
726             image,
727             xoffset: x,
728             yoffset: y,
729             xstride: width,
730             ystride: height,
731         }
732     }
733 
734     /// Change the coordinates of this subimage.
change_bounds(&mut self, x: u32, y: u32, width: u32, height: u32)735     pub fn change_bounds(&mut self, x: u32, y: u32, width: u32, height: u32) {
736         self.xoffset = x;
737         self.yoffset = y;
738         self.xstride = width;
739         self.ystride = height;
740     }
741 
742     /// Convert this subimage to an ImageBuffer
to_image(&self) -> ImageBuffer<DerefPixel<I>, Vec<DerefSubpixel<I>>> where I: Deref, I::Target: GenericImage + 'static,743     pub fn to_image(&self) -> ImageBuffer<DerefPixel<I>, Vec<DerefSubpixel<I>>>
744     where
745         I: Deref,
746         I::Target: GenericImage + 'static,
747     {
748         let mut out = ImageBuffer::new(self.xstride, self.ystride);
749         let borrowed = self.image.deref();
750 
751         for y in 0..self.ystride {
752             for x in 0..self.xstride {
753                 let p = borrowed.get_pixel(x + self.xoffset, y + self.yoffset);
754                 out.put_pixel(x, y, p);
755             }
756         }
757 
758         out
759     }
760 }
761 
762 #[allow(deprecated)]
763 impl<I> GenericImageView for SubImage<I>
764 where
765     I: Deref,
766     I::Target: GenericImageView + Sized,
767 {
768     type Pixel = DerefPixel<I>;
769     type InnerImageView = I::Target;
770 
dimensions(&self) -> (u32, u32)771     fn dimensions(&self) -> (u32, u32) {
772         (self.xstride, self.ystride)
773     }
774 
bounds(&self) -> (u32, u32, u32, u32)775     fn bounds(&self) -> (u32, u32, u32, u32) {
776         (self.xoffset, self.yoffset, self.xstride, self.ystride)
777     }
778 
get_pixel(&self, x: u32, y: u32) -> Self::Pixel779     fn get_pixel(&self, x: u32, y: u32) -> Self::Pixel {
780         self.image.get_pixel(x + self.xoffset, y + self.yoffset)
781     }
782 
view(&self, x: u32, y: u32, width: u32, height: u32) -> SubImage<&Self::InnerImageView>783     fn view(&self, x: u32, y: u32, width: u32, height: u32) -> SubImage<&Self::InnerImageView> {
784         let x = self.xoffset + x;
785         let y = self.yoffset + y;
786         SubImage::new(self.inner(), x, y, width, height)
787     }
788 
inner(&self) -> &Self::InnerImageView789     fn inner(&self) -> &Self::InnerImageView {
790         &self.image
791     }
792 }
793 
794 #[allow(deprecated)]
795 impl<I> GenericImage for SubImage<I>
796 where
797     I: DerefMut,
798     I::Target: GenericImage + Sized,
799 {
800     type InnerImage = I::Target;
801 
get_pixel_mut(&mut self, x: u32, y: u32) -> &mut Self::Pixel802     fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut Self::Pixel {
803         self.image.get_pixel_mut(x + self.xoffset, y + self.yoffset)
804     }
805 
put_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel)806     fn put_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel) {
807         self.image
808             .put_pixel(x + self.xoffset, y + self.yoffset, pixel)
809     }
810 
811     /// DEPRECATED: This method will be removed. Blend the pixel directly instead.
blend_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel)812     fn blend_pixel(&mut self, x: u32, y: u32, pixel: Self::Pixel) {
813         self.image
814             .blend_pixel(x + self.xoffset, y + self.yoffset, pixel)
815     }
816 
sub_image( &mut self, x: u32, y: u32, width: u32, height: u32, ) -> SubImage<&mut Self::InnerImage>817     fn sub_image(
818         &mut self,
819         x: u32,
820         y: u32,
821         width: u32,
822         height: u32,
823     ) -> SubImage<&mut Self::InnerImage> {
824         let x = self.xoffset + x;
825         let y = self.yoffset + y;
826         SubImage::new(self.inner_mut(), x, y, width, height)
827     }
828 
inner_mut(&mut self) -> &mut Self::InnerImage829     fn inner_mut(&mut self) -> &mut Self::InnerImage {
830         &mut self.image
831     }
832 }
833 
834 #[cfg(test)]
835 mod tests {
836     use std::io;
837     use std::path::Path;
838 
839     use super::{ColorType, ImageDecoder, ImageResult, GenericImage, GenericImageView, load_rect, ImageFormat};
840     use crate::buffer::{GrayImage, ImageBuffer};
841     use crate::color::Rgba;
842     use crate::math::Rect;
843 
844     #[test]
845     /// Test that alpha blending works as expected
test_image_alpha_blending()846     fn test_image_alpha_blending() {
847         let mut target = ImageBuffer::new(1, 1);
848         target.put_pixel(0, 0, Rgba([255u8, 0, 0, 255]));
849         assert!(*target.get_pixel(0, 0) == Rgba([255, 0, 0, 255]));
850         target.blend_pixel(0, 0, Rgba([0, 255, 0, 255]));
851         assert!(*target.get_pixel(0, 0) == Rgba([0, 255, 0, 255]));
852 
853         // Blending an alpha channel onto a solid background
854         target.blend_pixel(0, 0, Rgba([255, 0, 0, 127]));
855         assert!(*target.get_pixel(0, 0) == Rgba([127, 127, 0, 255]));
856 
857         // Blending two alpha channels
858         target.put_pixel(0, 0, Rgba([0, 255, 0, 127]));
859         target.blend_pixel(0, 0, Rgba([255, 0, 0, 127]));
860         assert!(*target.get_pixel(0, 0) == Rgba([169, 85, 0, 190]));
861     }
862 
863     #[test]
test_in_bounds()864     fn test_in_bounds() {
865         let mut target = ImageBuffer::new(2, 2);
866         target.put_pixel(0, 0, Rgba([255u8, 0, 0, 255]));
867 
868         assert!(target.in_bounds(0, 0));
869         assert!(target.in_bounds(1, 0));
870         assert!(target.in_bounds(0, 1));
871         assert!(target.in_bounds(1, 1));
872 
873         assert!(!target.in_bounds(2, 0));
874         assert!(!target.in_bounds(0, 2));
875         assert!(!target.in_bounds(2, 2));
876     }
877 
878     #[test]
test_can_subimage_clone_nonmut()879     fn test_can_subimage_clone_nonmut() {
880         let mut source = ImageBuffer::new(3, 3);
881         source.put_pixel(1, 1, Rgba([255u8, 0, 0, 255]));
882 
883         // A non-mutable copy of the source image
884         let source = source.clone();
885 
886         // Clone a view into non-mutable to a separate buffer
887         let cloned = source.view(1, 1, 1, 1).to_image();
888 
889         assert!(cloned.get_pixel(0, 0) == source.get_pixel(1, 1));
890     }
891 
892     #[test]
test_can_nest_views()893     fn test_can_nest_views() {
894         let mut source = ImageBuffer::from_pixel(3, 3, Rgba([255u8, 0, 0, 255]));
895 
896         {
897             let mut sub1 = source.sub_image(0, 0, 2, 2);
898             let mut sub2 = sub1.sub_image(1, 1, 1, 1);
899             sub2.put_pixel(0, 0, Rgba([0, 0, 0, 0]));
900         }
901 
902         assert_eq!(*source.get_pixel(1, 1), Rgba([0, 0, 0, 0]));
903 
904         let view1 = source.view(0, 0, 2, 2);
905         assert_eq!(*source.get_pixel(1, 1), view1.get_pixel(1, 1));
906 
907         let view2 = view1.view(1, 1, 1, 1);
908         assert_eq!(*source.get_pixel(1, 1), view2.get_pixel(0, 0));
909     }
910 
911     #[test]
test_load_rect()912     fn test_load_rect() {
913         struct MockDecoder {scanline_number: u64, scanline_bytes: u64}
914         impl<'a> ImageDecoder<'a> for MockDecoder {
915             type Reader = Box<dyn io::Read>;
916             fn dimensions(&self) -> (u32, u32) {(5, 5)}
917             fn color_type(&self) -> ColorType {  ColorType::L8 }
918             fn into_reader(self) -> ImageResult<Self::Reader> {unimplemented!()}
919             fn scanline_bytes(&self) -> u64 { self.scanline_bytes }
920         }
921 
922         const DATA: [u8; 25] = [0,  1,  2,  3,  4,
923                                 5,  6,  7,  8,  9,
924                                 10, 11, 12, 13, 14,
925                                 15, 16, 17, 18, 19,
926                                 20, 21, 22, 23, 24];
927 
928         fn seek_scanline(m: &mut MockDecoder, n: u64) -> io::Result<()> {
929             m.scanline_number = n;
930             Ok(())
931         }
932         fn read_scanline(m: &mut MockDecoder, buf: &mut [u8]) -> io::Result<usize> {
933             let bytes_read = m.scanline_number * m.scanline_bytes;
934             if bytes_read >= 25 {
935                 return Ok(0);
936             }
937 
938             let len = m.scanline_bytes.min(25 - bytes_read);
939             buf[..(len as usize)].copy_from_slice(&DATA[(bytes_read as usize)..][..(len as usize)]);
940             m.scanline_number += 1;
941             Ok(len as usize)
942         }
943 
944         for scanline_bytes in 1..30 {
945             let mut output = [0u8; 26];
946 
947             load_rect(0, 0, 5, 5, &mut output, |_|{},
948                       &mut MockDecoder{scanline_number:0, scanline_bytes},
949                       seek_scanline, read_scanline).unwrap();
950             assert_eq!(output[0..25], DATA);
951             assert_eq!(output[25], 0);
952 
953             output = [0u8; 26];
954             load_rect(3, 2, 1, 1, &mut output, |_|{},
955                       &mut MockDecoder{scanline_number:0, scanline_bytes},
956                       seek_scanline, read_scanline).unwrap();
957             assert_eq!(output[0..2], [13, 0]);
958 
959             output = [0u8; 26];
960             load_rect(3, 2, 2, 2, &mut output, |_|{},
961                       &mut MockDecoder{scanline_number:0, scanline_bytes},
962                       seek_scanline, read_scanline).unwrap();
963             assert_eq!(output[0..5], [13, 14, 18, 19, 0]);
964 
965 
966             output = [0u8; 26];
967             load_rect(1, 1, 2, 4, &mut output, |_|{},
968                       &mut MockDecoder{scanline_number:0, scanline_bytes},
969                       seek_scanline, read_scanline).unwrap();
970             assert_eq!(output[0..9], [6, 7, 11, 12, 16, 17, 21, 22, 0]);
971 
972         }
973     }
974 
975     #[test]
test_image_format_from_path()976     fn test_image_format_from_path() {
977         fn from_path(s: &str) -> ImageResult<ImageFormat> {
978             ImageFormat::from_path(Path::new(s))
979         }
980         assert_eq!(from_path("./a.jpg").unwrap(), ImageFormat::Jpeg);
981         assert_eq!(from_path("./a.jpeg").unwrap(), ImageFormat::Jpeg);
982         assert_eq!(from_path("./a.JPEG").unwrap(), ImageFormat::Jpeg);
983         assert_eq!(from_path("./a.pNg").unwrap(), ImageFormat::Png);
984         assert_eq!(from_path("./a.gif").unwrap(), ImageFormat::Gif);
985         assert_eq!(from_path("./a.webp").unwrap(), ImageFormat::WebP);
986         assert_eq!(from_path("./a.tiFF").unwrap(), ImageFormat::Tiff);
987         assert_eq!(from_path("./a.tif").unwrap(), ImageFormat::Tiff);
988         assert_eq!(from_path("./a.tga").unwrap(), ImageFormat::Tga);
989         assert_eq!(from_path("./a.dds").unwrap(), ImageFormat::Dds);
990         assert_eq!(from_path("./a.bmp").unwrap(), ImageFormat::Bmp);
991         assert_eq!(from_path("./a.Ico").unwrap(), ImageFormat::Ico);
992         assert_eq!(from_path("./a.hdr").unwrap(), ImageFormat::Hdr);
993         assert_eq!(from_path("./a.pbm").unwrap(), ImageFormat::Pnm);
994         assert_eq!(from_path("./a.pAM").unwrap(), ImageFormat::Pnm);
995         assert_eq!(from_path("./a.Ppm").unwrap(), ImageFormat::Pnm);
996         assert_eq!(from_path("./a.pgm").unwrap(), ImageFormat::Pnm);
997         assert!(from_path("./a.txt").is_err());
998         assert!(from_path("./a").is_err());
999     }
1000 
1001     #[test]
test_generic_image_copy_within_oob()1002     fn test_generic_image_copy_within_oob() {
1003         let mut image: GrayImage = ImageBuffer::from_raw(4, 4, vec![0u8; 16]).unwrap();
1004         assert!(!image.sub_image(0, 0, 4, 4).copy_within(Rect { x: 0, y: 0, width: 5, height: 4 }, 0, 0));
1005         assert!(!image.sub_image(0, 0, 4, 4).copy_within(Rect { x: 0, y: 0, width: 4, height: 5 }, 0, 0));
1006         assert!(!image.sub_image(0, 0, 4, 4).copy_within(Rect { x: 1, y: 0, width: 4, height: 4 }, 0, 0));
1007         assert!(!image.sub_image(0, 0, 4, 4).copy_within(Rect { x: 0, y: 0, width: 4, height: 4 }, 1, 0));
1008         assert!(!image.sub_image(0, 0, 4, 4).copy_within(Rect { x: 0, y: 1, width: 4, height: 4 }, 0, 0));
1009         assert!(!image.sub_image(0, 0, 4, 4).copy_within(Rect { x: 0, y: 0, width: 4, height: 4 }, 0, 1));
1010         assert!(!image.sub_image(0, 0, 4, 4).copy_within(Rect { x: 1, y: 1, width: 4, height: 4 }, 0, 0));
1011     }
1012 
1013     #[test]
test_generic_image_copy_within_tl()1014     fn test_generic_image_copy_within_tl() {
1015         let data = &[
1016             00, 01, 02, 03,
1017             04, 05, 06, 07,
1018             08, 09, 10, 11,
1019             12, 13, 14, 15
1020         ];
1021         let expected = [
1022             00, 01, 02, 03,
1023             04, 00, 01, 02,
1024             08, 04, 05, 06,
1025             12, 08, 09, 10,
1026         ];
1027         let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1028         assert!(image.sub_image(0, 0, 4, 4).copy_within(Rect { x: 0, y: 0, width: 3, height: 3 }, 1, 1));
1029         assert_eq!(&image.into_raw(), &expected);
1030     }
1031 
1032     #[test]
test_generic_image_copy_within_tr()1033     fn test_generic_image_copy_within_tr() {
1034         let data = &[
1035             00, 01, 02, 03,
1036             04, 05, 06, 07,
1037             08, 09, 10, 11,
1038             12, 13, 14, 15
1039         ];
1040         let expected = [
1041             00, 01, 02, 03,
1042             01, 02, 03, 07,
1043             05, 06, 07, 11,
1044             09, 10, 11, 15
1045         ];
1046         let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1047         assert!(image.sub_image(0, 0, 4, 4).copy_within(Rect { x: 1, y: 0, width: 3, height: 3 }, 0, 1));
1048         assert_eq!(&image.into_raw(), &expected);
1049     }
1050 
1051     #[test]
test_generic_image_copy_within_bl()1052     fn test_generic_image_copy_within_bl() {
1053         let data = &[
1054             00, 01, 02, 03,
1055             04, 05, 06, 07,
1056             08, 09, 10, 11,
1057             12, 13, 14, 15
1058         ];
1059         let expected = [
1060             00, 04, 05, 06,
1061             04, 08, 09, 10,
1062             08, 12, 13, 14,
1063             12, 13, 14, 15
1064         ];
1065         let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1066         assert!(image.sub_image(0, 0, 4, 4).copy_within(Rect { x: 0, y: 1, width: 3, height: 3 }, 1, 0));
1067         assert_eq!(&image.into_raw(), &expected);
1068     }
1069 
1070     #[test]
test_generic_image_copy_within_br()1071     fn test_generic_image_copy_within_br() {
1072         let data = &[
1073             00, 01, 02, 03,
1074             04, 05, 06, 07,
1075             08, 09, 10, 11,
1076             12, 13, 14, 15
1077         ];
1078         let expected = [
1079             05, 06, 07, 03,
1080             09, 10, 11, 07,
1081             13, 14, 15, 11,
1082             12, 13, 14, 15
1083         ];
1084         let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1085         assert!(image.sub_image(0, 0, 4, 4).copy_within(Rect { x: 1, y: 1, width: 3, height: 3 }, 0, 0));
1086         assert_eq!(&image.into_raw(), &expected);
1087     }
1088 }
1089