feim 0.25.1

Modular crate for working with images in Rust
Documentation
use super::convert::ConvertFrom;
use super::{Color, Zero};

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[repr(C)]
pub struct Cmyk {
    pub c: u8,
    pub m: u8,
    pub y: u8,
    pub k: u8,
}

impl Zero for Cmyk {
    const ZERO: Self = Cmyk {
        c: 0,
        m: 0,
        y: 0,
        k: 0,
    };
}

impl Color for Cmyk {
    fn as_rgba(&self) -> (u32, u32, u32, u32) {
        let c = self.c as u32;
        let m = self.m as u32;
        let y = self.y as u32;
        let k = self.k as u32;

        let w = 0xffff - k * 0x101;

        let r = (0xffff - c * 0x101) * w / 0xffff;
        let g = (0xffff - m * 0x101) * w / 0xffff;
        let b = (0xffff - y * 0x101) * w / 0xffff;
        let a = 0xffff;

        (r, g, b, a)
    }
}

impl<C: Color> ConvertFrom<C> for Cmyk {
    fn convert_from(c: C) -> Cmyk {
        let (r, g, b, _) = c.as_rgba();

        let w = std::cmp::min(std::cmp::min(r, g), b);

        if w == 0 {
            return Cmyk {
                c: 0,
                m: 0,
                y: 0,
                k: 0xff,
            };
        }

        let c = (w - r) * 0xffff / w;
        let m = (w - g) * 0xffff / w;
        let y = (w - b) * 0xffff / w;
        let k = 0xffff - w;

        Cmyk {
            c: ((c >> 8) & 0xff) as u8,
            m: ((m >> 8) & 0xff) as u8,
            y: ((y >> 8) & 0xff) as u8,
            k: ((k >> 8) & 0xff) as u8,
        }
    }
}

impl From<Cmyk> for u32 {
    fn from(cmyk: Cmyk) -> u32 {
        let c = cmyk.c as u32;
        let m = (cmyk.m as u32) << 8;
        let y = (cmyk.y as u32) << (8 * 2);
        let k = (cmyk.k as u32) << (8 * 3);
        c | m | y | k
    }
}

impl From<u32> for Cmyk {
    fn from(cmyk: u32) -> Cmyk {
        let c = (cmyk & 0xff) as u8;
        let m = ((cmyk & 0xff00) >> 8) as u8;
        let y = ((cmyk & 0xff0000) >> 16) as u8;
        let k = ((cmyk & 0xff000000) >> 24) as u8;
        Cmyk { c, m, y, k }
    }
}