Merge remote-tracking branch 'origin/master' into oom
This commit is contained in:
commit
2c9e02d347
5 files changed
+82
-38
No files matched your search
+41
-33
@@ -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(())
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
Reference in new issue
Block a user