use alloc::vec::Vec;
use crate::error::{Result, ValidationError};
#[derive(Debug)]
pub(crate) struct SizeData {
pub(crate) decoder_capabilities: u16,
pub(crate) reference_grid_width: u32,
pub(crate) reference_grid_height: u32,
pub(crate) image_area_x_offset: u32,
pub(crate) image_area_y_offset: u32,
pub(crate) tile_width: u32,
pub(crate) tile_height: u32,
pub(crate) tile_x_offset: u32,
pub(crate) tile_y_offset: u32,
pub(crate) component_sizes: Vec<ComponentSizeInfo>,
pub(crate) x_shrink_factor: u32,
pub(crate) y_shrink_factor: u32,
pub(crate) x_resolution_shrink_factor: u32,
pub(crate) y_resolution_shrink_factor: u32,
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct ComponentSizeInfo {
pub(crate) precision: u8,
pub(crate) signed: bool,
pub(crate) horizontal_resolution: u8,
pub(crate) vertical_resolution: u8,
}
impl SizeData {
pub(crate) fn tile_x_coord(&self, idx: u32) -> u32 {
idx % self.num_x_tiles()
}
pub(crate) fn tile_y_coord(&self, idx: u32) -> u32 {
idx / self.num_x_tiles()
}
pub(crate) fn num_x_tiles(&self) -> u32 {
(self.reference_grid_width - self.tile_x_offset).div_ceil(self.tile_width)
}
pub(crate) fn num_y_tiles(&self) -> u32 {
(self.reference_grid_height - self.tile_y_offset).div_ceil(self.tile_height)
}
pub(crate) fn num_tiles(&self) -> u32 {
self.num_x_tiles().saturating_mul(self.num_y_tiles())
}
pub(crate) fn image_width(&self) -> u32 {
self.checked_image_width()
.expect("validated JPEG 2000 horizontal shrink factors")
}
pub(crate) fn image_height(&self) -> u32 {
self.checked_image_height()
.expect("validated JPEG 2000 vertical shrink factors")
}
pub(crate) fn checked_image_width(&self) -> Result<u32> {
let shrink_factor = self.checked_x_shrink_factor()?;
Ok((self.reference_grid_width - self.image_area_x_offset).div_ceil(shrink_factor))
}
pub(crate) fn checked_image_height(&self) -> Result<u32> {
let shrink_factor = self.checked_y_shrink_factor()?;
Ok((self.reference_grid_height - self.image_area_y_offset).div_ceil(shrink_factor))
}
pub(crate) fn checked_x_shrink_factor(&self) -> Result<u32> {
self.x_shrink_factor
.checked_mul(self.x_resolution_shrink_factor)
.filter(|factor| *factor != 0)
.ok_or(ValidationError::InvalidDimensions.into())
}
pub(crate) fn checked_y_shrink_factor(&self) -> Result<u32> {
self.y_shrink_factor
.checked_mul(self.y_resolution_shrink_factor)
.filter(|factor| *factor != 0)
.ok_or(ValidationError::InvalidDimensions.into())
}
pub(crate) fn reference_image_width(&self) -> u32 {
self.reference_grid_width - self.image_area_x_offset
}
pub(crate) fn reference_image_height(&self) -> u32 {
self.reference_grid_height - self.image_area_y_offset
}
}