use once_cell::sync::Lazy;
pub static COSINE_TABLE_16: Lazy<[f32; 256]> = Lazy::new(setup_cosines16);
const OO_SQRT2: f32 = 1.0 / std::f32::consts::SQRT_2;
pub const fn build_copy_matrix16() -> [usize; 256] {
let mut matrix = [0usize; 256];
let mut diag = false;
let mut right = true;
let mut i = 0;
let mut j = 0;
let mut count = 0;
while count < 16 * 16 {
matrix[j * 16 + i] = count;
count += 1;
if !diag {
if right {
if i < 15 {
i += 1;
} else {
j += 1;
}
right = false;
diag = true;
} else {
if j < 15 {
j += 1;
} else {
i += 1;
}
right = true;
diag = true;
}
} else if right {
if i < 15 {
i += 1;
} else {
j += 1;
}
if j > 0 {
j = j.saturating_sub(1);
}
if i == 15 || j == 0 {
diag = false;
}
} else {
if j < 15 {
j += 1;
} else {
i += 1;
}
if i > 0 {
i = i.saturating_sub(1);
}
if j == 15 || i == 0 {
diag = false;
}
}
}
matrix
}
pub const fn build_dequantize_table16() -> [f32; 256] {
let mut table = [0.0f32; 256];
let mut j = 0;
while j < 16 {
let mut i = 0;
while i < 16 {
table[j * 16 + i] = 1.0 + 2.0 * ((i + j) as f32);
i += 1;
}
j += 1;
}
table
}
pub fn setup_cosines16() -> [f32; 256] {
let hposz: f32 = std::f32::consts::PI * 0.5 / 16.0;
let mut cosine_table = [0.0f32; 256];
for u in 0..16 {
for n in 0..16 {
cosine_table[u * 16 + n] = ((2.0 * n as f32 + 1.0) * u as f32 * hposz).cos();
}
}
cosine_table
}
pub fn idct_column16(linein: &[f32], lineout: &mut [f32], column: usize) {
for n in 0..16 {
let mut total = OO_SQRT2 * linein[column];
for u in 1..16 {
let usize = u * 16;
total += linein[usize + column] * COSINE_TABLE_16[usize + n];
}
lineout[16 * n + column] = total;
}
}
pub fn idct_line16(linein: &[f32], lineout: &mut [f32], line: usize) {
const OOSOB: f32 = 2.0 / 16.0;
let line_size = line * 16;
for n in 0..16 {
let mut total = OO_SQRT2 * linein[line_size];
for u in 1..16 {
total += linein[line_size + u] * COSINE_TABLE_16[u * 16 + n];
}
lineout[line_size + n] = total * OOSOB;
}
}