diff --git a/src/encoder/mod.rs b/src/encoder/mod.rs index 96ba414..ab626cf 100644 --- a/src/encoder/mod.rs +++ b/src/encoder/mod.rs @@ -1,6 +1,7 @@ use byteorder::NativeEndian; use std::collections::BTreeMap; use std::io::{Seek, Write}; +use std::mem; use decoder::ifd::{self, Tag}; use error::{TiffError, TiffFormatError, TiffResult}; @@ -351,6 +352,8 @@ impl TiffEncoder { }; NativeEndian::write_header(&mut encoder.writer)?; + // blank the IFD offset location + encoder.writer.write_u32(0)?; Ok(encoder) } @@ -417,9 +420,9 @@ pub struct DirectoryEncoder<'a, W: 'a + Write + Seek> { impl<'a, W: 'a + Write + Seek> DirectoryEncoder<'a, W> { fn new(writer: &'a mut TiffWriter) -> TiffResult> { + // the previous word is the IFD offset position + let ifd_pointer_pos = writer.offset() - mem::size_of::() as u64; writer.pad_word_boundary()?; - let ifd_pointer_pos = writer.offset(); - writer.write_u32(0)?; Ok(DirectoryEncoder { writer, dropped: false, diff --git a/src/encoder/writer.rs b/src/encoder/writer.rs index 78a128d..ba4c4c5 100644 --- a/src/encoder/writer.rs +++ b/src/encoder/writer.rs @@ -98,6 +98,7 @@ impl TiffWriter { let padding = [0, 0, 0]; let padd_len = 4 - (self.offset % 4); self.writer.write_all(&padding[..padd_len as usize])?; + self.offset += padd_len; } Ok(()) diff --git a/tests/encode_images.rs b/tests/encode_images.rs index 2ae8c1c..6256cec 100644 --- a/tests/encode_images.rs +++ b/tests/encode_images.rs @@ -260,4 +260,35 @@ fn test_signed() { 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]); } -} \ No newline at end of file +} + +#[test] +/// check multipage image handling +fn test_multipage_image() { + let mut img_file = Cursor::new(Vec::new()); + + { + // first create a multipage image with 2 images + let mut img_encoder = TiffEncoder::new(&mut img_file).unwrap(); + + // write first grayscale image (2x2 16-bit) + let img1: Vec = [1, 2, 3, 4].to_vec(); + img_encoder.write_image::(2, 2, &img1[..]); + // write second grayscale image (3x3 8-bit) + let img2: Vec = [9, 8, 7, 6, 5, 4, 3, 2, 1].to_vec(); + img_encoder.write_image::(3, 3, &img2[..]); + } + + // seek to the beginning of the file, so that it can be decoded + img_file.seek(SeekFrom::Start(0)).unwrap(); + + { + let mut img_decoder = Decoder::new(&mut img_file).unwrap(); + + // check the dimensions of the image in the first page + assert_eq!(img_decoder.dimensions().unwrap(), (2, 2)); + img_decoder.next_image().unwrap(); + // check the dimensions of the image in the second page + assert_eq!(img_decoder.dimensions().unwrap(), (3, 3)); + } +}