#![forbid(unsafe_code)]
use crate::DecodeError;
use mediaway_sw::h264::BitReader;
const MAX_TILE_WIDTH_B64: u32 = 64;
const MIN_TILE_WIDTH_B64: u32 = 4;
const fn calc_min_log2_tile_cols(sb64_cols: u32) -> u32 {
let mut min_log2 = 0u32;
while (MAX_TILE_WIDTH_B64 << min_log2) < sb64_cols {
min_log2 += 1;
}
min_log2
}
const fn calc_max_log2_tile_cols(sb64_cols: u32) -> u32 {
let mut max_log2 = 1u32;
while (sb64_cols >> max_log2) >= MIN_TILE_WIDTH_B64 {
max_log2 += 1;
}
max_log2 - 1
}
pub(super) fn parse(r: &mut BitReader<'_>, mi_cols: u32) -> Result<(), DecodeError> {
let map_err = |_| DecodeError::InvalidInput;
let sb64_cols = mi_cols.div_ceil(8);
let min_log2_tile_cols = calc_min_log2_tile_cols(sb64_cols);
let max_log2_tile_cols = calc_max_log2_tile_cols(sb64_cols);
let mut tile_cols_log2 = min_log2_tile_cols;
while tile_cols_log2 < max_log2_tile_cols {
if r.read_bit().map_err(map_err)? == 0 {
break;
}
tile_cols_log2 += 1;
}
if tile_cols_log2 != 0 {
return Err(DecodeError::Unsupported);
}
let mut tile_rows_log2 = r.read_bit().map_err(map_err)?;
if tile_rows_log2 == 1 {
let increment = r.read_bit().map_err(map_err)?;
tile_rows_log2 += increment;
}
if tile_rows_log2 != 0 {
return Err(DecodeError::Unsupported);
}
Ok(())
}
#[cfg(test)]
#[path = "tile_info_tests.rs"]
mod tests;