pub const LOG2_FRAC_TABLE_LEN: usize = 24;
pub const Q3_BITS_PER_WHOLE_BIT: u32 = 8;
pub const LOG2_FRAC_TABLE: [u8; LOG2_FRAC_TABLE_LEN] = [
0, 8, 13, 16, 19, 21, 23, 24, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 34, 35, 36, 36, 37, 37,
];
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Log2FracError {
CodedBandsOutOfRange { coded_bands: u32 },
}
pub fn log2_frac(coded_bands: u32) -> Result<u8, Log2FracError> {
if coded_bands >= LOG2_FRAC_TABLE_LEN as u32 {
return Err(Log2FracError::CodedBandsOutOfRange { coded_bands });
}
Ok(LOG2_FRAC_TABLE[coded_bands as usize])
}
pub fn log2_frac_row() -> &'static [u8; LOG2_FRAC_TABLE_LEN] {
&LOG2_FRAC_TABLE
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn table_shape_constant_matches_struct() {
assert_eq!(LOG2_FRAC_TABLE_LEN, 24);
assert_eq!(LOG2_FRAC_TABLE.len(), LOG2_FRAC_TABLE_LEN);
}
#[test]
fn q3_unit_denominator_is_eight() {
assert_eq!(Q3_BITS_PER_WHOLE_BIT, 8);
}
#[test]
fn csv_index_0_is_zero() {
assert_eq!(LOG2_FRAC_TABLE[0], 0);
assert_eq!(log2_frac(0).unwrap(), 0);
}
#[test]
fn csv_index_1_is_eight() {
assert_eq!(LOG2_FRAC_TABLE[1], 8);
assert_eq!(log2_frac(1).unwrap(), 8);
}
#[test]
fn csv_index_2_is_thirteen() {
assert_eq!(LOG2_FRAC_TABLE[2], 13);
assert_eq!(log2_frac(2).unwrap(), 13);
}
#[test]
fn csv_index_4_is_nineteen() {
assert_eq!(LOG2_FRAC_TABLE[4], 19);
assert_eq!(log2_frac(4).unwrap(), 19);
}
#[test]
fn csv_index_15_is_thirty_two() {
assert_eq!(LOG2_FRAC_TABLE[14], 32);
assert_eq!(LOG2_FRAC_TABLE[15], 32);
assert_eq!(log2_frac(15).unwrap(), 32);
}
#[test]
fn csv_index_21_is_thirty_six() {
assert_eq!(LOG2_FRAC_TABLE[21], 36);
assert_eq!(log2_frac(21).unwrap(), 36);
}
#[test]
fn csv_index_23_is_thirty_seven() {
assert_eq!(LOG2_FRAC_TABLE[23], 37);
assert_eq!(log2_frac(23).unwrap(), 37);
}
#[test]
fn table_is_monotone_non_decreasing() {
for w in LOG2_FRAC_TABLE.windows(2) {
assert!(
w[0] <= w[1],
"LOG2_FRAC_TABLE not monotone non-decreasing at pair {:?}",
w
);
}
}
#[test]
fn entries_are_at_or_above_eight_times_log2() {
for (n, &entry) in LOG2_FRAC_TABLE.iter().enumerate().skip(1) {
let floor_log2 = (u32::BITS - 1 - (n as u32).leading_zeros()) as u8;
let lower_bound = floor_log2.checked_mul(8).expect("log2 fits in u8");
assert!(
entry >= lower_bound,
"LOG2_FRAC_TABLE[{}] = {} should be >= 8 * floor(log2({})) = {}",
n,
entry,
n,
lower_bound
);
}
}
#[test]
fn log2_frac_accessor_is_total_over_in_range_inputs() {
for n in 0..LOG2_FRAC_TABLE_LEN as u32 {
let v = log2_frac(n).expect("in-range lookup");
assert_eq!(v, LOG2_FRAC_TABLE[n as usize]);
}
}
#[test]
fn log2_frac_rejects_coded_bands_out_of_range() {
let err = log2_frac(LOG2_FRAC_TABLE_LEN as u32).unwrap_err();
assert_eq!(err, Log2FracError::CodedBandsOutOfRange { coded_bands: 24 });
let err = log2_frac(u32::MAX).unwrap_err();
assert_eq!(
err,
Log2FracError::CodedBandsOutOfRange {
coded_bands: u32::MAX
}
);
}
#[test]
fn log2_frac_row_returns_full_24_byte_table() {
let row = log2_frac_row();
assert_eq!(row.len(), LOG2_FRAC_TABLE_LEN);
assert_eq!(row, &LOG2_FRAC_TABLE);
assert_eq!(row[0], 0);
assert_eq!(row[LOG2_FRAC_TABLE_LEN - 1], 37);
}
#[test]
fn pair_lookup_matches_row_lookup() {
let row = log2_frac_row();
for n in 0..LOG2_FRAC_TABLE_LEN as u32 {
assert_eq!(log2_frac(n).unwrap(), row[n as usize]);
}
}
#[test]
fn hybrid_reachable_index_pins_at_four_coded_bands() {
assert_eq!(log2_frac(4).unwrap(), 19);
}
#[test]
fn celt_only_reachable_index_pins_at_twenty_one_coded_bands() {
assert_eq!(log2_frac(21).unwrap(), 36);
}
}