//! All IO functionality needed for TIFF decoding use crate::bytecast; use crate::error::{TiffError, TiffResult}; use miniz_oxide::inflate; use std::io::{self, Read, Seek}; /// 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), }) } #[inline(always)] fn read_u16_into(&mut self, buffer: &mut [u16]) -> Result<(), io::Error> { self.read_exact(bytecast::u16_as_ne_mut_bytes(buffer))?; match self.byte_order() { ByteOrder::LittleEndian => for n in buffer { *n = u16::from_le(*n); }, ByteOrder::BigEndian => for n in buffer { *n = u16::from_be(*n); }, } Ok(()) } /// 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), }) } #[inline(always)] fn read_u32_into(&mut self, buffer: &mut [u32]) -> Result<(), io::Error> { self.read_exact(bytecast::u32_as_ne_mut_bytes(buffer))?; match self.byte_order() { ByteOrder::LittleEndian => for n in buffer { *n = u32::from_le(*n); }, ByteOrder::BigEndian => for n in buffer { *n = u32::from_be(*n); }, } Ok(()) } /// 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), }) } #[inline(always)] fn read_u64_into(&mut self, buffer: &mut [u64]) -> Result<(), io::Error> { self.read_exact(bytecast::u64_as_ne_mut_bytes(buffer))?; match self.byte_order() { ByteOrder::LittleEndian => for n in buffer { *n = u64::from_le(*n); }, ByteOrder::BigEndian => for n in buffer { *n = u64::from_be(*n); }, } Ok(()) } /// 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), })) } #[inline(always)] fn read_f32_into(&mut self, buffer: &mut [f32]) -> Result<(), io::Error> { self.read_exact(bytecast::f32_as_ne_mut_bytes(buffer))?; match self.byte_order() { ByteOrder::LittleEndian => for n in buffer { *n = f32::from_bits(u32::from_le(n.to_bits())); }, ByteOrder::BigEndian => for n in buffer { *n = f32::from_bits(u32::from_be(n.to_bits())); }, } Ok(()) } /// 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), })) } #[inline(always)] fn read_f64_into(&mut self, buffer: &mut [f64]) -> Result<(), io::Error> { self.read_exact(bytecast::f64_as_ne_mut_bytes(buffer))?; match self.byte_order() { ByteOrder::LittleEndian => for n in buffer { *n = f64::from_bits(u64::from_le(n.to_bits())); }, ByteOrder::BigEndian => for n in buffer { *n = f64::from_bits(u64::from_be(n.to_bits())); }, } Ok(()) } } /// Reader that decompresses DEFLATE streams pub struct DeflateReader { buffer: io::Cursor>, byte_order: ByteOrder, } impl DeflateReader { pub fn new( reader: &mut SmartReader, max_uncompressed_length: usize, ) -> TiffResult<(usize, Self)> { let byte_order = reader.byte_order; let mut compressed = Vec::new(); reader.read_to_end(&mut compressed)?; // TODO: Implement streaming compression, and remove this (temporary) and somewhat // misleading workaround. if compressed.len() > max_uncompressed_length { return Err(TiffError::LimitsExceeded); } let uncompressed = inflate::decompress_to_vec_zlib(&compressed).map_err(TiffError::from_inflate_status)?; Ok(( uncompressed.len(), Self { byte_order, buffer: io::Cursor::new(uncompressed), }, )) } } impl Read for DeflateReader { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.buffer.read(buf) } } impl EndianReader for DeflateReader { fn byte_order(&self) -> ByteOrder { self.byte_order } } /// Reader that decompresses LZW streams pub struct LZWReader { buffer: io::Cursor>, byte_order: ByteOrder, } impl LZWReader { /// Wraps a reader pub fn new( reader: &mut SmartReader, compressed_length: usize, max_uncompressed_length: usize, ) -> io::Result<(usize, LZWReader)> where R: Read + Seek, { let order = reader.byte_order; let mut compressed = vec![0; compressed_length as usize]; reader.read_exact(&mut compressed[..])?; let mut uncompressed = Vec::with_capacity(max_uncompressed_length); let mut decoder = weezl::decode::Decoder::with_tiff_size_switch(weezl::BitOrder::Msb, 8); let mut bytes_read = 0; while bytes_read < compressed_length && uncompressed.len() < max_uncompressed_length { let bytes_written = uncompressed.len(); uncompressed.reserve(1 << 12); let buffer_space = uncompressed.capacity(); uncompressed.resize(buffer_space, 0u8); let result = decoder.decode_bytes(&compressed[bytes_read..], &mut uncompressed[bytes_written..]); bytes_read += result.consumed_in; uncompressed.truncate(bytes_written + result.consumed_out); match result.status { Ok(weezl::LzwStatus::Ok) => {}, Ok(weezl::LzwStatus::Done) => break, Ok(weezl::LzwStatus::NoProgress) => return Err(io::Error::new( io::ErrorKind::UnexpectedEof, "no lzw end code found", )), Err(err) => return Err(io::Error::new(io::ErrorKind::InvalidData, err)), } } let bytes = uncompressed.len(); Ok(( bytes, LZWReader { buffer: io::Cursor::new(uncompressed), byte_order: order, }, )) } } impl Read for LZWReader { #[inline] fn read(&mut self, buf: &mut [u8]) -> io::Result { self.buffer.read(buf) } } impl EndianReader for LZWReader { #[inline(always)] fn byte_order(&self) -> ByteOrder { self.byte_order } } /// Reader that unpacks Apple's `PackBits` format pub struct PackBitsReader { buffer: io::Cursor>, byte_order: ByteOrder, } impl PackBitsReader { /// Wraps a reader pub fn new( mut reader: R, byte_order: ByteOrder, length: usize, ) -> io::Result<(usize, PackBitsReader)> { let mut buffer = Vec::new(); let mut read: usize = 0; while read < length { let lread = read_packbits_run(&mut reader, &mut buffer)?; if lread == 0 { return Err(io::ErrorKind::UnexpectedEof.into()); } read += lread; } Ok(( buffer.len(), PackBitsReader { buffer: io::Cursor::new(buffer), byte_order, }, )) } } fn read_packbits_run(reader: &mut R, buffer: &mut Vec) -> io::Result { let mut header: [u8; 1] = [0]; let bytes = reader.read(&mut header)?; match bytes { 0 => Ok(0), _ => match header[0] as i8 { -128 => Ok(1), h if h >= -127 && h <= -1 => { let new_len = buffer.len() + (1 - h as isize) as usize; reader.read_exact(&mut header)?; buffer.resize(new_len, header[0]); Ok(2) } h => { let num_vals = h as usize + 1; let start = buffer.len(); buffer.resize(start + num_vals, 0); reader.read_exact(&mut buffer[start..])?; Ok(num_vals + 1) } }, } } impl Read for PackBitsReader { #[inline] fn read(&mut self, buf: &mut [u8]) -> io::Result { self.buffer.read(buf) } } impl EndianReader for PackBitsReader { #[inline(always)] fn byte_order(&self) -> ByteOrder { self.byte_order } } /// Reader that is aware of the byte order. #[derive(Debug)] pub struct SmartReader where R: Read + Seek, { reader: R, pub byte_order: ByteOrder, } impl SmartReader where R: Read + Seek, { /// Wraps a reader pub fn wrap(reader: R, byte_order: ByteOrder) -> SmartReader { SmartReader { reader, byte_order } } } impl EndianReader for SmartReader where R: Read + Seek, { #[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, ByteOrder::LittleEndian, encoded_len).unwrap(); 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); } }