fast image operations
Diffstat (limited to 'src/scale.rs')
| -rw-r--r-- | src/scale.rs | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/scale.rs b/src/scale.rs new file mode 100644 index 0000000..0ba614b --- /dev/null +++ b/src/scale.rs @@ -0,0 +1,41 @@ +//! holds scaling operations, at current only the Nearest Neighbor +use crate::Image; + +/// [Nearest Neighbor](https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) image scaling algorithm implementation. +/// Use [`Nearest::scale`]. +pub struct Nearest; +impl Nearest { + /// Resize a image. + /// # Safety + /// + /// `image` must be as big or bigger than `width`, `height. + pub unsafe fn scale<const N: usize>( + image: Image<&[u8], N>, + width: u32, + height: u32, + ) -> Image<Vec<u8>, N> { + let x_scale = image.width() as f32 / width as f32; + let y_scale = image.height() as f32 / height as f32; + let mut out = Image::alloc(width, height); + for y in 0..height { + for x in 0..width { + let x1 = ((x as f32 + 0.5) * x_scale).floor() as u32; + let y1 = ((y as f32 + 0.5) * y_scale).floor() as u32; + // SAFETY: i asked the caller to make sure its ok + let px = unsafe { image.pixel(x1, y1) }; + // SAFETY: were looping over the width and height of out. its ok. + unsafe { out.set_pixel(x, y, px) }; + } + } + out + } +} + +#[test] +fn test_nearest() { + let i = Image::<_, 3>::open("src/cat.png"); + assert_eq!( + unsafe { Nearest::scale(i.as_ref(), 268, 178) }.buffer, + Image::<_, 3>::open("src/small_cat.png").buffer + ); +} |