1 use num_traits::{FromPrimitive, Num};
2 use std::collections::HashMap;
3 use std::io::{self, Read, Seek};
4 use std::cmp;
5 
6 use {ColorType, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError};
7 
8 use self::ifd::Directory;
9 
10 use self::stream::{ByteOrder, EndianReader, LZWReader, PackBitsReader, SmartReader};
11 
12 pub mod ifd;
13 mod stream;
14 
15 /// Result of a decoding process
16 #[derive(Debug)]
17 pub enum DecodingResult {
18     /// A vector of unsigned bytes
19     U8(Vec<u8>),
20     /// A vector of unsigned words
21     U16(Vec<u16>),
22 }
23 
24 impl DecodingResult {
new_u8(size: usize, limits: &Limits) -> TiffResult<DecodingResult>25     fn new_u8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
26         if size > limits.decoding_buffer_size {
27             Err(TiffError::LimitsExceeded)
28         } else {
29             Ok(DecodingResult::U8(vec![0; size]))
30         }
31     }
32 
new_u16(size: usize, limits: &Limits) -> TiffResult<DecodingResult>33     fn new_u16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
34         if size > limits.decoding_buffer_size / 2 {
35             Err(TiffError::LimitsExceeded)
36         } else {
37             Ok(DecodingResult::U16(vec![0; size]))
38         }
39     }
40 
as_buffer(&mut self, start: usize) -> DecodingBuffer41     pub fn as_buffer(&mut self, start: usize) -> DecodingBuffer {
42         match *self {
43             DecodingResult::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[start..]),
44             DecodingResult::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[start..]),
45         }
46     }
47 }
48 
49 // A buffer for image decoding
50 pub enum DecodingBuffer<'a> {
51     /// A slice of unsigned bytes
52     U8(&'a mut [u8]),
53     /// A slice of unsigned words
54     U16(&'a mut [u16]),
55 }
56 
57 impl<'a> DecodingBuffer<'a> {
len(&self) -> usize58     fn len(&self) -> usize {
59         match *self {
60             DecodingBuffer::U8(ref buf) => buf.len(),
61             DecodingBuffer::U16(ref buf) => buf.len(),
62         }
63     }
64 
byte_len(&self) -> usize65     fn byte_len(&self) -> usize {
66         match *self {
67             DecodingBuffer::U8(_) => 1,
68             DecodingBuffer::U16(_) => 2,
69         }
70     }
71 
copy<'b>(&'b mut self) -> DecodingBuffer<'b> where 'a: 'b,72     fn copy<'b>(&'b mut self) -> DecodingBuffer<'b>
73     where
74         'a: 'b,
75     {
76         match *self {
77             DecodingBuffer::U8(ref mut buf) => DecodingBuffer::U8(buf),
78             DecodingBuffer::U16(ref mut buf) => DecodingBuffer::U16(buf),
79         }
80     }
81 }
82 
83 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, FromPrimitive)]
84 pub enum PhotometricInterpretation {
85     WhiteIsZero = 0,
86     BlackIsZero = 1,
87     RGB = 2,
88     RGBPalette = 3,
89     TransparencyMask = 4,
90     CMYK = 5,
91     YCbCr = 6,
92     CIELab = 8,
93 }
94 
95 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, FromPrimitive)]
96 pub enum CompressionMethod {
97     None = 1,
98     Huffman = 2,
99     Fax3 = 3,
100     Fax4 = 4,
101     LZW = 5,
102     JPEG = 6,
103     PackBits = 0x8005,
104 }
105 
106 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, FromPrimitive)]
107 pub enum PlanarConfiguration {
108     Chunky = 1,
109     Planar = 2,
110 }
111 
112 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, FromPrimitive)]
113 enum Predictor {
114     None = 1,
115     Horizontal = 2,
116 }
117 
118 #[derive(Debug)]
119 struct StripDecodeState {
120     strip_index: usize,
121     strip_offsets: Vec<u32>,
122     strip_bytes: Vec<u32>,
123 }
124 
125 /// Decoding limits
126 #[derive(Clone, Debug)]
127 pub struct Limits {
128     /// The maximum size of any `DecodingResult` in bytes, the default is
129     /// 256MiB. If the entire image is decoded at once, then this will
130     /// be the maximum size of the image. If it is decoded one strip at a
131     /// time, this will be the maximum size of a strip.
132     decoding_buffer_size: usize,
133     /// The maximum size of any ifd value in bytes, the default is
134     /// 1MiB.
135     ifd_value_size: usize,
136 }
137 
138 impl Default for Limits {
default() -> Limits139     fn default() -> Limits {
140         Limits {
141             decoding_buffer_size: 256 * 1024 * 1024,
142             ifd_value_size: 1024 * 1024,
143         }
144     }
145 }
146 
147 /// The representation of a TIFF decoder
148 ///
149 /// Currently does not support decoding of interlaced images
150 #[derive(Debug)]
151 pub struct Decoder<R>
152 where
153     R: Read + Seek,
154 {
155     reader: SmartReader<R>,
156     byte_order: ByteOrder,
157     limits: Limits,
158     next_ifd: Option<u32>,
159     ifd: Option<Directory>,
160     width: u32,
161     height: u32,
162     bits_per_sample: Vec<u8>,
163     samples: u8,
164     photometric_interpretation: PhotometricInterpretation,
165     compression_method: CompressionMethod,
166     strip_decoder: Option<StripDecodeState>,
167 }
168 
169 trait Wrapping {
wrapping_add(&self, other: Self) -> Self170     fn wrapping_add(&self, other: Self) -> Self;
171 }
172 
173 impl Wrapping for u8 {
wrapping_add(&self, other: Self) -> Self174     fn wrapping_add(&self, other: Self) -> Self {
175         u8::wrapping_add(*self, other)
176     }
177 }
178 
179 impl Wrapping for u16 {
wrapping_add(&self, other: Self) -> Self180     fn wrapping_add(&self, other: Self) -> Self {
181         u16::wrapping_add(*self, other)
182     }
183 }
184 
rev_hpredict_nsamp<T>(image: &mut [T], size: (u32, u32), samples: usize) where T: Num + Copy + Wrapping,185 fn rev_hpredict_nsamp<T>(image: &mut [T], size: (u32, u32), samples: usize)
186 where
187     T: Num + Copy + Wrapping,
188 {
189     let width = size.0 as usize;
190     let height = size.1 as usize;
191     for row in 0..height {
192         for col in samples..width * samples {
193             let prev_pixel = image[(row * width * samples + col - samples)];
194             let pixel = &mut image[(row * width * samples + col)];
195             *pixel = pixel.wrapping_add(prev_pixel);
196         }
197     }
198 }
199 
rev_hpredict(image: DecodingBuffer, size: (u32, u32), color_type: ColorType) -> TiffResult<()>200 fn rev_hpredict(image: DecodingBuffer, size: (u32, u32), color_type: ColorType) -> TiffResult<()> {
201     let samples = match color_type {
202         ColorType::Gray(8) | ColorType::Gray(16) => 1,
203         ColorType::RGB(8) | ColorType::RGB(16) => 3,
204         ColorType::RGBA(8) | ColorType::RGBA(16) | ColorType::CMYK(8) => 4,
205         _ => {
206             return Err(TiffError::UnsupportedError(
207                 TiffUnsupportedError::HorizontalPredictor(color_type),
208             ))
209         }
210     };
211     match image {
212         DecodingBuffer::U8(buf) => {
213             rev_hpredict_nsamp(buf, size, samples);
214         }
215         DecodingBuffer::U16(buf) => {
216             rev_hpredict_nsamp(buf, size, samples);
217         }
218     }
219     Ok(())
220 }
221 
222 impl<R: Read + Seek> Decoder<R> {
223     /// Create a new decoder that decodes from the stream ```r```
new(r: R) -> TiffResult<Decoder<R>>224     pub fn new(r: R) -> TiffResult<Decoder<R>> {
225         Decoder {
226             reader: SmartReader::wrap(r, ByteOrder::LittleEndian),
227             byte_order: ByteOrder::LittleEndian,
228             limits: Default::default(),
229             next_ifd: None,
230             ifd: None,
231             width: 0,
232             height: 0,
233             bits_per_sample: vec![1],
234             samples: 1,
235             photometric_interpretation: PhotometricInterpretation::BlackIsZero,
236             compression_method: CompressionMethod::None,
237             strip_decoder: None,
238         }
239         .init()
240     }
241 
with_limits(mut self, limits: Limits) -> Decoder<R>242     pub fn with_limits(mut self, limits: Limits) -> Decoder<R> {
243         self.limits = limits;
244         self
245     }
246 
dimensions(&mut self) -> TiffResult<(u32, u32)>247     pub fn dimensions(&mut self) -> TiffResult<(u32, u32)> {
248         Ok((self.width, self.height))
249     }
250 
colortype(&mut self) -> TiffResult<ColorType>251     pub fn colortype(&mut self) -> TiffResult<ColorType> {
252         match self.photometric_interpretation {
253             // TODO: catch also [ 8, 8, 8, _] this does not work due to a bug in rust atm
254             PhotometricInterpretation::RGB if self.bits_per_sample == [8, 8, 8, 8] => {
255                 Ok(ColorType::RGBA(8))
256             }
257             PhotometricInterpretation::RGB if self.bits_per_sample == [8, 8, 8] => {
258                 Ok(ColorType::RGB(8))
259             }
260             PhotometricInterpretation::RGB if self.bits_per_sample == [16, 16, 16, 16] => {
261                 Ok(ColorType::RGBA(16))
262             }
263             PhotometricInterpretation::RGB if self.bits_per_sample == [16, 16, 16] => {
264                 Ok(ColorType::RGB(16))
265             }
266             PhotometricInterpretation::CMYK if self.bits_per_sample == [8, 8, 8, 8] => {
267                 Ok(ColorType::CMYK(8))
268             }
269             PhotometricInterpretation::BlackIsZero | PhotometricInterpretation::WhiteIsZero
270                 if self.bits_per_sample.len() == 1 =>
271             {
272                 Ok(ColorType::Gray(self.bits_per_sample[0]))
273             }
274 
275             // TODO: this is bad we should not fail at this point
276             _ => Err(TiffError::UnsupportedError(
277                 TiffUnsupportedError::InterpretationWithBits(
278                     self.photometric_interpretation,
279                     self.bits_per_sample.clone(),
280                 ),
281             )),
282         }
283     }
284 
read_header(&mut self) -> TiffResult<()>285     fn read_header(&mut self) -> TiffResult<()> {
286         let mut endianess = Vec::with_capacity(2);
287         try!(self.reader.by_ref().take(2).read_to_end(&mut endianess));
288         match &*endianess {
289             b"II" => {
290                 self.byte_order = ByteOrder::LittleEndian;
291                 self.reader.byte_order = ByteOrder::LittleEndian;
292             }
293             b"MM" => {
294                 self.byte_order = ByteOrder::BigEndian;
295                 self.reader.byte_order = ByteOrder::BigEndian;
296             }
297             _ => {
298                 return Err(TiffError::FormatError(
299                     TiffFormatError::TiffSignatureNotFound,
300                 ))
301             }
302         }
303         if try!(self.read_short()) != 42 {
304             return Err(TiffError::FormatError(
305                 TiffFormatError::TiffSignatureInvalid,
306             ));
307         }
308         self.next_ifd = match try!(self.read_long()) {
309             0 => None,
310             n => Some(n),
311         };
312         Ok(())
313     }
314 
315     /// Initializes the decoder.
init(mut self) -> TiffResult<Decoder<R>>316     pub fn init(mut self) -> TiffResult<Decoder<R>> {
317         try!(self.read_header());
318         self.next_image()?;
319         Ok(self)
320     }
321 
322     /// Reads in the next image.
323     /// If there is no further image in the TIFF file a format error is returned.
324     /// To determine whether there are more images call `TIFFDecoder::more_images` instead.
next_image(&mut self) -> TiffResult<()>325     pub fn next_image(&mut self) -> TiffResult<()> {
326         self.ifd = Some(try!(self.read_ifd()));
327         self.width = try!(self.get_tag_u32(ifd::Tag::ImageWidth));
328         self.height = try!(self.get_tag_u32(ifd::Tag::ImageLength));
329         self.strip_decoder = None;
330         self.photometric_interpretation = match FromPrimitive::from_u32(try!(
331             self.get_tag_u32(ifd::Tag::PhotometricInterpretation)
332         )) {
333             Some(val) => val,
334             None => {
335                 return Err(TiffError::UnsupportedError(
336                     TiffUnsupportedError::UnknownInterpretation,
337                 ))
338             }
339         };
340         if let Some(val) = try!(self.find_tag_u32(ifd::Tag::Compression)) {
341             match FromPrimitive::from_u32(val) {
342                 Some(method) => self.compression_method = method,
343                 None => {
344                     return Err(TiffError::UnsupportedError(
345                         TiffUnsupportedError::UnknownCompressionMethod,
346                     ))
347                 }
348             }
349         }
350         if let Some(val) = try!(self.find_tag_u32(ifd::Tag::SamplesPerPixel)) {
351             self.samples = val as u8
352         }
353         match self.samples {
354             1 => {
355                 if let Some(val) = try!(self.find_tag_u32(ifd::Tag::BitsPerSample)) {
356                     self.bits_per_sample = vec![val as u8]
357                 }
358             }
359             3 | 4 => {
360                 if let Some(val) = try!(self.find_tag_u32_vec(ifd::Tag::BitsPerSample)) {
361                     self.bits_per_sample = val.iter().map(|&v| v as u8).collect()
362                 }
363             }
364             _ => {
365                 return Err(TiffError::UnsupportedError(
366                     TiffUnsupportedError::UnsupportedSampleDepth(self.samples),
367                 ))
368             }
369         }
370         Ok(())
371     }
372 
373     /// Returns `true` if there is at least one more image available.
more_images(&self) -> bool374     pub fn more_images(&self) -> bool {
375         self.next_ifd.is_some()
376     }
377 
378     /// Returns the byte_order
byte_order(&self) -> ByteOrder379     pub fn byte_order(&self) -> ByteOrder {
380         self.byte_order
381     }
382 
383     /// Reads a TIFF short value
384     #[inline]
read_short(&mut self) -> Result<u16, io::Error>385     pub fn read_short(&mut self) -> Result<u16, io::Error> {
386         self.reader.read_u16()
387     }
388 
389     /// Reads a TIFF long value
390     #[inline]
read_long(&mut self) -> Result<u32, io::Error>391     pub fn read_long(&mut self) -> Result<u32, io::Error> {
392         self.reader.read_u32()
393     }
394 
395     /// Reads a string
396     #[inline]
read_string(&mut self, length: usize) -> TiffResult<String>397     pub fn read_string(&mut self, length: usize) -> TiffResult<String> {
398         let mut out = String::with_capacity(length);
399         self.reader.read_to_string(&mut out)?;
400         // Strings may be null-terminated, so we trim anything downstream of the null byte
401         let trimmed = out.bytes().take_while(|&n| n != 0).collect::<Vec<u8>>();
402         Ok(String::from_utf8(trimmed)?)
403     }
404 
405     /// Reads a TIFF IFA offset/value field
406     #[inline]
read_offset(&mut self) -> Result<[u8; 4], io::Error>407     pub fn read_offset(&mut self) -> Result<[u8; 4], io::Error> {
408         let mut val = [0; 4];
409         try!(self.reader.read_exact(&mut val));
410         Ok(val)
411     }
412 
413     /// Moves the cursor to the specified offset
414     #[inline]
goto_offset(&mut self, offset: u32) -> io::Result<()>415     pub fn goto_offset(&mut self, offset: u32) -> io::Result<()> {
416         self.reader
417             .seek(io::SeekFrom::Start(u64::from(offset)))
418             .map(|_| ())
419     }
420 
421     /// Reads a IFD entry.
422     // An IFD entry has four fields:
423     //
424     // Tag   2 bytes
425     // Type  2 bytes
426     // Count 4 bytes
427     // Value 4 bytes either a pointer the value itself
read_entry(&mut self) -> TiffResult<Option<(ifd::Tag, ifd::Entry)>>428     fn read_entry(&mut self) -> TiffResult<Option<(ifd::Tag, ifd::Entry)>> {
429         let tag = ifd::Tag::from_u16(try!(self.read_short()));
430         let type_: ifd::Type = match FromPrimitive::from_u16(try!(self.read_short())) {
431             Some(t) => t,
432             None => {
433                 // Unknown type. Skip this entry according to spec.
434                 try!(self.read_long());
435                 try!(self.read_long());
436                 return Ok(None);
437             }
438         };
439         Ok(Some((
440             tag,
441             ifd::Entry::new(
442                 type_,
443                 try!(self.read_long()),   // count
444                 try!(self.read_offset()), // offset
445             ),
446         )))
447     }
448 
449     /// Reads the next IFD
read_ifd(&mut self) -> TiffResult<Directory>450     fn read_ifd(&mut self) -> TiffResult<Directory> {
451         let mut dir: Directory = HashMap::new();
452         match self.next_ifd {
453             None => {
454                 return Err(TiffError::FormatError(
455                     TiffFormatError::ImageFileDirectoryNotFound,
456                 ))
457             }
458             Some(offset) => try!(self.goto_offset(offset)),
459         }
460         for _ in 0..try!(self.read_short()) {
461             let (tag, entry) = match try!(self.read_entry()) {
462                 Some(val) => val,
463                 None => continue, // Unknown data type in tag, skip
464             };
465             dir.insert(tag, entry);
466         }
467         self.next_ifd = match try!(self.read_long()) {
468             0 => None,
469             n => Some(n),
470         };
471         Ok(dir)
472     }
473 
474     /// Tries to retrieve a tag.
475     /// Return `Ok(None)` if the tag is not present.
find_tag(&mut self, tag: ifd::Tag) -> TiffResult<Option<ifd::Value>>476     pub fn find_tag(&mut self, tag: ifd::Tag) -> TiffResult<Option<ifd::Value>> {
477         let entry = match self.ifd.as_ref().unwrap().get(&tag) {
478             None => return Ok(None),
479             Some(entry) => entry.clone(),
480         };
481 
482         let limits = self.limits.clone();
483 
484         Ok(Some(try!(entry.val(&limits, self))))
485     }
486 
487     /// Tries to retrieve a tag and convert it to the desired type.
find_tag_u32(&mut self, tag: ifd::Tag) -> TiffResult<Option<u32>>488     pub fn find_tag_u32(&mut self, tag: ifd::Tag) -> TiffResult<Option<u32>> {
489         match self.find_tag(tag)? {
490             Some(val) => val.into_u32().map(Some),
491             None => Ok(None),
492         }
493     }
494 
495     /// Tries to retrieve a tag and convert it to the desired type.
find_tag_u32_vec(&mut self, tag: ifd::Tag) -> TiffResult<Option<Vec<u32>>>496     pub fn find_tag_u32_vec(&mut self, tag: ifd::Tag) -> TiffResult<Option<Vec<u32>>> {
497         match self.find_tag(tag)? {
498             Some(val) => val.into_u32_vec().map(Some),
499             None => Ok(None),
500         }
501     }
502 
503     /// Tries to retrieve a tag.
504     /// Returns an error if the tag is not present
get_tag(&mut self, tag: ifd::Tag) -> TiffResult<ifd::Value>505     pub fn get_tag(&mut self, tag: ifd::Tag) -> TiffResult<ifd::Value> {
506         match try!(self.find_tag(tag)) {
507             Some(val) => Ok(val),
508             None => Err(TiffError::FormatError(
509                 TiffFormatError::RequiredTagNotFound(tag),
510             )),
511         }
512     }
513 
514     /// Tries to retrieve a tag and convert it to the desired type.
get_tag_u32(&mut self, tag: ifd::Tag) -> TiffResult<u32>515     pub fn get_tag_u32(&mut self, tag: ifd::Tag) -> TiffResult<u32> {
516         self.get_tag(tag)?.into_u32()
517     }
518 
519     /// Tries to retrieve a tag and convert it to the desired type.
get_tag_u32_vec(&mut self, tag: ifd::Tag) -> TiffResult<Vec<u32>>520     pub fn get_tag_u32_vec(&mut self, tag: ifd::Tag) -> TiffResult<Vec<u32>> {
521         self.get_tag(tag)?.into_u32_vec()
522     }
523 
524     /// Decompresses the strip into the supplied buffer.
525     /// Returns the number of bytes read.
expand_strip<'a>( &mut self, buffer: DecodingBuffer<'a>, offset: u32, length: u32, max_uncompressed_length: usize, ) -> TiffResult<usize>526     fn expand_strip<'a>(
527         &mut self,
528         buffer: DecodingBuffer<'a>,
529         offset: u32,
530         length: u32,
531         max_uncompressed_length: usize,
532     ) -> TiffResult<usize> {
533         let color_type = try!(self.colortype());
534         try!(self.goto_offset(offset));
535         let (bytes, mut reader): (usize, Box<EndianReader>) = match self.compression_method {
536             CompressionMethod::None => {
537                 let order = self.reader.byte_order;
538                 (
539                     length as usize,
540                     Box::new(SmartReader::wrap(&mut self.reader, order)),
541                 )
542             }
543             CompressionMethod::LZW => {
544                 let (bytes, reader) = try!(LZWReader::new(
545                     &mut self.reader,
546                     length as usize,
547                     max_uncompressed_length
548                 ));
549                 (bytes, Box::new(reader))
550             }
551             CompressionMethod::PackBits => {
552                 let order = self.reader.byte_order;
553                 let (bytes, reader) = try!(PackBitsReader::new(
554                     &mut self.reader,
555                     order,
556                     length as usize
557                 ));
558                 (bytes, Box::new(reader))
559             }
560             method => {
561                 return Err(TiffError::UnsupportedError(
562                     TiffUnsupportedError::UnsupportedCompressionMethod(method),
563                 ))
564             }
565         };
566 
567         if bytes / buffer.byte_len() > max_uncompressed_length {
568             return Err(TiffError::FormatError(
569                 TiffFormatError::InconsistentSizesEncountered,
570             ));
571         }
572 
573         Ok(match (color_type, buffer) {
574             (ColorType::RGB(8), DecodingBuffer::U8(ref mut buffer))
575             | (ColorType::RGBA(8), DecodingBuffer::U8(ref mut buffer))
576             | (ColorType::CMYK(8), DecodingBuffer::U8(ref mut buffer)) => {
577                 try!(reader.read_exact(&mut buffer[..bytes]));
578                 bytes
579             }
580             (ColorType::RGBA(16), DecodingBuffer::U16(ref mut buffer))
581             | (ColorType::RGB(16), DecodingBuffer::U16(ref mut buffer)) => {
582                 try!(reader.read_u16_into(&mut buffer[..bytes / 2]));
583                 bytes / 2
584             }
585             (ColorType::Gray(16), DecodingBuffer::U16(ref mut buffer)) => {
586                 try!(reader.read_u16_into(&mut buffer[..bytes / 2]));
587                 if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero {
588                     for datum in buffer[..bytes / 2].iter_mut() {
589                         *datum = 0xffff - *datum
590                     }
591                 }
592                 bytes / 2
593             }
594             (ColorType::Gray(n), DecodingBuffer::U8(ref mut buffer)) if n <= 8 => {
595                 try!(reader.read_exact(&mut buffer[..bytes]));
596                 if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero {
597                     for byte in buffer[..bytes].iter_mut() {
598                         *byte = 0xff - *byte
599                     }
600                 }
601                 bytes
602             }
603             (type_, _) => {
604                 return Err(TiffError::UnsupportedError(
605                     TiffUnsupportedError::UnsupportedColorType(type_),
606                 ))
607             }
608         })
609     }
610 
611     /// Number of strips in image
strip_count(&mut self) -> TiffResult<u32>612     pub fn strip_count(&mut self) -> TiffResult<u32> {
613         let rows_per_strip = self
614             .get_tag_u32(ifd::Tag::RowsPerStrip)
615             .unwrap_or(self.height);
616 
617         if rows_per_strip == 0 {
618             return Ok(0);
619         }
620 
621         Ok((self.height + rows_per_strip - 1) / rows_per_strip)
622     }
623 
initialize_strip_decoder(&mut self) -> TiffResult<()>624     fn initialize_strip_decoder(&mut self) -> TiffResult<()> {
625         if self.strip_decoder.is_none() {
626             let strip_offsets = self.get_tag_u32_vec(ifd::Tag::StripOffsets)?;
627             let strip_bytes = self.get_tag_u32_vec(ifd::Tag::StripByteCounts)?;
628 
629             self.strip_decoder = Some(StripDecodeState {
630                 strip_index: 0,
631                 strip_offsets,
632                 strip_bytes,
633             });
634         }
635         Ok(())
636     }
637 
read_strip_to_buffer(&mut self, mut buffer: DecodingBuffer) -> TiffResult<()>638     pub fn read_strip_to_buffer(&mut self, mut buffer: DecodingBuffer) -> TiffResult<()> {
639         self.initialize_strip_decoder()?;
640 
641         let index = self.strip_decoder.as_ref().unwrap().strip_index;
642         let offset = *self
643             .strip_decoder
644             .as_ref()
645             .unwrap()
646             .strip_offsets
647             .get(index)
648             .ok_or(TiffError::FormatError(
649                 TiffFormatError::InconsistentSizesEncountered,
650             ))?;
651         let byte_count = *self
652             .strip_decoder
653             .as_ref()
654             .unwrap()
655             .strip_bytes
656             .get(index)
657             .ok_or(TiffError::FormatError(
658                 TiffFormatError::InconsistentSizesEncountered,
659             ))?;
660 
661         let rows_per_strip = self
662             .get_tag_u32(ifd::Tag::RowsPerStrip)
663             .unwrap_or(self.height) as usize;
664 
665         let strip_height = cmp::min(
666             rows_per_strip,
667             self.height as usize - index * rows_per_strip,
668         );
669 
670         let buffer_size = self.width as usize * strip_height * self.bits_per_sample.len();
671 
672         if buffer.len() < buffer_size || byte_count as usize / buffer.byte_len() > buffer_size {
673             return Err(TiffError::FormatError(
674                 TiffFormatError::InconsistentSizesEncountered,
675             ));
676         }
677 
678         let units_read = self.expand_strip(buffer.copy(), offset, byte_count, buffer_size)?;
679 
680         self.strip_decoder.as_mut().unwrap().strip_index += 1;
681 
682         if index as u32 == self.strip_count()? {
683             self.strip_decoder = None;
684         }
685 
686         if units_read < buffer_size {
687             return Err(TiffError::FormatError(
688                 TiffFormatError::InconsistentSizesEncountered,
689             ));
690         }
691         if let Ok(predictor) = self.get_tag_u32(ifd::Tag::Predictor) {
692             match FromPrimitive::from_u32(predictor) {
693                 Some(Predictor::None) => (),
694                 Some(Predictor::Horizontal) => {
695                     rev_hpredict(
696                         buffer.copy(),
697                         (self.width, strip_height as u32),
698                         self.colortype()?,
699                     )?;
700                 }
701                 None => {
702                     return Err(TiffError::FormatError(TiffFormatError::UnknownPredictor(
703                         predictor,
704                     )))
705                 }
706             }
707         }
708         Ok(())
709     }
710 
711     /// Read a single strip from the image and return it as a Vector
read_strip(&mut self) -> TiffResult<DecodingResult>712     pub fn read_strip(&mut self) -> TiffResult<DecodingResult> {
713         self.initialize_strip_decoder()?;
714         let index = self.strip_decoder.as_ref().unwrap().strip_index;
715 
716         let rows_per_strip = self
717             .get_tag_u32(ifd::Tag::RowsPerStrip)
718             .unwrap_or(self.height) as usize;
719 
720         let strip_height = cmp::min(
721             rows_per_strip,
722             self.height as usize - index * rows_per_strip,
723         );
724 
725         let buffer_size = self.width as usize * strip_height * self.bits_per_sample.iter().count();
726 
727         let mut result = match self.bits_per_sample.iter().cloned().max().unwrap_or(8) {
728             n if n <= 8 => DecodingResult::new_u8(buffer_size, &self.limits)?,
729             n if n <= 16 => DecodingResult::new_u16(buffer_size, &self.limits)?,
730             n => {
731                 return Err(TiffError::UnsupportedError(
732                     TiffUnsupportedError::UnsupportedBitsPerChannel(n),
733                 ))
734             }
735         };
736 
737         self.read_strip_to_buffer(result.as_buffer(0))?;
738 
739         Ok(result)
740     }
741 
742     /// Decodes the entire image and return it as a Vector
read_image(&mut self) -> TiffResult<DecodingResult>743     pub fn read_image(&mut self) -> TiffResult<DecodingResult> {
744         self.initialize_strip_decoder()?;
745         let rows_per_strip = self
746             .get_tag_u32(ifd::Tag::RowsPerStrip)
747             .unwrap_or(self.height) as usize;
748 
749         let samples_per_strip =
750             self.width as usize * rows_per_strip * self.bits_per_sample.iter().count();
751 
752         let buffer_size =
753             self.width as usize * self.height as usize * self.bits_per_sample.iter().count();
754 
755         let mut result = match self.bits_per_sample.iter().cloned().max().unwrap_or(8) {
756             n if n <= 8 => DecodingResult::new_u8(buffer_size, &self.limits)?,
757             n if n <= 16 => DecodingResult::new_u16(buffer_size, &self.limits)?,
758             n => {
759                 return Err(TiffError::UnsupportedError(
760                     TiffUnsupportedError::UnsupportedBitsPerChannel(n),
761                 ))
762             }
763         };
764 
765         for i in 0..self.strip_count()? as usize {
766             self.read_strip_to_buffer(result.as_buffer(samples_per_strip * i))?;
767         }
768 
769         Ok(result)
770     }
771 }
772