fix: Big tiff decoding and add tests
This commit is contained in:
1 parent
23751bd8c5
commit
797e3dca07
6 files changed
+57
-6
No files matched your search
+9
-4
@@ -122,10 +122,16 @@ impl Entry {
|
|||||||
decoder: &mut super::Decoder<R>,
|
decoder: &mut super::Decoder<R>,
|
||||||
) -> TiffResult<Value> {
|
) -> TiffResult<Value> {
|
||||||
let bo = decoder.byte_order();
|
let bo = decoder.byte_order();
|
||||||
let bigtiff_value = if decoder.bigtiff && 4 < self.count && self.count <= 8 {
|
let bigtiff_value = if decoder.bigtiff {
|
||||||
match (self.type_, self.count) {
|
match (self.type_, self.count) {
|
||||||
(Type::BYTE, n) => Some(offset_to_bytes(n as usize, self)?),
|
(Type::BYTE, 5) => Some(offset_to_bytes(5, self)?),
|
||||||
(Type::SBYTE, n) => Some(offset_to_sbytes(n as usize, self)?),
|
(Type::BYTE, 6) => Some(offset_to_bytes(6, self)?),
|
||||||
|
(Type::BYTE, 7) => Some(offset_to_bytes(7, self)?),
|
||||||
|
(Type::BYTE, 8) => Some(offset_to_bytes(8, self)?),
|
||||||
|
(Type::SBYTE, 5) => Some(offset_to_sbytes(5, self)?),
|
||||||
|
(Type::SBYTE, 6) => Some(offset_to_sbytes(6, self)?),
|
||||||
|
(Type::SBYTE, 7) => Some(offset_to_sbytes(7, self)?),
|
||||||
|
(Type::SBYTE, 8) => Some(offset_to_sbytes(8, self)?),
|
||||||
(Type::SHORT, 3) => {
|
(Type::SHORT, 3) => {
|
||||||
let mut r = self.r(bo);
|
let mut r = self.r(bo);
|
||||||
Some(List(vec![
|
Some(List(vec![
|
||||||
@@ -249,7 +255,6 @@ impl Entry {
|
|||||||
Ok(SRational(decoder.read_slong()?.into(), decoder.read_slong()?.into()))
|
Ok(SRational(decoder.read_slong()?.into(), decoder.read_slong()?.into()))
|
||||||
}),
|
}),
|
||||||
(Type::ASCII, n) => {
|
(Type::ASCII, n) => {
|
||||||
println!("ASCIII COUNT {}", n);
|
|
||||||
let n = usize::try_from(n)?;
|
let n = usize::try_from(n)?;
|
||||||
if n > limits.decoding_buffer_size {
|
if n > limits.decoding_buffer_size {
|
||||||
return Err(TiffError::LimitsExceeded);
|
return Err(TiffError::LimitsExceeded);
|
||||||
|
|||||||
+2
-2
@@ -528,7 +528,8 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
}
|
}
|
||||||
Some(offset) => self.goto_offset(offset)?,
|
Some(offset) => self.goto_offset(offset)?,
|
||||||
}
|
}
|
||||||
for _ in 0..self.read_short()? {
|
let num_tags = if self.bigtiff { self.read_long8()? } else { self.read_short()?.into() };
|
||||||
|
for _ in 0..num_tags {
|
||||||
let (tag, entry) = match self.read_entry()? {
|
let (tag, entry) = match self.read_entry()? {
|
||||||
Some(val) => val,
|
Some(val) => val,
|
||||||
None => continue, // Unknown data type in tag, skip
|
None => continue, // Unknown data type in tag, skip
|
||||||
@@ -545,7 +546,6 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
/// Tries to retrieve a tag.
|
/// Tries to retrieve a tag.
|
||||||
/// Return `Ok(None)` if the tag is not present.
|
/// Return `Ok(None)` if the tag is not present.
|
||||||
pub fn find_tag(&mut self, tag: Tag) -> TiffResult<Option<ifd::Value>> {
|
pub fn find_tag(&mut self, tag: Tag) -> TiffResult<Option<ifd::Value>> {
|
||||||
println!("IFD {:?}", self.ifd.as_ref().unwrap().get(&tag));
|
|
||||||
let entry = match self.ifd.as_ref().unwrap().get(&tag) {
|
let entry = match self.ifd.as_ref().unwrap().get(&tag) {
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
Some(entry) => entry.clone(),
|
Some(entry) => entry.clone(),
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
extern crate tiff;
|
||||||
|
|
||||||
|
use tiff::decoder::Decoder;
|
||||||
|
use tiff::tags::Tag;
|
||||||
|
use tiff::ColorType;
|
||||||
|
|
||||||
|
use std::fs::File;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
const TEST_IMAGE_DIR: &str = "./tests/images/bigtiff";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_big_tiff() {
|
||||||
|
let filenames = ["BigTIFF.tif", "BigTIFFMotorola.tif", "BigTIFFLong.tif"];
|
||||||
|
for filename in filenames.iter() {
|
||||||
|
let path = PathBuf::from(TEST_IMAGE_DIR).join(filename);
|
||||||
|
let img_file = File::open(path).expect("Cannot find test image!");
|
||||||
|
let mut decoder = Decoder::new(img_file).expect("Cannot create decoder");
|
||||||
|
assert_eq!(
|
||||||
|
decoder.dimensions().expect("Cannot get dimensions"),
|
||||||
|
(64, 64)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
decoder.colortype().expect("Cannot get colortype"),
|
||||||
|
ColorType::RGB(8)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
decoder
|
||||||
|
.get_tag_u64(Tag::StripOffsets)
|
||||||
|
.expect("Cannot get StripOffsets"),
|
||||||
|
16
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
decoder
|
||||||
|
.get_tag_u64(Tag::RowsPerStrip)
|
||||||
|
.expect("Cannot get RowsPerStrip"),
|
||||||
|
64
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
decoder
|
||||||
|
.get_tag_u64(Tag::StripByteCounts)
|
||||||
|
.expect("Cannot get StripByteCounts"),
|
||||||
|
12288
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in new issue
Block a user