use log::{debug, error, warn};
use std::io::SeekFrom;
use crate::io::seekable::SeekableReader;
use crate::tiff::errors::{TiffError, TiffResult};
use crate::io::byte_order::ByteOrderHandler;
use crate::tiff::constants::header;
pub fn validate_ifd_offset(offset: u64, file_size: u64) -> TiffResult<()> {
if offset >= file_size || offset < 8 {
return Err(TiffError::GenericError(format!(
"Invalid IFD offset: {} (file size: {})",
offset, file_size
)));
}
Ok(())
}
pub fn get_file_size(reader: &mut dyn SeekableReader) -> TiffResult<u64> {
let current_position = reader.seek(SeekFrom::Current(0))?;
let file_size = match reader.seek(SeekFrom::End(0)) {
Ok(size) => {
reader.seek(SeekFrom::Start(current_position))?;
size
},
Err(e) => {
warn!("Could not determine file size: {}", e);
reader.seek(SeekFrom::Start(current_position))?;
u64::MAX
}
};
Ok(file_size)
}
pub fn validate_bigtiff_header(
reader: &mut dyn SeekableReader,
byte_order_handler: &Box<dyn ByteOrderHandler>
) -> TiffResult<()> {
let offset_size = byte_order_handler.read_u16(reader)?;
let zeros = byte_order_handler.read_u16(reader)?;
debug!("BigTIFF offset size: {}", offset_size);
debug!("BigTIFF zeros: {}", zeros);
if offset_size != header::BIGTIFF_OFFSET_SIZE || zeros != 0 {
error!("Invalid BigTIFF header: offset_size={}, zeros={}", offset_size, zeros);
return Err(TiffError::InvalidBigTIFFHeader);
}
Ok(())
}
pub fn validate_range<T>(value: T, min: T, max: T, name: &str) -> TiffResult<()>
where
T: PartialOrd + std::fmt::Display,
{
if value < min || value > max {
return Err(TiffError::GenericError(format!(
"Invalid {}: {} (must be between {} and {})",
name, value, min, max
)));
}
Ok(())
}