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
+82 -38

No files matched your search

+41 -33
View File
@@ -662,57 +662,65 @@ impl<R: Read + Seek> Decoder<R> {
self.width = self.get_tag_u32(Tag::ImageWidth)?; self.width = self.get_tag_u32(Tag::ImageWidth)?;
self.height = self.get_tag_u32(Tag::ImageLength)?; self.height = self.get_tag_u32(Tag::ImageLength)?;
self.strip_decoder = None; self.strip_decoder = None;
self.tile_decoder = None;
self.tile_attributes = None;
self.photometric_interpretation = self self.photometric_interpretation = self
.find_tag_unsigned(Tag::PhotometricInterpretation)? .find_tag_unsigned(Tag::PhotometricInterpretation)?
.and_then(PhotometricInterpretation::from_u16) .and_then(PhotometricInterpretation::from_u16)
.ok_or(TiffUnsupportedError::UnknownInterpretation)?; .ok_or(TiffUnsupportedError::UnknownInterpretation)?;
if let Some(val) = self.find_tag_unsigned(Tag::Compression)? { // Try to parse both the compression method and the number, format, and bits of the included samples.
self.compression_method = CompressionMethod::from_u16(val) // If they are not explicitly specified, those tags are reset to their default values and not carried from previous images.
.ok_or(TiffUnsupportedError::UnknownCompressionMethod)?; self.compression_method = match self.find_tag_unsigned(Tag::Compression)? {
} Some(val) => CompressionMethod::from_u16(val)
if let Some(val) = self.find_tag_unsigned(Tag::SamplesPerPixel)? { .ok_or(TiffUnsupportedError::UnknownCompressionMethod)?,
self.samples = val; None => CompressionMethod::None,
} };
if let Some(vals) = self.find_tag_unsigned_vec(Tag::SampleFormat)? {
self.sample_format = vals 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() .into_iter()
.map(SampleFormat::from_u16_exhaustive) .map(SampleFormat::from_u16_exhaustive)
.collect(); .collect();
// TODO: for now, only homogenous formats across samples are supported. // TODO: for now, only homogenous formats across samples are supported.
if !self.sample_format.windows(2).all(|s| s[0] == s[1]) { if !sample_format.windows(2).all(|s| s[0] == s[1]) {
return Err(TiffUnsupportedError::UnsupportedSampleFormat( return Err(TiffUnsupportedError::UnsupportedSampleFormat(
self.sample_format.clone(), self.sample_format.clone(),
) )
.into()); .into());
} }
}
match self.samples {
1 | 3 | 4 => {
if let Some(val) = self.find_tag_unsigned_vec(Tag::BitsPerSample)? {
self.bits_per_sample = val;
}
}
_ => return Err(TiffUnsupportedError::UnsupportedSampleDepth(self.samples).into()),
}
self.chunk_type = sample_format
match ( }
self.get_tag_u32(Tag::RowsPerStrip), None => vec![SampleFormat::Uint],
self.get_tag_u32(Tag::TileWidth), };
self.get_tag_u32(Tag::TileLength),
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),
) { ) {
(Ok(_), Err(_), Err(_)) => ChunkType::Strip, (true, true, false, false) => ChunkType::Strip,
(Err(_), Ok(_), Ok(_)) => ChunkType::Tile, (false, false, true, true) => 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(
_ => return Err(TiffError::FormatError(TiffFormatError::Format( TiffFormatError::StripTileTagConflict,
String::from( ))
"Neither strips nor tiles were found or both were used in the same file", }
),
))),
}; };
Ok(()) Ok(())
+32
View File
@@ -20,6 +20,14 @@ impl ColorType for Gray8 {
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::Uint]; const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::Uint];
} }
pub struct GrayI8;
impl ColorType for GrayI8 {
type Inner = i8;
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::BlackIsZero;
const BITS_PER_SAMPLE: &'static [u16] = &[8];
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::Int];
}
pub struct Gray16; pub struct Gray16;
impl ColorType for Gray16 { impl ColorType for Gray16 {
type Inner = u16; type Inner = u16;
@@ -28,6 +36,14 @@ impl ColorType for Gray16 {
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::Uint]; const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::Uint];
} }
pub struct GrayI16;
impl ColorType for GrayI16 {
type Inner = i16;
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::BlackIsZero;
const BITS_PER_SAMPLE: &'static [u16] = &[16];
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::Int];
}
pub struct Gray32; pub struct Gray32;
impl ColorType for Gray32 { impl ColorType for Gray32 {
type Inner = u32; type Inner = u32;
@@ -36,6 +52,14 @@ impl ColorType for Gray32 {
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::Uint]; const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::Uint];
} }
pub struct GrayI32;
impl ColorType for GrayI32 {
type Inner = i32;
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::BlackIsZero;
const BITS_PER_SAMPLE: &'static [u16] = &[32];
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::Int];
}
pub struct Gray32Float; pub struct Gray32Float;
impl ColorType for Gray32Float { impl ColorType for Gray32Float {
type Inner = f32; type Inner = f32;
@@ -52,6 +76,14 @@ impl ColorType for Gray64 {
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::Uint]; const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::Uint];
} }
pub struct GrayI64;
impl ColorType for GrayI64 {
type Inner = i64;
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::BlackIsZero;
const BITS_PER_SAMPLE: &'static [u16] = &[64];
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::Int];
}
pub struct Gray64Float; pub struct Gray64Float;
impl ColorType for Gray64Float { impl ColorType for Gray64Float {
type Inner = f64; type Inner = f64;
+2
View File
@@ -63,6 +63,7 @@ pub enum TiffFormatError {
SignedIntegerExpected(Value), SignedIntegerExpected(Value),
Format(String), Format(String),
RequiredTagEmpty(Tag), RequiredTagEmpty(Tag),
StripTileTagConflict,
#[doc(hidden)] #[doc(hidden)]
/// Do not match against this variant. It may get removed. /// Do not match against this variant. It may get removed.
__NonExhaustive, __NonExhaustive,
@@ -113,6 +114,7 @@ impl fmt::Display for TiffFormatError {
} }
Format(ref val) => write!(fmt, "Invalid format: {:?}.", val), Format(ref val) => write!(fmt, "Invalid format: {:?}.", val),
RequiredTagEmpty(ref val) => write!(fmt, "Required tag {:?} was empty.", val), RequiredTagEmpty(ref val) => write!(fmt, "Required tag {:?} was empty.", val),
StripTileTagConflict => write!(fmt, "File should contain either (StripByteCounts and StripOffsets) or (TileByteCounts and TileOffsets), other combination was found."),
__NonExhaustive => unreachable!(), __NonExhaustive => unreachable!(),
} }
} }
+7 -5
View File
@@ -287,7 +287,6 @@ fn test_tiled_incremental() {
#[test] #[test]
fn test_div_zero() { fn test_div_zero() {
use tiff::tags;
use tiff::{TiffError, TiffFormatError}; use tiff::{TiffError, TiffFormatError};
let image = [ let image = [
@@ -298,12 +297,10 @@ fn test_div_zero() {
178, 178, 178, 178, 178, 178,
]; ];
let mut decoder = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap(); let err = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err();
let err = decoder.read_image().unwrap_err();
match err { match err {
TiffError::FormatError(TiffFormatError::InvalidTagValueType(tags::Tag::TileWidth)) => {} TiffError::FormatError(TiffFormatError::StripTileTagConflict) => {}
unexpected => panic!("Unexpected error {}", unexpected), unexpected => panic!("Unexpected error {}", unexpected),
} }
} }
@@ -530,3 +527,8 @@ fn timeout() {
} }
*/ */
} }
#[test]
fn test_no_rows_per_strip() {
test_image_sum_u8("no_rows_per_strip.tiff", ColorType::RGB(8), 99448840);
}
Binary file not shown.