153 lines
3.5 KiB
Rust
153 lines
3.5 KiB
Rust
use std::io::{Error, ErrorKind, Read, Result, Seek, SeekFrom};
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
|
pub enum Endian {
|
|
Little,
|
|
Big,
|
|
}
|
|
|
|
pub struct TiffRead<R: Read + Seek> {
|
|
reader: R,
|
|
endian: Endian,
|
|
}
|
|
|
|
impl<R: Read + Seek> TiffRead<R> {
|
|
pub fn new(mut reader: R) -> Result<Self> {
|
|
let error = Error::new(ErrorKind::InvalidData, "Invalid Tiff format");
|
|
|
|
let mut data = [0_u8; 2];
|
|
reader.read_exact(&mut data)?;
|
|
let endian = if data[0] == 0x49 && data[1] == 0x49 {
|
|
Endian::Little
|
|
} else if data[0] == 0x4d && data[1] == 0x4d {
|
|
Endian::Big
|
|
} else {
|
|
return Err(error);
|
|
};
|
|
|
|
reader.read_exact(&mut data)?;
|
|
let magic_number = match endian {
|
|
Endian::Little => u16::from_le_bytes(data),
|
|
Endian::Big => u16::from_be_bytes(data),
|
|
};
|
|
if magic_number != 42 {
|
|
return Err(error);
|
|
}
|
|
|
|
Ok(Self { reader, endian })
|
|
}
|
|
|
|
pub fn endian(&self) -> Endian {
|
|
self.endian
|
|
}
|
|
}
|
|
|
|
impl<R: Read + Seek> Read for TiffRead<R> {
|
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
|
self.reader.read(buf)
|
|
}
|
|
}
|
|
|
|
impl<R: Read + Seek> Seek for TiffRead<R> {
|
|
fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
|
|
self.reader.seek(pos)
|
|
}
|
|
}
|
|
|
|
impl<R: Read + Seek> TiffRead<R> {
|
|
pub fn seek_from_start(&mut self, offset: u32) -> Result<u64> {
|
|
self.reader.seek(SeekFrom::Start(offset.into()))
|
|
}
|
|
|
|
pub fn read_ascii(&mut self) -> Result<char> {
|
|
let data = self.read_n::<1>()?;
|
|
Ok(data[0] as char)
|
|
}
|
|
|
|
pub fn read_n<const N: usize>(&mut self) -> Result<[u8; N]> {
|
|
let mut data = [0_u8; N];
|
|
self.read_exact(&mut data)?;
|
|
Ok(data)
|
|
}
|
|
|
|
pub fn read_u8(&mut self) -> Result<u8> {
|
|
let data = self.read_n()?;
|
|
match self.endian {
|
|
Endian::Little => Ok(u8::from_le_bytes(data)),
|
|
Endian::Big => Ok(u8::from_be_bytes(data)),
|
|
}
|
|
}
|
|
|
|
pub fn read_u16(&mut self) -> Result<u16> {
|
|
let data = self.read_n()?;
|
|
match self.endian {
|
|
Endian::Little => Ok(u16::from_le_bytes(data)),
|
|
Endian::Big => Ok(u16::from_be_bytes(data)),
|
|
}
|
|
}
|
|
|
|
pub fn read_u32(&mut self) -> Result<u32> {
|
|
let data = self.read_n()?;
|
|
match self.endian {
|
|
Endian::Little => Ok(u32::from_le_bytes(data)),
|
|
Endian::Big => Ok(u32::from_be_bytes(data)),
|
|
}
|
|
}
|
|
|
|
pub fn read_u64(&mut self) -> Result<u64> {
|
|
let data = self.read_n()?;
|
|
match self.endian {
|
|
Endian::Little => Ok(u64::from_le_bytes(data)),
|
|
Endian::Big => Ok(u64::from_be_bytes(data)),
|
|
}
|
|
}
|
|
|
|
pub fn read_i8(&mut self) -> Result<i8> {
|
|
let data = self.read_n()?;
|
|
match self.endian {
|
|
Endian::Little => Ok(i8::from_le_bytes(data)),
|
|
Endian::Big => Ok(i8::from_be_bytes(data)),
|
|
}
|
|
}
|
|
|
|
pub fn read_i16(&mut self) -> Result<i16> {
|
|
let data = self.read_n()?;
|
|
match self.endian {
|
|
Endian::Little => Ok(i16::from_le_bytes(data)),
|
|
Endian::Big => Ok(i16::from_be_bytes(data)),
|
|
}
|
|
}
|
|
|
|
pub fn read_i32(&mut self) -> Result<i32> {
|
|
let data = self.read_n()?;
|
|
match self.endian {
|
|
Endian::Little => Ok(i32::from_le_bytes(data)),
|
|
Endian::Big => Ok(i32::from_be_bytes(data)),
|
|
}
|
|
}
|
|
|
|
pub fn read_i64(&mut self) -> Result<i64> {
|
|
let data = self.read_n()?;
|
|
match self.endian {
|
|
Endian::Little => Ok(i64::from_le_bytes(data)),
|
|
Endian::Big => Ok(i64::from_be_bytes(data)),
|
|
}
|
|
}
|
|
|
|
pub fn read_f32(&mut self) -> Result<f32> {
|
|
let data = self.read_n()?;
|
|
match self.endian {
|
|
Endian::Little => Ok(f32::from_le_bytes(data)),
|
|
Endian::Big => Ok(f32::from_be_bytes(data)),
|
|
}
|
|
}
|
|
|
|
pub fn read_f64(&mut self) -> Result<f64> {
|
|
let data = self.read_n()?;
|
|
match self.endian {
|
|
Endian::Little => Ok(f64::from_le_bytes(data)),
|
|
Endian::Big => Ok(f64::from_be_bytes(data)),
|
|
}
|
|
}
|
|
}
|