#[derive(Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct XorShufDither {
count_frames: bool,
frame_cnt: usize,
}
impl XorShufDither {
pub fn set_count_frames(&mut self, count_frames: bool) {
self.count_frames = count_frames;
}
}
impl XorShufDither {
const MASK: ([f32; 256], [u8; 256]) = {
let mut state = (0, 1, 1, 1);
const fn xorshift((mut a, mut x, mut y, mut z): (u8, u8, u8, u8)) -> (u8, u8, u8, u8) {
let t = x ^ (x << 4);
x = y;
y = z;
z = a;
a = z ^ t ^ (z >> 1) ^ (t << 1);
(a, x, y, z)
}
state = xorshift(state);
state = xorshift(state);
state = xorshift(state);
let mut arr = [0.0; 256];
let mut arr2 = [0; 256];
let mut i = 0;
while i < 256 {
state = xorshift(state);
arr2[i] = state.0;
arr[i] = (state.0 as f32 / 256.0) - 0.5;
i += 1;
}
(arr, arr2)
};
}
impl Dithering for XorShufDither {
fn new_frame(&mut self, _: usize, _h: usize) {
self.frame_cnt += 1;
}
fn dither(&self, interp: f32, x: usize, y: usize, z: usize) -> f32 {
let idx =
((x + 1) * (y + 1) * (z + 1) * if self.count_frames { self.frame_cnt } else { 1 })
% 256;
interp + Self::MASK.0[idx]
}
}
pub trait Dithering {
fn new_frame(&mut self, w: usize, h: usize);
fn dither(&self, interp: f32, x: usize, y: usize, z: usize) -> f32;
}
impl Dithering for () {
fn new_frame(&mut self, _: usize, _h: usize) {}
fn dither(&self, interp: f32, _: usize, _: usize, _: usize) -> f32 {
interp
}
}