Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65bc24d5d9 | ||
|
|
7fc75f194a | ||
|
|
7679be19c1 | ||
|
|
0e9f8e3b5b | ||
|
|
c900129f2c | ||
|
|
61234c0005 | ||
|
|
1416af1018 | ||
|
|
87d652ae5e | ||
|
|
b5a78fbec4 | ||
|
|
30640d50ff | ||
|
|
b87770225f | ||
|
|
d38b65eeb2 | ||
|
|
ee27553cf6 | ||
|
|
5a809a728e | ||
|
|
b0b99fc536 | ||
|
|
3bce92781c | ||
|
|
907bbee576 | ||
|
|
fc0dafcde2 | ||
|
|
945a02d1e1 | ||
|
|
ef3294d1fe | ||
|
|
0311402999 | ||
|
|
361578df00 | ||
|
|
bd23428f52 | ||
|
|
d32adf8ef4 |
No files matched your search
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
rust: ["1.48", stable, beta, nightly]
|
rust: ["1.61", stable, beta, nightly]
|
||||||
command: [build, test]
|
command: [build, test]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -20,7 +20,7 @@ jobs:
|
|||||||
- name: test
|
- name: test
|
||||||
run: >
|
run: >
|
||||||
cargo test --tests --benches --no-default-features --features "$FEATURES"
|
cargo test --tests --benches --no-default-features --features "$FEATURES"
|
||||||
if: ${{ matrix.rust != '1.48' }}
|
if: ${{ matrix.rust != '1.61' }}
|
||||||
env:
|
env:
|
||||||
FEATURES: ${{ matrix.features }}
|
FEATURES: ${{ matrix.features }}
|
||||||
rustfmt:
|
rustfmt:
|
||||||
|
|||||||
+30
@@ -1,3 +1,33 @@
|
|||||||
|
# Version 0.8.0
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* The minimum supported rust version is now indicated in `Cargo.toml`.
|
||||||
|
* The enums `TiffFormatError` and `TiffUnsupportedError` are now
|
||||||
|
marked with the `#[non_exhaustive]` attribute.
|
||||||
|
* Additionally, tag related enums `Value`, `Tags`, `Type`, `CompressionMethod`,
|
||||||
|
`PhotometricInterpretation`, `PlanarConfiguration`, `Predictor`,
|
||||||
|
`ResolutionUnit`, `SampleFormat` are also changed.
|
||||||
|
|
||||||
|
Removals:
|
||||||
|
* Removed deprecated methods of `Decoder`: `init`, `read_jpeg`,
|
||||||
|
`read_strip_to_buffer`, `read_strip`, `read_tile`. The implicit chunk (row or
|
||||||
|
tile) index order could not be easily tracked by the caller. New separate
|
||||||
|
utility interfaces may be introduced at a later point, for now callers are
|
||||||
|
obligated to choose their own.
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
* Update to `jpeg_decoder = 0.3`.
|
||||||
|
|
||||||
|
# Version 0.7.4
|
||||||
|
|
||||||
|
New features:
|
||||||
|
* Creating an encoder for invalid, zero-sized images is now rejected.
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
* Fix panic, in a case where decoding jpeg encoded images did not expect the
|
||||||
|
jpeg decoder to return an error.
|
||||||
|
* Fix panic by validating `rows_per_strip` better, fixing a division-by-zero.
|
||||||
|
|
||||||
# Version 0.7.3
|
# Version 0.7.3
|
||||||
|
|
||||||
New features:
|
New features:
|
||||||
|
|||||||
+12
-4
@@ -1,16 +1,24 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tiff"
|
name = "tiff"
|
||||||
version = "0.7.3"
|
version = "0.8.0"
|
||||||
authors = ["The image-rs Developers"]
|
edition = "2018"
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
|
# note: when changed, also update test runner in `.github/workflows/rust.yml`
|
||||||
|
rust-version = "1.61.0"
|
||||||
|
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "TIFF decoding and encoding library in pure Rust"
|
description = "TIFF decoding and encoding library in pure Rust"
|
||||||
|
authors = ["The image-rs Developers"]
|
||||||
|
|
||||||
repository = "https://github.com/image-rs/image-tiff"
|
repository = "https://github.com/image-rs/image-tiff"
|
||||||
|
categories = ["multimedia::images", "multimedia::encoding"]
|
||||||
|
|
||||||
exclude = ["tests/images/*", "tests/fuzz_images/*"]
|
exclude = ["tests/images/*", "tests/fuzz_images/*"]
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
weezl = "0.1.0"
|
weezl = "0.1.0"
|
||||||
jpeg = { package = "jpeg-decoder", version = "0.2.4", default-features = false }
|
jpeg = { package = "jpeg-decoder", version = "0.3.0", default-features = false }
|
||||||
flate2 = "1.0.20"
|
flate2 = "1.0.20"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
+1
-7
@@ -17,6 +17,7 @@ use self::Value::{
|
|||||||
|
|
||||||
#[allow(unused_qualifications)]
|
#[allow(unused_qualifications)]
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
Byte(u8),
|
Byte(u8),
|
||||||
Short(u16),
|
Short(u16),
|
||||||
@@ -34,8 +35,6 @@ pub enum Value {
|
|||||||
Ascii(String),
|
Ascii(String),
|
||||||
Ifd(u32),
|
Ifd(u32),
|
||||||
IfdBig(u64),
|
IfdBig(u64),
|
||||||
#[doc(hidden)] // Do not match against this.
|
|
||||||
__NonExhaustive,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
@@ -361,7 +360,6 @@ impl Entry {
|
|||||||
| Type::RATIONAL
|
| Type::RATIONAL
|
||||||
| Type::SRATIONAL
|
| Type::SRATIONAL
|
||||||
| Type::IFD8 => 8,
|
| Type::IFD8 => 8,
|
||||||
Type::__NonExhaustive => unreachable!(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let value_bytes = match self.count.checked_mul(tag_size) {
|
let value_bytes = match self.count.checked_mul(tag_size) {
|
||||||
@@ -398,7 +396,6 @@ impl Entry {
|
|||||||
| Type::SLONG
|
| Type::SLONG
|
||||||
| Type::FLOAT
|
| Type::FLOAT
|
||||||
| Type::IFD => unreachable!(),
|
| Type::IFD => unreachable!(),
|
||||||
Type::__NonExhaustive => unreachable!(),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +441,6 @@ impl Entry {
|
|||||||
reader.goto_offset(self.r(bo).read_u32()?.into())?;
|
reader.goto_offset(self.r(bo).read_u32()?.into())?;
|
||||||
IfdBig(reader.read_u64()?)
|
IfdBig(reader.read_u64()?)
|
||||||
}
|
}
|
||||||
Type::__NonExhaustive => unreachable!(),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,7 +524,6 @@ impl Entry {
|
|||||||
| Type::IFD8 => {
|
| Type::IFD8 => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
Type::__NonExhaustive => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,7 +606,6 @@ impl Entry {
|
|||||||
}
|
}
|
||||||
Ok(Ascii(String::from_utf8(out)?))
|
Ok(Ascii(String::from_utf8(out)?))
|
||||||
}
|
}
|
||||||
Type::__NonExhaustive => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+18
-3
@@ -97,6 +97,11 @@ impl Image {
|
|||||||
|
|
||||||
let width = tag_reader.require_tag(Tag::ImageWidth)?.into_u32()?;
|
let width = tag_reader.require_tag(Tag::ImageWidth)?.into_u32()?;
|
||||||
let height = tag_reader.require_tag(Tag::ImageLength)?.into_u32()?;
|
let height = tag_reader.require_tag(Tag::ImageLength)?.into_u32()?;
|
||||||
|
if width == 0 || height == 0 {
|
||||||
|
return Err(TiffError::FormatError(TiffFormatError::InvalidDimensions(
|
||||||
|
width, height,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
let photometric_interpretation = tag_reader
|
let photometric_interpretation = tag_reader
|
||||||
.find_tag(Tag::PhotometricInterpretation)?
|
.find_tag(Tag::PhotometricInterpretation)?
|
||||||
@@ -208,7 +213,11 @@ impl Image {
|
|||||||
strip_decoder = Some(StripDecodeState { rows_per_strip });
|
strip_decoder = Some(StripDecodeState { rows_per_strip });
|
||||||
tile_attributes = None;
|
tile_attributes = None;
|
||||||
|
|
||||||
if chunk_offsets.len() != chunk_bytes.len() {
|
if chunk_offsets.len() != chunk_bytes.len()
|
||||||
|
|| rows_per_strip == 0
|
||||||
|
|| u32::try_from(chunk_offsets.len())?
|
||||||
|
!= height.saturating_sub(1) / rows_per_strip + 1
|
||||||
|
{
|
||||||
return Err(TiffError::FormatError(
|
return Err(TiffError::FormatError(
|
||||||
TiffFormatError::InconsistentSizesEncountered,
|
TiffFormatError::InconsistentSizesEncountered,
|
||||||
));
|
));
|
||||||
@@ -345,7 +354,14 @@ impl Image {
|
|||||||
|
|
||||||
let jpeg_reader = JpegReader::new(reader, compressed_length, jpeg_tables)?;
|
let jpeg_reader = JpegReader::new(reader, compressed_length, jpeg_tables)?;
|
||||||
let mut decoder = jpeg::Decoder::new(jpeg_reader);
|
let mut decoder = jpeg::Decoder::new(jpeg_reader);
|
||||||
let data = decoder.decode().unwrap();
|
let data = match decoder.decode() {
|
||||||
|
Ok(data) => data,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(TiffError::FormatError(TiffFormatError::Format(
|
||||||
|
e.to_string(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Box::new(Cursor::new(data))
|
Box::new(Cursor::new(data))
|
||||||
}
|
}
|
||||||
@@ -448,7 +464,6 @@ impl Image {
|
|||||||
TiffUnsupportedError::FloatingPointPredictor(color_type),
|
TiffUnsupportedError::FloatingPointPredictor(color_type),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Predictor::__NonExhaustive => unreachable!(),
|
|
||||||
},
|
},
|
||||||
(type_, _) => {
|
(type_, _) => {
|
||||||
return Err(TiffError::UnsupportedError(
|
return Err(TiffError::UnsupportedError(
|
||||||
|
|||||||
@@ -301,7 +301,6 @@ where
|
|||||||
reader: SmartReader<R>,
|
reader: SmartReader<R>,
|
||||||
bigtiff: bool,
|
bigtiff: bool,
|
||||||
limits: Limits,
|
limits: Limits,
|
||||||
current_chunk: u32,
|
|
||||||
next_ifd: Option<u64>,
|
next_ifd: Option<u64>,
|
||||||
ifd_offsets: Vec<u64>,
|
ifd_offsets: Vec<u64>,
|
||||||
seen_ifds: HashSet<u64>,
|
seen_ifds: HashSet<u64>,
|
||||||
@@ -430,7 +429,6 @@ fn fix_endianness_and_predict(
|
|||||||
_ => unreachable!("Caller should have validated arguments. Please file a bug."),
|
_ => unreachable!("Caller should have validated arguments. Please file a bug."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Predictor::__NonExhaustive => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,7 +584,6 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
chunk_offsets: Vec::new(),
|
chunk_offsets: Vec::new(),
|
||||||
chunk_bytes: Vec::new(),
|
chunk_bytes: Vec::new(),
|
||||||
},
|
},
|
||||||
current_chunk: 0,
|
|
||||||
};
|
};
|
||||||
decoder.next_image()?;
|
decoder.next_image()?;
|
||||||
Ok(decoder)
|
Ok(decoder)
|
||||||
@@ -638,7 +635,6 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
if let Some(ifd_offset) = self.ifd_offsets.get(ifd_index) {
|
if let Some(ifd_offset) = self.ifd_offsets.get(ifd_index) {
|
||||||
let (ifd, _next_ifd) = Self::read_ifd(&mut self.reader, self.bigtiff, *ifd_offset)?;
|
let (ifd, _next_ifd) = Self::read_ifd(&mut self.reader, self.bigtiff, *ifd_offset)?;
|
||||||
|
|
||||||
self.current_chunk = 0;
|
|
||||||
self.image = Image::from_reader(&mut self.reader, ifd, &self.limits, self.bigtiff)?;
|
self.image = Image::from_reader(&mut self.reader, ifd, &self.limits, self.bigtiff)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -649,13 +645,6 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reset the decoder.
|
|
||||||
#[deprecated = "Never should have been public. Only use Decoder::new()"]
|
|
||||||
pub fn init(self) -> TiffResult<Decoder<R>> {
|
|
||||||
let Self { reader, .. } = self;
|
|
||||||
Self::new(reader.into_inner())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn next_ifd(&mut self) -> TiffResult<(Directory, Option<u64>)> {
|
fn next_ifd(&mut self) -> TiffResult<(Directory, Option<u64>)> {
|
||||||
if self.next_ifd.is_none() {
|
if self.next_ifd.is_none() {
|
||||||
return Err(TiffError::FormatError(
|
return Err(TiffError::FormatError(
|
||||||
@@ -686,7 +675,6 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
pub fn next_image(&mut self) -> TiffResult<()> {
|
pub fn next_image(&mut self) -> TiffResult<()> {
|
||||||
let (ifd, _next_ifd) = self.next_ifd()?;
|
let (ifd, _next_ifd) = self.next_ifd()?;
|
||||||
|
|
||||||
self.current_chunk = 0;
|
|
||||||
self.image = Image::from_reader(&mut self.reader, ifd, &self.limits, self.bigtiff)?;
|
self.image = Image::from_reader(&mut self.reader, ifd, &self.limits, self.bigtiff)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1037,33 +1025,6 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
Ok(u32::try_from(self.image().chunk_offsets.len())?)
|
Ok(u32::try_from(self.image().chunk_offsets.len())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated = "Use read_image instead"]
|
|
||||||
pub fn read_jpeg(&mut self) -> TiffResult<DecodingResult> {
|
|
||||||
self.read_image()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[deprecated = "Use read_chunk_to_buffer instead"]
|
|
||||||
pub fn read_strip_to_buffer(&mut self, mut buffer: DecodingBuffer) -> TiffResult<()> {
|
|
||||||
self.check_chunk_type(ChunkType::Strip)?;
|
|
||||||
|
|
||||||
let offset = self.image.chunk_file_range(self.current_chunk)?.0;
|
|
||||||
self.goto_offset_u64(offset)?;
|
|
||||||
|
|
||||||
let byte_order = self.reader.byte_order;
|
|
||||||
let output_width = usize::try_from(self.image().width)?;
|
|
||||||
self.image.expand_chunk(
|
|
||||||
&mut self.reader,
|
|
||||||
buffer.copy(),
|
|
||||||
output_width,
|
|
||||||
byte_order,
|
|
||||||
self.current_chunk,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.current_chunk += 1;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_chunk_to_buffer(
|
pub fn read_chunk_to_buffer(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut buffer: DecodingBuffer,
|
mut buffer: DecodingBuffer,
|
||||||
@@ -1139,30 +1100,6 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read a single strip from the image and return it as a Vector. This method does not return
|
|
||||||
/// information on the size of the strip read and so the caller must take care of the final
|
|
||||||
/// strip in the image as the data read may be less than the expected strip size. This interface
|
|
||||||
/// may change at a future date to reflect this.
|
|
||||||
#[deprecated = "Use read_chunk instead"]
|
|
||||||
pub fn read_strip(&mut self) -> TiffResult<DecodingResult> {
|
|
||||||
let result = self.read_chunk(self.current_chunk)?;
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read a single tile from the image and return it as a Vector. This method does not return
|
|
||||||
/// information on the size of the tile read and so the caller must take care of tiles on the
|
|
||||||
/// rightmost column and the bottommost row in the image as the data read may be less than the
|
|
||||||
/// expected tile size. This interface may change at a future date to reflect this.
|
|
||||||
#[deprecated = "Use read_chunk instead"]
|
|
||||||
pub fn read_tile(&mut self) -> TiffResult<DecodingResult> {
|
|
||||||
let result = self.read_chunk(self.current_chunk)?;
|
|
||||||
|
|
||||||
self.current_chunk += 1;
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read the specified chunk (at index `chunk_index`) and return the binary data as a Vector.
|
/// Read the specified chunk (at index `chunk_index`) and return the binary data as a Vector.
|
||||||
pub fn read_chunk(&mut self, chunk_index: u32) -> TiffResult<DecodingResult> {
|
pub fn read_chunk(&mut self, chunk_index: u32) -> TiffResult<DecodingResult> {
|
||||||
let data_dims = self.image().chunk_data_dimensions(chunk_index)?;
|
let data_dims = self.image().chunk_data_dimensions(chunk_index)?;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use std::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::TiffResult,
|
error::TiffResult,
|
||||||
tags::{CompressionMethod, ResolutionUnit, Tag},
|
tags::{CompressionMethod, ResolutionUnit, Tag},
|
||||||
|
TiffError, TiffFormatError,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod colortype;
|
pub mod colortype;
|
||||||
@@ -349,6 +350,12 @@ impl<'a, W: 'a + Write + Seek, T: ColorType, K: TiffKind, D: Compression>
|
|||||||
height: u32,
|
height: u32,
|
||||||
compression: D,
|
compression: D,
|
||||||
) -> TiffResult<Self> {
|
) -> TiffResult<Self> {
|
||||||
|
if width == 0 || height == 0 {
|
||||||
|
return Err(TiffError::FormatError(TiffFormatError::InvalidDimensions(
|
||||||
|
width, height,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
let row_samples = u64::from(width) * u64::try_from(<T>::BITS_PER_SAMPLE.len())?;
|
let row_samples = u64::from(width) * u64::try_from(<T>::BITS_PER_SAMPLE.len())?;
|
||||||
let row_bytes = row_samples * u64::from(<T::Inner>::BYTE_LEN);
|
let row_bytes = row_samples * u64::from(<T::Inner>::BYTE_LEN);
|
||||||
|
|
||||||
|
|||||||
+4
-8
@@ -43,6 +43,7 @@ pub enum TiffError {
|
|||||||
/// The list of variants may grow to incorporate errors of future features. Matching against this
|
/// The list of variants may grow to incorporate errors of future features. Matching against this
|
||||||
/// exhaustively is not covered by interface stability guarantees.
|
/// exhaustively is not covered by interface stability guarantees.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub enum TiffFormatError {
|
pub enum TiffFormatError {
|
||||||
TiffSignatureNotFound,
|
TiffSignatureNotFound,
|
||||||
TiffSignatureInvalid,
|
TiffSignatureInvalid,
|
||||||
@@ -56,6 +57,7 @@ pub enum TiffFormatError {
|
|||||||
actual_samples: usize,
|
actual_samples: usize,
|
||||||
required_samples: usize,
|
required_samples: usize,
|
||||||
},
|
},
|
||||||
|
InvalidDimensions(u32, u32),
|
||||||
InvalidTag,
|
InvalidTag,
|
||||||
InvalidTagValueType(Tag),
|
InvalidTagValueType(Tag),
|
||||||
RequiredTagNotFound(Tag),
|
RequiredTagNotFound(Tag),
|
||||||
@@ -67,9 +69,6 @@ pub enum TiffFormatError {
|
|||||||
RequiredTagEmpty(Tag),
|
RequiredTagEmpty(Tag),
|
||||||
StripTileTagConflict,
|
StripTileTagConflict,
|
||||||
CycleInOffsets,
|
CycleInOffsets,
|
||||||
#[doc(hidden)]
|
|
||||||
/// Do not match against this variant. It may get removed.
|
|
||||||
__NonExhaustive,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for TiffFormatError {
|
impl fmt::Display for TiffFormatError {
|
||||||
@@ -100,6 +99,7 @@ impl fmt::Display for TiffFormatError {
|
|||||||
actual_samples, required_samples
|
actual_samples, required_samples
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
InvalidDimensions(width, height) => write!(fmt, "Invalid dimensions: {}x{}.", width, height),
|
||||||
InvalidTag => write!(fmt, "Image contains invalid tag."),
|
InvalidTag => write!(fmt, "Image contains invalid tag."),
|
||||||
InvalidTagValueType(ref tag) => {
|
InvalidTagValueType(ref tag) => {
|
||||||
write!(fmt, "Tag `{:?}` did not have the expected value type.", tag)
|
write!(fmt, "Tag `{:?}` did not have the expected value type.", tag)
|
||||||
@@ -119,7 +119,6 @@ impl fmt::Display for TiffFormatError {
|
|||||||
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."),
|
StripTileTagConflict => write!(fmt, "File should contain either (StripByteCounts and StripOffsets) or (TileByteCounts and TileOffsets), other combination was found."),
|
||||||
CycleInOffsets => write!(fmt, "File contained a cycle in the list of IFDs"),
|
CycleInOffsets => write!(fmt, "File contained a cycle in the list of IFDs"),
|
||||||
__NonExhaustive => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,6 +132,7 @@ impl fmt::Display for TiffFormatError {
|
|||||||
/// The list of variants may grow. Matching against this exhaustively is not covered by interface
|
/// The list of variants may grow. Matching against this exhaustively is not covered by interface
|
||||||
/// stability guarantees.
|
/// stability guarantees.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub enum TiffUnsupportedError {
|
pub enum TiffUnsupportedError {
|
||||||
FloatingPointPredictor(ColorType),
|
FloatingPointPredictor(ColorType),
|
||||||
HorizontalPredictor(ColorType),
|
HorizontalPredictor(ColorType),
|
||||||
@@ -146,9 +146,6 @@ pub enum TiffUnsupportedError {
|
|||||||
UnsupportedBitsPerChannel(u8),
|
UnsupportedBitsPerChannel(u8),
|
||||||
UnsupportedPlanarConfig(Option<PlanarConfiguration>),
|
UnsupportedPlanarConfig(Option<PlanarConfiguration>),
|
||||||
UnsupportedDataType,
|
UnsupportedDataType,
|
||||||
#[doc(hidden)]
|
|
||||||
/// Do not match against this variant. It may get removed.
|
|
||||||
__NonExhaustive,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for TiffUnsupportedError {
|
impl fmt::Display for TiffUnsupportedError {
|
||||||
@@ -194,7 +191,6 @@ impl fmt::Display for TiffUnsupportedError {
|
|||||||
write!(fmt, "Unsupported planar configuration “{:?}”.", config)
|
write!(fmt, "Unsupported planar configuration “{:?}”.", config)
|
||||||
}
|
}
|
||||||
UnsupportedDataType => write!(fmt, "Unsupported data type."),
|
UnsupportedDataType => write!(fmt, "Unsupported data type."),
|
||||||
__NonExhaustive => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
//! lossless and lossy compression.
|
//! lossless and lossy compression.
|
||||||
//!
|
//!
|
||||||
//! # Related Links
|
//! # Related Links
|
||||||
//! * <https://www.adobe.io/open/standards/TIFF.html> - The TIFF specification
|
//! * <https://web.archive.org/web/20210108073850/https://www.adobe.io/open/standards/TIFF.html> - The TIFF specification
|
||||||
|
|
||||||
extern crate jpeg;
|
extern crate jpeg;
|
||||||
extern crate weezl;
|
extern crate weezl;
|
||||||
|
|||||||
+1
-4
@@ -9,11 +9,9 @@ macro_rules! tags {
|
|||||||
} => {
|
} => {
|
||||||
$( #[$enum_attr] )*
|
$( #[$enum_attr] )*
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub enum $name {
|
pub enum $name {
|
||||||
$($(#[$ident_attr])* $tag,)*
|
$($(#[$ident_attr])* $tag,)*
|
||||||
// FIXME: switch to non_exhaustive once stabilized and compiler requirement new enough
|
|
||||||
#[doc(hidden)]
|
|
||||||
__NonExhaustive,
|
|
||||||
$(
|
$(
|
||||||
#[doc = $unknown_doc]
|
#[doc = $unknown_doc]
|
||||||
Unknown($ty),
|
Unknown($ty),
|
||||||
@@ -34,7 +32,6 @@ macro_rules! tags {
|
|||||||
match *self {
|
match *self {
|
||||||
$( $name::$tag => $val, )*
|
$( $name::$tag => $val, )*
|
||||||
$( $name::Unknown(n) => { $unknown_doc; n }, )*
|
$( $name::Unknown(n) => { $unknown_doc; n }, )*
|
||||||
$name::__NonExhaustive => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-30
@@ -380,16 +380,7 @@ fn oom() {
|
|||||||
0, 0, 0, 40, 0, 0, 0, 23, 1, 4, 0, 1, 0, 0, 0, 178, 48, 178, 178, 178, 178, 162, 178,
|
0, 0, 0, 40, 0, 0, 0, 23, 1, 4, 0, 1, 0, 0, 0, 178, 48, 178, 178, 178, 178, 162, 178,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut decoder = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap();
|
let _ = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err();
|
||||||
|
|
||||||
let err = decoder.read_image().unwrap_err();
|
|
||||||
|
|
||||||
match err {
|
|
||||||
tiff::TiffError::UnsupportedError(tiff::TiffUnsupportedError::InterpretationWithBits(
|
|
||||||
..,
|
|
||||||
)) => {}
|
|
||||||
unexpected => panic!("Unexpected error {}", unexpected),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -401,14 +392,7 @@ fn fuzzer_testcase4() {
|
|||||||
0, 0, 0, 40, 0, 0, 0, 23, 1, 4, 0, 1, 0, 0, 0, 48, 178, 178, 178, 0, 1, 0, 13, 13,
|
0, 0, 0, 40, 0, 0, 0, 23, 1, 4, 0, 1, 0, 0, 0, 48, 178, 178, 178, 0, 1, 0, 13, 13,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut decoder = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap();
|
let _ = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err();
|
||||||
|
|
||||||
let err = decoder.read_image().unwrap_err();
|
|
||||||
|
|
||||||
match err {
|
|
||||||
tiff::TiffError::IoError(_) => {}
|
|
||||||
unexpected => panic!("Unexpected error {}", unexpected),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -429,9 +413,6 @@ fn fuzzer_testcase2() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn invalid_jpeg_tag_2() {
|
fn invalid_jpeg_tag_2() {
|
||||||
use tiff::tags;
|
|
||||||
use tiff::{TiffError, TiffFormatError};
|
|
||||||
|
|
||||||
let image = [
|
let image = [
|
||||||
73, 73, 42, 0, 8, 0, 0, 0, 16, 0, 254, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 242, 0, 1, 4, 0, 1, 0,
|
73, 73, 42, 0, 8, 0, 0, 0, 16, 0, 254, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 242, 0, 1, 4, 0, 1, 0,
|
||||||
0, 0, 0, 129, 16, 0, 1, 1, 4, 0, 1, 0, 0, 0, 214, 0, 0, 248, 253, 1, 3, 0, 1, 0, 0, 0, 64,
|
0, 0, 0, 129, 16, 0, 1, 1, 4, 0, 1, 0, 0, 0, 214, 0, 0, 248, 253, 1, 3, 0, 1, 0, 0, 0, 64,
|
||||||
@@ -443,15 +424,7 @@ fn invalid_jpeg_tag_2() {
|
|||||||
0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 36, 73, 73, 0, 42, 36, 36, 36, 36, 0, 0, 8, 0,
|
0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 36, 73, 73, 0, 42, 36, 36, 36, 36, 0, 0, 8, 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut decoder = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap();
|
let _ = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err();
|
||||||
|
|
||||||
let err = decoder.read_image().unwrap_err();
|
|
||||||
|
|
||||||
match err {
|
|
||||||
TiffError::FormatError(TiffFormatError::InvalidTagValueType(tags::Tag::JPEGTables)) => {}
|
|
||||||
TiffError::LimitsExceeded => {}
|
|
||||||
unexpected => panic!("Unexpected error {}", unexpected),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ fn test_encode_ifd() {
|
|||||||
{
|
{
|
||||||
let mut tiff = TiffEncoder::new(&mut data).unwrap();
|
let mut tiff = TiffEncoder::new(&mut data).unwrap();
|
||||||
let mut image_encoder = tiff.new_image::<colortype::Gray8>(1, 1).unwrap();
|
let mut image_encoder = tiff.new_image::<colortype::Gray8>(1, 1).unwrap();
|
||||||
|
image_encoder.write_strip(&[1]).unwrap();
|
||||||
let encoder = image_encoder.encoder();
|
let encoder = image_encoder.encoder();
|
||||||
|
|
||||||
// Use the "reusable" tags section as per the TIFF6 spec
|
// Use the "reusable" tags section as per the TIFF6 spec
|
||||||
@@ -320,6 +321,7 @@ fn test_multiple_byte() {
|
|||||||
{
|
{
|
||||||
let mut tiff = TiffEncoder::new(&mut data).unwrap();
|
let mut tiff = TiffEncoder::new(&mut data).unwrap();
|
||||||
let mut image_encoder = tiff.new_image::<colortype::Gray8>(1, 1).unwrap();
|
let mut image_encoder = tiff.new_image::<colortype::Gray8>(1, 1).unwrap();
|
||||||
|
image_encoder.write_strip(&[1]).unwrap();
|
||||||
let encoder = image_encoder.encoder();
|
let encoder = image_encoder.encoder();
|
||||||
|
|
||||||
encoder.write_tag(Tag::Unknown(65000), &[1_u8][..]).unwrap();
|
encoder.write_tag(Tag::Unknown(65000), &[1_u8][..]).unwrap();
|
||||||
@@ -360,6 +362,7 @@ fn test_signed() {
|
|||||||
{
|
{
|
||||||
let mut tiff = TiffEncoder::new(&mut data).unwrap();
|
let mut tiff = TiffEncoder::new(&mut data).unwrap();
|
||||||
let mut image_encoder = tiff.new_image::<colortype::Gray8>(1, 1).unwrap();
|
let mut image_encoder = tiff.new_image::<colortype::Gray8>(1, 1).unwrap();
|
||||||
|
image_encoder.write_strip(&[1]).unwrap();
|
||||||
let encoder = image_encoder.encoder();
|
let encoder = image_encoder.encoder();
|
||||||
|
|
||||||
//Use the "reusable" tags section as per the TIFF6 spec
|
//Use the "reusable" tags section as per the TIFF6 spec
|
||||||
|
|||||||
Reference in new issue
Block a user