//! All IO functionality needed for TIFF decoding use std::io::{self, BufRead, BufReader, Read, Seek, Take}; /// Byte order of the TIFF file. #[derive(Clone, Copy, Debug)] pub enum ByteOrder { /// little endian byte order LittleEndian, /// big endian byte order BigEndian, } /// Reader that is aware of the byte order. pub trait EndianReader: Read { /// Byte order that should be adhered to fn byte_order(&self) -> ByteOrder; /// Reads an u16 #[inline(always)] fn read_u16(&mut self) -> Result { let mut n = [0u8; 2]; self.read_exact(&mut n)?; Ok(match self.byte_order() { ByteOrder::LittleEndian => u16::from_le_bytes(n), ByteOrder::BigEndian => u16::from_be_bytes(n), }) } /// Reads an i8 #[inline(always)] fn read_i8(&mut self) -> Result { let mut n = [0u8; 1]; self.read_exact(&mut n)?; Ok(match self.byte_order() { ByteOrder::LittleEndian => i8::from_le_bytes(n), ByteOrder::BigEndian => i8::from_be_bytes(n), }) } /// Reads an i16 #[inline(always)] fn read_i16(&mut self) -> Result { let mut n = [0u8; 2]; self.read_exact(&mut n)?; Ok(match self.byte_order() { ByteOrder::LittleEndian => i16::from_le_bytes(n), ByteOrder::BigEndian => i16::from_be_bytes(n), }) } /// Reads an u32 #[inline(always)] fn read_u32(&mut self) -> Result { let mut n = [0u8; 4]; self.read_exact(&mut n)?; Ok(match self.byte_order() { ByteOrder::LittleEndian => u32::from_le_bytes(n), ByteOrder::BigEndian => u32::from_be_bytes(n), }) } /// Reads an i32 #[inline(always)] fn read_i32(&mut self) -> Result { let mut n = [0u8; 4]; self.read_exact(&mut n)?; Ok(match self.byte_order() { ByteOrder::LittleEndian => i32::from_le_bytes(n), ByteOrder::BigEndian => i32::from_be_bytes(n), }) } /// Reads an u64 #[inline(always)] fn read_u64(&mut self) -> Result { let mut n = [0u8; 8]; self.read_exact(&mut n)?; Ok(match self.byte_order() { ByteOrder::LittleEndian => u64::from_le_bytes(n), ByteOrder::BigEndian => u64::from_be_bytes(n), }) } /// Reads an i64 #[inline(always)] fn read_i64(&mut self) -> Result { let mut n = [0u8; 8]; self.read_exact(&mut n)?; Ok(match self.byte_order() { ByteOrder::LittleEndian => i64::from_le_bytes(n), ByteOrder::BigEndian => i64::from_be_bytes(n), }) } /// Reads an f32 #[inline(always)] fn read_f32(&mut self) -> Result { let mut n = [0u8; 4]; self.read_exact(&mut n)?; Ok(f32::from_bits(match self.byte_order() { ByteOrder::LittleEndian => u32::from_le_bytes(n), ByteOrder::BigEndian => u32::from_be_bytes(n), })) } /// Reads an f64 #[inline(always)] fn read_f64(&mut self) -> Result { let mut n = [0u8; 8]; self.read_exact(&mut n)?; Ok(f64::from_bits(match self.byte_order() { ByteOrder::LittleEndian => u64::from_le_bytes(n), ByteOrder::BigEndian => u64::from_be_bytes(n), })) } } /// /// # READERS /// /// /// ## Deflate Reader /// pub type DeflateReader = flate2::read::ZlibDecoder; /// /// ## LZW Reader /// /// Reader that decompresses LZW streams pub struct LZWReader { reader: BufReader>, decoder: weezl::decode::Decoder, } impl LZWReader { /// Wraps a reader pub fn new(reader: R, compressed_length: usize) -> LZWReader { Self { reader: BufReader::with_capacity( (32 * 1024).min(compressed_length), reader.take(u64::try_from(compressed_length).unwrap()), ), decoder: weezl::decode::Decoder::with_tiff_size_switch(weezl::BitOrder::Msb, 8), } } } impl Read for LZWReader { fn read(&mut self, buf: &mut [u8]) -> io::Result { loop { let result = self.decoder.decode_bytes(self.reader.fill_buf()?, buf); self.reader.consume(result.consumed_in); match result.status { Ok(weezl::LzwStatus::Ok) => { if result.consumed_out == 0 { continue; } else { return Ok(result.consumed_out); } } Ok(weezl::LzwStatus::NoProgress) => { assert_eq!(result.consumed_in, 0); assert_eq!(result.consumed_out, 0); assert!(self.reader.buffer().is_empty()); return Err(io::Error::new( io::ErrorKind::UnexpectedEof, "no lzw end code found", )); } Ok(weezl::LzwStatus::Done) => { return Ok(result.consumed_out); } Err(err) => return Err(io::Error::new(io::ErrorKind::InvalidData, err)), } } } } /// /// ## PackBits Reader /// enum PackBitsReaderState { Header, Literal, Repeat { value: u8 }, } /// Reader that unpacks Apple's `PackBits` format pub struct PackBitsReader { reader: Take, state: PackBitsReaderState, count: usize, } impl PackBitsReader { /// Wraps a reader pub fn new(reader: R, length: u64) -> Self { Self { reader: reader.take(length), state: PackBitsReaderState::Header, count: 0, } } } impl Read for PackBitsReader { fn read(&mut self, buf: &mut [u8]) -> io::Result { while let PackBitsReaderState::Header = self.state { if self.reader.limit() == 0 { return Ok(0); } let mut header: [u8; 1] = [0]; self.reader.read_exact(&mut header)?; let h = header[0] as i8; if (-127..=-1).contains(&h) { let mut data: [u8; 1] = [0]; self.reader.read_exact(&mut data)?; self.state = PackBitsReaderState::Repeat { value: data[0] }; self.count = (1 - h as isize) as usize; } else if h >= 0 { self.state = PackBitsReaderState::Literal; self.count = h as usize + 1; } else { // h = -128 is a no-op. } } let length = buf.len().min(self.count); let actual = match self.state { PackBitsReaderState::Literal => self.reader.read(&mut buf[..length])?, PackBitsReaderState::Repeat { value } => { for b in &mut buf[..length] { *b = value; } length } PackBitsReaderState::Header => unreachable!(), }; self.count -= actual; if self.count == 0 { self.state = PackBitsReaderState::Header; } Ok(actual) } } /// /// ## SmartReader Reader /// /// Reader that is aware of the byte order. #[derive(Debug)] pub struct SmartReader where R: Read, { reader: R, pub byte_order: ByteOrder, } impl SmartReader where R: Read, { /// Wraps a reader pub fn wrap(reader: R, byte_order: ByteOrder) -> SmartReader { SmartReader { reader, byte_order } } pub fn into_inner(self) -> R { self.reader } } impl SmartReader { pub fn goto_offset(&mut self, offset: u64) -> io::Result<()> { self.seek(io::SeekFrom::Start(offset)).map(|_| ()) } } impl EndianReader for SmartReader where R: Read, { #[inline(always)] fn byte_order(&self) -> ByteOrder { self.byte_order } } impl Read for SmartReader { #[inline] fn read(&mut self, buf: &mut [u8]) -> io::Result { self.reader.read(buf) } } impl Seek for SmartReader { #[inline] fn seek(&mut self, pos: io::SeekFrom) -> io::Result { self.reader.seek(pos) } } #[cfg(test)] mod test { use super::*; #[test] fn test_packbits() { let encoded = vec![ 0xFE, 0xAA, 0x02, 0x80, 0x00, 0x2A, 0xFD, 0xAA, 0x03, 0x80, 0x00, 0x2A, 0x22, 0xF7, 0xAA, ]; let encoded_len = encoded.len(); let buff = io::Cursor::new(encoded); let mut decoder = PackBitsReader::new(buff, encoded_len as u64); let mut decoded = Vec::new(); decoder.read_to_end(&mut decoded).unwrap(); let expected = vec![ 0xAA, 0xAA, 0xAA, 0x80, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0x80, 0x00, 0x2A, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, ]; assert_eq!(decoded, expected); } }