ezk-image 0.4.3

Convert pixel and color formats such and RGB, YUV (YCbCr), ICtCp
Documentation
use crate::formats::rgb::{RgbaBlock, RgbaPixel, RgbaSrc};
use crate::planes::read_planes;
use crate::primitive::Primitive;
use crate::vector::Vector;
use crate::{ConvertError, ImageRef, ImageRefExt};
use std::marker::PhantomData;

pub(crate) struct ReadRgb<'a, const SWIZZLE: u8, P: Primitive> {
    rgb: &'a [u8],

    rgb_stride: usize,

    max_value: f32,

    _m: PhantomData<&'a [P]>,
}

impl<'a, const SWIZZLE: u8, P: Primitive> ReadRgb<'a, SWIZZLE, P> {
    pub(crate) fn new(src: &'a dyn ImageRef) -> Result<Self, ConvertError> {
        src.bounds_check()?;

        let [(rgb, rgb_stride)] = read_planes(src.planes())?;

        Ok(Self {
            rgb,
            rgb_stride,
            max_value: crate::formats::max_value_for_bits(src.format().bits_per_component()),
            _m: PhantomData,
        })
    }
}

impl<const SWIZZLE: u8, P: Primitive> RgbaSrc for ReadRgb<'_, SWIZZLE, P> {
    #[inline(always)]
    unsafe fn read<V: Vector>(&mut self, x: usize, y: usize) -> RgbaBlock<V> {
        let rgb00offset = y * self.rgb_stride + x * 3 * P::SIZE;
        let rgb10offset = (y + 1) * self.rgb_stride + x * 3 * P::SIZE;

        let [[r00, g00, b00], [r01, g01, b01]] =
            P::load_3x_interleaved_2x::<V>(&self.rgb[rgb00offset..]);
        let [[r10, g10, b10], [r11, g11, b11]] =
            P::load_3x_interleaved_2x::<V>(&self.rgb[rgb10offset..]);

        let r00 = r00.vdivf(self.max_value);
        let g00 = g00.vdivf(self.max_value);
        let b00 = b00.vdivf(self.max_value);

        let r01 = r01.vdivf(self.max_value);
        let g01 = g01.vdivf(self.max_value);
        let b01 = b01.vdivf(self.max_value);

        let r10 = r10.vdivf(self.max_value);
        let g10 = g10.vdivf(self.max_value);
        let b10 = b10.vdivf(self.max_value);

        let r11 = r11.vdivf(self.max_value);
        let g11 = g11.vdivf(self.max_value);
        let b11 = b11.vdivf(self.max_value);

        let px00 = RgbaPixel::from_components::<SWIZZLE>(r00, g00, b00, <V>::splat(1.0));
        let px01 = RgbaPixel::from_components::<SWIZZLE>(r01, g01, b01, <V>::splat(1.0));
        let px10 = RgbaPixel::from_components::<SWIZZLE>(r10, g10, b10, <V>::splat(1.0));
        let px11 = RgbaPixel::from_components::<SWIZZLE>(r11, g11, b11, <V>::splat(1.0));

        RgbaBlock {
            px00,
            px01,
            px10,
            px11,
        }
    }
}