diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 706513d..3667211 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use std::convert::TryFrom; use std::io::{self, Read, Seek}; -use crate::{ColorType, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError}; +use crate::{bytecast, ColorType, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError}; use self::ifd::Directory; use crate::tags::{ @@ -211,6 +211,24 @@ impl<'a> DecodingBuffer<'a> { DecodingBuffer::I64(ref mut buf) => DecodingBuffer::I64(buf), } } + + fn prefix<'b>(&'b mut self, new_length: usize) -> DecodingBuffer<'b> + where + 'a: 'b, + { + match *self { + DecodingBuffer::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[..new_length]), + DecodingBuffer::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[..new_length]), + DecodingBuffer::U32(ref mut buf) => DecodingBuffer::U32(&mut buf[..new_length]), + DecodingBuffer::U64(ref mut buf) => DecodingBuffer::U64(&mut buf[..new_length]), + DecodingBuffer::F32(ref mut buf) => DecodingBuffer::F32(&mut buf[..new_length]), + DecodingBuffer::F64(ref mut buf) => DecodingBuffer::F64(&mut buf[..new_length]), + DecodingBuffer::I8(ref mut buf) => DecodingBuffer::I8(&mut buf[..new_length]), + DecodingBuffer::I16(ref mut buf) => DecodingBuffer::I16(&mut buf[..new_length]), + DecodingBuffer::I32(ref mut buf) => DecodingBuffer::I32(&mut buf[..new_length]), + DecodingBuffer::I64(ref mut buf) => DecodingBuffer::I64(&mut buf[..new_length]), + } + } } #[derive(Debug)] @@ -892,8 +910,7 @@ impl Decoder { mut buffer: DecodingBuffer<'a>, offset: u64, length: u64, - strip_sample_count: usize, - ) -> TiffResult { + ) -> TiffResult<()> { // Validate that the provided buffer is of the expected type. let color_type = self.colortype()?; match (color_type, &buffer) { @@ -912,31 +929,22 @@ impl Decoder { // Construct necessary reader to perform decompression. self.goto_offset_u64(offset)?; - let (bytes, mut reader): (usize, Box) = match self.compression_method { - CompressionMethod::None => { - let order = self.reader.byte_order; - ( - usize::try_from(length)?, - Box::new(SmartReader::wrap(&mut self.reader, order)), - ) - } - CompressionMethod::LZW => { - let (bytes, reader) = LZWReader::new( + let byte_order = self.reader.byte_order; + let mut reader: Box = match self.compression_method { + CompressionMethod::None => Box::new(&mut self.reader), + CompressionMethod::LZW => Box::new( + LZWReader::new( &mut self.reader, usize::try_from(length)?, - strip_sample_count * buffer.byte_len(), - )?; - (bytes, Box::new(reader)) - } + buffer.len() * buffer.byte_len(), + )? + .1, + ), CompressionMethod::PackBits => { - let order = self.reader.byte_order; - let (bytes, reader) = - PackBitsReader::new(&mut self.reader, order, usize::try_from(length)?)?; - (bytes, Box::new(reader)) + Box::new(PackBitsReader::new(&mut self.reader, usize::try_from(length)?)?.1) } CompressionMethod::OldDeflate => { - let (bytes, reader) = DeflateReader::new(&mut self.reader, strip_sample_count)?; - (bytes, Box::new(reader)) + Box::new(DeflateReader::new(&mut self.reader, buffer.len() * buffer.byte_len())?.1) } method => { return Err(TiffError::UnsupportedError( @@ -945,83 +953,100 @@ impl Decoder { } }; - // FIXME: this might be suboptimal. We might default remaining bits to ยด0`, which some - // other decoders might do. - if bytes / buffer.byte_len() > strip_sample_count { - return Err(TiffError::FormatError( - TiffFormatError::UnexpectedCompressedData { - actual_bytes: bytes, - required_bytes: strip_sample_count * buffer.byte_len(), - }, - )); + // Read into output buffer. + { + let buffer = match &mut buffer { + DecodingBuffer::U8(buf) => &mut *buf, + DecodingBuffer::I8(buf) => bytecast::i8_as_ne_mut_bytes(buf), + DecodingBuffer::U16(buf) => bytecast::u16_as_ne_mut_bytes(buf), + DecodingBuffer::I16(buf) => bytecast::i16_as_ne_mut_bytes(buf), + DecodingBuffer::U32(buf) => bytecast::u32_as_ne_mut_bytes(buf), + DecodingBuffer::I32(buf) => bytecast::i32_as_ne_mut_bytes(buf), + DecodingBuffer::U64(buf) => bytecast::u64_as_ne_mut_bytes(buf), + DecodingBuffer::I64(buf) => bytecast::i64_as_ne_mut_bytes(buf), + DecodingBuffer::F32(buf) => bytecast::f32_as_ne_mut_bytes(buf), + DecodingBuffer::F64(buf) => bytecast::f64_as_ne_mut_bytes(buf), + }; + + let mut bytes_written = 0; + while bytes_written < buffer.len() { + match reader.read(&mut buffer[bytes_written..]) { + Ok(0) => break, + Ok(n) => bytes_written += n, + Err(e) if e.kind() == io::ErrorKind::Interrupted => {} + Err(e) => Err(e)?, + } + } + for b in &mut buffer[bytes_written..] { + *b = 0; + } } - // Read into the output buffer. - let samples = bytes / buffer.byte_len(); - match buffer { - DecodingBuffer::U8(ref mut buffer) => { - reader.read_exact(&mut buffer[..samples])? - } - DecodingBuffer::U16(ref mut buffer) => { - reader.read_u16_into(&mut buffer[..samples])? - } - DecodingBuffer::U32(ref mut buffer) => { - reader.read_u32_into(&mut buffer[..samples])? - } - DecodingBuffer::U64(ref mut buffer) => { - reader.read_u64_into(&mut buffer[..samples])? - } - DecodingBuffer::I8(ref mut buffer) => { - reader.read_i8_into(&mut buffer[..samples])? - } - DecodingBuffer::I16(ref mut buffer) => { - reader.read_i16_into(&mut buffer[..samples])? - } - DecodingBuffer::I32(ref mut buffer) => { - reader.read_i32_into(&mut buffer[..samples])? - } - DecodingBuffer::I64(ref mut buffer) => { - reader.read_i64_into(&mut buffer[..samples])? - } - DecodingBuffer::F32(ref mut buffer) => { - reader.read_f32_into(&mut buffer[..samples])? - } - DecodingBuffer::F64(ref mut buffer) => { - reader.read_f64_into(&mut buffer[..samples])? - } + // Fix endianness. If `byte_order` matches the host, then conversion is a no-op. + match byte_order { + ByteOrder::LittleEndian => match &mut buffer { + DecodingBuffer::U8(_) | DecodingBuffer::I8(_) => {} + DecodingBuffer::U16(buf) => buf.iter_mut().for_each(|v| *v = u16::from_le(*v)), + DecodingBuffer::I16(buf) => buf.iter_mut().for_each(|v| *v = i16::from_le(*v)), + DecodingBuffer::U32(buf) => buf.iter_mut().for_each(|v| *v = u32::from_le(*v)), + DecodingBuffer::I32(buf) => buf.iter_mut().for_each(|v| *v = i32::from_le(*v)), + DecodingBuffer::U64(buf) => buf.iter_mut().for_each(|v| *v = u64::from_le(*v)), + DecodingBuffer::I64(buf) => buf.iter_mut().for_each(|v| *v = i64::from_le(*v)), + DecodingBuffer::F32(buf) => buf + .iter_mut() + .for_each(|v| *v = f32::from_bits(u32::from_le(v.to_bits()))), + DecodingBuffer::F64(buf) => buf + .iter_mut() + .for_each(|v| *v = f64::from_bits(u64::from_le(v.to_bits()))), + }, + ByteOrder::BigEndian => match &mut buffer { + DecodingBuffer::U8(_) | DecodingBuffer::I8(_) => {} + DecodingBuffer::U16(buf) => buf.iter_mut().for_each(|v| *v = u16::from_be(*v)), + DecodingBuffer::I16(buf) => buf.iter_mut().for_each(|v| *v = i16::from_be(*v)), + DecodingBuffer::U32(buf) => buf.iter_mut().for_each(|v| *v = u32::from_be(*v)), + DecodingBuffer::I32(buf) => buf.iter_mut().for_each(|v| *v = i32::from_be(*v)), + DecodingBuffer::U64(buf) => buf.iter_mut().for_each(|v| *v = u64::from_be(*v)), + DecodingBuffer::I64(buf) => buf.iter_mut().for_each(|v| *v = i64::from_be(*v)), + DecodingBuffer::F32(buf) => buf + .iter_mut() + .for_each(|v| *v = f32::from_bits(u32::from_be(v.to_bits()))), + DecodingBuffer::F64(buf) => buf + .iter_mut() + .for_each(|v| *v = f64::from_bits(u64::from_be(v.to_bits()))), + }, } // Invert colors if necessary. if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { - match (color_type, buffer) { + match (color_type, &mut buffer) { (ColorType::Gray(64), DecodingBuffer::U64(ref mut buffer)) => { - for datum in buffer[..samples].iter_mut() { + for datum in buffer.iter_mut() { *datum = 0xffff_ffff_ffff_ffff - *datum } } (ColorType::Gray(32), DecodingBuffer::U32(ref mut buffer)) => { - for datum in buffer[..samples].iter_mut() { + for datum in buffer.iter_mut() { *datum = 0xffff_ffff - *datum } } (ColorType::Gray(16), DecodingBuffer::U16(ref mut buffer)) => { - for datum in buffer[..samples].iter_mut() { + for datum in buffer.iter_mut() { *datum = 0xffff - *datum } } (ColorType::Gray(n), DecodingBuffer::U8(ref mut buffer)) if n <= 8 => { - for byte in buffer[..samples].iter_mut() { + for byte in buffer.iter_mut() { *byte = 0xff - *byte } } (ColorType::Gray(32), DecodingBuffer::F32(ref mut buffer)) => { - for datum in buffer[..samples].iter_mut() { + for datum in buffer.iter_mut() { // FIXME: assumes [0, 1) range for floats *datum = 1.0 - *datum } } (ColorType::Gray(64), DecodingBuffer::F64(ref mut buffer)) => { - for datum in buffer[..samples].iter_mut() { + for datum in buffer.iter_mut() { // FIXME: assumes [0, 1) range for floats *datum = 1.0 - *datum } @@ -1030,7 +1055,7 @@ impl Decoder { } } - Ok(samples) + Ok(()) } /// Number of strips in image @@ -1149,20 +1174,12 @@ impl Decoder { )); } - let units_read = self.expand_strip(buffer.copy(), offset, byte_count, buffer_size)?; + self.expand_strip(buffer.prefix(buffer_size), offset, byte_count)?; self.strip_decoder.as_mut().unwrap().strip_index += 1; if u32::try_from(index)? == self.strip_count()? { self.strip_decoder = None; } - if units_read < buffer_size { - return Err(TiffError::FormatError( - TiffFormatError::InconsistentStripSamples { - actual_samples: units_read, - required_samples: buffer_size, - }, - )); - } if let Ok(predictor) = self.get_tag_unsigned(Tag::Predictor) { match Predictor::from_u16(predictor) { Some(Predictor::None) => (), diff --git a/src/decoder/stream.rs b/src/decoder/stream.rs index ce8d4fc..8702ca3 100644 --- a/src/decoder/stream.rs +++ b/src/decoder/stream.rs @@ -1,6 +1,5 @@ //! 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}; @@ -30,24 +29,6 @@ pub trait EndianReader: Read { }) } - #[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 i8 #[inline(always)] fn read_i8(&mut self) -> Result { @@ -59,24 +40,6 @@ pub trait EndianReader: Read { }) } - #[inline(always)] - fn read_i8_into(&mut self, buffer: &mut [i8]) -> Result<(), io::Error> { - self.read_exact(bytecast::i8_as_ne_mut_bytes(buffer))?; - match self.byte_order() { - ByteOrder::LittleEndian => { - for n in buffer { - *n = i8::from_le(*n); - } - } - ByteOrder::BigEndian => { - for n in buffer { - *n = i8::from_be(*n); - } - } - } - Ok(()) - } - /// Reads an i16 #[inline(always)] fn read_i16(&mut self) -> Result { @@ -88,24 +51,6 @@ pub trait EndianReader: Read { }) } - #[inline(always)] - fn read_i16_into(&mut self, buffer: &mut [i16]) -> Result<(), io::Error> { - self.read_exact(bytecast::i16_as_ne_mut_bytes(buffer))?; - match self.byte_order() { - ByteOrder::LittleEndian => { - for n in buffer { - *n = i16::from_le(*n); - } - } - ByteOrder::BigEndian => { - for n in buffer { - *n = i16::from_be(*n); - } - } - } - Ok(()) - } - /// Reads an u32 #[inline(always)] fn read_u32(&mut self) -> Result { @@ -117,42 +62,6 @@ pub trait EndianReader: Read { }) } - #[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(()) - } - - #[inline(always)] - fn read_i32_into(&mut self, buffer: &mut [i32]) -> Result<(), io::Error> { - self.read_exact(bytecast::i32_as_ne_mut_bytes(buffer))?; - match self.byte_order() { - ByteOrder::LittleEndian => { - for n in buffer { - *n = i32::from_le(*n); - } - } - ByteOrder::BigEndian => { - for n in buffer { - *n = i32::from_be(*n); - } - } - } - Ok(()) - } - /// Reads an i32 #[inline(always)] fn read_i32(&mut self) -> Result { @@ -175,42 +84,6 @@ pub trait EndianReader: Read { }) } - #[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(()) - } - - #[inline(always)] - fn read_i64_into(&mut self, buffer: &mut [i64]) -> Result<(), io::Error> { - self.read_exact(bytecast::i64_as_ne_mut_bytes(buffer))?; - match self.byte_order() { - ByteOrder::LittleEndian => { - for n in buffer { - *n = i64::from_le(*n); - } - } - ByteOrder::BigEndian => { - for n in buffer { - *n = i64::from_be(*n); - } - } - } - Ok(()) - } - /// Reads an i64 #[inline(always)] fn read_i64(&mut self) -> Result { @@ -233,24 +106,6 @@ pub trait EndianReader: Read { })) } - #[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 { @@ -261,24 +116,6 @@ pub trait EndianReader: Read { 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(()) - } } /// @@ -292,7 +129,6 @@ pub trait EndianReader: Read { /// Reader that decompresses DEFLATE streams pub struct DeflateReader { buffer: io::Cursor>, - byte_order: ByteOrder, } impl DeflateReader { @@ -300,7 +136,6 @@ impl DeflateReader { 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)?; @@ -316,7 +151,6 @@ impl DeflateReader { Ok(( uncompressed.len(), Self { - byte_order, buffer: io::Cursor::new(uncompressed), }, )) @@ -329,12 +163,6 @@ impl Read for DeflateReader { } } -impl EndianReader for DeflateReader { - fn byte_order(&self) -> ByteOrder { - self.byte_order - } -} - /// /// ## LZW Reader /// @@ -342,7 +170,6 @@ impl EndianReader for DeflateReader { /// Reader that decompresses LZW streams pub struct LZWReader { buffer: io::Cursor>, - byte_order: ByteOrder, } impl LZWReader { @@ -355,7 +182,6 @@ impl 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); @@ -393,7 +219,6 @@ impl LZWReader { bytes, LZWReader { buffer: io::Cursor::new(uncompressed), - byte_order: order, }, )) } @@ -406,20 +231,12 @@ impl Read for LZWReader { } } -impl EndianReader for LZWReader { - #[inline(always)] - fn byte_order(&self) -> ByteOrder { - self.byte_order - } -} - /// /// ## JPEG Reader (for "new-style" JPEG format (TIFF compression tag 7)) /// pub(crate) struct JpegReader { buffer: io::Cursor>, - byte_order: ByteOrder, } impl JpegReader { /// Constructs new JpegReader wrapping a SmartReader. @@ -442,8 +259,6 @@ impl JpegReader { where R: Read + Seek, { - let order = reader.byte_order; - // Read jpeg image data let mut segment = vec![0; length as usize]; reader.read_exact(&mut segment[..])?; @@ -457,12 +272,10 @@ impl JpegReader { Ok(JpegReader { buffer: io::Cursor::new(jpeg_data), - byte_order: order, }) } None => Ok(JpegReader { buffer: io::Cursor::new(segment), - byte_order: order, }), } } @@ -475,13 +288,6 @@ impl Read for JpegReader { } } -impl EndianReader for JpegReader { - #[inline(always)] - fn byte_order(&self) -> ByteOrder { - self.byte_order - } -} - /// /// ## PackBits Reader /// @@ -489,14 +295,12 @@ impl EndianReader for JpegReader { /// 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(); @@ -512,7 +316,6 @@ impl PackBitsReader { buffer.len(), PackBitsReader { buffer: io::Cursor::new(buffer), - byte_order, }, )) } @@ -551,13 +354,6 @@ impl Read for PackBitsReader { } } -impl EndianReader for PackBitsReader { - #[inline(always)] - fn byte_order(&self) -> ByteOrder { - self.byte_order - } -} - /// /// ## SmartReader Reader /// @@ -619,8 +415,7 @@ mod test { let encoded_len = encoded.len(); let buff = io::Cursor::new(encoded); - let (_, mut decoder) = - PackBitsReader::new(buff, ByteOrder::LittleEndian, encoded_len).unwrap(); + let (_, mut decoder) = PackBitsReader::new(buff, encoded_len).unwrap(); let mut decoded = Vec::new(); decoder.read_to_end(&mut decoded).unwrap();