use super::{traits::*, *};
use std::num::NonZeroU32;
pub struct Nearest;
impl ScalingAlgorithm for Nearest {
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);
unsafe {
fr::Resizer::new(fr::ResizeAlg::Nearest)
.resize(&ChannelCount::<N>::wrap(i), &mut dst.view_mut())
};
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);
unsafe {
fr::Resizer::new(fr::ResizeAlg::Convolution(fr::FilterType::$for))
.resize(&ChannelCount::<N>::wrap(i), &mut dst.view_mut())
};
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);
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);
unsafe { Image::new(dst.width(), dst.height(), dst.into_vec().into()) }
}
}
};
}
pub struct Lanczos3 {}
alg!(Lanczos3);
pub struct CatmullRom {}
alg!(CatmullRom);
pub struct Bilinear {}
alg!(Bilinear);
pub struct Box {}
alg!(Box);
pub struct Hamming {}
alg!(Hamming);
pub struct Mitchell {}
alg!(Mitchell);