use std::{
cmp::{max, min},
num::NonZeroUsize,
};
use crate::util::Pixel;
use semisafe::option::unwrap as semisafe_opt_unwrap;
pub unsafe fn limit_changes<T: Pixel>(
dest: *mut u8,
dest_stride_bytes: NonZeroUsize,
src: *const u8,
src_stride_bytes: NonZeroUsize,
width: NonZeroUsize,
height: NonZeroUsize,
limit: u16,
) {
let dest: *mut T = dest.cast();
let src: *const T = src.cast();
let limit = semisafe_opt_unwrap(T::from(limit));
let dest_stride_pixels =
unsafe { NonZeroUsize::new_unchecked(dest_stride_bytes.get() / size_of::<T>()) };
let src_stride_pixels =
unsafe { NonZeroUsize::new_unchecked(src_stride_bytes.get() / size_of::<T>()) };
for h in 0..height.get() {
let dest_row_offset = h * dest_stride_pixels.get();
let src_row_offset = h * src_stride_pixels.get();
for i in 0..width.get() {
let dest = dest.add(dest_row_offset + i);
let src = src.add(src_row_offset + i);
*dest = min(
max(*dest, (*src).saturating_sub(limit)),
(*src).saturating_add(limit),
);
}
}
}