Compare commits

..
1 Commits
Author SHA1 Message Date
Atul Bhosale 0dedc32e9b Format code using 'cargo fmt' 2020-03-17 22:13:58 +05:30
12 changed files with 347 additions and 145 deletions

No files matched your search

-9
View File
@@ -1,12 +1,3 @@
# Version 0.5.0
* Added support for 32-bit and 64-bit decoded values.
* Added CMYK(16|32|64) color type support.
* Check many internal integer conversions to increase stability. This should
only lead to images being reported as faulty that would previously silently
break platform limits. If there are any false positives, please report them.
* Remove an erroneous check of decoded length in lzw compressed images.
# Version 0.4.0
* Several enumerations are now non_exhaustive for future extensions.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tiff"
version = "0.5.0"
version = "0.4.0"
authors = [
"ccgn",
"bvssvni <bvssvni@gmail.com>",
+14 -14
View File
@@ -9,8 +9,7 @@ use super::stream::{ByteOrder, EndianReader, SmartReader};
use tags::{Tag, Type};
use {TiffError, TiffFormatError, TiffResult, TiffUnsupportedError};
use self::Value::{Ascii, List, Rational, Unsigned, Signed, SRational};
use self::Value::{Ascii, List, Rational, SRational, Signed, Unsigned};
#[allow(unused_qualifications)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -72,7 +71,7 @@ impl Value {
new_vec.push(numerator);
new_vec.push(denominator);
}
_ => new_vec.push(v.into_i32()?)
_ => new_vec.push(v.into_i32()?),
}
}
Ok(new_vec)
@@ -182,16 +181,10 @@ impl Entry {
Ok(SRational(numerator, denominator))
}
(Type::RATIONAL, n) => self.decode_offset(n, bo, limits, decoder, |decoder| {
Ok(Rational(
decoder.read_long()?,
decoder.read_long()?,
))
Ok(Rational(decoder.read_long()?, decoder.read_long()?))
}),
(Type::SRATIONAL, n) => self.decode_offset(n, bo, limits, decoder, |decoder| {
Ok(SRational(
decoder.read_slong()?,
decoder.read_slong()?,
))
Ok(SRational(decoder.read_slong()?, decoder.read_slong()?))
}),
(Type::ASCII, n) => {
let n = usize::try_from(n)?;
@@ -209,7 +202,14 @@ impl Entry {
}
#[inline]
fn decode_offset<R, F>(&self, value_count: u32, bo: ByteOrder, limits: &super::Limits, decoder: &mut super::Decoder<R>, decode_fn: F) -> TiffResult<Value>
fn decode_offset<R, F>(
&self,
value_count: u32,
bo: ByteOrder,
limits: &super::Limits,
decoder: &mut super::Decoder<R>,
decode_fn: F,
) -> TiffResult<Value>
where
R: Read + Seek,
F: Fn(&mut super::Decoder<R>) -> TiffResult<Value>,
@@ -235,7 +235,7 @@ fn offset_to_bytes(n: usize, entry: &Entry) -> TiffResult<Value> {
entry.offset[0..n]
.iter()
.map(|&e| Unsigned(u32::from(e)))
.collect()
.collect(),
))
}
@@ -246,7 +246,7 @@ fn offset_to_sbytes(n: usize, entry: &Entry) -> TiffResult<Value> {
entry.offset[0..n]
.iter()
.map(|&e| Signed(i32::from(e as i8)))
.collect()
.collect(),
))
}
+55 -46
View File
@@ -1,14 +1,16 @@
use std::convert::TryFrom;
use std::collections::HashMap;
use std::io::{self, Read, Seek};
use std::cmp;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::io::{self, Read, Seek};
use {ColorType, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError};
use self::ifd::Directory;
use tags::{CompressionMethod, PhotometricInterpretation, Predictor, Tag, Type};
use self::stream::{ByteOrder, EndianReader, LZWReader, DeflateReader, PackBitsReader, SmartReader};
use self::stream::{
ByteOrder, DeflateReader, EndianReader, LZWReader, PackBitsReader, SmartReader,
};
pub mod ifd;
mod stream;
@@ -217,8 +219,14 @@ fn rev_hpredict(image: DecodingBuffer, size: (u32, u32), color_type: ColorType)
let samples = match color_type {
ColorType::Gray(8) | ColorType::Gray(16) | ColorType::Gray(32) | ColorType::Gray(64) => 1,
ColorType::RGB(8) | ColorType::RGB(16) | ColorType::RGB(32) | ColorType::RGB(64) => 3,
ColorType::RGBA(8) | ColorType::RGBA(16) | ColorType::RGBA(32) | ColorType::RGBA(64)
| ColorType::CMYK(8) | ColorType::CMYK(16) | ColorType::CMYK(32) | ColorType::CMYK(64) => 4,
ColorType::RGBA(8)
| ColorType::RGBA(16)
| ColorType::RGBA(32)
| ColorType::RGBA(64)
| ColorType::CMYK(8)
| ColorType::CMYK(16)
| ColorType::CMYK(32)
| ColorType::CMYK(64) => 4,
_ => {
return Err(TiffError::UnsupportedError(
TiffUnsupportedError::HorizontalPredictor(color_type),
@@ -273,8 +281,7 @@ impl<R: Read + Seek> Decoder<R> {
pub fn colortype(&mut self) -> TiffResult<ColorType> {
match self.photometric_interpretation {
PhotometricInterpretation::RGB => {
match self.bits_per_sample[..] {
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)),
_ => Err(TiffError::UnsupportedError(
@@ -283,10 +290,8 @@ impl<R: Read + Seek> Decoder<R> {
self.bits_per_sample.clone(),
),
)),
}
},
PhotometricInterpretation::CMYK => {
match self.bits_per_sample[..] {
PhotometricInterpretation::CMYK => match self.bits_per_sample[..] {
[c, m, y, k] if [c, c, c] == [m, y, k] => Ok(ColorType::CMYK(c)),
_ => Err(TiffError::UnsupportedError(
TiffUnsupportedError::InterpretationWithBits(
@@ -294,7 +299,6 @@ impl<R: Read + Seek> Decoder<R> {
self.bits_per_sample.clone(),
),
)),
}
},
PhotometricInterpretation::BlackIsZero | PhotometricInterpretation::WhiteIsZero
if self.bits_per_sample.len() == 1 =>
@@ -371,9 +375,11 @@ impl<R: Read + Seek> Decoder<R> {
self.samples = val;
}
match self.samples {
1 | 3 | 4 => if let Some(val) = self.find_tag_unsigned_vec(Tag::BitsPerSample)? {
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()),
}
Ok(())
@@ -516,20 +522,30 @@ impl<R: Read + Seek> Decoder<R> {
/// Tries to retrieve a tag and convert it to the desired unsigned type.
pub fn find_tag_unsigned<T: TryFrom<u32>>(&mut self, tag: Tag) -> TiffResult<Option<T>> {
self.find_tag(tag)?
.map(|v| v.into_u32()).transpose()?
.map(|value| T::try_from(value)
.map_err(|_| TiffFormatError::InvalidTagValueType(tag).into()))
.map(|v| v.into_u32())
.transpose()?
.map(|value| {
T::try_from(value).map_err(|_| TiffFormatError::InvalidTagValueType(tag).into())
})
.transpose()
}
/// Tries to retrieve a vector of all a tag's values and convert them to
/// the desired unsigned type.
pub fn find_tag_unsigned_vec<T: TryFrom<u32>>(&mut self, tag: Tag) -> TiffResult<Option<Vec<T>>> {
pub fn find_tag_unsigned_vec<T: TryFrom<u32>>(
&mut self,
tag: Tag,
) -> TiffResult<Option<Vec<T>>> {
self.find_tag(tag)?
.map(|v| v.into_u32_vec()).transpose()?
.map(|v| v.into_iter()
.map(|u| T::try_from(u).map_err(|_| TiffFormatError::InvalidTagValueType(tag).into()))
.collect())
.map(|v| v.into_u32_vec())
.transpose()?
.map(|v| {
v.into_iter()
.map(|u| {
T::try_from(u).map_err(|_| TiffFormatError::InvalidTagValueType(tag).into())
})
.collect()
})
.transpose()
}
@@ -584,21 +600,19 @@ impl<R: Read + Seek> Decoder<R> {
let (bytes, reader) = LZWReader::new(
&mut self.reader,
usize::try_from(length)?,
max_uncompressed_length * buffer.byte_len()
max_uncompressed_length,
)?;
(bytes, Box::new(reader))
}
CompressionMethod::PackBits => {
let order = self.reader.byte_order;
let (bytes, reader) = PackBitsReader::new(
&mut self.reader,
order,
usize::try_from(length)?,
)?;
let (bytes, reader) =
PackBitsReader::new(&mut self.reader, order, usize::try_from(length)?)?;
(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, max_uncompressed_length)?;
(bytes, Box::new(reader))
}
method => {
@@ -685,9 +699,7 @@ impl<R: Read + Seek> Decoder<R> {
/// Number of strips in image
pub fn strip_count(&mut self) -> TiffResult<u32> {
let rows_per_strip = self
.get_tag_u32(Tag::RowsPerStrip)
.unwrap_or(self.height);
let rows_per_strip = self.get_tag_u32(Tag::RowsPerStrip).unwrap_or(self.height);
if rows_per_strip == 0 {
return Ok(0);
@@ -733,9 +745,8 @@ impl<R: Read + Seek> Decoder<R> {
TiffFormatError::InconsistentSizesEncountered,
))?;
let rows_per_strip = usize::try_from(self
.get_tag_u32(Tag::RowsPerStrip)
.unwrap_or(self.height))?;
let rows_per_strip =
usize::try_from(self.get_tag_u32(Tag::RowsPerStrip).unwrap_or(self.height))?;
let strip_height = cmp::min(
rows_per_strip,
@@ -744,7 +755,9 @@ impl<R: Read + Seek> Decoder<R> {
let buffer_size = usize::try_from(self.width)? * strip_height * self.bits_per_sample.len();
if buffer.len() < buffer_size {
if buffer.len() < buffer_size
|| usize::try_from(byte_count)? / buffer.byte_len() > buffer_size
{
return Err(TiffError::FormatError(
TiffFormatError::InconsistentSizesEncountered,
));
@@ -792,11 +805,9 @@ impl<R: Read + Seek> Decoder<R> {
n if n <= 16 => DecodingResult::new_u16(buffer_size, &self.limits),
n if n <= 32 => DecodingResult::new_u32(buffer_size, &self.limits),
n if n <= 64 => DecodingResult::new_u64(buffer_size, &self.limits),
n => {
Err(TiffError::UnsupportedError(
n => Err(TiffError::UnsupportedError(
TiffUnsupportedError::UnsupportedBitsPerChannel(n),
))
}
)),
}
}
@@ -805,9 +816,8 @@ impl<R: Read + Seek> Decoder<R> {
self.initialize_strip_decoder()?;
let index = self.strip_decoder.as_ref().unwrap().strip_index;
let rows_per_strip = usize::try_from(self
.get_tag_u32(Tag::RowsPerStrip)
.unwrap_or(self.height))?;
let rows_per_strip =
usize::try_from(self.get_tag_u32(Tag::RowsPerStrip).unwrap_or(self.height))?;
let strip_height = cmp::min(
rows_per_strip,
@@ -824,9 +834,8 @@ impl<R: Read + Seek> Decoder<R> {
/// Decodes the entire image and return it as a Vector
pub fn read_image(&mut self) -> TiffResult<DecodingResult> {
self.initialize_strip_decoder()?;
let rows_per_strip = usize::try_from(self
.get_tag_u32(Tag::RowsPerStrip)
.unwrap_or(self.height))?;
let rows_per_strip =
usize::try_from(self.get_tag_u32(Tag::RowsPerStrip).unwrap_or(self.height))?;
let samples_per_strip =
usize::try_from(self.width)? * rows_per_strip * self.bits_per_sample.len();
+46 -19
View File
@@ -4,8 +4,8 @@ use std::convert::TryFrom;
use std::io::{Seek, Write};
use std::mem;
use tags::{self, ResolutionUnit, Tag, Type};
use error::{TiffError, TiffFormatError, TiffResult};
use tags::{self, ResolutionUnit, Tag, Type};
pub mod colortype;
mod writer;
@@ -61,8 +61,7 @@ impl TiffValue for [i8] {
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
// We write using nativeedian so this should be safe
let slice =
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len()) };
let slice = unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len()) };
writer.write_bytes(slice)?;
Ok(())
}
@@ -95,8 +94,12 @@ impl TiffValue for [i16] {
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
// We write using nativeedian so this should be safe
let slice =
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * Self::BYTE_LEN as usize) };
let slice = unsafe {
::std::slice::from_raw_parts(
self.as_ptr() as *const u8,
self.len() * Self::BYTE_LEN as usize,
)
};
writer.write_bytes(slice)?;
Ok(())
}
@@ -129,8 +132,12 @@ impl TiffValue for [i32] {
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
// We write using nativeedian so this should be safe
let slice =
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * Self::BYTE_LEN as usize) };
let slice = unsafe {
::std::slice::from_raw_parts(
self.as_ptr() as *const u8,
self.len() * Self::BYTE_LEN as usize,
)
};
writer.write_bytes(slice)?;
Ok(())
}
@@ -407,14 +414,20 @@ impl<W: Write + Seek> TiffEncoder<W> {
where
[C::Inner]: TiffValue,
{
let num_pix = usize::try_from(width)?.checked_mul(usize::try_from(height)?)
.ok_or_else(|| ::std::io::Error::new(
let num_pix = usize::try_from(width)?
.checked_mul(usize::try_from(height)?)
.ok_or_else(|| {
::std::io::Error::new(
::std::io::ErrorKind::InvalidInput,
"Image width * height exceeds usize"))?;
"Image width * height exceeds usize",
)
})?;
if data.len() < num_pix {
return Err(::std::io::Error::new(
::std::io::ErrorKind::InvalidData,
"Input data slice is undersized for provided dimensions").into());
"Input data slice is undersized for provided dimensions",
)
.into());
}
let encoder = DirectoryEncoder::new(&mut self.writer)?;
@@ -464,8 +477,10 @@ impl<'a, W: 'a + Write + Seek> DirectoryEncoder<'a, W> {
value.write(&mut writer)?;
}
self.ifd
.insert(tag.to_u16(), (<T>::FIELD_TYPE.to_u16(), value.count(), bytes));
self.ifd.insert(
tag.to_u16(),
(<T>::FIELD_TYPE.to_u16(), value.count(), bytes),
);
Ok(())
}
@@ -597,7 +612,10 @@ impl<'a, W: 'a + Write + Seek, T: ColorType> ImageEncoder<'a, W, T> {
encoder.write_tag(Tag::RowsPerStrip, u32::try_from(rows_per_strip)?)?;
encoder.write_tag(Tag::SamplesPerPixel, u16::try_from(<T>::BITS_PER_SAMPLE.len())?)?;
encoder.write_tag(
Tag::SamplesPerPixel,
u16::try_from(<T>::BITS_PER_SAMPLE.len())?,
)?;
encoder.write_tag(Tag::XResolution, Rational { n: 1, d: 1 })?;
encoder.write_tag(Tag::YResolution, Rational { n: 1, d: 1 })?;
encoder.write_tag(Tag::ResolutionUnit, ResolutionUnit::None.to_u16())?;
@@ -622,7 +640,8 @@ impl<'a, W: 'a + Write + Seek, T: ColorType> ImageEncoder<'a, W, T> {
return 0;
}
let start_row = ::std::cmp::min(u64::from(self.height), self.strip_idx * self.rows_per_strip);
let start_row =
::std::cmp::min(u64::from(self.height), self.strip_idx * self.rows_per_strip);
let end_row = ::std::cmp::min(
u64::from(self.height),
(self.strip_idx + 1) * self.rows_per_strip,
@@ -641,7 +660,9 @@ impl<'a, W: 'a + Write + Seek, T: ColorType> ImageEncoder<'a, W, T> {
if u64::try_from(value.len())? != samples {
return Err(::std::io::Error::new(
::std::io::ErrorKind::InvalidData,
"Slice is wrong size for strip").into());
"Slice is wrong size for strip",
)
.into());
}
let offset = self.encoder.write_data(value)?;
@@ -654,14 +675,20 @@ impl<'a, W: 'a + Write + Seek, T: ColorType> ImageEncoder<'a, W, T> {
/// Set image resolution
pub fn resolution(&mut self, unit: ResolutionUnit, value: Rational) {
self.encoder.write_tag(Tag::ResolutionUnit, unit.to_u16()).unwrap();
self.encoder.write_tag(Tag::XResolution, value.clone()).unwrap();
self.encoder
.write_tag(Tag::ResolutionUnit, unit.to_u16())
.unwrap();
self.encoder
.write_tag(Tag::XResolution, value.clone())
.unwrap();
self.encoder.write_tag(Tag::YResolution, value).unwrap();
}
/// Set image resolution unit
pub fn resolution_unit(&mut self, unit: ResolutionUnit) {
self.encoder.write_tag(Tag::ResolutionUnit, unit.to_u16()).unwrap();
self.encoder
.write_tag(Tag::ResolutionUnit, unit.to_u16())
.unwrap();
}
/// Set image x-resolution
+1 -1
View File
@@ -1,5 +1,5 @@
use error::TiffResult;
use byteorder::{BigEndian, ByteOrder, LittleEndian, NativeEndian, WriteBytesExt};
use error::TiffResult;
use std::io::{self, Seek, SeekFrom, Write};
pub trait TiffByteOrder: ByteOrder {
+5 -4
View File
@@ -3,9 +3,9 @@ use std::fmt;
use std::io;
use std::string;
use decoder::ifd::{Value};
use tags::{CompressionMethod, PhotometricInterpretation, PlanarConfiguration, Tag};
use decoder::ifd::Value;
use miniz_oxide::inflate::TINFLStatus;
use tags::{CompressionMethod, PhotometricInterpretation, PlanarConfiguration, Tag};
use ColorType;
/// Tiff error kinds.
@@ -62,8 +62,9 @@ impl fmt::Display for TiffFormatError {
ImageFileDirectoryNotFound => write!(fmt, "Image file directory not found."),
InconsistentSizesEncountered => write!(fmt, "Inconsistent sizes encountered."),
InvalidTag => write!(fmt, "Image contains invalid tag."),
InvalidTagValueType(ref tag) =>
write!(fmt, "Tag `{:?}` did not have the expected value type.", tag),
InvalidTagValueType(ref tag) => {
write!(fmt, "Tag `{:?}` did not have the expected value type.", tag)
}
RequiredTagNotFound(ref tag) => write!(fmt, "Required tag `{:?}` not found.", tag),
UnknownPredictor(ref predictor) => {
write!(fmt, "Unknown predictor “{}” encountered", predictor)
-1
View File
@@ -131,7 +131,6 @@ pub enum Type(u16) {
}
}
tags! {
pub enum CompressionMethod(u16) {
None = 1,
+4 -8
View File
@@ -21,7 +21,7 @@ macro_rules! test_image_sum {
DecodingResult::$buffer(res) => {
let sum: $sum_ty = res.into_iter().map(<$sum_ty>::from).sum();
assert_eq!(sum, expected_sum);
},
}
_ => panic!("Wrong bit depth"),
}
}
@@ -42,7 +42,9 @@ fn test_image_color_type_unsupported(file: &str, expected_type: ColorType) {
let mut decoder = Decoder::new(img_file).expect("Cannot create decoder");
assert_eq!(decoder.colortype().unwrap(), expected_type);
assert!(match decoder.read_image() {
Err(tiff::TiffError::UnsupportedError(tiff::TiffUnsupportedError::UnsupportedColorType(_))) => true,
Err(tiff::TiffError::UnsupportedError(
tiff::TiffUnsupportedError::UnsupportedColorType(_),
)) => true,
_ => false,
});
}
@@ -149,12 +151,6 @@ fn test_decode_data() {
}
}
#[test]
fn issue_69() {
test_image_sum_u16("issue_69_lzw.tiff", ColorType::Gray(16), 1015486);
test_image_sum_u16("issue_69_packbits.tiff", ColorType::Gray(16), 1015486);
}
// TODO: GrayA support
//#[test]
//fn test_gray_alpha_u8()
+221 -42
View File
@@ -1,9 +1,9 @@
extern crate tiff;
use tiff::decoder::{Decoder, DecodingResult};
use tiff::encoder::{colortype, TiffEncoder, SRational};
use tiff::ColorType;
use tiff::encoder::{colortype, SRational, TiffEncoder};
use tiff::tags::Tag;
use tiff::ColorType;
use std::fs::File;
use std::io::{Cursor, Seek, SeekFrom};
@@ -58,7 +58,10 @@ const TEST_IMAGE_DIR: &str = "./tests/images/";
macro_rules! test_roundtrip {
($name:ident, $buffer:ident, $buffer_ty:ty) => {
fn $name<C: colortype::ColorType<Inner=$buffer_ty>>(file: &str, expected_type: ColorType) {
fn $name<C: colortype::ColorType<Inner = $buffer_ty>>(
file: &str,
expected_type: ColorType,
) {
let path = PathBuf::from(TEST_IMAGE_DIR).join(file);
let img_file = File::open(path).expect("Cannot find test image!");
let mut decoder = Decoder::new(img_file).expect("Cannot create decoder");
@@ -74,8 +77,7 @@ macro_rules! test_roundtrip {
let mut tiff = TiffEncoder::new(&mut file).unwrap();
let (width, height) = decoder.dimensions().unwrap();
tiff.write_image::<C>(width, height, &image_data)
.unwrap();
tiff.write_image::<C>(width, height, &image_data).unwrap();
}
file.seek(SeekFrom::Start(0)).unwrap();
{
@@ -155,21 +157,64 @@ fn test_multiple_byte() {
let encoder = image_encoder.encoder();
encoder.write_tag(Tag::Unknown(65000), &[1_u8][..]).unwrap();
encoder.write_tag(Tag::Unknown(65001), &[1_u8, 2][..]).unwrap();
encoder.write_tag(Tag::Unknown(65002), &[1_u8, 2, 3][..]).unwrap();
encoder.write_tag(Tag::Unknown(65003), &[1_u8, 2, 3, 4][..]).unwrap();
encoder.write_tag(Tag::Unknown(65004), &[1_u8, 2, 3, 4, 5][..]).unwrap();
encoder
.write_tag(Tag::Unknown(65001), &[1_u8, 2][..])
.unwrap();
encoder
.write_tag(Tag::Unknown(65002), &[1_u8, 2, 3][..])
.unwrap();
encoder
.write_tag(Tag::Unknown(65003), &[1_u8, 2, 3, 4][..])
.unwrap();
encoder
.write_tag(Tag::Unknown(65004), &[1_u8, 2, 3, 4, 5][..])
.unwrap();
}
data.set_position(0);
{
let mut decoder = Decoder::new(&mut data).unwrap();
assert_eq!(decoder.get_tag(Tag::Unknown(65000)).unwrap().into_u32_vec().unwrap(), [1]);
assert_eq!(decoder.get_tag(Tag::Unknown(65001)).unwrap().into_u32_vec().unwrap(), [1, 2]);
assert_eq!(decoder.get_tag(Tag::Unknown(65002)).unwrap().into_u32_vec().unwrap(), [1, 2, 3]);
assert_eq!(decoder.get_tag(Tag::Unknown(65003)).unwrap().into_u32_vec().unwrap(), [1, 2, 3, 4]);
assert_eq!(decoder.get_tag(Tag::Unknown(65004)).unwrap().into_u32_vec().unwrap(), [1, 2, 3, 4, 5]);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65000))
.unwrap()
.into_u32_vec()
.unwrap(),
[1]
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65001))
.unwrap()
.into_u32_vec()
.unwrap(),
[1, 2]
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65002))
.unwrap()
.into_u32_vec()
.unwrap(),
[1, 2, 3]
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65003))
.unwrap()
.into_u32_vec()
.unwrap(),
[1, 2, 3, 4]
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65004))
.unwrap()
.into_u32_vec()
.unwrap(),
[1, 2, 3, 4, 5]
);
}
}
@@ -185,23 +230,48 @@ fn test_signed() {
//Use the "reusable" tags section as per the TIFF6 spec
encoder.write_tag(Tag::Unknown(65000), -1_i8).unwrap();
encoder.write_tag(Tag::Unknown(65001), &[-1_i8][..]).unwrap();
encoder.write_tag(Tag::Unknown(65002), &[-1_i8, 2][..]).unwrap();
encoder.write_tag(Tag::Unknown(65003), &[-1_i8, 2, -3][..]).unwrap();
encoder.write_tag(Tag::Unknown(65004), &[-1_i8, 2, -3, 4][..]).unwrap();
encoder.write_tag(Tag::Unknown(65005), &[-1_i8, 2, -3, 4, -5][..]).unwrap();
encoder
.write_tag(Tag::Unknown(65001), &[-1_i8][..])
.unwrap();
encoder
.write_tag(Tag::Unknown(65002), &[-1_i8, 2][..])
.unwrap();
encoder
.write_tag(Tag::Unknown(65003), &[-1_i8, 2, -3][..])
.unwrap();
encoder
.write_tag(Tag::Unknown(65004), &[-1_i8, 2, -3, 4][..])
.unwrap();
encoder
.write_tag(Tag::Unknown(65005), &[-1_i8, 2, -3, 4, -5][..])
.unwrap();
encoder.write_tag(Tag::Unknown(65010), -1_i16).unwrap();
encoder.write_tag(Tag::Unknown(65011), -1_i16).unwrap();
encoder.write_tag(Tag::Unknown(65012), &[-1_i16, 2][..]).unwrap();
encoder.write_tag(Tag::Unknown(65013), &[-1_i16, 2, -3][..]).unwrap();
encoder
.write_tag(Tag::Unknown(65012), &[-1_i16, 2][..])
.unwrap();
encoder
.write_tag(Tag::Unknown(65013), &[-1_i16, 2, -3][..])
.unwrap();
encoder.write_tag(Tag::Unknown(65020), -1_i32).unwrap();
encoder.write_tag(Tag::Unknown(65021), &[-1_i32][..]).unwrap();
encoder.write_tag(Tag::Unknown(65022), &[-1_i32, 2][..]).unwrap();
encoder
.write_tag(Tag::Unknown(65021), &[-1_i32][..])
.unwrap();
encoder
.write_tag(Tag::Unknown(65022), &[-1_i32, 2][..])
.unwrap();
encoder.write_tag(Tag::Unknown(65030), SRational { n: -1, d: 100 }).unwrap();
encoder.write_tag(Tag::Unknown(65031), &[SRational { n: -1, d: 100 }, SRational { n: 2, d: 100 }][..]).unwrap();
encoder
.write_tag(Tag::Unknown(65030), SRational { n: -1, d: 100 })
.unwrap();
encoder
.write_tag(
Tag::Unknown(65031),
&[SRational { n: -1, d: 100 }, SRational { n: 2, d: 100 }][..],
)
.unwrap();
}
//Rewind the cursor for reading
@@ -209,24 +279,129 @@ fn test_signed() {
{
let mut decoder = Decoder::new(&mut data).unwrap();
assert_eq!(decoder.get_tag(Tag::Unknown(65000)).unwrap().into_i32().unwrap(), -1, );
assert_eq!(decoder.get_tag(Tag::Unknown(65001)).unwrap().into_i32_vec().unwrap(), [-1]);
assert_eq!(decoder.get_tag(Tag::Unknown(65002)).unwrap().into_i32_vec().unwrap(), [-1, 2]);
assert_eq!(decoder.get_tag(Tag::Unknown(65003)).unwrap().into_i32_vec().unwrap(), [-1, 2, -3]);
assert_eq!(decoder.get_tag(Tag::Unknown(65004)).unwrap().into_i32_vec().unwrap(), [-1, 2, -3, 4]);
assert_eq!(decoder.get_tag(Tag::Unknown(65005)).unwrap().into_i32_vec().unwrap(), [-1, 2, -3, 4, -5], );
assert_eq!(
decoder
.get_tag(Tag::Unknown(65000))
.unwrap()
.into_i32()
.unwrap(),
-1,
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65001))
.unwrap()
.into_i32_vec()
.unwrap(),
[-1]
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65002))
.unwrap()
.into_i32_vec()
.unwrap(),
[-1, 2]
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65003))
.unwrap()
.into_i32_vec()
.unwrap(),
[-1, 2, -3]
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65004))
.unwrap()
.into_i32_vec()
.unwrap(),
[-1, 2, -3, 4]
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65005))
.unwrap()
.into_i32_vec()
.unwrap(),
[-1, 2, -3, 4, -5],
);
assert_eq!(decoder.get_tag(Tag::Unknown(65010)).unwrap().into_i32().unwrap(), -1);
assert_eq!(decoder.get_tag(Tag::Unknown(65011)).unwrap().into_i32_vec().unwrap(), [-1]);
assert_eq!(decoder.get_tag(Tag::Unknown(65012)).unwrap().into_i32_vec().unwrap(), [-1, 2]);
assert_eq!(decoder.get_tag(Tag::Unknown(65013)).unwrap().into_i32_vec().unwrap(), [-1, 2, -3]);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65010))
.unwrap()
.into_i32()
.unwrap(),
-1
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65011))
.unwrap()
.into_i32_vec()
.unwrap(),
[-1]
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65012))
.unwrap()
.into_i32_vec()
.unwrap(),
[-1, 2]
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65013))
.unwrap()
.into_i32_vec()
.unwrap(),
[-1, 2, -3]
);
assert_eq!(decoder.get_tag(Tag::Unknown(65020)).unwrap().into_i32().unwrap(), -1);
assert_eq!(decoder.get_tag(Tag::Unknown(65021)).unwrap().into_i32_vec().unwrap(), [-1]);
assert_eq!(decoder.get_tag(Tag::Unknown(65022)).unwrap().into_i32_vec().unwrap(), [-1, 2]);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65020))
.unwrap()
.into_i32()
.unwrap(),
-1
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65021))
.unwrap()
.into_i32_vec()
.unwrap(),
[-1]
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65022))
.unwrap()
.into_i32_vec()
.unwrap(),
[-1, 2]
);
assert_eq!(decoder.get_tag(Tag::Unknown(65030)).unwrap().into_i32_vec().unwrap(), [-1, 100]);
assert_eq!(decoder.get_tag(Tag::Unknown(65031)).unwrap().into_i32_vec().unwrap(), [-1_i32, 100, 2, 100]);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65030))
.unwrap()
.into_i32_vec()
.unwrap(),
[-1, 100]
);
assert_eq!(
decoder
.get_tag(Tag::Unknown(65031))
.unwrap()
.into_i32_vec()
.unwrap(),
[-1_i32, 100, 2, 100]
);
}
}
@@ -241,10 +416,14 @@ fn test_multipage_image() {
// write first grayscale image (2x2 16-bit)
let img1: Vec<u16> = [1, 2, 3, 4].to_vec();
img_encoder.write_image::<colortype::Gray16>(2, 2, &img1[..]).unwrap();
img_encoder
.write_image::<colortype::Gray16>(2, 2, &img1[..])
.unwrap();
// write second grayscale image (3x3 8-bit)
let img2: Vec<u8> = [9, 8, 7, 6, 5, 4, 3, 2, 1].to_vec();
img_encoder.write_image::<colortype::Gray8>(3, 3, &img2[..]).unwrap();
img_encoder
.write_image::<colortype::Gray8>(3, 3, &img2[..])
.unwrap();
}
// seek to the beginning of the file, so that it can be decoded
Binary file not shown.
Binary file not shown.