| 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)), |
| } |
| } |
| } |
|
|