//! All IO functionality needed for TIFF decoding use std::convert::TryFrom; use std::io::{self, BufRead, BufReader, Read, Seek, SeekFrom, Take}; use std::sync::Arc; /// 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)), } } } } /// /// ## JPEG Reader (for "new-style" JPEG format (TIFF compression tag 7)) /// pub(crate) struct JpegReader { jpeg_tables: Option>>, buffer: io::Cursor>, offset: usize, } impl JpegReader { /// Constructs new JpegReader wrapping a SmartReader. /// Because JPEG compression in TIFF allows to save quantization and/or huffman tables in one /// central location, the constructor accepts this data as `jpeg_tables` here containing either /// or both. /// These `jpeg_tables` are simply prepended to the remaining jpeg image data. /// Because these `jpeg_tables` start with a `SOI` (HEX: `0xFFD8`) or __start of image__ marker /// which is also at the beginning of the remaining JPEG image data and would /// confuse the JPEG renderer, one of these has to be taken off. In this case the first two /// bytes of the remaining JPEG data is removed because it follows `jpeg_tables`. /// Similary, `jpeg_tables` ends with a `EOI` (HEX: `0xFFD9`) or __end of image__ marker, /// this has to be removed as well (last two bytes of `jpeg_tables`). pub fn new( mut reader: R, length: u64, jpeg_tables: Option>>, ) -> io::Result { // Read jpeg image data let mut segment = vec![0; length as usize]; reader.read_exact(&mut segment[..])?; match jpeg_tables { Some(jpeg_tables) => { assert!( jpeg_tables.len() >= 2, "jpeg_tables, if given, must be at least 2 bytes long. Got {:?}", jpeg_tables ); assert!( length >= 2, "if jpeg_tables is given, length must be at least 2 bytes long, got {}", length ); let mut buffer = io::Cursor::new(segment); // Skip the first two bytes (marker bytes) buffer.seek(SeekFrom::Start(2))?; Ok(JpegReader { buffer, jpeg_tables: Some(jpeg_tables), offset: 0, }) } None => Ok(JpegReader { buffer: io::Cursor::new(segment), jpeg_tables: None, offset: 0, }), } } } impl Read for JpegReader { // #[inline] fn read(&mut self, buf: &mut [u8]) -> io::Result { let mut start = 0; if let Some(jpeg_tables) = &self.jpeg_tables { if jpeg_tables.len() - 2 > self.offset { // Read (rest of) jpeg_tables to buf (without the last two bytes) let size_remaining = jpeg_tables.len() - self.offset - 2; let to_copy = size_remaining.min(buf.len()); buf[start..start + to_copy] .copy_from_slice(&jpeg_tables[self.offset..self.offset + to_copy]); self.offset += to_copy; if to_copy == buf.len() { return Ok(to_copy); } start += to_copy; } } let read = self.buffer.read(&mut buf[start..])?; self.offset += read; Ok(read + start) } } /// /// ## 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 h >= -127 && h <= -1 { 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; } return 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); } }