From 583b241cef15e59507a6187bb58a6c38e682402f Mon Sep 17 00:00:00 2001 From: zroug <37004975+zroug@users.noreply.github.com> Date: Mon, 27 Aug 2018 23:05:16 +0200 Subject: [PATCH 1/3] Replaced unsafe code in Decoder::read_image --- src/decoder/mod.rs | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 045944a..2495de4 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -467,8 +467,8 @@ impl Decoder { * self.height as usize * self.bits_per_sample.iter().count(); let mut result = match self.bits_per_sample.iter().cloned().max().unwrap_or(8) { - n if n <= 8 => DecodingResult::U8(Vec::with_capacity(buffer_size)), - n if n <= 16 => DecodingResult::U16(Vec::with_capacity(buffer_size)), + n if n <= 8 => DecodingResult::U8(vec![0; buffer_size]), + n if n <= 16 => DecodingResult::U16(vec![0; buffer_size]), n => return Err( TiffError::UnsupportedError( format!("{} bits per channel not supported", n) @@ -483,13 +483,6 @@ impl Decoder { )) } } - // Safe since the uninitialized values are never read. - match result { - DecodingResult::U8(ref mut buffer) => - unsafe { buffer.set_len(buffer_size) }, - DecodingResult::U16(ref mut buffer) => - unsafe { buffer.set_len(buffer_size) }, - } let mut units_read = 0; for (i, (&offset, &byte_count)) in try!(self.get_tag_u32_vec(ifd::Tag::StripOffsets)) .iter().zip(try!(self.get_tag_u32_vec(ifd::Tag::StripByteCounts)).iter()).enumerate() { @@ -514,14 +507,8 @@ impl Decoder { break } } - // Shrink length such that the uninitialized memory is not exposed. if units_read < buffer_size { - match result { - DecodingResult::U8(ref mut buffer) => - unsafe { buffer.set_len(units_read) }, - DecodingResult::U16(ref mut buffer) => - unsafe { buffer.set_len(units_read) }, - } + return Err(TiffError::FormatError("Inconsistent sizes encountered.".to_string())); } if let Ok(predictor) = self.get_tag_u32(ifd::Tag::Predictor) { result = match FromPrimitive::from_u32(predictor) { From 724e5e8c801ce82f4189414f9371f9f70267c99c Mon Sep 17 00:00:00 2001 From: zroug <37004975+zroug@users.noreply.github.com> Date: Mon, 27 Aug 2018 23:05:16 +0200 Subject: [PATCH 2/3] Fixed: Decoder::expand_strip might not read the full strip --- src/decoder/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 2495de4..2c7bdcd 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -422,7 +422,8 @@ impl Decoder { (ColorType:: RGB(8), DecodingBuffer::U8(ref mut buffer)) | (ColorType::RGBA(8), DecodingBuffer::U8(ref mut buffer)) | (ColorType::CMYK(8), DecodingBuffer::U8(ref mut buffer)) => { - try!(reader.read(&mut buffer[..bytes])) + try!(reader.read_exact(&mut buffer[..bytes])); + bytes } (ColorType::RGBA(16), DecodingBuffer::U16(ref mut buffer)) | (ColorType:: RGB(16), DecodingBuffer::U16(ref mut buffer)) => { From 345aff0629117ca4dae318157d530b3fd878e793 Mon Sep 17 00:00:00 2001 From: zroug <37004975+zroug@users.noreply.github.com> Date: Mon, 27 Aug 2018 23:05:16 +0200 Subject: [PATCH 3/3] Greatly improved performance for 16 bit images --- src/decoder/mod.rs | 10 ++++------ src/decoder/stream.rs | 8 ++++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 2c7bdcd..48580b4 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -427,15 +427,13 @@ impl Decoder { } (ColorType::RGBA(16), DecodingBuffer::U16(ref mut buffer)) | (ColorType:: RGB(16), DecodingBuffer::U16(ref mut buffer)) => { - for datum in buffer[..bytes/2].iter_mut() { - *datum = try!(reader.read_u16()) - } + try!(reader.read_u16_into(&mut buffer[..bytes/2])); bytes/2 } (ColorType::Gray(16), DecodingBuffer::U16(ref mut buffer)) => { - for datum in buffer[..bytes/2].iter_mut() { - *datum = try!(reader.read_u16()); - if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { + try!(reader.read_u16_into(&mut buffer[..bytes/2])); + if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { + for datum in buffer[..bytes/2].iter_mut() { *datum = 0xffff - *datum } } diff --git a/src/decoder/stream.rs b/src/decoder/stream.rs index 090a833..c80b84e 100644 --- a/src/decoder/stream.rs +++ b/src/decoder/stream.rs @@ -28,6 +28,14 @@ pub trait EndianReader: Read { } } + #[inline(always)] + fn read_u16_into(&mut self, buffer: &mut [u16]) -> Result<(), io::Error> { + match self.byte_order() { + ByteOrder::LittleEndian => ::read_u16_into::(self, buffer), + ByteOrder::BigEndian => ::read_u16_into::(self, buffer) + } + } + /// Reads an u32 #[inline(always)] fn read_u32(&mut self) -> Result {