Merge pull request #108 from image-rs/short-read-in-lzw

Fix lzw decoding stopping short of full decode
This commit is contained in:
HeroicKatora authored and GitHub committed 2020-12-06 02:52:06 +01:00
commit ef004cee48
3 files changed
+50 -9

No files matched your search

+19 -7
View File
@@ -342,6 +342,11 @@ impl<R: Read + Seek> Decoder<R> {
PhotometricInterpretation::RGB => match self.bits_per_sample[..] {
[r, g, b] if [r, r] == [g, b] => Ok(ColorType::RGB(r)),
[r, g, b, a] if [r, r, r] == [g, b, a] => Ok(ColorType::RGBA(r)),
// FIXME: We should _ignore_ other components. In particular:
// > Beware of extra components. Some TIFF files may have more components per pixel
// than you think. A Baseline TIFF reader must skip over them gracefully,using the
// values of the SamplesPerPixel and BitsPerSample fields.
// > -- TIFF 6.0 Specification, Section 7, Additional Baseline requirements.
_ => Err(TiffError::UnsupportedError(
TiffUnsupportedError::InterpretationWithBits(
self.photometric_interpretation,
@@ -764,7 +769,7 @@ impl<R: Read + Seek> Decoder<R> {
buffer: DecodingBuffer<'a>,
offset: u64,
length: u64,
max_uncompressed_length: usize,
strip_sample_count: usize,
) -> TiffResult<usize> {
let color_type = self.colortype()?;
self.goto_offset_u64(offset)?;
@@ -780,7 +785,7 @@ impl<R: Read + Seek> Decoder<R> {
let (bytes, reader) = LZWReader::new(
&mut self.reader,
usize::try_from(length)?,
max_uncompressed_length * buffer.byte_len(),
strip_sample_count * buffer.byte_len(),
)?;
(bytes, Box::new(reader))
}
@@ -791,8 +796,7 @@ impl<R: Read + Seek> Decoder<R> {
(bytes, Box::new(reader))
}
CompressionMethod::OldDeflate => {
let (bytes, reader) =
DeflateReader::new(&mut self.reader, max_uncompressed_length)?;
let (bytes, reader) = DeflateReader::new(&mut self.reader, strip_sample_count)?;
(bytes, Box::new(reader))
}
method => {
@@ -802,9 +806,14 @@ impl<R: Read + Seek> Decoder<R> {
}
};
if bytes / buffer.byte_len() > max_uncompressed_length {
// 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::InconsistentSizesEncountered,
TiffFormatError::UnexpectedCompressedData {
actual_bytes: bytes,
required_bytes: strip_sample_count * buffer.byte_len(),
},
));
}
@@ -1037,7 +1046,10 @@ impl<R: Read + Seek> Decoder<R> {
if units_read < buffer_size {
return Err(TiffError::FormatError(
TiffFormatError::InconsistentSizesEncountered,
TiffFormatError::InconsistentStripSamples {
actual_samples: units_read,
required_samples: buffer_size,
},
));
}
if let Ok(predictor) = self.get_tag_unsigned(Tag::Predictor) {
+3 -2
View File
@@ -267,10 +267,11 @@ impl LZWReader {
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 {
while uncompressed.len() < max_uncompressed_length {
let bytes_written = uncompressed.len();
uncompressed.reserve(1 << 12);
let buffer_space = uncompressed.capacity();
let buffer_space = uncompressed.capacity().min(max_uncompressed_length);
uncompressed.resize(buffer_space, 0u8);
let result = decoder.decode_bytes(