fast image operations
Diffstat (limited to 'src/scale/algorithms.rs')
| -rw-r--r-- | src/scale/algorithms.rs | 113 |
1 files changed, 0 insertions, 113 deletions
diff --git a/src/scale/algorithms.rs b/src/scale/algorithms.rs deleted file mode 100644 index eaec38c..0000000 --- a/src/scale/algorithms.rs +++ /dev/null @@ -1,113 +0,0 @@ -use super::{traits::*, *}; -use std::num::NonZeroU32; - -/// [Nearest Neighbor](https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) image scaling algorithm. -pub struct Nearest; - -impl ScalingAlgorithm for Nearest { - /// Can be used on non opaque too! (Nearest is special like that). - fn scale_opaque<const N: usize>( - i: Image<&[u8], N>, - w: NonZeroU32, - h: NonZeroU32, - ) -> Image<std::boxed::Box<[u8]>, N> - where - ChannelCount<N>: ToImageView<N>, - { - let mut dst = fr::Image::new(w, h); - // SAFETY: swear, the pixel types are the same - unsafe { - fr::Resizer::new(fr::ResizeAlg::Nearest) - .resize(&ChannelCount::<N>::wrap(i), &mut dst.view_mut()) - }; - - // SAFETY: ctor - unsafe { Image::new(dst.width(), dst.height(), dst.into_vec().into()) } - } - - #[inline] - fn scale_transparent<const N: usize>( - i: Image<&mut [u8], N>, - w: NonZeroU32, - h: NonZeroU32, - ) -> Image<std::boxed::Box<[u8]>, N> - where - ChannelCount<N>: AlphaDiv<N>, - { - Self::scale_opaque(i.as_ref(), w, h) - } -} - -macro_rules! alg { - ($for:ident) => { - impl ScalingAlgorithm for $for { - fn scale_opaque<const N: usize>( - i: Image<&[u8], N>, - w: NonZeroU32, - h: NonZeroU32, - ) -> Image<std::boxed::Box<[u8]>, N> - where - ChannelCount<N>: ToImageView<N>, - { - let mut dst = fr::Image::new(w, h); - // SAFETY: swear, the pixel types are the same - unsafe { - fr::Resizer::new(fr::ResizeAlg::Convolution(fr::FilterType::$for)) - .resize(&ChannelCount::<N>::wrap(i), &mut dst.view_mut()) - }; - - // SAFETY: ctor - unsafe { Image::new(dst.width(), dst.height(), dst.into_vec().into()) } - } - - fn scale_transparent<const N: usize>( - i: Image<&mut [u8], N>, - w: NonZeroU32, - h: NonZeroU32, - ) -> Image<std::boxed::Box<[u8]>, N> - where - ChannelCount<N>: AlphaDiv<N>, - { - let mut dst = fr::Image::new(w, h); - // SAFETY: yes - unsafe { - fr::Resizer::new(fr::ResizeAlg::Convolution(fr::FilterType::$for)) - .resize(&ChannelCount::<N>::handle(i).view(), &mut dst.view_mut()) - } - - ChannelCount::<N>::unhandle(&mut dst); - - // SAFETY: ctor - unsafe { Image::new(dst.width(), dst.height(), dst.into_vec().into()) } - } - } - }; -} - -/// [Lanczos](https://en.wikipedia.org/wiki/Lanczos_resampling) scaling with a filter size (*a*) of 3. -pub struct Lanczos3 {} -alg!(Lanczos3); - -/// [Catmull-Rom](https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline) bicubic filtering. -pub struct CatmullRom {} -alg!(CatmullRom); - -/// Linear interpolation. -pub struct Bilinear {} -alg!(Bilinear); - -/// The opposite of [`Nearest`]. -pub struct Box {} -alg!(Box); - -/// Hamming filtering has the same performance as a [`Bilinear`] filter, while -/// providing image (downscaling) quality comparable to bicubic filters like -/// [`CatmullRom`] or [`Mitchell`]. Creates a sharper image than [`Bilinear`] filtering, -/// and doesn't have dislocations on local level like [`Box`] suffers from. -/// Not recommended for upscaling. -pub struct Hamming {} -alg!(Hamming); - -/// [Mitchell–Netravali](https://en.wikipedia.org/wiki/Mitchell%E2%80%93Netravali_filters) bicubic filtering. -pub struct Mitchell {} -alg!(Mitchell); |