1use std::collections::{HashMap, HashSet};
2use std::convert::TryFrom;
3use std::io::{self, Read, Seek};
4use std::ops::Range;
5
6use crate::{
7 bytecast, ColorType, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError, UsageError,
8};
9
10use self::ifd::Directory;
11use self::image::Image;
12use crate::tags::{
13 CompressionMethod, PhotometricInterpretation, PlanarConfiguration, Predictor, SampleFormat,
14 Tag, Type,
15};
16
17use self::stream::{ByteOrder, EndianReader, SmartReader};
18
19pub mod ifd;
20mod image;
21mod stream;
22mod tag_reader;
23
24/// Result of a decoding process
25#[derive(Debug)]
26pub enum DecodingResult {
27 /// A vector of unsigned bytes
28 U8(Vec<u8>),
29 /// A vector of unsigned words
30 U16(Vec<u16>),
31 /// A vector of 32 bit unsigned ints
32 U32(Vec<u32>),
33 /// A vector of 64 bit unsigned ints
34 U64(Vec<u64>),
35 /// A vector of 32 bit IEEE floats
36 F32(Vec<f32>),
37 /// A vector of 64 bit IEEE floats
38 F64(Vec<f64>),
39 /// A vector of 8 bit signed ints
40 I8(Vec<i8>),
41 /// A vector of 16 bit signed ints
42 I16(Vec<i16>),
43 /// A vector of 32 bit signed ints
44 I32(Vec<i32>),
45 /// A vector of 64 bit signed ints
46 I64(Vec<i64>),
47}
48
49impl DecodingResult {
50 fn new_u8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
51 if size > limits.decoding_buffer_size {
52 Err(TiffError::LimitsExceeded)
53 } else {
54 Ok(DecodingResult::U8(vec![0; size]))
55 }
56 }
57
58 fn new_u16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
59 if size > limits.decoding_buffer_size / 2 {
60 Err(TiffError::LimitsExceeded)
61 } else {
62 Ok(DecodingResult::U16(vec![0; size]))
63 }
64 }
65
66 fn new_u32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
67 if size > limits.decoding_buffer_size / 4 {
68 Err(TiffError::LimitsExceeded)
69 } else {
70 Ok(DecodingResult::U32(vec![0; size]))
71 }
72 }
73
74 fn new_u64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
75 if size > limits.decoding_buffer_size / 8 {
76 Err(TiffError::LimitsExceeded)
77 } else {
78 Ok(DecodingResult::U64(vec![0; size]))
79 }
80 }
81
82 fn new_f32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
83 if size > limits.decoding_buffer_size / std::mem::size_of::<f32>() {
84 Err(TiffError::LimitsExceeded)
85 } else {
86 Ok(DecodingResult::F32(vec![0.0; size]))
87 }
88 }
89
90 fn new_f64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
91 if size > limits.decoding_buffer_size / std::mem::size_of::<f64>() {
92 Err(TiffError::LimitsExceeded)
93 } else {
94 Ok(DecodingResult::F64(vec![0.0; size]))
95 }
96 }
97
98 fn new_i8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
99 if size > limits.decoding_buffer_size / std::mem::size_of::<i8>() {
100 Err(TiffError::LimitsExceeded)
101 } else {
102 Ok(DecodingResult::I8(vec![0; size]))
103 }
104 }
105
106 fn new_i16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
107 if size > limits.decoding_buffer_size / 2 {
108 Err(TiffError::LimitsExceeded)
109 } else {
110 Ok(DecodingResult::I16(vec![0; size]))
111 }
112 }
113
114 fn new_i32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
115 if size > limits.decoding_buffer_size / 4 {
116 Err(TiffError::LimitsExceeded)
117 } else {
118 Ok(DecodingResult::I32(vec![0; size]))
119 }
120 }
121
122 fn new_i64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
123 if size > limits.decoding_buffer_size / 8 {
124 Err(TiffError::LimitsExceeded)
125 } else {
126 Ok(DecodingResult::I64(vec![0; size]))
127 }
128 }
129
130 pub fn as_buffer(&mut self, start: usize) -> DecodingBuffer {
131 match *self {
132 DecodingResult::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[start..]),
133 DecodingResult::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[start..]),
134 DecodingResult::U32(ref mut buf) => DecodingBuffer::U32(&mut buf[start..]),
135 DecodingResult::U64(ref mut buf) => DecodingBuffer::U64(&mut buf[start..]),
136 DecodingResult::F32(ref mut buf) => DecodingBuffer::F32(&mut buf[start..]),
137 DecodingResult::F64(ref mut buf) => DecodingBuffer::F64(&mut buf[start..]),
138 DecodingResult::I8(ref mut buf) => DecodingBuffer::I8(&mut buf[start..]),
139 DecodingResult::I16(ref mut buf) => DecodingBuffer::I16(&mut buf[start..]),
140 DecodingResult::I32(ref mut buf) => DecodingBuffer::I32(&mut buf[start..]),
141 DecodingResult::I64(ref mut buf) => DecodingBuffer::I64(&mut buf[start..]),
142 }
143 }
144}
145
146// A buffer for image decoding
147pub enum DecodingBuffer<'a> {
148 /// A slice of unsigned bytes
149 U8(&'a mut [u8]),
150 /// A slice of unsigned words
151 U16(&'a mut [u16]),
152 /// A slice of 32 bit unsigned ints
153 U32(&'a mut [u32]),
154 /// A slice of 64 bit unsigned ints
155 U64(&'a mut [u64]),
156 /// A slice of 32 bit IEEE floats
157 F32(&'a mut [f32]),
158 /// A slice of 64 bit IEEE floats
159 F64(&'a mut [f64]),
160 /// A slice of 8 bits signed ints
161 I8(&'a mut [i8]),
162 /// A slice of 16 bits signed ints
163 I16(&'a mut [i16]),
164 /// A slice of 32 bits signed ints
165 I32(&'a mut [i32]),
166 /// A slice of 64 bits signed ints
167 I64(&'a mut [i64]),
168}
169
170impl<'a> DecodingBuffer<'a> {
171 fn byte_len(&self) -> usize {
172 match *self {
173 DecodingBuffer::U8(_) => 1,
174 DecodingBuffer::U16(_) => 2,
175 DecodingBuffer::U32(_) => 4,
176 DecodingBuffer::U64(_) => 8,
177 DecodingBuffer::F32(_) => 4,
178 DecodingBuffer::F64(_) => 8,
179 DecodingBuffer::I8(_) => 1,
180 DecodingBuffer::I16(_) => 2,
181 DecodingBuffer::I32(_) => 4,
182 DecodingBuffer::I64(_) => 8,
183 }
184 }
185
186 fn copy<'b>(&'b mut self) -> DecodingBuffer<'b>
187 where
188 'a: 'b,
189 {
190 match *self {
191 DecodingBuffer::U8(ref mut buf) => DecodingBuffer::U8(buf),
192 DecodingBuffer::U16(ref mut buf) => DecodingBuffer::U16(buf),
193 DecodingBuffer::U32(ref mut buf) => DecodingBuffer::U32(buf),
194 DecodingBuffer::U64(ref mut buf) => DecodingBuffer::U64(buf),
195 DecodingBuffer::F32(ref mut buf) => DecodingBuffer::F32(buf),
196 DecodingBuffer::F64(ref mut buf) => DecodingBuffer::F64(buf),
197 DecodingBuffer::I8(ref mut buf) => DecodingBuffer::I8(buf),
198 DecodingBuffer::I16(ref mut buf) => DecodingBuffer::I16(buf),
199 DecodingBuffer::I32(ref mut buf) => DecodingBuffer::I32(buf),
200 DecodingBuffer::I64(ref mut buf) => DecodingBuffer::I64(buf),
201 }
202 }
203
204 fn subrange<'b>(&'b mut self, range: Range<usize>) -> DecodingBuffer<'b>
205 where
206 'a: 'b,
207 {
208 match *self {
209 DecodingBuffer::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[range]),
210 DecodingBuffer::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[range]),
211 DecodingBuffer::U32(ref mut buf) => DecodingBuffer::U32(&mut buf[range]),
212 DecodingBuffer::U64(ref mut buf) => DecodingBuffer::U64(&mut buf[range]),
213 DecodingBuffer::F32(ref mut buf) => DecodingBuffer::F32(&mut buf[range]),
214 DecodingBuffer::F64(ref mut buf) => DecodingBuffer::F64(&mut buf[range]),
215 DecodingBuffer::I8(ref mut buf) => DecodingBuffer::I8(&mut buf[range]),
216 DecodingBuffer::I16(ref mut buf) => DecodingBuffer::I16(&mut buf[range]),
217 DecodingBuffer::I32(ref mut buf) => DecodingBuffer::I32(&mut buf[range]),
218 DecodingBuffer::I64(ref mut buf) => DecodingBuffer::I64(&mut buf[range]),
219 }
220 }
221
222 fn as_bytes_mut(&mut self) -> &mut [u8] {
223 match self {
224 DecodingBuffer::U8(ref mut buf) => buf,
225 DecodingBuffer::I8(buf) => bytecast::i8_as_ne_mut_bytes(buf),
226 DecodingBuffer::U16(buf) => bytecast::u16_as_ne_mut_bytes(buf),
227 DecodingBuffer::I16(buf) => bytecast::i16_as_ne_mut_bytes(buf),
228 DecodingBuffer::U32(buf) => bytecast::u32_as_ne_mut_bytes(buf),
229 DecodingBuffer::I32(buf) => bytecast::i32_as_ne_mut_bytes(buf),
230 DecodingBuffer::U64(buf) => bytecast::u64_as_ne_mut_bytes(buf),
231 DecodingBuffer::I64(buf) => bytecast::i64_as_ne_mut_bytes(buf),
232 DecodingBuffer::F32(buf) => bytecast::f32_as_ne_mut_bytes(buf),
233 DecodingBuffer::F64(buf) => bytecast::f64_as_ne_mut_bytes(buf),
234 }
235 }
236}
237
238#[derive(Debug, Copy, Clone, PartialEq)]
239/// Chunk type of the internal representation
240pub enum ChunkType {
241 Strip,
242 Tile,
243}
244
245/// Decoding limits
246#[derive(Clone, Debug)]
247pub struct Limits {
248 /// The maximum size of any `DecodingResult` in bytes, the default is
249 /// 256MiB. If the entire image is decoded at once, then this will
250 /// be the maximum size of the image. If it is decoded one strip at a
251 /// time, this will be the maximum size of a strip.
252 pub decoding_buffer_size: usize,
253 /// The maximum size of any ifd value in bytes, the default is
254 /// 1MiB.
255 pub ifd_value_size: usize,
256 /// Maximum size for intermediate buffer which may be used to limit the amount of data read per
257 /// segment even if the entire image is decoded at once.
258 pub intermediate_buffer_size: usize,
259 /// The purpose of this is to prevent all the fields of the struct from
260 /// being public, as this would make adding new fields a major version
261 /// bump.
262 _non_exhaustive: (),
263}
264
265impl Limits {
266 /// A configuration that does not impose any limits.
267 ///
268 /// This is a good start if the caller only wants to impose selective limits, contrary to the
269 /// default limits which allows selectively disabling limits.
270 ///
271 /// Note that this configuration is likely to crash on excessively large images since,
272 /// naturally, the machine running the program does not have infinite memory.
273 pub fn unlimited() -> Limits {
274 Limits {
275 decoding_buffer_size: usize::max_value(),
276 ifd_value_size: usize::max_value(),
277 intermediate_buffer_size: usize::max_value(),
278 _non_exhaustive: (),
279 }
280 }
281}
282
283impl Default for Limits {
284 fn default() -> Limits {
285 Limits {
286 decoding_buffer_size: 256 * 1024 * 1024,
287 intermediate_buffer_size: 128 * 1024 * 1024,
288 ifd_value_size: 1024 * 1024,
289 _non_exhaustive: (),
290 }
291 }
292}
293
294/// The representation of a TIFF decoder
295///
296/// Currently does not support decoding of interlaced images
297#[derive(Debug)]
298pub struct Decoder<R>
299where
300 R: Read + Seek,
301{
302 reader: SmartReader<R>,
303 bigtiff: bool,
304 limits: Limits,
305 next_ifd: Option<u64>,
306 ifd_offsets: Vec<u64>,
307 seen_ifds: HashSet<u64>,
308 image: Image,
309}
310
311trait Wrapping {
312 fn wrapping_add(&self, other: Self) -> Self;
313}
314
315impl Wrapping for u8 {
316 fn wrapping_add(&self, other: Self) -> Self {
317 u8::wrapping_add(*self, rhs:other)
318 }
319}
320
321impl Wrapping for u16 {
322 fn wrapping_add(&self, other: Self) -> Self {
323 u16::wrapping_add(*self, rhs:other)
324 }
325}
326
327impl Wrapping for u32 {
328 fn wrapping_add(&self, other: Self) -> Self {
329 u32::wrapping_add(*self, rhs:other)
330 }
331}
332
333impl Wrapping for u64 {
334 fn wrapping_add(&self, other: Self) -> Self {
335 u64::wrapping_add(*self, rhs:other)
336 }
337}
338
339impl Wrapping for i8 {
340 fn wrapping_add(&self, other: Self) -> Self {
341 i8::wrapping_add(*self, rhs:other)
342 }
343}
344
345impl Wrapping for i16 {
346 fn wrapping_add(&self, other: Self) -> Self {
347 i16::wrapping_add(*self, rhs:other)
348 }
349}
350
351impl Wrapping for i32 {
352 fn wrapping_add(&self, other: Self) -> Self {
353 i32::wrapping_add(*self, rhs:other)
354 }
355}
356
357impl Wrapping for i64 {
358 fn wrapping_add(&self, other: Self) -> Self {
359 i64::wrapping_add(*self, rhs:other)
360 }
361}
362
363fn rev_hpredict_nsamp<T: Copy + Wrapping>(image: &mut [T], samples: usize) {
364 for col: usize in samples..image.len() {
365 image[col] = image[col].wrapping_add(image[col - samples]);
366 }
367}
368
369pub fn fp_predict_f32(input: &mut [u8], output: &mut [f32], samples: usize) {
370 rev_hpredict_nsamp(image:input, samples);
371 for i: usize in 0..output.len() {
372 // TODO: use f32::from_be_bytes() when we can (version 1.40)
373 output[i] = f32::from_bits(u32::from_be_bytes([
374 input[i],
375 input[input.len() / 4 + i],
376 input[input.len() / 4 * 2 + i],
377 input[input.len() / 4 * 3 + i],
378 ]));
379 }
380}
381
382pub fn fp_predict_f64(input: &mut [u8], output: &mut [f64], samples: usize) {
383 rev_hpredict_nsamp(image:input, samples);
384 for i: usize in 0..output.len() {
385 // TODO: use f64::from_be_bytes() when we can (version 1.40)
386 output[i] = f64::from_bits(u64::from_be_bytes([
387 input[i],
388 input[input.len() / 8 + i],
389 input[input.len() / 8 * 2 + i],
390 input[input.len() / 8 * 3 + i],
391 input[input.len() / 8 * 4 + i],
392 input[input.len() / 8 * 5 + i],
393 input[input.len() / 8 * 6 + i],
394 input[input.len() / 8 * 7 + i],
395 ]));
396 }
397}
398
399fn fix_endianness_and_predict(
400 mut image: DecodingBuffer,
401 samples: usize,
402 byte_order: ByteOrder,
403 predictor: Predictor,
404) {
405 match predictor {
406 Predictor::None => {
407 fix_endianness(&mut image, byte_order);
408 }
409 Predictor::Horizontal => {
410 fix_endianness(&mut image, byte_order);
411 match image {
412 DecodingBuffer::U8(buf) => rev_hpredict_nsamp(buf, samples),
413 DecodingBuffer::U16(buf) => rev_hpredict_nsamp(buf, samples),
414 DecodingBuffer::U32(buf) => rev_hpredict_nsamp(buf, samples),
415 DecodingBuffer::U64(buf) => rev_hpredict_nsamp(buf, samples),
416 DecodingBuffer::I8(buf) => rev_hpredict_nsamp(buf, samples),
417 DecodingBuffer::I16(buf) => rev_hpredict_nsamp(buf, samples),
418 DecodingBuffer::I32(buf) => rev_hpredict_nsamp(buf, samples),
419 DecodingBuffer::I64(buf) => rev_hpredict_nsamp(buf, samples),
420 DecodingBuffer::F32(_) | DecodingBuffer::F64(_) => {
421 unreachable!("Caller should have validated arguments. Please file a bug.")
422 }
423 }
424 }
425 Predictor::FloatingPoint => {
426 let mut buffer_copy = image.as_bytes_mut().to_vec();
427 match image {
428 DecodingBuffer::F32(buf) => fp_predict_f32(&mut buffer_copy, buf, samples),
429 DecodingBuffer::F64(buf) => fp_predict_f64(&mut buffer_copy, buf, samples),
430 _ => unreachable!("Caller should have validated arguments. Please file a bug."),
431 }
432 }
433 }
434}
435
436fn invert_colors_unsigned<T>(buffer: &mut [T], max: T)
437where
438 T: std::ops::Sub<T> + std::ops::Sub<Output = T> + Copy,
439{
440 for datum: &mut T in buffer.iter_mut() {
441 *datum = max - *datum
442 }
443}
444
445fn invert_colors_fp<T>(buffer: &mut [T], max: T)
446where
447 T: std::ops::Sub<T> + std::ops::Sub<Output = T> + Copy,
448{
449 for datum: &mut T in buffer.iter_mut() {
450 // FIXME: assumes [0, 1) range for floats
451 *datum = max - *datum
452 }
453}
454
455fn invert_colors(buf: &mut DecodingBuffer, color_type: ColorType) {
456 match (color_type, buf) {
457 (ColorType::Gray(64), DecodingBuffer::U64(ref mut buffer: &mut &mut [u64])) => {
458 invert_colors_unsigned(buffer, max:0xffff_ffff_ffff_ffff);
459 }
460 (ColorType::Gray(32), DecodingBuffer::U32(ref mut buffer: &mut &mut [u32])) => {
461 invert_colors_unsigned(buffer, max:0xffff_ffff);
462 }
463 (ColorType::Gray(16), DecodingBuffer::U16(ref mut buffer: &mut &mut [u16])) => {
464 invert_colors_unsigned(buffer, max:0xffff);
465 }
466 (ColorType::Gray(n: u8), DecodingBuffer::U8(ref mut buffer: &mut &mut [u8])) if n <= 8 => {
467 invert_colors_unsigned(buffer, max:0xff);
468 }
469 (ColorType::Gray(32), DecodingBuffer::F32(ref mut buffer: &mut &mut [f32])) => {
470 invert_colors_fp(buffer, max:1.0);
471 }
472 (ColorType::Gray(64), DecodingBuffer::F64(ref mut buffer: &mut &mut [f64])) => {
473 invert_colors_fp(buffer, max:1.0);
474 }
475 _ => {}
476 }
477}
478
479/// Fix endianness. If `byte_order` matches the host, then conversion is a no-op.
480fn fix_endianness(buf: &mut DecodingBuffer, byte_order: ByteOrder) {
481 match byte_order {
482 ByteOrder::LittleEndian => match buf {
483 DecodingBuffer::U8(_) | DecodingBuffer::I8(_) => {}
484 DecodingBuffer::U16(b) => b.iter_mut().for_each(|v| *v = u16::from_le(*v)),
485 DecodingBuffer::I16(b) => b.iter_mut().for_each(|v| *v = i16::from_le(*v)),
486 DecodingBuffer::U32(b) => b.iter_mut().for_each(|v| *v = u32::from_le(*v)),
487 DecodingBuffer::I32(b) => b.iter_mut().for_each(|v| *v = i32::from_le(*v)),
488 DecodingBuffer::U64(b) => b.iter_mut().for_each(|v| *v = u64::from_le(*v)),
489 DecodingBuffer::I64(b) => b.iter_mut().for_each(|v| *v = i64::from_le(*v)),
490 DecodingBuffer::F32(b) => b
491 .iter_mut()
492 .for_each(|v| *v = f32::from_bits(u32::from_le(v.to_bits()))),
493 DecodingBuffer::F64(b) => b
494 .iter_mut()
495 .for_each(|v| *v = f64::from_bits(u64::from_le(v.to_bits()))),
496 },
497 ByteOrder::BigEndian => match buf {
498 DecodingBuffer::U8(_) | DecodingBuffer::I8(_) => {}
499 DecodingBuffer::U16(b) => b.iter_mut().for_each(|v| *v = u16::from_be(*v)),
500 DecodingBuffer::I16(b) => b.iter_mut().for_each(|v| *v = i16::from_be(*v)),
501 DecodingBuffer::U32(b) => b.iter_mut().for_each(|v| *v = u32::from_be(*v)),
502 DecodingBuffer::I32(b) => b.iter_mut().for_each(|v| *v = i32::from_be(*v)),
503 DecodingBuffer::U64(b) => b.iter_mut().for_each(|v| *v = u64::from_be(*v)),
504 DecodingBuffer::I64(b) => b.iter_mut().for_each(|v| *v = i64::from_be(*v)),
505 DecodingBuffer::F32(b) => b
506 .iter_mut()
507 .for_each(|v| *v = f32::from_bits(u32::from_be(v.to_bits()))),
508 DecodingBuffer::F64(b) => b
509 .iter_mut()
510 .for_each(|v| *v = f64::from_bits(u64::from_be(v.to_bits()))),
511 },
512 };
513}
514
515impl<R: Read + Seek> Decoder<R> {
516 /// Create a new decoder that decodes from the stream ```r```
517 pub fn new(mut r: R) -> TiffResult<Decoder<R>> {
518 let mut endianess = Vec::with_capacity(2);
519 (&mut r).take(2).read_to_end(&mut endianess)?;
520 let byte_order = match &*endianess {
521 b"II" => ByteOrder::LittleEndian,
522 b"MM" => ByteOrder::BigEndian,
523 _ => {
524 return Err(TiffError::FormatError(
525 TiffFormatError::TiffSignatureNotFound,
526 ))
527 }
528 };
529 let mut reader = SmartReader::wrap(r, byte_order);
530
531 let bigtiff = match reader.read_u16()? {
532 42 => false,
533 43 => {
534 // Read bytesize of offsets (in bigtiff it's alway 8 but provide a way to move to 16 some day)
535 if reader.read_u16()? != 8 {
536 return Err(TiffError::FormatError(
537 TiffFormatError::TiffSignatureNotFound,
538 ));
539 }
540 // This constant should always be 0
541 if reader.read_u16()? != 0 {
542 return Err(TiffError::FormatError(
543 TiffFormatError::TiffSignatureNotFound,
544 ));
545 }
546 true
547 }
548 _ => {
549 return Err(TiffError::FormatError(
550 TiffFormatError::TiffSignatureInvalid,
551 ))
552 }
553 };
554 let next_ifd = if bigtiff {
555 Some(reader.read_u64()?)
556 } else {
557 Some(u64::from(reader.read_u32()?))
558 };
559
560 let mut seen_ifds = HashSet::new();
561 seen_ifds.insert(*next_ifd.as_ref().unwrap());
562 let ifd_offsets = vec![*next_ifd.as_ref().unwrap()];
563
564 let mut decoder = Decoder {
565 reader,
566 bigtiff,
567 limits: Default::default(),
568 next_ifd,
569 ifd_offsets,
570 seen_ifds,
571 image: Image {
572 ifd: None,
573 width: 0,
574 height: 0,
575 bits_per_sample: 1,
576 samples: 1,
577 sample_format: vec![SampleFormat::Uint],
578 photometric_interpretation: PhotometricInterpretation::BlackIsZero,
579 compression_method: CompressionMethod::None,
580 jpeg_tables: None,
581 predictor: Predictor::None,
582 chunk_type: ChunkType::Strip,
583 planar_config: PlanarConfiguration::Chunky,
584 strip_decoder: None,
585 tile_attributes: None,
586 chunk_offsets: Vec::new(),
587 chunk_bytes: Vec::new(),
588 },
589 };
590 decoder.next_image()?;
591 Ok(decoder)
592 }
593
594 pub fn with_limits(mut self, limits: Limits) -> Decoder<R> {
595 self.limits = limits;
596 self
597 }
598
599 pub fn dimensions(&mut self) -> TiffResult<(u32, u32)> {
600 Ok((self.image().width, self.image().height))
601 }
602
603 pub fn colortype(&mut self) -> TiffResult<ColorType> {
604 self.image().colortype()
605 }
606
607 fn image(&self) -> &Image {
608 &self.image
609 }
610
611 /// Loads the IFD at the specified index in the list, if one exists
612 pub fn seek_to_image(&mut self, ifd_index: usize) -> TiffResult<()> {
613 // Check whether we have seen this IFD before, if so then the index will be less than the length of the list of ifd offsets
614 if ifd_index >= self.ifd_offsets.len() {
615 // We possibly need to load in the next IFD
616 if self.next_ifd.is_none() {
617 return Err(TiffError::FormatError(
618 TiffFormatError::ImageFileDirectoryNotFound,
619 ));
620 }
621
622 loop {
623 // Follow the list until we find the one we want, or we reach the end, whichever happens first
624 let (_ifd, next_ifd) = self.next_ifd()?;
625
626 if next_ifd.is_none() {
627 break;
628 }
629
630 if ifd_index < self.ifd_offsets.len() {
631 break;
632 }
633 }
634 }
635
636 // If the index is within the list of ifds then we can load the selected image/IFD
637 if let Some(ifd_offset) = self.ifd_offsets.get(ifd_index) {
638 let (ifd, _next_ifd) = Self::read_ifd(&mut self.reader, self.bigtiff, *ifd_offset)?;
639
640 self.image = Image::from_reader(&mut self.reader, ifd, &self.limits, self.bigtiff)?;
641
642 Ok(())
643 } else {
644 Err(TiffError::FormatError(
645 TiffFormatError::ImageFileDirectoryNotFound,
646 ))
647 }
648 }
649
650 fn next_ifd(&mut self) -> TiffResult<(Directory, Option<u64>)> {
651 if self.next_ifd.is_none() {
652 return Err(TiffError::FormatError(
653 TiffFormatError::ImageFileDirectoryNotFound,
654 ));
655 }
656
657 let (ifd, next_ifd) = Self::read_ifd(
658 &mut self.reader,
659 self.bigtiff,
660 self.next_ifd.take().unwrap(),
661 )?;
662
663 if let Some(next) = next_ifd {
664 if !self.seen_ifds.insert(next) {
665 return Err(TiffError::FormatError(TiffFormatError::CycleInOffsets));
666 }
667 self.next_ifd = Some(next);
668 self.ifd_offsets.push(next);
669 }
670
671 Ok((ifd, next_ifd))
672 }
673
674 /// Reads in the next image.
675 /// If there is no further image in the TIFF file a format error is returned.
676 /// To determine whether there are more images call `TIFFDecoder::more_images` instead.
677 pub fn next_image(&mut self) -> TiffResult<()> {
678 let (ifd, _next_ifd) = self.next_ifd()?;
679
680 self.image = Image::from_reader(&mut self.reader, ifd, &self.limits, self.bigtiff)?;
681 Ok(())
682 }
683
684 /// Returns `true` if there is at least one more image available.
685 pub fn more_images(&self) -> bool {
686 self.next_ifd.is_some()
687 }
688
689 /// Returns the byte_order
690 pub fn byte_order(&self) -> ByteOrder {
691 self.reader.byte_order
692 }
693
694 #[inline]
695 pub fn read_ifd_offset(&mut self) -> Result<u64, io::Error> {
696 if self.bigtiff {
697 self.read_long8()
698 } else {
699 self.read_long().map(u64::from)
700 }
701 }
702
703 /// Reads a TIFF byte value
704 #[inline]
705 pub fn read_byte(&mut self) -> Result<u8, io::Error> {
706 let mut buf = [0; 1];
707 self.reader.read_exact(&mut buf)?;
708 Ok(buf[0])
709 }
710
711 /// Reads a TIFF short value
712 #[inline]
713 pub fn read_short(&mut self) -> Result<u16, io::Error> {
714 self.reader.read_u16()
715 }
716
717 /// Reads a TIFF sshort value
718 #[inline]
719 pub fn read_sshort(&mut self) -> Result<i16, io::Error> {
720 self.reader.read_i16()
721 }
722
723 /// Reads a TIFF long value
724 #[inline]
725 pub fn read_long(&mut self) -> Result<u32, io::Error> {
726 self.reader.read_u32()
727 }
728
729 /// Reads a TIFF slong value
730 #[inline]
731 pub fn read_slong(&mut self) -> Result<i32, io::Error> {
732 self.reader.read_i32()
733 }
734
735 /// Reads a TIFF float value
736 #[inline]
737 pub fn read_float(&mut self) -> Result<f32, io::Error> {
738 self.reader.read_f32()
739 }
740
741 /// Reads a TIFF double value
742 #[inline]
743 pub fn read_double(&mut self) -> Result<f64, io::Error> {
744 self.reader.read_f64()
745 }
746
747 #[inline]
748 pub fn read_long8(&mut self) -> Result<u64, io::Error> {
749 self.reader.read_u64()
750 }
751
752 #[inline]
753 pub fn read_slong8(&mut self) -> Result<i64, io::Error> {
754 self.reader.read_i64()
755 }
756
757 /// Reads a string
758 #[inline]
759 pub fn read_string(&mut self, length: usize) -> TiffResult<String> {
760 let mut out = vec![0; length];
761 self.reader.read_exact(&mut out)?;
762 // Strings may be null-terminated, so we trim anything downstream of the null byte
763 if let Some(first) = out.iter().position(|&b| b == 0) {
764 out.truncate(first);
765 }
766 Ok(String::from_utf8(out)?)
767 }
768
769 /// Reads a TIFF IFA offset/value field
770 #[inline]
771 pub fn read_offset(&mut self) -> TiffResult<[u8; 4]> {
772 if self.bigtiff {
773 return Err(TiffError::FormatError(
774 TiffFormatError::InconsistentSizesEncountered,
775 ));
776 }
777 let mut val = [0; 4];
778 self.reader.read_exact(&mut val)?;
779 Ok(val)
780 }
781
782 /// Reads a TIFF IFA offset/value field
783 #[inline]
784 pub fn read_offset_u64(&mut self) -> Result<[u8; 8], io::Error> {
785 let mut val = [0; 8];
786 self.reader.read_exact(&mut val)?;
787 Ok(val)
788 }
789
790 /// Moves the cursor to the specified offset
791 #[inline]
792 pub fn goto_offset(&mut self, offset: u32) -> io::Result<()> {
793 self.goto_offset_u64(offset.into())
794 }
795
796 #[inline]
797 pub fn goto_offset_u64(&mut self, offset: u64) -> io::Result<()> {
798 self.reader.seek(io::SeekFrom::Start(offset)).map(|_| ())
799 }
800
801 /// Reads a IFD entry.
802 // An IFD entry has four fields:
803 //
804 // Tag 2 bytes
805 // Type 2 bytes
806 // Count 4 bytes
807 // Value 4 bytes either a pointer the value itself
808 fn read_entry(
809 reader: &mut SmartReader<R>,
810 bigtiff: bool,
811 ) -> TiffResult<Option<(Tag, ifd::Entry)>> {
812 let tag = Tag::from_u16_exhaustive(reader.read_u16()?);
813 let type_ = match Type::from_u16(reader.read_u16()?) {
814 Some(t) => t,
815 None => {
816 // Unknown type. Skip this entry according to spec.
817 reader.read_u32()?;
818 reader.read_u32()?;
819 return Ok(None);
820 }
821 };
822 let entry = if bigtiff {
823 let mut offset = [0; 8];
824
825 let count = reader.read_u64()?;
826 reader.read_exact(&mut offset)?;
827 ifd::Entry::new_u64(type_, count, offset)
828 } else {
829 let mut offset = [0; 4];
830
831 let count = reader.read_u32()?;
832 reader.read_exact(&mut offset)?;
833 ifd::Entry::new(type_, count, offset)
834 };
835 Ok(Some((tag, entry)))
836 }
837
838 /// Reads the IFD starting at the indicated location.
839 fn read_ifd(
840 reader: &mut SmartReader<R>,
841 bigtiff: bool,
842 ifd_location: u64,
843 ) -> TiffResult<(Directory, Option<u64>)> {
844 reader.goto_offset(ifd_location)?;
845
846 let mut dir: Directory = HashMap::new();
847
848 let num_tags = if bigtiff {
849 reader.read_u64()?
850 } else {
851 reader.read_u16()?.into()
852 };
853 for _ in 0..num_tags {
854 let (tag, entry) = match Self::read_entry(reader, bigtiff)? {
855 Some(val) => val,
856 None => {
857 continue;
858 } // Unknown data type in tag, skip
859 };
860 dir.insert(tag, entry);
861 }
862
863 let next_ifd = if bigtiff {
864 reader.read_u64()?
865 } else {
866 reader.read_u32()?.into()
867 };
868
869 let next_ifd = match next_ifd {
870 0 => None,
871 _ => Some(next_ifd),
872 };
873
874 Ok((dir, next_ifd))
875 }
876
877 /// Tries to retrieve a tag.
878 /// Return `Ok(None)` if the tag is not present.
879 pub fn find_tag(&mut self, tag: Tag) -> TiffResult<Option<ifd::Value>> {
880 let entry = match self.image().ifd.as_ref().unwrap().get(&tag) {
881 None => return Ok(None),
882 Some(entry) => entry.clone(),
883 };
884
885 Ok(Some(entry.val(
886 &self.limits,
887 self.bigtiff,
888 &mut self.reader,
889 )?))
890 }
891
892 /// Tries to retrieve a tag and convert it to the desired unsigned type.
893 pub fn find_tag_unsigned<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<Option<T>> {
894 self.find_tag(tag)?
895 .map(|v| v.into_u64())
896 .transpose()?
897 .map(|value| {
898 T::try_from(value).map_err(|_| TiffFormatError::InvalidTagValueType(tag).into())
899 })
900 .transpose()
901 }
902
903 /// Tries to retrieve a vector of all a tag's values and convert them to
904 /// the desired unsigned type.
905 pub fn find_tag_unsigned_vec<T: TryFrom<u64>>(
906 &mut self,
907 tag: Tag,
908 ) -> TiffResult<Option<Vec<T>>> {
909 self.find_tag(tag)?
910 .map(|v| v.into_u64_vec())
911 .transpose()?
912 .map(|v| {
913 v.into_iter()
914 .map(|u| {
915 T::try_from(u).map_err(|_| TiffFormatError::InvalidTagValueType(tag).into())
916 })
917 .collect()
918 })
919 .transpose()
920 }
921
922 /// Tries to retrieve a tag and convert it to the desired unsigned type.
923 /// Returns an error if the tag is not present.
924 pub fn get_tag_unsigned<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<T> {
925 self.find_tag_unsigned(tag)?
926 .ok_or_else(|| TiffFormatError::RequiredTagNotFound(tag).into())
927 }
928
929 /// Tries to retrieve a tag.
930 /// Returns an error if the tag is not present
931 pub fn get_tag(&mut self, tag: Tag) -> TiffResult<ifd::Value> {
932 match self.find_tag(tag)? {
933 Some(val) => Ok(val),
934 None => Err(TiffError::FormatError(
935 TiffFormatError::RequiredTagNotFound(tag),
936 )),
937 }
938 }
939
940 /// Tries to retrieve a tag and convert it to the desired type.
941 pub fn get_tag_u32(&mut self, tag: Tag) -> TiffResult<u32> {
942 self.get_tag(tag)?.into_u32()
943 }
944 pub fn get_tag_u64(&mut self, tag: Tag) -> TiffResult<u64> {
945 self.get_tag(tag)?.into_u64()
946 }
947
948 /// Tries to retrieve a tag and convert it to the desired type.
949 pub fn get_tag_f32(&mut self, tag: Tag) -> TiffResult<f32> {
950 self.get_tag(tag)?.into_f32()
951 }
952
953 /// Tries to retrieve a tag and convert it to the desired type.
954 pub fn get_tag_f64(&mut self, tag: Tag) -> TiffResult<f64> {
955 self.get_tag(tag)?.into_f64()
956 }
957
958 /// Tries to retrieve a tag and convert it to the desired type.
959 pub fn get_tag_u32_vec(&mut self, tag: Tag) -> TiffResult<Vec<u32>> {
960 self.get_tag(tag)?.into_u32_vec()
961 }
962
963 pub fn get_tag_u16_vec(&mut self, tag: Tag) -> TiffResult<Vec<u16>> {
964 self.get_tag(tag)?.into_u16_vec()
965 }
966 pub fn get_tag_u64_vec(&mut self, tag: Tag) -> TiffResult<Vec<u64>> {
967 self.get_tag(tag)?.into_u64_vec()
968 }
969
970 /// Tries to retrieve a tag and convert it to the desired type.
971 pub fn get_tag_f32_vec(&mut self, tag: Tag) -> TiffResult<Vec<f32>> {
972 self.get_tag(tag)?.into_f32_vec()
973 }
974
975 /// Tries to retrieve a tag and convert it to the desired type.
976 pub fn get_tag_f64_vec(&mut self, tag: Tag) -> TiffResult<Vec<f64>> {
977 self.get_tag(tag)?.into_f64_vec()
978 }
979
980 /// Tries to retrieve a tag and convert it to a 8bit vector.
981 pub fn get_tag_u8_vec(&mut self, tag: Tag) -> TiffResult<Vec<u8>> {
982 self.get_tag(tag)?.into_u8_vec()
983 }
984
985 /// Tries to retrieve a tag and convert it to a ascii vector.
986 pub fn get_tag_ascii_string(&mut self, tag: Tag) -> TiffResult<String> {
987 self.get_tag(tag)?.into_string()
988 }
989
990 fn check_chunk_type(&self, expected: ChunkType) -> TiffResult<()> {
991 if expected != self.image().chunk_type {
992 return Err(TiffError::UsageError(UsageError::InvalidChunkType(
993 expected,
994 self.image().chunk_type,
995 )));
996 }
997
998 Ok(())
999 }
1000
1001 /// The chunk type (Strips / Tiles) of the image
1002 pub fn get_chunk_type(&self) -> ChunkType {
1003 self.image().chunk_type
1004 }
1005
1006 /// Number of strips in image
1007 pub fn strip_count(&mut self) -> TiffResult<u32> {
1008 self.check_chunk_type(ChunkType::Strip)?;
1009 let rows_per_strip = self.image().strip_decoder.as_ref().unwrap().rows_per_strip;
1010
1011 if rows_per_strip == 0 {
1012 return Ok(0);
1013 }
1014
1015 // rows_per_strip - 1 can never fail since we know it's at least 1
1016 let height = match self.image().height.checked_add(rows_per_strip - 1) {
1017 Some(h) => h,
1018 None => return Err(TiffError::IntSizeError),
1019 };
1020
1021 let strips = match self.image().planar_config {
1022 PlanarConfiguration::Chunky => height / rows_per_strip,
1023 PlanarConfiguration::Planar => height / rows_per_strip * self.image().samples as u32,
1024 };
1025
1026 Ok(strips)
1027 }
1028
1029 /// Number of tiles in image
1030 pub fn tile_count(&mut self) -> TiffResult<u32> {
1031 self.check_chunk_type(ChunkType::Tile)?;
1032 Ok(u32::try_from(self.image().chunk_offsets.len())?)
1033 }
1034
1035 pub fn read_chunk_to_buffer(
1036 &mut self,
1037 mut buffer: DecodingBuffer,
1038 chunk_index: u32,
1039 output_width: usize,
1040 ) -> TiffResult<()> {
1041 let offset = self.image.chunk_file_range(chunk_index)?.0;
1042 self.goto_offset_u64(offset)?;
1043
1044 let byte_order = self.reader.byte_order;
1045
1046 self.image.expand_chunk(
1047 &mut self.reader,
1048 buffer.copy(),
1049 output_width,
1050 byte_order,
1051 chunk_index,
1052 &self.limits,
1053 )?;
1054
1055 Ok(())
1056 }
1057
1058 fn result_buffer(&self, width: usize, height: usize) -> TiffResult<DecodingResult> {
1059 let buffer_size = match width
1060 .checked_mul(height)
1061 .and_then(|x| x.checked_mul(self.image().samples_per_pixel()))
1062 {
1063 Some(s) => s,
1064 None => return Err(TiffError::LimitsExceeded),
1065 };
1066
1067 let max_sample_bits = self.image().bits_per_sample;
1068 match self
1069 .image()
1070 .sample_format
1071 .first()
1072 .unwrap_or(&SampleFormat::Uint)
1073 {
1074 SampleFormat::Uint => match max_sample_bits {
1075 n if n <= 8 => DecodingResult::new_u8(buffer_size, &self.limits),
1076 n if n <= 16 => DecodingResult::new_u16(buffer_size, &self.limits),
1077 n if n <= 32 => DecodingResult::new_u32(buffer_size, &self.limits),
1078 n if n <= 64 => DecodingResult::new_u64(buffer_size, &self.limits),
1079 n => Err(TiffError::UnsupportedError(
1080 TiffUnsupportedError::UnsupportedBitsPerChannel(n),
1081 )),
1082 },
1083 SampleFormat::IEEEFP => match max_sample_bits {
1084 32 => DecodingResult::new_f32(buffer_size, &self.limits),
1085 64 => DecodingResult::new_f64(buffer_size, &self.limits),
1086 n => Err(TiffError::UnsupportedError(
1087 TiffUnsupportedError::UnsupportedBitsPerChannel(n),
1088 )),
1089 },
1090 SampleFormat::Int => match max_sample_bits {
1091 n if n <= 8 => DecodingResult::new_i8(buffer_size, &self.limits),
1092 n if n <= 16 => DecodingResult::new_i16(buffer_size, &self.limits),
1093 n if n <= 32 => DecodingResult::new_i32(buffer_size, &self.limits),
1094 n if n <= 64 => DecodingResult::new_i64(buffer_size, &self.limits),
1095 n => Err(TiffError::UnsupportedError(
1096 TiffUnsupportedError::UnsupportedBitsPerChannel(n),
1097 )),
1098 },
1099 format => Err(TiffUnsupportedError::UnsupportedSampleFormat(vec![*format]).into()),
1100 }
1101 }
1102
1103 /// Read the specified chunk (at index `chunk_index`) and return the binary data as a Vector.
1104 pub fn read_chunk(&mut self, chunk_index: u32) -> TiffResult<DecodingResult> {
1105 let data_dims = self.image().chunk_data_dimensions(chunk_index)?;
1106
1107 let mut result = self.result_buffer(data_dims.0 as usize, data_dims.1 as usize)?;
1108
1109 self.read_chunk_to_buffer(result.as_buffer(0), chunk_index, data_dims.0 as usize)?;
1110
1111 Ok(result)
1112 }
1113
1114 /// Returns the default chunk size for the current image. Any given chunk in the image is at most as large as
1115 /// the value returned here. For the size of the data (chunk minus padding), use `chunk_data_dimensions`.
1116 pub fn chunk_dimensions(&self) -> (u32, u32) {
1117 self.image().chunk_dimensions().unwrap()
1118 }
1119
1120 /// Returns the size of the data in the chunk with the specified index. This is the default size of the chunk,
1121 /// minus any padding.
1122 pub fn chunk_data_dimensions(&self, chunk_index: u32) -> (u32, u32) {
1123 self.image()
1124 .chunk_data_dimensions(chunk_index)
1125 .expect("invalid chunk_index")
1126 }
1127
1128 /// Decodes the entire image and return it as a Vector
1129 pub fn read_image(&mut self) -> TiffResult<DecodingResult> {
1130 let width = self.image().width;
1131 let height = self.image().height;
1132 let mut result = self.result_buffer(width as usize, height as usize)?;
1133 if width == 0 || height == 0 {
1134 return Ok(result);
1135 }
1136
1137 let chunk_dimensions = self.image().chunk_dimensions()?;
1138 let chunk_dimensions = (
1139 chunk_dimensions.0.min(width),
1140 chunk_dimensions.1.min(height),
1141 );
1142 if chunk_dimensions.0 == 0 || chunk_dimensions.1 == 0 {
1143 return Err(TiffError::FormatError(
1144 TiffFormatError::InconsistentSizesEncountered,
1145 ));
1146 }
1147
1148 let samples = self.image().samples_per_pixel();
1149 if samples == 0 {
1150 return Err(TiffError::FormatError(
1151 TiffFormatError::InconsistentSizesEncountered,
1152 ));
1153 }
1154
1155 let chunks_across = ((width - 1) / chunk_dimensions.0 + 1) as usize;
1156 let strip_samples = width as usize * chunk_dimensions.1 as usize * samples;
1157
1158 let image_chunks = self.image().chunk_offsets.len() / self.image().strips_per_pixel();
1159 // For multi-band images, only the first band is read.
1160 // Possible improvements:
1161 // * pass requested band as parameter
1162 // * collect bands to a RGB encoding result in case of RGB bands
1163 for chunk in 0..image_chunks {
1164 self.goto_offset_u64(self.image().chunk_offsets[chunk])?;
1165
1166 let x = chunk % chunks_across;
1167 let y = chunk / chunks_across;
1168 let buffer_offset = y * strip_samples + x * chunk_dimensions.0 as usize * samples;
1169 let byte_order = self.reader.byte_order;
1170 self.image.expand_chunk(
1171 &mut self.reader,
1172 result.as_buffer(buffer_offset).copy(),
1173 width as usize,
1174 byte_order,
1175 chunk as u32,
1176 &self.limits,
1177 )?;
1178 }
1179
1180 Ok(result)
1181 }
1182}
1183