const INT_SIZE: usize = std::mem::size_of::<isize>() * 8;
pub(super) fn abs(x: isize) -> isize {
let m = x >> (INT_SIZE - 1);
(x ^ m) - m
}
pub(super) fn paeth(a: u8, b: u8, c: u8) -> u8 {
let mut pc = c as isize;
let mut pa = (b as isize).wrapping_sub(pc);
let mut pb = (a as isize).wrapping_sub(pc);
pc = abs(pa + pb);
pa = abs(pa);
pb = abs(pb);
if pa <= pb && pa <= pc {
return a;
} else if pb <= pc {
return b;
}
c
}
pub(super) fn filter_paeth(cdat: &mut [u8], pdat: &[u8], bytes_per_pixel: usize) {
for i in 0..bytes_per_pixel {
let mut a = 0;
let mut c = 0;
let mut j = i;
while j < cdat.len() {
let b = pdat[j] as isize;
let mut pa = b - c;
let mut pb = a - c;
let pc = abs(pa + pb);
pa = abs(pa);
pb = abs(pb);
if pa <= pb && pa <= pc {
} else if pb <= pc {
a = b
} else {
a = c
}
a += cdat[j] as isize;
a &= 0xff;
cdat[j] = a as u8;
c = b;
j += bytes_per_pixel;
}
}
}