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