Merge remote-tracking branch 'origin/master' into oom

This commit is contained in:
5225225 committed 2021-09-06 17:53:16 +01:00
commit 2c9e02d347
5 files changed
+92 -48

No files matched your search

+51 -43
View File
@@ -662,58 +662,66 @@ impl<R: Read + Seek> Decoder<R> {
self.width = self.get_tag_u32(Tag::ImageWidth)?;
self.height = self.get_tag_u32(Tag::ImageLength)?;
self.strip_decoder = None;
self.tile_decoder = None;
self.tile_attributes = None;
self.photometric_interpretation = self
.find_tag_unsigned(Tag::PhotometricInterpretation)?
.and_then(PhotometricInterpretation::from_u16)
.ok_or(TiffUnsupportedError::UnknownInterpretation)?;
if let Some(val) = self.find_tag_unsigned(Tag::Compression)? {
self.compression_method = CompressionMethod::from_u16(val)
.ok_or(TiffUnsupportedError::UnknownCompressionMethod)?;
}
if let Some(val) = self.find_tag_unsigned(Tag::SamplesPerPixel)? {
self.samples = val;
}
if let Some(vals) = self.find_tag_unsigned_vec(Tag::SampleFormat)? {
self.sample_format = vals
.into_iter()
.map(SampleFormat::from_u16_exhaustive)
.collect();
// Try to parse both the compression method and the number, format, and bits of the included samples.
// If they are not explicitly specified, those tags are reset to their default values and not carried from previous images.
self.compression_method = match self.find_tag_unsigned(Tag::Compression)? {
Some(val) => CompressionMethod::from_u16(val)
.ok_or(TiffUnsupportedError::UnknownCompressionMethod)?,
None => CompressionMethod::None,
};
// TODO: for now, only homogenous formats across samples are supported.
if !self.sample_format.windows(2).all(|s| s[0] == s[1]) {
return Err(TiffUnsupportedError::UnsupportedSampleFormat(
self.sample_format.clone(),
)
.into());
}
}
match self.samples {
1 | 3 | 4 => {
if let Some(val) = self.find_tag_unsigned_vec(Tag::BitsPerSample)? {
self.bits_per_sample = val;
self.samples = self.find_tag_unsigned(Tag::SamplesPerPixel)?.unwrap_or(1);
self.sample_format = match self.find_tag_unsigned_vec(Tag::SampleFormat)? {
Some(vals) => {
let sample_format: Vec<_> = vals
.into_iter()
.map(SampleFormat::from_u16_exhaustive)
.collect();
// TODO: for now, only homogenous formats across samples are supported.
if !sample_format.windows(2).all(|s| s[0] == s[1]) {
return Err(TiffUnsupportedError::UnsupportedSampleFormat(
self.sample_format.clone(),
)
.into());
}
}
_ => return Err(TiffUnsupportedError::UnsupportedSampleDepth(self.samples).into()),
}
self.chunk_type =
match (
self.get_tag_u32(Tag::RowsPerStrip),
self.get_tag_u32(Tag::TileWidth),
self.get_tag_u32(Tag::TileLength),
) {
(Ok(_), Err(_), Err(_)) => ChunkType::Strip,
(Err(_), Ok(_), Ok(_)) => ChunkType::Tile,
// TODO: The spec says not to use both strip-oriented fields and tile-oriented fields.
// We can relax this later if it becomes a problem
_ => return Err(TiffError::FormatError(TiffFormatError::Format(
String::from(
"Neither strips nor tiles were found or both were used in the same file",
),
))),
};
sample_format
}
None => vec![SampleFormat::Uint],
};
self.bits_per_sample = match self.samples {
1 | 3 | 4 => self
.find_tag_unsigned_vec(Tag::BitsPerSample)?
.unwrap_or_else(|| vec![1]),
_ => return Err(TiffUnsupportedError::UnsupportedSampleDepth(self.samples).into()),
};
let ifd = self.ifd.as_ref().unwrap();
self.chunk_type = match (
ifd.contains_key(&Tag::StripByteCounts),
ifd.contains_key(&Tag::StripOffsets),
ifd.contains_key(&Tag::TileByteCounts),
ifd.contains_key(&Tag::TileOffsets),
) {
(true, true, false, false) => ChunkType::Strip,
(false, false, true, true) => ChunkType::Tile,
(_, _, _, _) => {
return Err(TiffError::FormatError(
TiffFormatError::StripTileTagConflict,
))
}
};
Ok(())
}