#![allow(dead_code)]
pub const BLOCK_DIM: usize = 8;
pub const DCT_BLOCK_SIZE: usize = BLOCK_DIM * BLOCK_DIM;
pub const GROUP_DIM: usize = 256;
pub const GROUP_DIM_IN_BLOCKS: usize = GROUP_DIM / BLOCK_DIM;
pub const DC_GROUP_DIM: usize = GROUP_DIM * BLOCK_DIM;
pub const DC_GROUP_DIM_IN_BLOCKS: usize = DC_GROUP_DIM / BLOCK_DIM;
pub const TILE_DIM: usize = 64;
pub const TILE_DIM_IN_BLOCKS: usize = TILE_DIM / BLOCK_DIM;
pub const JPEG_UPSAMPLING_H_SHIFT: [usize; 4] = [0, 1, 1, 0];
pub const JPEG_UPSAMPLING_V_SHIFT: [usize; 4] = [0, 1, 0, 1];
#[inline]
pub const fn div_ceil(a: usize, b: usize) -> usize {
#[allow(clippy::manual_div_ceil)]
{
(a + b - 1) / b
}
}
#[inline]
pub fn clamp<T: PartialOrd>(val: T, low: T, hi: T) -> T {
if val < low {
low
} else if val > hi {
hi
} else {
val
}
}
#[inline]
pub const fn pack_signed(value: i32) -> u32 {
((value as u32) << 1) ^ (((!(value as u32)) >> 31).wrapping_sub(1))
}
#[inline]
pub const fn ceil_log2_nonzero(n: usize) -> u32 {
if n <= 1 {
0
} else {
usize::BITS - (n - 1).leading_zeros()
}
}
#[inline]
pub const fn floor_log2_nonzero(n: u32) -> u32 {
31 - n.leading_zeros()
}
#[cfg(feature = "unsafe-performance")]
#[allow(unsafe_code, clippy::uninit_assumed_init)]
#[inline(always)]
pub fn uninit_buf<const N: usize>() -> [f32; N] {
unsafe { core::mem::MaybeUninit::<[f32; N]>::uninit().assume_init() }
}
#[cfg(not(feature = "unsafe-performance"))]
#[inline(always)]
pub fn uninit_buf<const N: usize>() -> [f32; N] {
[0.0f32; N]
}
#[cfg(feature = "unsafe-performance")]
#[allow(unsafe_code)]
#[inline(always)]
pub fn as_array_ref<const N: usize>(slice: &[f32], offset: usize) -> &[f32; N] {
debug_assert!(offset + N <= slice.len());
unsafe { &*(slice.as_ptr().add(offset) as *const [f32; N]) }
}
#[cfg(not(feature = "unsafe-performance"))]
#[inline(always)]
pub fn as_array_ref<const N: usize>(slice: &[f32], offset: usize) -> &[f32; N] {
slice[offset..offset + N].try_into().unwrap()
}
#[cfg(feature = "unsafe-performance")]
#[allow(unsafe_code)]
#[inline(always)]
pub fn as_array_mut<const N: usize>(slice: &mut [f32], offset: usize) -> &mut [f32; N] {
debug_assert!(offset + N <= slice.len());
unsafe { &mut *(slice.as_mut_ptr().add(offset) as *mut [f32; N]) }
}
#[cfg(not(feature = "unsafe-performance"))]
#[inline(always)]
pub fn as_array_mut<const N: usize>(slice: &mut [f32], offset: usize) -> &mut [f32; N] {
(&mut slice[offset..offset + N]).try_into().unwrap()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_pack_signed() {
assert_eq!(pack_signed(0), 0);
assert_eq!(pack_signed(1), 2);
assert_eq!(pack_signed(-1), 1);
assert_eq!(pack_signed(2), 4);
assert_eq!(pack_signed(-2), 3);
assert_eq!(pack_signed(3), 6);
assert_eq!(pack_signed(-3), 5);
}
#[test]
fn test_ceil_log2_nonzero() {
assert_eq!(ceil_log2_nonzero(1), 0);
assert_eq!(ceil_log2_nonzero(2), 1);
assert_eq!(ceil_log2_nonzero(3), 2);
assert_eq!(ceil_log2_nonzero(4), 2);
assert_eq!(ceil_log2_nonzero(5), 3);
assert_eq!(ceil_log2_nonzero(8), 3);
assert_eq!(ceil_log2_nonzero(9), 4);
}
#[test]
fn test_floor_log2_nonzero() {
assert_eq!(floor_log2_nonzero(1), 0);
assert_eq!(floor_log2_nonzero(2), 1);
assert_eq!(floor_log2_nonzero(3), 1);
assert_eq!(floor_log2_nonzero(4), 2);
assert_eq!(floor_log2_nonzero(7), 2);
assert_eq!(floor_log2_nonzero(8), 3);
assert_eq!(floor_log2_nonzero(16), 4);
}
#[test]
fn test_div_ceil() {
assert_eq!(div_ceil(0, 8), 0);
assert_eq!(div_ceil(1, 8), 1);
assert_eq!(div_ceil(8, 8), 1);
assert_eq!(div_ceil(9, 8), 2);
assert_eq!(div_ceil(16, 8), 2);
assert_eq!(div_ceil(256, 8), 32);
}
}