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