pixelflow-filters 0.1.0

Official in-repository filters for PixelFlow.
//! Deterministic dither helpers shared by conversion filters.

use semisafe::slice::get as semisafe_get;

/// Fixed Fruit-style blue-noise ranks from libplacebo/mpv.
pub(crate) const FRUIT_DITHER_8X8: [[u8; 8]; 8] = [
    [1, 45, 10, 39, 2, 44, 32, 24],
    [36, 30, 54, 17, 60, 21, 53, 11],
    [58, 7, 27, 49, 13, 41, 6, 46],
    [25, 33, 43, 3, 37, 19, 57, 31],
    [0, 52, 20, 61, 23, 48, 14, 35],
    [62, 15, 47, 12, 42, 4, 56, 8],
    [29, 40, 5, 38, 16, 50, 34, 26],
    [51, 18, 59, 22, 55, 28, 9, 63],
];

/// Returns centered dither offset in one code-value unit.
#[must_use]
pub(crate) fn fruit_offset(plane: usize, x: usize, y: usize) -> f32 {
    let row = (y + plane * 3) & 7;
    let column = (x + plane * 5) & 7;
    let value = *semisafe_get(semisafe_get(&FRUIT_DITHER_8X8, row), column);
    (f32::from(value) + 0.5) / 64.0 - 0.5
}

#[cfg(test)]
mod tests {
    use super::{FRUIT_DITHER_8X8, fruit_offset};

    #[test]
    fn fruit_dither_matrix_is_stable() {
        assert_eq!(FRUIT_DITHER_8X8[0], [1, 45, 10, 39, 2, 44, 32, 24]);
        assert_eq!(FRUIT_DITHER_8X8[7], [51, 18, 59, 22, 55, 28, 9, 63]);
    }

    #[test]
    fn fruit_dither_offsets_are_centered_in_one_code_unit() {
        assert!((fruit_offset(0, 0, 0) - (-0.4765625)).abs() <= f32::EPSILON);
        assert!((fruit_offset(0, 5, 0) - 0.1953125).abs() <= f32::EPSILON);
        assert_ne!(fruit_offset(0, 0, 0), fruit_offset(1, 0, 0));
    }
}