use std::io::{Error, ErrorKind, Read, Result, Seek, SeekFrom}; #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum Endian { Little, Big, } pub struct TiffRead { reader: R, endian: Endian, } impl TiffRead { pub fn new(mut reader: R) -> Result { 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 Read for TiffRead { fn read(&mut self, buf: &mut [u8]) -> Result { self.reader.read(buf) } } impl Seek for TiffRead { fn seek(&mut self, pos: SeekFrom) -> Result { self.reader.seek(pos) } } impl TiffRead { pub fn seek_from_start(&mut self, offset: u32) -> Result { self.reader.seek(SeekFrom::Start(offset.into())) } pub fn read_ascii(&mut self) -> Result { let data = self.read_n::<1>()?; Ok(data[0] as char) } pub fn read_n(&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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { let data = self.read_n()?; match self.endian { Endian::Little => Ok(f64::from_le_bytes(data)), Endian::Big => Ok(f64::from_be_bytes(data)), } } }