use crate::encode::tables::ZIGZAG_ORDER;
pub fn quantize_block(coeffs: &[i32; 64], quant_table: &[u16; 64], output: &mut [i16; 64]) {
for zigzag_pos in 0..64 {
let natural_idx = ZIGZAG_ORDER[zigzag_pos];
let coeff = coeffs[natural_idx];
let quant = quant_table[natural_idx] as i32;
let quantized = if coeff >= 0 {
(coeff + (quant >> 1)) / quant
} else {
(coeff - (quant >> 1)) / quant
};
output[zigzag_pos] = quantized as i16;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn quantize_all_zeros() {
let coeffs = [0i32; 64];
let quant = [16u16; 64];
let mut output = [0i16; 64];
quantize_block(&coeffs, &quant, &mut output);
for (i, &v) in output.iter().enumerate() {
assert_eq!(v, 0, "expected 0 at zigzag index {i}, got {v}");
}
}
#[test]
fn quantize_dc_coefficient() {
let mut coeffs = [0i32; 64];
coeffs[0] = 800; let mut quant = [1u16; 64];
quant[0] = 16;
let mut output = [0i16; 64];
quantize_block(&coeffs, &quant, &mut output);
assert_eq!(output[0], 50);
}
#[test]
fn quantize_rounding() {
let mut coeffs = [0i32; 64];
coeffs[0] = 25; let mut quant = [1u16; 64];
quant[0] = 16;
let mut output = [0i16; 64];
quantize_block(&coeffs, &quant, &mut output);
assert_eq!(output[0], 2);
}
#[test]
fn quantize_negative_rounding() {
let mut coeffs = [0i32; 64];
coeffs[0] = -25; let mut quant = [1u16; 64];
quant[0] = 16;
let mut output = [0i16; 64];
quantize_block(&coeffs, &quant, &mut output);
assert_eq!(output[0], -2);
}
#[test]
fn quantize_zigzag_ordering() {
let mut coeffs = [0i32; 64];
coeffs[1] = 100; coeffs[8] = 200; let quant = [1u16; 64];
let mut output = [0i16; 64];
quantize_block(&coeffs, &quant, &mut output);
assert_eq!(output[1], 100); assert_eq!(output[2], 200); }
}