feim 0.25.1

Modular crate for working with images in Rust
Documentation
use super::Color;
#[cfg(feature = "col-gray16")]
use super::Gray16;
#[cfg(feature = "col-nrgba64")]
use super::Nrgba64;
#[cfg(feature = "col-rgb48")]
use super::Rgb48;
use crate::specialized::{self, No};

pub trait ConvertFrom<C, Specialized = No>
where
    C: Color,
{
    /// Returns the result of converting a color from `C` into
    /// `Self`.
    fn convert_from(c: C) -> Self;
}

impl<C: Color> ConvertFrom<C, specialized::For<C>> for C {
    #[inline(always)]
    fn convert_from(color: C) -> C {
        color
    }
}

pub trait ConvertInto<C, Specialized = No>
where
    C: Color,
{
    /// Returns the result of converting a color from `Self` into
    /// `C`.
    fn convert_into(self) -> C;
}

impl<A, B, Specialized> ConvertInto<B, Specialized> for A
where
    A: Color,
    B: ConvertFrom<A, Specialized> + Color,
{
    #[inline(always)]
    fn convert_into(self) -> B {
        B::convert_from(self)
    }
}

pub trait ConvertIntoGeneric<C>
where
    C: Color,
{
    /// Returns the result of converting a color from `Self` into
    /// `C`, with a generic implementation.
    fn convert_into_generic(self) -> C;
}

impl<A, B> ConvertIntoGeneric<B> for A
where
    A: Color,
    B: ConvertFrom<A, specialized::No> + Color,
{
    #[inline(always)]
    fn convert_into_generic(self) -> B {
        self.convert_into()
    }
}

pub trait ConvertIntoSpecializedFor {
    /// Returns the result of converting a color from `Self` into
    /// `C`, with a specialized implementation for some color.
    fn convert_into_specialized_for<C>(self) -> C
    where
        Self: Color + Sized,
        C: Color + ConvertFrom<Self, specialized::For<C>>;
}

impl<A> ConvertIntoSpecializedFor for A
where
    A: Color,
{
    #[inline(always)]
    fn convert_into_specialized_for<B>(self) -> B
    where
        B: Color + ConvertFrom<A, specialized::For<B>>,
    {
        self.convert_into()
    }
}

pub trait ConvertIntoSpecialized<C>
where
    C: Color,
{
    /// Returns the result of converting a color from `Self` into
    /// `C`, with a specialized implementation.
    fn convert_into_specialized(self) -> C;
}

impl<A, B> ConvertIntoSpecialized<B> for A
where
    A: Color,
    B: ConvertFrom<A, specialized::Aye> + Color,
{
    #[inline(always)]
    fn convert_into_specialized(self) -> B {
        self.convert_into()
    }
}

#[allow(unused_macros)]
macro_rules! encode_as_impl {
    ($type:ident, $intermediate:ty) => {
        impl<E1> $crate::buffer::RawPixBuf<$type<E1>> {
            // TODO: change buffer in place, so we don't
            // need to allocate a new one for the conversion
            fn encode_as_impl<E2>(self) -> $crate::buffer::RawPixBuf<$type<E2>>
            where
                E1: super::Endianness + Copy,
                E2: super::Endianness + Copy,
                $type<E1>: Color,
                $type<E2>: Color + From<$intermediate>,
                $intermediate: From<$type<E1>>,
            {
                use $crate::buffer::AsTypedMut;
                use $crate::image::Dimensions;

                let (width, height) = self.dimensions();
                let mut new_buffer = $crate::buffer::RawPixBuf::new(width, height);

                for (pix, new_pix) in self
                    .into_pixels()
                    .into_iter()
                    .zip(new_buffer.as_typed_mut().iter_mut())
                {
                    *new_pix = pix.convert_into();
                }

                new_buffer
            }
        }
    };
}

#[cfg(feature = "col-nrgba64")]
encode_as_impl!(Nrgba64, u64);

#[cfg(feature = "col-gray16")]
encode_as_impl!(Gray16, u16);

#[cfg(feature = "col-rgb48")]
encode_as_impl!(Rgb48, u64);

#[cfg(feature = "col-nrgba64")]
impl<E1> crate::buffer::RawPixBuf<Nrgba64<E1>> {
    #[inline]
    pub fn encode_as<E2>(self) -> crate::buffer::RawPixBuf<Nrgba64<E2>>
    where
        E1: super::Endianness + Copy,
        E2: super::Endianness + Copy,
        Nrgba64<E1>: Color,
        Nrgba64<E2>: Color + From<u64>,
        u64: From<Nrgba64<E1>>,
    {
        self.encode_as_impl()
    }
}

#[cfg(feature = "col-gray16")]
impl<E1> crate::buffer::RawPixBuf<Gray16<E1>> {
    #[inline]
    pub fn encode_as<E2>(self) -> crate::buffer::RawPixBuf<Gray16<E2>>
    where
        E1: super::Endianness + Copy,
        E2: super::Endianness + Copy,
        Gray16<E1>: Color,
        Gray16<E2>: Color + From<u16>,
        u16: From<Gray16<E1>>,
    {
        self.encode_as_impl()
    }
}

#[cfg(feature = "col-rgb48")]
impl<E1> crate::buffer::RawPixBuf<Rgb48<E1>> {
    #[inline]
    pub fn encode_as<E2>(self) -> crate::buffer::RawPixBuf<Rgb48<E2>>
    where
        E1: super::Endianness + Copy,
        E2: super::Endianness + Copy,
        Rgb48<E1>: Color,
        Rgb48<E2>: Color + From<u64>,
        u64: From<Rgb48<E1>>,
    {
        self.encode_as_impl()
    }
}