From 60c6e0cd9099c67374b7c5fb3933325cad069ee4 Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Sat, 10 Apr 2021 14:49:04 -0400 Subject: [PATCH 1/4] Simplify de-compression logic --- src/decoder/stream.rs | 82 ++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 47 deletions(-) diff --git a/src/decoder/stream.rs b/src/decoder/stream.rs index ce8d4fc..332d5a4 100644 --- a/src/decoder/stream.rs +++ b/src/decoder/stream.rs @@ -358,22 +358,19 @@ impl LZWReader { 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 uncompressed = vec![0; max_uncompressed_length]; let mut decoder = weezl::decode::Decoder::with_tiff_size_switch(weezl::BitOrder::Msb, 8); + let mut bytes_read = 0; + let mut bytes_written = 0; - while uncompressed.len() < max_uncompressed_length { - let bytes_written = uncompressed.len(); - uncompressed.reserve(1 << 12); - let buffer_space = uncompressed.capacity().min(max_uncompressed_length); - uncompressed.resize(buffer_space, 0u8); - + while bytes_written < max_uncompressed_length { let result = decoder.decode_bytes( &compressed[bytes_read..], &mut uncompressed[bytes_written..], ); bytes_read += result.consumed_in; - uncompressed.truncate(bytes_written + result.consumed_out); + bytes_written += result.consumed_out; match result.status { Ok(weezl::LzwStatus::Ok) => {} @@ -388,9 +385,9 @@ impl LZWReader { } } - let bytes = uncompressed.len(); + uncompressed.resize(bytes_written, 0); Ok(( - bytes, + uncompressed.len(), LZWReader { buffer: io::Cursor::new(uncompressed), byte_order: order, @@ -453,7 +450,7 @@ impl JpegReader { let mut jpeg_data = tables.clone(); let truncated_length = jpeg_data.len() - 2; jpeg_data.truncate(truncated_length); - jpeg_data.extend_from_slice(&mut segment[2..]); + jpeg_data.extend_from_slice(&segment[2..]); Ok(JpegReader { buffer: io::Cursor::new(jpeg_data), @@ -500,14 +497,31 @@ impl PackBitsReader { 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()); + let mut header: [u8; 1] = [0]; + let mut data: [u8; 1] = [0]; + + let mut bytes_read = 0; + while bytes_read < length { + reader.read_exact(&mut header)?; + bytes_read += 1; + + let h = header[0] as i8; + if h >= -127 && h <= -1 { + let new_len = buffer.len() + (1 - h as isize) as usize; + reader.read_exact(&mut data)?; + buffer.resize(new_len, data[0]); + bytes_read += 1; + } else if h >= 0 { + let num_vals = h as usize + 1; + let start = buffer.len(); + buffer.resize(start + num_vals, 0); + reader.read_exact(&mut buffer[start..])?; + bytes_read += num_vals + } else { + // h = -128 is a no-op. } - read += lread; } + Ok(( buffer.len(), PackBitsReader { @@ -518,32 +532,6 @@ impl PackBitsReader { } } -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 { @@ -566,7 +554,7 @@ impl EndianReader for PackBitsReader { #[derive(Debug)] pub struct SmartReader where - R: Read + Seek, + R: Read, { reader: R, pub byte_order: ByteOrder, @@ -574,7 +562,7 @@ where impl SmartReader where - R: Read + Seek, + R: Read, { /// Wraps a reader pub fn wrap(reader: R, byte_order: ByteOrder) -> SmartReader { @@ -584,7 +572,7 @@ where impl EndianReader for SmartReader where - R: Read + Seek, + R: Read, { #[inline(always)] fn byte_order(&self) -> ByteOrder { @@ -592,7 +580,7 @@ where } } -impl Read for SmartReader { +impl Read for SmartReader { #[inline] fn read(&mut self, buf: &mut [u8]) -> io::Result { self.reader.read(buf) From 7641dcbd3f6402c1fa8bc9e93e5aedaa96aa819c Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Sat, 10 Apr 2021 15:02:16 -0400 Subject: [PATCH 2/4] Refactoring to simplify expand_strip function --- src/decoder/mod.rs | 175 ++++++++++++++++----------------------------- 1 file changed, 63 insertions(+), 112 deletions(-) diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index c345410..706513d 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -889,12 +889,28 @@ impl Decoder { /// Returns the number of bytes read. fn expand_strip<'a>( &mut self, - buffer: DecodingBuffer<'a>, + mut buffer: DecodingBuffer<'a>, offset: u64, length: u64, strip_sample_count: usize, ) -> TiffResult { + // Validate that the provided buffer is of the expected type. let color_type = self.colortype()?; + match (color_type, &buffer) { + (ColorType::RGB(n), _) + | (ColorType::RGBA(n), _) + | (ColorType::CMYK(n), _) + | (ColorType::Gray(n), _) + if usize::from(n) == buffer.byte_len() * 8 => {} + (ColorType::Gray(n), DecodingBuffer::U8(_)) if n <= 8 => {} + (type_, _) => { + return Err(TiffError::UnsupportedError( + TiffUnsupportedError::UnsupportedColorType(type_), + )) + } + } + + // Construct necessary reader to perform decompression. self.goto_offset_u64(offset)?; let (bytes, mut reader): (usize, Box) = match self.compression_method { CompressionMethod::None => { @@ -940,146 +956,81 @@ impl Decoder { )); } - Ok(match (color_type, buffer) { - (ColorType::RGB(8), DecodingBuffer::U8(ref mut buffer)) - | (ColorType::RGBA(8), DecodingBuffer::U8(ref mut buffer)) - | (ColorType::CMYK(8), DecodingBuffer::U8(ref mut buffer)) => { - reader.read_exact(&mut buffer[..bytes])?; - bytes + // Read into the output buffer. + let samples = bytes / buffer.byte_len(); + match buffer { + DecodingBuffer::U8(ref mut buffer) => { + reader.read_exact(&mut buffer[..samples])? } - (ColorType::RGBA(16), DecodingBuffer::U16(ref mut buffer)) - | (ColorType::RGB(16), DecodingBuffer::U16(ref mut buffer)) - | (ColorType::CMYK(16), DecodingBuffer::U16(ref mut buffer)) => { - reader.read_u16_into(&mut buffer[..bytes / 2])?; - bytes / 2 + DecodingBuffer::U16(ref mut buffer) => { + reader.read_u16_into(&mut buffer[..samples])? } - (ColorType::RGBA(32), DecodingBuffer::U32(ref mut buffer)) - | (ColorType::RGB(32), DecodingBuffer::U32(ref mut buffer)) - | (ColorType::CMYK(32), DecodingBuffer::U32(ref mut buffer)) => { - reader.read_u32_into(&mut buffer[..bytes / 4])?; - bytes / 4 + DecodingBuffer::U32(ref mut buffer) => { + reader.read_u32_into(&mut buffer[..samples])? } - (ColorType::RGBA(32), DecodingBuffer::F32(ref mut buffer)) - | (ColorType::RGB(32), DecodingBuffer::F32(ref mut buffer)) - | (ColorType::CMYK(32), DecodingBuffer::F32(ref mut buffer)) => { - reader.read_f32_into(&mut buffer[..bytes / 4])?; - bytes / 4 + DecodingBuffer::U64(ref mut buffer) => { + reader.read_u64_into(&mut buffer[..samples])? } - (ColorType::RGBA(64), DecodingBuffer::F64(ref mut buffer)) - | (ColorType::RGB(64), DecodingBuffer::F64(ref mut buffer)) - | (ColorType::CMYK(64), DecodingBuffer::F64(ref mut buffer)) => { - reader.read_f64_into(&mut buffer[..bytes / 8])?; - bytes / 8 + DecodingBuffer::I8(ref mut buffer) => { + reader.read_i8_into(&mut buffer[..samples])? } - (ColorType::RGBA(64), DecodingBuffer::U64(ref mut buffer)) - | (ColorType::RGB(64), DecodingBuffer::U64(ref mut buffer)) - | (ColorType::CMYK(64), DecodingBuffer::U64(ref mut buffer)) => { - reader.read_u64_into(&mut buffer[..bytes / 8])?; - bytes / 8 + DecodingBuffer::I16(ref mut buffer) => { + reader.read_i16_into(&mut buffer[..samples])? } - (ColorType::RGBA(8), DecodingBuffer::I8(ref mut buffer)) - | (ColorType::RGB(8), DecodingBuffer::I8(ref mut buffer)) - | (ColorType::CMYK(8), DecodingBuffer::I8(ref mut buffer)) => { - reader.read_i8_into(&mut buffer[..bytes])?; - bytes + DecodingBuffer::I32(ref mut buffer) => { + reader.read_i32_into(&mut buffer[..samples])? } - (ColorType::RGBA(16), DecodingBuffer::I16(ref mut buffer)) - | (ColorType::RGB(16), DecodingBuffer::I16(ref mut buffer)) - | (ColorType::CMYK(16), DecodingBuffer::I16(ref mut buffer)) => { - reader.read_i16_into(&mut buffer[..bytes / 2])?; - bytes / 2 + 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])? + } + } - (ColorType::Gray(64), DecodingBuffer::U64(ref mut buffer)) => { - reader.read_u64_into(&mut buffer[..bytes / 8])?; - if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { - for datum in buffer[..bytes / 8].iter_mut() { + // Invert colors if necessary. + if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { + match (color_type, buffer) { + (ColorType::Gray(64), DecodingBuffer::U64(ref mut buffer)) => { + for datum in buffer[..samples].iter_mut() { *datum = 0xffff_ffff_ffff_ffff - *datum } } - bytes / 8 - } - (ColorType::Gray(64), DecodingBuffer::I64(ref mut buffer)) => { - reader.read_i64_into(&mut buffer[..bytes / 8])?; - bytes / 8 - } - (ColorType::Gray(32), DecodingBuffer::U32(ref mut buffer)) => { - reader.read_u32_into(&mut buffer[..bytes / 4])?; - if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { - for datum in buffer[..bytes / 4].iter_mut() { + (ColorType::Gray(32), DecodingBuffer::U32(ref mut buffer)) => { + for datum in buffer[..samples].iter_mut() { *datum = 0xffff_ffff - *datum } } - bytes / 4 - } - (ColorType::Gray(32), DecodingBuffer::I32(ref mut buffer)) => { - reader.read_i32_into(&mut buffer[..bytes / 4])?; - bytes / 4 - } - (ColorType::Gray(16), DecodingBuffer::U16(ref mut buffer)) => { - reader.read_u16_into(&mut buffer[..bytes / 2])?; - if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { - for datum in buffer[..bytes / 2].iter_mut() { + (ColorType::Gray(16), DecodingBuffer::U16(ref mut buffer)) => { + for datum in buffer[..samples].iter_mut() { *datum = 0xffff - *datum } } - bytes / 2 - } - (ColorType::Gray(8), DecodingBuffer::I8(ref mut buffer)) => { - reader.read_i8_into(&mut buffer[..bytes])?; - if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { - for datum in buffer[..bytes].iter_mut() { - *datum = !*datum; + (ColorType::Gray(n), DecodingBuffer::U8(ref mut buffer)) if n <= 8 => { + for byte in buffer[..samples].iter_mut() { + *byte = 0xff - *byte } } - bytes - } - // The following conversions interpret the image as in libtiff. - // In particular, MIN is white and MAX is black and not Zero as the name would imply. - (ColorType::Gray(16), DecodingBuffer::I16(ref mut buffer)) => { - reader.read_i16_into(&mut buffer[..bytes / 2])?; - if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { - for datum in buffer[..bytes / 2].iter_mut() { - *datum = !*datum; - } - } - bytes / 2 - } - (ColorType::Gray(n), DecodingBuffer::U8(ref mut buffer)) if n <= 8 => { - reader.read_exact(&mut buffer[..bytes])?; - if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { - for byte in buffer[..bytes].iter_mut() { - *byte = !*byte; - } - } - bytes - } - (ColorType::Gray(32), DecodingBuffer::F32(ref mut buffer)) => { - reader.read_f32_into(&mut buffer[..bytes / 4])?; - if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { - for datum in buffer[..bytes / 4].iter_mut() { + (ColorType::Gray(32), DecodingBuffer::F32(ref mut buffer)) => { + for datum in buffer[..samples].iter_mut() { // FIXME: assumes [0, 1) range for floats *datum = 1.0 - *datum } } - bytes / 4 - } - (ColorType::Gray(64), DecodingBuffer::F64(ref mut buffer)) => { - reader.read_f64_into(&mut buffer[..bytes / 8])?; - if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { - for datum in buffer[..bytes / 8].iter_mut() { + (ColorType::Gray(64), DecodingBuffer::F64(ref mut buffer)) => { + for datum in buffer[..samples].iter_mut() { // FIXME: assumes [0, 1) range for floats *datum = 1.0 - *datum } } - bytes / 8 + _ => {} } - (type_, _) => { - return Err(TiffError::UnsupportedError( - TiffUnsupportedError::UnsupportedColorType(type_), - )) - } - }) + } + + Ok(samples) } /// Number of strips in image From 201b95f7496e14f19683789d72bf55d57149b912 Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Sat, 10 Apr 2021 21:15:46 -0400 Subject: [PATCH 3/4] Improve `expand_strip` and remove `read_{u16, u32, ...}_into` --- src/decoder/mod.rs | 181 +++++++++++++++++++----------------- src/decoder/stream.rs | 207 +----------------------------------------- 2 files changed, 100 insertions(+), 288 deletions(-) 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(); From 1eb9c4fab774e5c4f4e8b26f75d8c3765a025e6e Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Sat, 10 Apr 2021 21:45:04 -0400 Subject: [PATCH 4/4] fix borrow check issue on rustc 1.34.2 --- src/decoder/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 3667211..0cd082a 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -973,7 +973,7 @@ impl Decoder { match reader.read(&mut buffer[bytes_written..]) { Ok(0) => break, Ok(n) => bytes_written += n, - Err(e) if e.kind() == io::ErrorKind::Interrupted => {} + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} Err(e) => Err(e)?, } }