Skip to main content

tiff/decoder/
mod.rs

1use std::alloc::{Layout, LayoutError};
2use std::collections::BTreeMap;
3use std::io::{self, Read, Seek};
4use std::num::NonZeroUsize;
5
6use crate::tags::{
7    CompressionMethod, IfdPointer, PhotometricInterpretation, PlanarConfiguration, Predictor,
8    SampleFormat, Tag, Type, ValueBuffer,
9};
10use crate::{
11    bytecast, ColorType, Directory, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError,
12    UsageError,
13};
14use half::f16;
15
16use self::image::Image;
17use self::stream::{ByteOrder, EndianReader};
18
19mod cycles;
20pub mod ifd;
21mod image;
22mod stream;
23mod tag_reader;
24
25/// An index referring to a (rectangular) region of an image.
26#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
27pub struct TiffCodingUnit(pub u32);
28
29/// Result of a decoding process
30#[derive(Debug)]
31pub enum DecodingResult {
32    /// A vector of unsigned bytes
33    U8(Vec<u8>),
34    /// A vector of unsigned words
35    U16(Vec<u16>),
36    /// A vector of 32 bit unsigned ints
37    U32(Vec<u32>),
38    /// A vector of 64 bit unsigned ints
39    U64(Vec<u64>),
40    /// A vector of 16 bit IEEE floats (held in u16)
41    F16(Vec<f16>),
42    /// A vector of 32 bit IEEE floats
43    F32(Vec<f32>),
44    /// A vector of 64 bit IEEE floats
45    F64(Vec<f64>),
46    /// A vector of 8 bit signed ints
47    I8(Vec<i8>),
48    /// A vector of 16 bit signed ints
49    I16(Vec<i16>),
50    /// A vector of 32 bit signed ints
51    I32(Vec<i32>),
52    /// A vector of 64 bit signed ints
53    I64(Vec<i64>),
54}
55
56impl DecodingResult {
57    /// Reallocate the buffer to decode all planes of the indicated layout.
58    pub fn resize_to(
59        &mut self,
60        buffer: &BufferLayoutPreference,
61        limits: &Limits,
62    ) -> Result<(), TiffError> {
63        let sample_type = buffer.sample_type.ok_or(TiffError::UnsupportedError(
64            TiffUnsupportedError::UnknownInterpretation,
65        ))?;
66
67        let extent = sample_type.extent_for_bytes(buffer.complete_len);
68        self.resize_to_extent(extent, limits)
69    }
70
71    fn resize_to_extent(
72        &mut self,
73        extent: DecodingExtent,
74        limits: &Limits,
75    ) -> Result<(), TiffError> {
76        // FIXME: we *can* reuse the allocation sometimes.
77        *self = extent.to_result_buffer(limits)?;
78        Ok(())
79    }
80
81    fn new<T: Default + Copy>(
82        size: usize,
83        limits: &Limits,
84        from_fn: fn(Vec<T>) -> Self,
85    ) -> TiffResult<DecodingResult> {
86        if size > limits.decoding_buffer_size / core::mem::size_of::<T>() {
87            Err(TiffError::LimitsExceeded)
88        } else {
89            Ok(from_fn(vec![T::default(); size]))
90        }
91    }
92
93    fn new_u8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
94        Self::new(size, limits, DecodingResult::U8)
95    }
96
97    fn new_u16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
98        Self::new(size, limits, DecodingResult::U16)
99    }
100
101    fn new_u32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
102        Self::new(size, limits, DecodingResult::U32)
103    }
104
105    fn new_u64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
106        Self::new(size, limits, DecodingResult::U64)
107    }
108
109    fn new_f32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
110        Self::new(size, limits, DecodingResult::F32)
111    }
112
113    fn new_f64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
114        Self::new(size, limits, DecodingResult::F64)
115    }
116
117    fn new_f16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
118        Self::new(size, limits, DecodingResult::F16)
119    }
120
121    fn new_i8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
122        Self::new(size, limits, DecodingResult::I8)
123    }
124
125    fn new_i16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
126        Self::new(size, limits, DecodingResult::I16)
127    }
128
129    fn new_i32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
130        Self::new(size, limits, DecodingResult::I32)
131    }
132
133    fn new_i64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
134        Self::new(size, limits, DecodingResult::I64)
135    }
136
137    /// Get a view of this buffer starting from the nth _sample_ of the current type.
138    pub fn as_buffer(&mut self, start: usize) -> DecodingBuffer<'_> {
139        match *self {
140            DecodingResult::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[start..]),
141            DecodingResult::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[start..]),
142            DecodingResult::U32(ref mut buf) => DecodingBuffer::U32(&mut buf[start..]),
143            DecodingResult::U64(ref mut buf) => DecodingBuffer::U64(&mut buf[start..]),
144            DecodingResult::F16(ref mut buf) => DecodingBuffer::F16(&mut buf[start..]),
145            DecodingResult::F32(ref mut buf) => DecodingBuffer::F32(&mut buf[start..]),
146            DecodingResult::F64(ref mut buf) => DecodingBuffer::F64(&mut buf[start..]),
147            DecodingResult::I8(ref mut buf) => DecodingBuffer::I8(&mut buf[start..]),
148            DecodingResult::I16(ref mut buf) => DecodingBuffer::I16(&mut buf[start..]),
149            DecodingResult::I32(ref mut buf) => DecodingBuffer::I32(&mut buf[start..]),
150            DecodingResult::I64(ref mut buf) => DecodingBuffer::I64(&mut buf[start..]),
151        }
152    }
153}
154
155// A buffer for image decoding
156pub enum DecodingBuffer<'a> {
157    /// A slice of unsigned bytes
158    U8(&'a mut [u8]),
159    /// A slice of unsigned words
160    U16(&'a mut [u16]),
161    /// A slice of 32 bit unsigned ints
162    U32(&'a mut [u32]),
163    /// A slice of 64 bit unsigned ints
164    U64(&'a mut [u64]),
165    /// A slice of 16 bit IEEE floats
166    F16(&'a mut [f16]),
167    /// A slice of 32 bit IEEE floats
168    F32(&'a mut [f32]),
169    /// A slice of 64 bit IEEE floats
170    F64(&'a mut [f64]),
171    /// A slice of 8 bits signed ints
172    I8(&'a mut [i8]),
173    /// A slice of 16 bits signed ints
174    I16(&'a mut [i16]),
175    /// A slice of 32 bits signed ints
176    I32(&'a mut [i32]),
177    /// A slice of 64 bits signed ints
178    I64(&'a mut [i64]),
179}
180
181impl<'a> DecodingBuffer<'a> {
182    pub fn as_bytes(&self) -> &[u8] {
183        match self {
184            DecodingBuffer::U8(buf) => buf,
185            DecodingBuffer::I8(buf) => bytecast::i8_as_ne_bytes(buf),
186            DecodingBuffer::U16(buf) => bytecast::u16_as_ne_bytes(buf),
187            DecodingBuffer::I16(buf) => bytecast::i16_as_ne_bytes(buf),
188            DecodingBuffer::U32(buf) => bytecast::u32_as_ne_bytes(buf),
189            DecodingBuffer::I32(buf) => bytecast::i32_as_ne_bytes(buf),
190            DecodingBuffer::U64(buf) => bytecast::u64_as_ne_bytes(buf),
191            DecodingBuffer::I64(buf) => bytecast::i64_as_ne_bytes(buf),
192            DecodingBuffer::F16(buf) => bytecast::f16_as_ne_bytes(buf),
193            DecodingBuffer::F32(buf) => bytecast::f32_as_ne_bytes(buf),
194            DecodingBuffer::F64(buf) => bytecast::f64_as_ne_bytes(buf),
195        }
196    }
197
198    pub fn as_bytes_mut(&mut self) -> &mut [u8] {
199        match self {
200            DecodingBuffer::U8(buf) => buf,
201            DecodingBuffer::I8(buf) => bytecast::i8_as_ne_mut_bytes(buf),
202            DecodingBuffer::U16(buf) => bytecast::u16_as_ne_mut_bytes(buf),
203            DecodingBuffer::I16(buf) => bytecast::i16_as_ne_mut_bytes(buf),
204            DecodingBuffer::U32(buf) => bytecast::u32_as_ne_mut_bytes(buf),
205            DecodingBuffer::I32(buf) => bytecast::i32_as_ne_mut_bytes(buf),
206            DecodingBuffer::U64(buf) => bytecast::u64_as_ne_mut_bytes(buf),
207            DecodingBuffer::I64(buf) => bytecast::i64_as_ne_mut_bytes(buf),
208            DecodingBuffer::F16(buf) => bytecast::f16_as_ne_mut_bytes(buf),
209            DecodingBuffer::F32(buf) => bytecast::f32_as_ne_mut_bytes(buf),
210            DecodingBuffer::F64(buf) => bytecast::f64_as_ne_mut_bytes(buf),
211        }
212    }
213
214    pub fn byte_len(&self) -> usize {
215        self.as_bytes().len()
216    }
217}
218
219#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
220pub enum DecodingSampleType {
221    U8,
222    U16,
223    U32,
224    U64,
225    F16,
226    F32,
227    F64,
228    I8,
229    I16,
230    I32,
231    I64,
232}
233
234impl DecodingSampleType {
235    fn extent_for_bytes(self, bytes: usize) -> DecodingExtent {
236        match self {
237            DecodingSampleType::U8 => DecodingExtent::U8(bytes),
238            DecodingSampleType::U16 => DecodingExtent::U16(bytes.div_ceil(2)),
239            DecodingSampleType::U32 => DecodingExtent::U32(bytes.div_ceil(4)),
240            DecodingSampleType::U64 => DecodingExtent::U64(bytes.div_ceil(8)),
241            DecodingSampleType::I8 => DecodingExtent::I8(bytes),
242            DecodingSampleType::I16 => DecodingExtent::I16(bytes.div_ceil(2)),
243            DecodingSampleType::I32 => DecodingExtent::I32(bytes.div_ceil(4)),
244            DecodingSampleType::I64 => DecodingExtent::I64(bytes.div_ceil(8)),
245            DecodingSampleType::F16 => DecodingExtent::F16(bytes.div_ceil(2)),
246            DecodingSampleType::F32 => DecodingExtent::F32(bytes.div_ceil(4)),
247            DecodingSampleType::F64 => DecodingExtent::F64(bytes.div_ceil(8)),
248        }
249    }
250}
251
252/// Information on the byte buffer that should be supplied to the decoder.
253///
254/// This is relevant for [`Decoder::read_image_bytes`] and [`Decoder::read_chunk_bytes`] where the
255/// caller provided buffer must fit the expectations of the decoder to be filled with data from the
256/// current image.
257#[non_exhaustive]
258#[derive(Debug, Clone)]
259pub struct BufferLayoutPreference {
260    /// Minimum byte size of the buffer to read image data.
261    pub len: usize,
262    /// The interpretation of each sample in the image.
263    ///
264    /// We only support a uniform sample layout. Detailed information for mixed colors may be added
265    /// in the future and will become available by explicit query. The same goes for the bit-depth
266    /// of samples that must also be uniform.
267    pub sample_format: SampleFormat,
268    /// The type representation for each sample. Only available for depths and formats which the
269    /// library can describe.
270    pub sample_type: Option<DecodingSampleType>,
271    /// Minimum number of bytes to represent a row of image data of the requested content.
272    pub row_stride: Option<NonZeroUsize>,
273    /// Number of planes in the image.
274    pub planes: usize,
275    /// Number of bytes used to represent one plane.
276    pub plane_stride: Option<NonZeroUsize>,
277    /// Number of bytes of data when reading all planes.
278    pub complete_len: usize,
279}
280
281impl BufferLayoutPreference {
282    fn from_planes(layout: &image::PlaneLayout) -> Self {
283        BufferLayoutPreference {
284            len: layout.readout.plane_stride,
285            row_stride: core::num::NonZeroUsize::new(layout.readout.row_stride),
286            planes: layout.plane_offsets.len(),
287            plane_stride: core::num::NonZeroUsize::new(layout.readout.plane_stride),
288            complete_len: layout.total_bytes,
289            sample_format: layout.readout.sample_format,
290            sample_type: Self::sample_type(layout.readout.sample_format, layout.readout.color),
291        }
292    }
293
294    fn sample_type(sample_format: SampleFormat, color: ColorType) -> Option<DecodingSampleType> {
295        Some(match sample_format {
296            SampleFormat::Uint => match color.bit_depth() {
297                n if n <= 8 => DecodingSampleType::U8,
298                n if n <= 16 => DecodingSampleType::U16,
299                n if n <= 32 => DecodingSampleType::U32,
300                n if n <= 64 => DecodingSampleType::U64,
301                _ => return None,
302            },
303            SampleFormat::IEEEFP => match color.bit_depth() {
304                16 => DecodingSampleType::F16,
305                32 => DecodingSampleType::F32,
306                64 => DecodingSampleType::F64,
307                _ => return None,
308            },
309            SampleFormat::Int => match color.bit_depth() {
310                n if n <= 8 => DecodingSampleType::I8,
311                n if n <= 16 => DecodingSampleType::I16,
312                n if n <= 32 => DecodingSampleType::I32,
313                n if n <= 64 => DecodingSampleType::I64,
314                _ => return None,
315            },
316            _other => {
317                return None;
318            }
319        })
320    }
321}
322
323impl image::ReadoutLayout {
324    // FIXME: when planes are not homogenous (i.e. subsampled or differing depths) then the
325    // `readout_for_size` or `to_plane_layout` needs a parameter to determine the planes being
326    // read instead of assuming a constant repeated size for them.
327    fn result_extent_for_planes(
328        self: &image::ReadoutLayout,
329        planes: core::ops::Range<u16>,
330    ) -> TiffResult<DecodingExtent> {
331        let buffer = self.to_plane_layout()?;
332
333        // The layout is for all planes. So restrict ourselves to the planes that were requested.
334        let offset = match buffer.plane_offsets.get(usize::from(planes.start)) {
335            Some(n) => *n,
336            None => {
337                return Err(TiffError::UsageError(UsageError::InvalidPlaneIndex(
338                    planes.start,
339                )))
340            }
341        };
342
343        let end = match buffer.plane_offsets.get(usize::from(planes.end)) {
344            Some(n) => *n,
345            None => buffer.total_bytes,
346        };
347
348        let buffer_bytes = end - offset;
349        let bits_per_sample = self.color.bit_depth();
350
351        let Some(sample_type) = BufferLayoutPreference::sample_type(self.sample_format, self.color)
352        else {
353            if matches!(
354                self.sample_format,
355                SampleFormat::Uint | SampleFormat::Int | SampleFormat::IEEEFP
356            ) {
357                return Err(TiffError::UnsupportedError(
358                    TiffUnsupportedError::UnsupportedSampleDepth(bits_per_sample),
359                ));
360            } else {
361                return Err(TiffError::UnsupportedError(
362                    TiffUnsupportedError::UnsupportedSampleFormat(vec![self.sample_format]),
363                ));
364            }
365        };
366
367        Ok(sample_type.extent_for_bytes(buffer_bytes))
368    }
369
370    #[inline(always)]
371    fn assert_min_layout<T>(&self, buffer: &[T]) -> TiffResult<()> {
372        if core::mem::size_of_val(buffer) < self.plane_stride {
373            Err(TiffError::UsageError(
374                UsageError::InsufficientOutputBufferSize {
375                    needed: self.plane_stride,
376                    provided: buffer.len(),
377                },
378            ))
379        } else {
380            Ok(())
381        }
382    }
383}
384
385/// The count and matching discriminant for a `DecodingBuffer`.
386#[derive(Clone)]
387enum DecodingExtent {
388    U8(usize),
389    U16(usize),
390    U32(usize),
391    U64(usize),
392    F16(usize),
393    F32(usize),
394    F64(usize),
395    I8(usize),
396    I16(usize),
397    I32(usize),
398    I64(usize),
399}
400
401impl DecodingExtent {
402    fn to_result_buffer(&self, limits: &Limits) -> TiffResult<DecodingResult> {
403        match *self {
404            DecodingExtent::U8(count) => DecodingResult::new_u8(count, limits),
405            DecodingExtent::U16(count) => DecodingResult::new_u16(count, limits),
406            DecodingExtent::U32(count) => DecodingResult::new_u32(count, limits),
407            DecodingExtent::U64(count) => DecodingResult::new_u64(count, limits),
408            DecodingExtent::F16(count) => DecodingResult::new_f16(count, limits),
409            DecodingExtent::F32(count) => DecodingResult::new_f32(count, limits),
410            DecodingExtent::F64(count) => DecodingResult::new_f64(count, limits),
411            DecodingExtent::I8(count) => DecodingResult::new_i8(count, limits),
412            DecodingExtent::I16(count) => DecodingResult::new_i16(count, limits),
413            DecodingExtent::I32(count) => DecodingResult::new_i32(count, limits),
414            DecodingExtent::I64(count) => DecodingResult::new_i64(count, limits),
415        }
416    }
417
418    fn preferred_layout(self) -> TiffResult<Layout> {
419        fn overflow(_: LayoutError) -> TiffError {
420            TiffError::LimitsExceeded
421        }
422
423        match self {
424            DecodingExtent::U8(count) => Layout::array::<u8>(count),
425            DecodingExtent::U16(count) => Layout::array::<u16>(count),
426            DecodingExtent::U32(count) => Layout::array::<u32>(count),
427            DecodingExtent::U64(count) => Layout::array::<u64>(count),
428            DecodingExtent::F16(count) => Layout::array::<f16>(count),
429            DecodingExtent::F32(count) => Layout::array::<f32>(count),
430            DecodingExtent::F64(count) => Layout::array::<f64>(count),
431            DecodingExtent::I8(count) => Layout::array::<i8>(count),
432            DecodingExtent::I16(count) => Layout::array::<i16>(count),
433            DecodingExtent::I32(count) => Layout::array::<i32>(count),
434            DecodingExtent::I64(count) => Layout::array::<i64>(count),
435        }
436        .map_err(overflow)
437    }
438
439    fn sample_type(&self) -> DecodingSampleType {
440        match *self {
441            DecodingExtent::U8(_) => DecodingSampleType::U8,
442            DecodingExtent::U16(_) => DecodingSampleType::U16,
443            DecodingExtent::U32(_) => DecodingSampleType::U32,
444            DecodingExtent::U64(_) => DecodingSampleType::U64,
445            DecodingExtent::F16(_) => DecodingSampleType::F16,
446            DecodingExtent::F32(_) => DecodingSampleType::F32,
447            DecodingExtent::F64(_) => DecodingSampleType::F64,
448            DecodingExtent::I8(_) => DecodingSampleType::I8,
449            DecodingExtent::I16(_) => DecodingSampleType::I16,
450            DecodingExtent::I32(_) => DecodingSampleType::I32,
451            DecodingExtent::I64(_) => DecodingSampleType::I64,
452        }
453    }
454}
455
456#[derive(Debug, Copy, Clone, PartialEq)]
457/// Chunk type of the internal representation
458pub enum ChunkType {
459    Strip,
460    Tile,
461}
462
463/// Decoding limits
464#[derive(Clone, Debug)]
465#[non_exhaustive]
466pub struct Limits {
467    /// The maximum size of any `DecodingResult` in bytes, the default is
468    /// 256MiB. If the entire image is decoded at once, then this will
469    /// be the maximum size of the image. If it is decoded one strip at a
470    /// time, this will be the maximum size of a strip.
471    pub decoding_buffer_size: usize,
472    /// The maximum size of any ifd value in bytes, the default is
473    /// 1MiB.
474    pub ifd_value_size: usize,
475    /// Maximum size for intermediate buffer which may be used to limit the amount of data read per
476    /// segment even if the entire image is decoded at once.
477    pub intermediate_buffer_size: usize,
478}
479
480impl Limits {
481    /// A configuration that does not impose any limits.
482    ///
483    /// This is a good start if the caller only wants to impose selective limits, contrary to the
484    /// default limits which allows selectively disabling limits.
485    ///
486    /// Note that this configuration is likely to crash on excessively large images since,
487    /// naturally, the machine running the program does not have infinite memory.
488    pub fn unlimited() -> Limits {
489        Limits {
490            decoding_buffer_size: usize::MAX,
491            ifd_value_size: usize::MAX,
492            intermediate_buffer_size: usize::MAX,
493        }
494    }
495}
496
497impl Default for Limits {
498    fn default() -> Limits {
499        Limits {
500            decoding_buffer_size: 256 * 1024 * 1024,
501            intermediate_buffer_size: 128 * 1024 * 1024,
502            ifd_value_size: 1024 * 1024,
503        }
504    }
505}
506
507/// The representation of a TIFF decoder
508///
509/// Currently does not support decoding of interlaced images
510#[derive(Debug)]
511pub struct Decoder<R>
512where
513    R: Read + Seek,
514{
515    /// There are grouped for borrow checker reasons. This allows us to implement methods that
516    /// borrow the stream access and the other fields mutably at the same time.
517    value_reader: ValueReader<R>,
518    current_ifd: Option<IfdPointer>,
519    next_ifd: Option<IfdPointer>,
520    /// The IFDs we visited already in this chain of IFDs.
521    ifd_offsets: Vec<IfdPointer>,
522    /// Map from the ifd into the `ifd_offsets` ordered list.
523    seen_ifds: cycles::IfdCycles,
524    image: Image,
525}
526
527/// All the information needed to read and interpret byte slices from the underlying file, i.e. to
528/// turn an entry of a tag into an `ifd::Value` or otherwise fetch arrays of similar types. Used
529/// only as the type of the field [`Decoder::value_reader`] and passed to submodules.
530#[derive(Debug)]
531struct ValueReader<R> {
532    reader: EndianReader<R>,
533    bigtiff: bool,
534    limits: Limits,
535}
536
537/// Reads a directory's tag values from an underlying stream.
538pub struct IfdDecoder<'lt> {
539    inner: tag_reader::TagReader<'lt, dyn tag_reader::EntryDecoder + 'lt>,
540}
541
542fn rev_hpredict_nsamp(buf: &mut [u8], bit_depth: u8, samples: u16) {
543    fn one_byte_predict<const N: usize>(buf: &mut [u8]) {
544        for i in N..buf.len() {
545            buf[i] = buf[i].wrapping_add(buf[i - N]);
546        }
547    }
548
549    fn two_bytes_predict<const N: usize>(buf: &mut [u8]) {
550        for i in (2 * N..buf.len()).step_by(2) {
551            let v = u16::from_ne_bytes(buf[i..][..2].try_into().unwrap());
552            let p = u16::from_ne_bytes(buf[i - 2 * N..][..2].try_into().unwrap());
553            buf[i..][..2].copy_from_slice(&(v.wrapping_add(p)).to_ne_bytes());
554        }
555    }
556
557    fn four_bytes_predict<const N: usize>(buf: &mut [u8]) {
558        for i in (N * 4..buf.len()).step_by(4) {
559            let v = u32::from_ne_bytes(buf[i..][..4].try_into().unwrap());
560            let p = u32::from_ne_bytes(buf[i - 4 * N..][..4].try_into().unwrap());
561            buf[i..][..4].copy_from_slice(&(v.wrapping_add(p)).to_ne_bytes());
562        }
563    }
564
565    let samples = usize::from(samples);
566
567    match (bit_depth, samples) {
568        // Note we can't use `windows` or so due to the overlap between each iteration. We split
569        // the cases by the samples / lookback constant so that each is optimized individually.
570        // This is more code generated but each loop can then have a different vectorization
571        // strategy.
572        (0..=8, 1) => one_byte_predict::<1>(buf),
573        (0..=8, 2) => one_byte_predict::<2>(buf),
574        (0..=8, 3) => one_byte_predict::<3>(buf),
575        (0..=8, 4) => one_byte_predict::<4>(buf),
576        // The generic, sub-optimal case for the above.
577        (0..=8, _) => {
578            for i in samples..buf.len() {
579                buf[i] = buf[i].wrapping_add(buf[i - samples]);
580            }
581        }
582        (9..=16, 1) => {
583            two_bytes_predict::<1>(buf);
584        }
585        (9..=16, 2) => {
586            two_bytes_predict::<2>(buf);
587        }
588        (9..=16, 3) => {
589            two_bytes_predict::<3>(buf);
590        }
591        (9..=16, 4) => {
592            two_bytes_predict::<4>(buf);
593        }
594        (9..=16, _) => {
595            for i in (samples * 2..buf.len()).step_by(2) {
596                let v = u16::from_ne_bytes(buf[i..][..2].try_into().unwrap());
597                let p = u16::from_ne_bytes(buf[i - 2 * samples..][..2].try_into().unwrap());
598                buf[i..][..2].copy_from_slice(&(v.wrapping_add(p)).to_ne_bytes());
599            }
600        }
601        (17..=32, 1) => {
602            four_bytes_predict::<1>(buf);
603        }
604        (17..=32, 2) => {
605            four_bytes_predict::<2>(buf);
606        }
607        (17..=32, 3) => {
608            four_bytes_predict::<3>(buf);
609        }
610        (17..=32, 4) => {
611            four_bytes_predict::<4>(buf);
612        }
613        (17..=32, _) => {
614            for i in (samples * 4..buf.len()).step_by(4) {
615                let v = u32::from_ne_bytes(buf[i..][..4].try_into().unwrap());
616                let p = u32::from_ne_bytes(buf[i - 4 * samples..][..4].try_into().unwrap());
617                buf[i..][..4].copy_from_slice(&(v.wrapping_add(p)).to_ne_bytes());
618            }
619        }
620        (33..=64, _) => {
621            for i in (samples * 8..buf.len()).step_by(8) {
622                let v = u64::from_ne_bytes(buf[i..][..8].try_into().unwrap());
623                let p = u64::from_ne_bytes(buf[i - 8 * samples..][..8].try_into().unwrap());
624                buf[i..][..8].copy_from_slice(&(v.wrapping_add(p)).to_ne_bytes());
625            }
626        }
627        _ => {
628            unreachable!("Caller should have validated arguments. Please file a bug.")
629        }
630    }
631}
632
633fn predict_f32(input: &mut [u8], output: &mut [u8], samples: u16) {
634    let samples = usize::from(samples);
635
636    for i in samples..input.len() {
637        input[i] = input[i].wrapping_add(input[i - samples]);
638    }
639
640    for (i, chunk) in output.chunks_mut(4).enumerate() {
641        chunk.copy_from_slice(&u32::to_ne_bytes(u32::from_be_bytes([
642            input[i],
643            input[input.len() / 4 + i],
644            input[input.len() / 4 * 2 + i],
645            input[input.len() / 4 * 3 + i],
646        ])));
647    }
648}
649
650fn predict_f16(input: &mut [u8], output: &mut [u8], samples: u16) {
651    let samples = usize::from(samples);
652
653    for i in samples..input.len() {
654        input[i] = input[i].wrapping_add(input[i - samples]);
655    }
656
657    for (i, chunk) in output.chunks_mut(2).enumerate() {
658        chunk.copy_from_slice(&u16::to_ne_bytes(u16::from_be_bytes([
659            input[i],
660            input[input.len() / 2 + i],
661        ])));
662    }
663}
664
665fn predict_f64(input: &mut [u8], output: &mut [u8], samples: u16) {
666    let samples = usize::from(samples);
667
668    for i in samples..input.len() {
669        input[i] = input[i].wrapping_add(input[i - samples]);
670    }
671
672    for (i, chunk) in output.chunks_mut(8).enumerate() {
673        chunk.copy_from_slice(&u64::to_ne_bytes(u64::from_be_bytes([
674            input[i],
675            input[input.len() / 8 + i],
676            input[input.len() / 8 * 2 + i],
677            input[input.len() / 8 * 3 + i],
678            input[input.len() / 8 * 4 + i],
679            input[input.len() / 8 * 5 + i],
680            input[input.len() / 8 * 6 + i],
681            input[input.len() / 8 * 7 + i],
682        ])));
683    }
684}
685
686fn fix_endianness_and_predict(
687    buf: &mut [u8],
688    bit_depth: u8,
689    samples: u16,
690    byte_order: ByteOrder,
691    predictor: Predictor,
692) {
693    match predictor {
694        Predictor::None => {
695            fix_endianness(buf, byte_order, bit_depth);
696        }
697        Predictor::Horizontal => {
698            fix_endianness(buf, byte_order, bit_depth);
699            rev_hpredict_nsamp(buf, bit_depth, samples);
700        }
701        Predictor::FloatingPoint => {
702            let mut buffer_copy = buf.to_vec();
703            match bit_depth {
704                16 => predict_f16(&mut buffer_copy, buf, samples),
705                32 => predict_f32(&mut buffer_copy, buf, samples),
706                64 => predict_f64(&mut buffer_copy, buf, samples),
707                _ => unreachable!("Caller should have validated arguments. Please file a bug."),
708            }
709        }
710    }
711}
712
713fn invert_colors(
714    buf: &mut [u8],
715    color_type: ColorType,
716    sample_format: SampleFormat,
717) -> TiffResult<()> {
718    match (color_type, sample_format) {
719        // Where pixels do not cross a byte boundary
720        (ColorType::Gray(1 | 2 | 4 | 8), SampleFormat::Uint) => {
721            for x in buf {
722                // Equivalent to both of the following:
723                //
724                // *x = 0xff - *x
725                // *x = !*x
726                //
727                // since -x = !x+1
728                *x = !*x;
729            }
730        }
731        (ColorType::Gray(16), SampleFormat::Uint) => {
732            for x in buf.chunks_mut(2) {
733                let v = u16::from_ne_bytes(x.try_into().unwrap());
734                x.copy_from_slice(&(0xffff - v).to_ne_bytes());
735            }
736        }
737        (ColorType::Gray(32), SampleFormat::Uint) => {
738            for x in buf.chunks_mut(4) {
739                let v = u32::from_ne_bytes(x.try_into().unwrap());
740                x.copy_from_slice(&(0xffff_ffff - v).to_ne_bytes());
741            }
742        }
743        (ColorType::Gray(64), SampleFormat::Uint) => {
744            for x in buf.chunks_mut(8) {
745                let v = u64::from_ne_bytes(x.try_into().unwrap());
746                x.copy_from_slice(&(0xffff_ffff_ffff_ffff - v).to_ne_bytes());
747            }
748        }
749        (ColorType::Gray(32), SampleFormat::IEEEFP) => {
750            for x in buf.chunks_mut(4) {
751                let v = f32::from_ne_bytes(x.try_into().unwrap());
752                x.copy_from_slice(&(1.0 - v).to_ne_bytes());
753            }
754        }
755        (ColorType::Gray(64), SampleFormat::IEEEFP) => {
756            for x in buf.chunks_mut(8) {
757                let v = f64::from_ne_bytes(x.try_into().unwrap());
758                x.copy_from_slice(&(1.0 - v).to_ne_bytes());
759            }
760        }
761        _ => {
762            return Err(TiffError::UnsupportedError(
763                TiffUnsupportedError::UnknownInterpretation,
764            ))
765        }
766    }
767
768    Ok(())
769}
770
771/// Fix endianness. If `byte_order` matches the host, then conversion is a no-op.
772fn fix_endianness(buf: &mut [u8], byte_order: ByteOrder, bit_depth: u8) {
773    let host = ByteOrder::native();
774
775    let class = match bit_depth {
776        0..=8 => crate::tags::EndianBytes::One,
777        9..=16 => crate::tags::EndianBytes::Two,
778        17..=32 => crate::tags::EndianBytes::Four,
779        _ => crate::tags::EndianBytes::Eight,
780    };
781
782    host.convert_endian_bytes(class, buf, byte_order);
783}
784
785impl<R: Read + Seek> Decoder<R> {
786    pub fn new(mut r: R) -> TiffResult<Decoder<R>> {
787        let mut endianess = Vec::with_capacity(2);
788        (&mut r).take(2).read_to_end(&mut endianess)?;
789        let byte_order = match &*endianess {
790            b"II" => ByteOrder::LittleEndian,
791            b"MM" => ByteOrder::BigEndian,
792            _ => {
793                return Err(TiffError::FormatError(
794                    TiffFormatError::TiffSignatureNotFound,
795                ))
796            }
797        };
798        let mut reader = EndianReader::new(r, byte_order);
799
800        let bigtiff = match reader.read_u16()? {
801            42 => false,
802            43 => {
803                // Read bytesize of offsets (in bigtiff it's alway 8 but provide a way to move to 16 some day)
804                if reader.read_u16()? != 8 {
805                    return Err(TiffError::FormatError(
806                        TiffFormatError::TiffSignatureNotFound,
807                    ));
808                }
809                // This constant should always be 0
810                if reader.read_u16()? != 0 {
811                    return Err(TiffError::FormatError(
812                        TiffFormatError::TiffSignatureNotFound,
813                    ));
814                }
815                true
816            }
817            _ => {
818                return Err(TiffError::FormatError(
819                    TiffFormatError::TiffSignatureInvalid,
820                ))
821            }
822        };
823
824        let next_ifd = if bigtiff {
825            Some(reader.read_u64()?)
826        } else {
827            Some(u64::from(reader.read_u32()?))
828        }
829        .map(IfdPointer);
830
831        let current_ifd = *next_ifd.as_ref().unwrap();
832        let ifd_offsets = vec![current_ifd];
833
834        let mut decoder = Decoder {
835            value_reader: ValueReader {
836                reader,
837                bigtiff,
838                limits: Default::default(),
839            },
840            next_ifd,
841            ifd_offsets,
842            current_ifd: None,
843            seen_ifds: cycles::IfdCycles::new(),
844            image: Image {
845                ifd: None,
846                width: 0,
847                height: 0,
848                bits_per_sample: 1,
849                samples: 1,
850                extra_samples: vec![],
851                photometric_samples: 1,
852                sample_format: SampleFormat::Uint,
853                photometric_interpretation: PhotometricInterpretation::BlackIsZero,
854                compression_method: CompressionMethod::None,
855                jpeg_tables: None,
856                predictor: Predictor::None,
857                chunk_type: ChunkType::Strip,
858                planar_config: PlanarConfiguration::Chunky,
859                strip_decoder: None,
860                tile_attributes: None,
861                chunk_offsets: Vec::new(),
862                chunk_bytes: Vec::new(),
863                chroma_subsampling: (2, 2),
864            },
865        };
866        decoder.next_image()?;
867        Ok(decoder)
868    }
869
870    pub fn with_limits(mut self, limits: Limits) -> Decoder<R> {
871        self.value_reader.limits = limits;
872        self
873    }
874
875    pub fn dimensions(&mut self) -> TiffResult<(u32, u32)> {
876        Ok((self.image().width, self.image().height))
877    }
878
879    pub fn colortype(&mut self) -> TiffResult<ColorType> {
880        self.image().colortype()
881    }
882
883    /// The offset of the directory representing the current image.
884    pub fn ifd_pointer(&mut self) -> Option<IfdPointer> {
885        self.current_ifd
886    }
887
888    fn image(&self) -> &Image {
889        &self.image
890    }
891
892    /// Loads the IFD at the specified index in the list, if one exists
893    pub fn seek_to_image(&mut self, ifd_index: usize) -> TiffResult<()> {
894        // 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
895        if ifd_index >= self.ifd_offsets.len() {
896            // We possibly need to load in the next IFD
897            if self.next_ifd.is_none() {
898                self.current_ifd = None;
899
900                return Err(TiffError::FormatError(
901                    TiffFormatError::ImageFileDirectoryNotFound,
902                ));
903            }
904
905            loop {
906                // Follow the list until we find the one we want, or we reach the end, whichever happens first
907                let ifd = self.next_ifd()?;
908
909                if ifd.next().is_none() {
910                    break;
911                }
912
913                if ifd_index < self.ifd_offsets.len() {
914                    break;
915                }
916            }
917        }
918
919        // If the index is within the list of ifds then we can load the selected image/IFD
920        if let Some(ifd_offset) = self.ifd_offsets.get(ifd_index) {
921            let ifd = self.value_reader.read_directory(*ifd_offset)?;
922            self.next_ifd = ifd.next();
923            self.current_ifd = Some(*ifd_offset);
924            self.image = Image::from_reader(&mut self.value_reader, ifd)?;
925
926            Ok(())
927        } else {
928            Err(TiffError::FormatError(
929                TiffFormatError::ImageFileDirectoryNotFound,
930            ))
931        }
932    }
933
934    fn next_ifd(&mut self) -> TiffResult<Directory> {
935        let Some(next_ifd) = self.next_ifd.take() else {
936            return Err(TiffError::FormatError(
937                TiffFormatError::ImageFileDirectoryNotFound,
938            ));
939        };
940
941        let ifd = self.value_reader.read_directory(next_ifd)?;
942
943        // Ensure this walk does not get us into a cycle.
944        self.seen_ifds.insert_next(next_ifd, ifd.next())?;
945
946        // Extend the list of known IFD offsets in this chain, if needed.
947        if self.ifd_offsets.last().copied() == self.current_ifd {
948            self.ifd_offsets.push(next_ifd);
949        }
950
951        self.current_ifd = Some(next_ifd);
952        self.next_ifd = ifd.next();
953
954        Ok(ifd)
955    }
956
957    /// Reads in the next image.
958    /// If there is no further image in the TIFF file a format error is returned.
959    /// To determine whether there are more images call `TIFFDecoder::more_images` instead.
960    pub fn next_image(&mut self) -> TiffResult<()> {
961        let ifd = self.next_ifd()?;
962        self.image = Image::from_reader(&mut self.value_reader, ifd)?;
963        Ok(())
964    }
965
966    /// Returns `true` if there is at least one more image available.
967    pub fn more_images(&self) -> bool {
968        self.next_ifd.is_some()
969    }
970
971    /// Returns the byte_order of the file.
972    ///
973    /// # Usage
974    ///
975    /// This is only relevant to interpreting raw bytes read from tags. The image decoding methods
976    /// will correct to the host byte order automatically.
977    pub fn byte_order(&self) -> ByteOrder {
978        self.value_reader.reader.byte_order
979    }
980
981    #[inline]
982    pub fn read_ifd_offset(&mut self) -> Result<u64, io::Error> {
983        if self.value_reader.bigtiff {
984            self.read_long8()
985        } else {
986            self.read_long().map(u64::from)
987        }
988    }
989
990    /// Returns a mutable reference to the stream being decoded.
991    pub fn inner(&mut self) -> &mut R {
992        self.value_reader.reader.inner()
993    }
994
995    /// Reads a TIFF byte value
996    #[inline]
997    pub fn read_byte(&mut self) -> Result<u8, io::Error> {
998        let mut buf = [0; 1];
999        self.value_reader.reader.inner().read_exact(&mut buf)?;
1000        Ok(buf[0])
1001    }
1002
1003    /// Reads a TIFF short value
1004    #[inline]
1005    pub fn read_short(&mut self) -> Result<u16, io::Error> {
1006        self.value_reader.reader.read_u16()
1007    }
1008
1009    /// Reads a TIFF sshort value
1010    #[inline]
1011    pub fn read_sshort(&mut self) -> Result<i16, io::Error> {
1012        self.value_reader.reader.read_i16()
1013    }
1014
1015    /// Reads a TIFF long value
1016    #[inline]
1017    pub fn read_long(&mut self) -> Result<u32, io::Error> {
1018        self.value_reader.reader.read_u32()
1019    }
1020
1021    /// Reads a TIFF slong value
1022    #[inline]
1023    pub fn read_slong(&mut self) -> Result<i32, io::Error> {
1024        self.value_reader.reader.read_i32()
1025    }
1026
1027    /// Reads a TIFF float value
1028    #[inline]
1029    pub fn read_float(&mut self) -> Result<f32, io::Error> {
1030        self.value_reader.reader.read_f32()
1031    }
1032
1033    /// Reads a TIFF double value
1034    #[inline]
1035    pub fn read_double(&mut self) -> Result<f64, io::Error> {
1036        self.value_reader.reader.read_f64()
1037    }
1038
1039    #[inline]
1040    pub fn read_long8(&mut self) -> Result<u64, io::Error> {
1041        self.value_reader.reader.read_u64()
1042    }
1043
1044    #[inline]
1045    pub fn read_slong8(&mut self) -> Result<i64, io::Error> {
1046        self.value_reader.reader.read_i64()
1047    }
1048
1049    /// Reads a string
1050    #[inline]
1051    pub fn read_string(&mut self, length: usize) -> TiffResult<String> {
1052        let mut out = vec![0; length];
1053        self.value_reader.reader.inner().read_exact(&mut out)?;
1054        // Strings may be null-terminated, so we trim anything downstream of the null byte
1055        if let Some(first) = out.iter().position(|&b| b == 0) {
1056            out.truncate(first);
1057        }
1058        Ok(String::from_utf8(out)?)
1059    }
1060
1061    /// Reads a TIFF IFA offset/value field
1062    #[inline]
1063    pub fn read_offset(&mut self) -> TiffResult<[u8; 4]> {
1064        if self.value_reader.bigtiff {
1065            return Err(TiffError::FormatError(
1066                TiffFormatError::InconsistentSizesEncountered,
1067            ));
1068        }
1069        let mut val = [0; 4];
1070        self.value_reader.reader.inner().read_exact(&mut val)?;
1071        Ok(val)
1072    }
1073
1074    /// Reads a TIFF IFA offset/value field
1075    #[inline]
1076    pub fn read_offset_u64(&mut self) -> Result<[u8; 8], io::Error> {
1077        let mut val = [0; 8];
1078        self.value_reader.reader.inner().read_exact(&mut val)?;
1079        Ok(val)
1080    }
1081
1082    /// Moves the cursor to the specified offset
1083    #[inline]
1084    pub fn goto_offset(&mut self, offset: u32) -> io::Result<()> {
1085        self.goto_offset_u64(offset.into())
1086    }
1087
1088    #[inline]
1089    pub fn goto_offset_u64(&mut self, offset: u64) -> io::Result<()> {
1090        self.value_reader.reader.goto_offset(offset)
1091    }
1092
1093    /// Read a tag-entry map from a known offset.
1094    ///
1095    /// A TIFF [`Directory`], aka. image file directory aka. IFD, refers to a map from
1096    /// tags–identified by a `u16`–to a typed vector of elements. It is encoded as a list
1097    /// of ascending tag values with the offset and type of their corresponding values. The
1098    /// semantic interpretations of a tag and its type requirements depend on the context of the
1099    /// directory. The main image directories, those iterated over by the `Decoder` after
1100    /// construction, are represented by [`Tag`] and [`ifd::Value`]. Other forms are EXIF and GPS
1101    /// data as well as thumbnail Sub-IFD representations associated with each image file.
1102    ///
1103    /// This method allows the decoding of a directory from an arbitrary offset in the image file
1104    /// with no specific semantic interpretation. Such an offset is usually found as the value of
1105    /// a tag, e.g. [`Tag::SubIfd`], [`Tag::ExifDirectory`], [`Tag::GpsDirectory`] and recovered
1106    /// from the associated value by [`ifd::Value::into_ifd_pointer`].
1107    ///
1108    /// The library will not verify whether the offset overlaps any other directory or would form a
1109    /// cycle with any other directory when calling this method. This will modify the position of
1110    /// the reader, i.e. continuing with direct reads at a later point will require going back with
1111    /// [`Self::goto_offset`].
1112    pub fn read_directory(&mut self, ptr: IfdPointer) -> TiffResult<Directory> {
1113        self.value_reader.read_directory(ptr)
1114    }
1115
1116    fn check_chunk_type(&self, expected: ChunkType) -> TiffResult<()> {
1117        if expected != self.image().chunk_type {
1118            return Err(TiffError::UsageError(UsageError::InvalidChunkType(
1119                expected,
1120                self.image().chunk_type,
1121            )));
1122        }
1123
1124        Ok(())
1125    }
1126
1127    /// The chunk type (Strips / Tiles) of the image
1128    pub fn get_chunk_type(&self) -> ChunkType {
1129        self.image().chunk_type
1130    }
1131
1132    /// Number of strips in image
1133    pub fn strip_count(&mut self) -> TiffResult<u32> {
1134        self.check_chunk_type(ChunkType::Strip)?;
1135        let rows_per_strip = self.image().strip_decoder.as_ref().unwrap().rows_per_strip;
1136
1137        if rows_per_strip == 0 {
1138            return Ok(0);
1139        }
1140
1141        // rows_per_strip - 1 can never fail since we know it's at least 1
1142        let height = match self.image().height.checked_add(rows_per_strip - 1) {
1143            Some(h) => h,
1144            None => return Err(TiffError::IntSizeError),
1145        };
1146
1147        let strips = match self.image().planar_config {
1148            PlanarConfiguration::Chunky => height / rows_per_strip,
1149            PlanarConfiguration::Planar => height / rows_per_strip * self.image().samples as u32,
1150        };
1151
1152        Ok(strips)
1153    }
1154
1155    /// Number of tiles in image
1156    pub fn tile_count(&mut self) -> TiffResult<u32> {
1157        self.check_chunk_type(ChunkType::Tile)?;
1158        Ok(u32::try_from(self.image().chunk_offsets.len())?)
1159    }
1160
1161    fn read_chunk_to_bytes(
1162        &mut self,
1163        buffer: &mut [u8],
1164        chunk_index: u32,
1165        layout: &image::ReadoutLayout,
1166    ) -> TiffResult<()> {
1167        let offset = self.image.chunk_file_range(chunk_index)?.0;
1168        self.goto_offset_u64(offset)?;
1169
1170        self.image
1171            .expand_chunk(&mut self.value_reader, buffer, layout, chunk_index)?;
1172
1173        Ok(())
1174    }
1175
1176    /// Returns the layout preferred to read the specified chunk with [`Self::read_chunk_bytes`].
1177    ///
1178    /// Returns the layout without being specific as to the underlying type for forward
1179    /// compatibility. Note that, in general, a TIFF may contain an almost arbitrary number of
1180    /// channels of individual *bit* length and format each.
1181    ///
1182    /// See [`Self::colortype`] to describe the sample types.
1183    pub fn image_chunk_buffer_layout(
1184        &mut self,
1185        chunk_index: u32,
1186    ) -> TiffResult<BufferLayoutPreference> {
1187        let data_dims = self.image().chunk_data_dimensions(chunk_index)?;
1188        let readout = self.image().readout_for_size(data_dims.0, data_dims.1)?;
1189
1190        let extent = readout.result_extent_for_planes(0..1)?;
1191        let sample_type = extent.sample_type();
1192        let layout = extent.preferred_layout()?;
1193
1194        let row_stride = core::num::NonZeroUsize::new(readout.minimum_row_stride);
1195        let plane_stride = core::num::NonZeroUsize::new(readout.plane_stride);
1196
1197        Ok(BufferLayoutPreference {
1198            len: layout.size(),
1199            row_stride,
1200            planes: 1,
1201            plane_stride,
1202            complete_len: layout.size(),
1203            sample_format: self.image().sample_format,
1204            sample_type: Some(sample_type),
1205        })
1206    }
1207
1208    /// Return the layout preferred to read several planes corresponding to the specified region.
1209    ///
1210    /// This is similar to [`Self::image_chunk_buffer_layout`] but can read chunks from all planes
1211    /// at the corresponding coordinates of the image.
1212    ///
1213    /// # Bugs
1214    ///
1215    /// Sub-sampled images are not yet supported properly.
1216    pub fn image_coding_unit_layout(
1217        &mut self,
1218        code_unit: TiffCodingUnit,
1219    ) -> TiffResult<BufferLayoutPreference> {
1220        match self.image().planar_config {
1221            PlanarConfiguration::Chunky => return self.image_chunk_buffer_layout(code_unit.0),
1222            PlanarConfiguration::Planar => {}
1223        }
1224
1225        let (width, height) = self.image().chunk_data_dimensions(code_unit.0)?;
1226
1227        let layout = self
1228            .image()
1229            .readout_for_size(width, height)?
1230            .to_plane_layout()?;
1231
1232        if code_unit.0 >= layout.readout.chunks_per_plane {
1233            return Err(TiffError::UsageError(UsageError::InvalidCodingUnit(
1234                code_unit.0,
1235                layout.readout.chunks_per_plane,
1236            )));
1237        }
1238
1239        Ok(BufferLayoutPreference::from_planes(&layout))
1240    }
1241
1242    /// Read the specified chunk (at index `chunk_index`) and return the binary data as a Vector.
1243    ///
1244    /// Note that for planar images each chunk contains only one sample of the underlying data.
1245    pub fn read_chunk(&mut self, chunk_index: u32) -> TiffResult<DecodingResult> {
1246        let (width, height) = self.image().chunk_data_dimensions(chunk_index)?;
1247
1248        let readout = self.image().readout_for_size(width, height)?;
1249
1250        let mut result = readout
1251            .result_extent_for_planes(0..1)?
1252            .to_result_buffer(&self.value_reader.limits)?;
1253
1254        self.read_chunk_to_bytes(result.as_buffer(0).as_bytes_mut(), chunk_index, &readout)?;
1255
1256        Ok(result)
1257    }
1258
1259    /// Read the specified chunk (at index `chunk_index`) into an allocated buffer.
1260    ///
1261    /// Returns a [`TiffError::UsageError`] if the chunk is smaller than the size indicated with a
1262    /// call to [`Self::image_chunk_buffer_layout`]. Note that the alignment may be arbitrary, but
1263    /// an alignment smaller than the preferred alignment may perform worse.
1264    ///
1265    /// Note that for planar images each chunk contains only one sample of the underlying data.
1266    pub fn read_chunk_bytes(&mut self, chunk_index: u32, buffer: &mut [u8]) -> TiffResult<()> {
1267        let (width, height) = self.image().chunk_data_dimensions(chunk_index)?;
1268
1269        let layout = self.image().readout_for_size(width, height)?;
1270        layout.assert_min_layout(buffer)?;
1271
1272        self.read_chunk_to_bytes(buffer, chunk_index, &layout)?;
1273
1274        Ok(())
1275    }
1276
1277    /// Read the specified chunk (at index `chunk_index`) into a provide buffer.
1278    ///
1279    /// It will re-allocate the buffer into the correct type and size, within the decoder's
1280    /// configured limits, and then pass it to the underlying method. This is essentially a
1281    /// type-safe wrapper around the raw [`Self::read_chunk_bytes`] method.
1282    ///
1283    /// Note that for planar images each chunk contains only one sample of the underlying data.
1284    pub fn read_chunk_to_buffer(
1285        &mut self,
1286        buffer: &mut DecodingResult,
1287        chunk_index: u32,
1288        output_width: usize,
1289    ) -> TiffResult<()> {
1290        let (width, height) = self.image().chunk_data_dimensions(chunk_index)?;
1291
1292        let mut layout = self.image().readout_for_size(width, height)?;
1293        layout.set_row_stride(output_width)?;
1294
1295        let extent = layout.result_extent_for_planes(0..1)?;
1296        buffer.resize_to_extent(extent, &self.value_reader.limits)?;
1297
1298        self.read_chunk_to_bytes(buffer.as_buffer(0).as_bytes_mut(), chunk_index, &layout)?;
1299
1300        Ok(())
1301    }
1302
1303    /// Read chunks corresponding to several planes of a region of pixels.
1304    ///
1305    /// For non planar images this is equivalent to [`Self::read_chunk_bytes`] as there is only one
1306    /// plane in the image. For planar images the planes are stored consecutively into the output
1307    /// buffer. Returns an error if not enough space for at least one plane is provided. Otherwise
1308    /// reads all planes that can be stored completely in the provided output buffer.
1309    ///
1310    /// A region is a rectangular assortment of pixels in the image, depending on the chunk type
1311    /// either strips or tiles. Borrowing terminology from JPEG we call the collection of all
1312    /// chunks from all planes that encode samples from the same region a "coding unit".
1313    ///
1314    /// # Bugs
1315    ///
1316    /// Sub-sampled images are not yet supported properly.
1317    pub fn read_coding_unit_bytes(
1318        &mut self,
1319        slice: TiffCodingUnit,
1320        buffer: &mut [u8],
1321    ) -> TiffResult<()> {
1322        let (width, height) = self.image().chunk_data_dimensions(slice.0)?;
1323        let readout = self.image().readout_for_size(width, height)?;
1324
1325        let ref layout @ image::PlaneLayout {
1326            ref plane_offsets,
1327            // We assume that is correct, so really it can be ignored.
1328            total_bytes: _,
1329            ref readout,
1330        } = readout.to_plane_layout()?;
1331
1332        if slice.0 >= readout.chunks_per_plane {
1333            return Err(TiffError::UsageError(UsageError::InvalidCodingUnit(
1334                slice.0,
1335                readout.chunks_per_plane,
1336            )));
1337        }
1338
1339        // No subsamples planes support, for now.
1340        let used_plane_offsets = usize::from(layout.used_planes(buffer)?);
1341        debug_assert!(used_plane_offsets >= 1, "Should have errored");
1342
1343        for (idx, &plane_offset) in plane_offsets[..used_plane_offsets].iter().enumerate() {
1344            let chunk = slice.0 + idx as u32 * readout.chunks_per_plane;
1345            self.goto_offset_u64(self.image().chunk_offsets[chunk as usize])?;
1346
1347            self.image.expand_chunk(
1348                &mut self.value_reader,
1349                &mut buffer[plane_offset..],
1350                readout,
1351                chunk,
1352            )?;
1353        }
1354
1355        Ok(())
1356    }
1357
1358    /// Returns the default chunk size for the current image. Any given chunk in the image is at most as large as
1359    /// the value returned here. For the size of the data (chunk minus padding), use `chunk_data_dimensions`.
1360    pub fn chunk_dimensions(&self) -> (u32, u32) {
1361        self.image().chunk_dimensions().unwrap()
1362    }
1363
1364    /// Returns the size of the data in the chunk with the specified index. This is the default size of the chunk,
1365    /// minus any padding.
1366    pub fn chunk_data_dimensions(&self, chunk_index: u32) -> (u32, u32) {
1367        self.image()
1368            .chunk_data_dimensions(chunk_index)
1369            .expect("invalid chunk_index")
1370    }
1371
1372    /// Returns the preferred buffer required to read the whole image with [`Self::read_image_bytes`].
1373    ///
1374    /// Returns the layout without being specific as to the underlying type for forward
1375    /// compatibility. Note that, in general, a TIFF may contain an almost arbitrary number of
1376    /// channels of individual *bit* length and format each.
1377    ///
1378    /// See [`Self::colortype`] to describe the sample types.
1379    ///
1380    /// # Bugs
1381    ///
1382    /// When the image is stored as a planar configuration, this method will currently only
1383    /// indicate the layout needed to read the first data plane. This will be fixed in a future
1384    /// major version of `tiff`.
1385    pub fn image_buffer_layout(&mut self) -> TiffResult<BufferLayoutPreference> {
1386        let layout = self.image().readout_for_image()?.to_plane_layout()?;
1387        Ok(BufferLayoutPreference::from_planes(&layout))
1388    }
1389
1390    /// Decodes the entire image and return it as a Vector
1391    ///
1392    /// # Examples
1393    ///
1394    /// This method is deprecated. For replacement usage see `examples/decode.rs`.
1395    ///
1396    /// # Bugs
1397    ///
1398    /// When the image is stored as a planar configuration, this method will currently only read
1399    /// the first sample's plane. This will be fixed in a future major version of `tiff`. To read
1400    /// multiple planes, [`Self::read_image_to_buffer`] can be used instead.
1401    ///
1402    /// # Intent to deprecate
1403    ///
1404    /// Use [`Self::read_image_to_buffer`] or a combination of [`DecodingResult::resize_to`] and
1405    /// [`Self::read_image_bytes`] instead where possible, preserving the buffer across multiple
1406    /// calls. This old method will likely keep its bugged planar behavior until it is fully
1407    /// replaced, to ensure that existing code will not run into unexpectedly large allocations
1408    /// that will error on limits instead.
1409    pub fn read_image(&mut self) -> TiffResult<DecodingResult> {
1410        let readout = self.image().readout_for_image()?;
1411
1412        let mut result = readout
1413            .result_extent_for_planes(0..1)?
1414            .to_result_buffer(&self.value_reader.limits)?;
1415
1416        self.read_image_bytes(result.as_buffer(0).as_bytes_mut())?;
1417
1418        Ok(result)
1419    }
1420
1421    /// Decodes the entire image into a provided buffer.
1422    ///
1423    /// It will re-allocate the buffer into the correct type and size, within the decoder's
1424    /// configured limits, and then pass it to the underlying method. This is essentially a
1425    /// type-safe wrapper around the raw [`Self::read_image_bytes`] method.
1426    ///
1427    /// ## Planar behavior
1428    ///
1429    /// If the image is stored as a planar configuration, an attempt is made to resize the buffer
1430    /// to hold all planes. If that does not fit then only the first plane is read. Check the
1431    /// buffer size against [`BufferLayoutPreference::complete_len`] to ensure that all planes were
1432    /// read:
1433    ///
1434    /// ```
1435    /// use tiff::decoder::{Decoder, DecodingResult};
1436    /// let mut result = DecodingResult::U8(vec![]);
1437    ///
1438    /// let mut reader = /* */
1439    /// # Decoder::new(std::io::Cursor::new(include_bytes!(concat!(
1440    /// #   env!("CARGO_MANIFEST_DIR"), "/tests/images/tiled-gray-i1.tif"
1441    /// # )))).unwrap();
1442    /// let layout = reader.read_image_to_buffer(&mut result)?;
1443    ///
1444    /// if result.as_buffer(0).as_bytes().len() < layout.complete_len {
1445    ///    println!("Only the first plane was read");
1446    /// }
1447    ///
1448    /// # Ok::<_, tiff::TiffError>(())
1449    /// ```
1450    ///
1451    /// # Examples
1452    ///
1453    /// ```
1454    /// use tiff::decoder::{Decoder, DecodingResult, Limits};
1455    ///
1456    /// let mut result = DecodingResult::I8(vec![]);
1457    ///
1458    /// let mut reader = /* */
1459    /// # Decoder::new(std::io::Cursor::new(include_bytes!(concat!(
1460    /// #   env!("CARGO_MANIFEST_DIR"), "/tests/images/tiled-gray-i1.tif"
1461    /// # )))).unwrap();
1462    ///
1463    /// reader.read_image_to_buffer(&mut result)?;
1464    ///
1465    /// # Ok::<_, tiff::TiffError>(())
1466    /// ```
1467    pub fn read_image_to_buffer(
1468        &mut self,
1469        result: &mut DecodingResult,
1470    ) -> TiffResult<BufferLayoutPreference> {
1471        let readout = self.image().readout_for_image()?;
1472        let planes = readout.to_plane_layout()?;
1473
1474        let num_planes = if planes.total_bytes <= self.value_reader.limits.decoding_buffer_size {
1475            planes.plane_offsets.len() as u16
1476        } else {
1477            1
1478        };
1479
1480        let layout = BufferLayoutPreference::from_planes(&planes);
1481        let extent = readout.result_extent_for_planes(0..num_planes)?;
1482        // Compatibility: if this extent is too large our configured limits we will fall back to
1483        // reading only the first plane.
1484        result.resize_to_extent(extent, &self.value_reader.limits)?;
1485
1486        self.read_image_bytes(result.as_buffer(0).as_bytes_mut())?;
1487
1488        Ok(layout)
1489    }
1490
1491    /// Decodes the entire image into a provided buffer.
1492    ///
1493    /// Returns a [`TiffError::UsageError`] if the chunk is smaller than the size indicated with a
1494    /// call to [`Self::image_buffer_layout`]. Note that the alignment may be arbitrary, but an
1495    /// alignment smaller than the preferred alignment may perform worse.
1496    ///
1497    /// # Error
1498    ///
1499    /// Returns an error if the buffer fits less than one plane. In particular, for non-planar
1500    /// images returns an error if the buffer does not fit the required size.
1501    pub fn read_image_bytes(&mut self, buffer: &mut [u8]) -> TiffResult<()> {
1502        let readout = self.image().readout_for_image()?;
1503
1504        let ref layout @ image::PlaneLayout {
1505            ref plane_offsets,
1506            // We assume that is correct, so really it can be ignored.
1507            total_bytes: _,
1508            ref readout,
1509        } = readout.to_plane_layout()?;
1510
1511        let used_plane_offsets = usize::from(layout.used_planes(buffer)?);
1512        debug_assert!(used_plane_offsets >= 1, "Should have errored");
1513
1514        // For multi-band images, only the first band is read.
1515        // Possible improvements:
1516        // * pass requested band as parameter
1517        // * collect bands to a RGB encoding result in case of RGB bands
1518        for chunk in 0..readout.chunks_per_plane {
1519            let x = (chunk % readout.chunks_across) as usize;
1520            let y = (chunk / readout.chunks_across) as usize;
1521
1522            let buffer_offset = y * readout.chunk_col_stride + x * readout.chunk_row_stride;
1523
1524            for (idx, &plane_offset) in plane_offsets[..used_plane_offsets].iter().enumerate() {
1525                let chunk = chunk + idx as u32 * readout.chunks_per_plane;
1526                self.goto_offset_u64(self.image().chunk_offsets[chunk as usize])?;
1527
1528                self.image.expand_chunk(
1529                    &mut self.value_reader,
1530                    &mut buffer[plane_offset..][buffer_offset..],
1531                    readout,
1532                    chunk,
1533                )?;
1534            }
1535        }
1536
1537        Ok(())
1538    }
1539
1540    /// Get the IFD decoder for our current image IFD.
1541    pub fn image_ifd(&mut self) -> IfdDecoder<'_> {
1542        IfdDecoder {
1543            inner: tag_reader::TagReader {
1544                decoder: &mut self.value_reader,
1545                ifd: self.image.ifd.as_ref().unwrap(),
1546            },
1547        }
1548    }
1549
1550    /// Prepare reading values for tags of a given directory.
1551    ///
1552    /// # Examples
1553    ///
1554    /// This method may be used to read the values of tags in directories that have been previously
1555    /// read with [`Decoder::read_directory`].
1556    ///
1557    /// ```no_run
1558    /// use tiff::decoder::Decoder;
1559    /// use tiff::tags::Tag;
1560    ///
1561    /// # use std::io::Cursor;
1562    /// # let mut data = Cursor::new(vec![0]);
1563    /// let mut decoder = Decoder::new(&mut data).unwrap();
1564    /// let sub_ifds = decoder.get_tag(Tag::SubIfd)?.into_ifd_vec()?;
1565    ///
1566    /// for ifd in sub_ifds {
1567    ///     let subdir = decoder.read_directory(ifd)?;
1568    ///     let subfile = decoder.read_directory_tags(&subdir).find_tag(Tag::SubfileType)?;
1569    ///     // omitted: handle the subfiles, e.g. thumbnails
1570    /// }
1571    ///
1572    /// # Ok::<_, tiff::TiffError>(())
1573    /// ```
1574    pub fn read_directory_tags<'ifd>(&'ifd mut self, ifd: &'ifd Directory) -> IfdDecoder<'ifd> {
1575        IfdDecoder {
1576            inner: tag_reader::TagReader {
1577                decoder: &mut self.value_reader,
1578                ifd,
1579            },
1580        }
1581    }
1582
1583    /// Tries to retrieve a tag from the current image directory.
1584    /// Return `Ok(None)` if the tag is not present.
1585    pub fn find_tag(&mut self, tag: Tag) -> TiffResult<Option<ifd::Value>> {
1586        self.image_ifd().find_tag(tag)
1587    }
1588
1589    /// Tries to retrieve a tag in the current image directory and convert it to the desired
1590    /// unsigned type.
1591    pub fn find_tag_unsigned<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<Option<T>> {
1592        self.image_ifd().find_tag_unsigned(tag)
1593    }
1594
1595    /// Tries to retrieve a vector of all a tag's values and convert them to the desired unsigned
1596    /// type.
1597    pub fn find_tag_unsigned_vec<T: TryFrom<u64>>(
1598        &mut self,
1599        tag: Tag,
1600    ) -> TiffResult<Option<Vec<T>>> {
1601        self.image_ifd().find_tag_unsigned_vec(tag)
1602    }
1603
1604    /// Tries to retrieve a tag from the current image directory and convert it to the desired
1605    /// unsigned type. Returns an error if the tag is not present.
1606    pub fn get_tag_unsigned<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<T> {
1607        self.image_ifd().get_tag_unsigned(tag)
1608    }
1609
1610    /// Tries to retrieve a tag from the current image directory.
1611    /// Returns an error if the tag is not present
1612    pub fn get_tag(&mut self, tag: Tag) -> TiffResult<ifd::Value> {
1613        self.image_ifd().get_tag(tag)
1614    }
1615
1616    pub fn get_tag_u32(&mut self, tag: Tag) -> TiffResult<u32> {
1617        self.get_tag(tag)?.into_u32()
1618    }
1619
1620    pub fn get_tag_u64(&mut self, tag: Tag) -> TiffResult<u64> {
1621        self.get_tag(tag)?.into_u64()
1622    }
1623
1624    /// Tries to retrieve a tag and convert it to the desired type.
1625    pub fn get_tag_f32(&mut self, tag: Tag) -> TiffResult<f32> {
1626        self.get_tag(tag)?.into_f32()
1627    }
1628
1629    /// Tries to retrieve a tag and convert it to the desired type.
1630    pub fn get_tag_f64(&mut self, tag: Tag) -> TiffResult<f64> {
1631        self.get_tag(tag)?.into_f64()
1632    }
1633
1634    /// Tries to retrieve a tag and convert it to the desired type.
1635    pub fn get_tag_u32_vec(&mut self, tag: Tag) -> TiffResult<Vec<u32>> {
1636        self.get_tag(tag)?.into_u32_vec()
1637    }
1638
1639    pub fn get_tag_u16_vec(&mut self, tag: Tag) -> TiffResult<Vec<u16>> {
1640        self.get_tag(tag)?.into_u16_vec()
1641    }
1642
1643    pub fn get_tag_u64_vec(&mut self, tag: Tag) -> TiffResult<Vec<u64>> {
1644        self.get_tag(tag)?.into_u64_vec()
1645    }
1646
1647    /// Tries to retrieve a tag and convert it to the desired type.
1648    pub fn get_tag_f32_vec(&mut self, tag: Tag) -> TiffResult<Vec<f32>> {
1649        self.get_tag(tag)?.into_f32_vec()
1650    }
1651
1652    /// Tries to retrieve a tag and convert it to the desired type.
1653    pub fn get_tag_f64_vec(&mut self, tag: Tag) -> TiffResult<Vec<f64>> {
1654        self.get_tag(tag)?.into_f64_vec()
1655    }
1656
1657    /// Tries to retrieve a tag and convert it to a 8bit vector.
1658    pub fn get_tag_u8_vec(&mut self, tag: Tag) -> TiffResult<Vec<u8>> {
1659        self.get_tag(tag)?.into_u8_vec()
1660    }
1661
1662    /// Tries to retrieve a tag and convert it to a ascii vector.
1663    pub fn get_tag_ascii_string(&mut self, tag: Tag) -> TiffResult<String> {
1664        self.get_tag(tag)?.into_string()
1665    }
1666
1667    pub fn tag_iter(&mut self) -> impl Iterator<Item = TiffResult<(Tag, ifd::Value)>> + '_ {
1668        self.image_ifd().tag_iter()
1669    }
1670}
1671
1672impl<R: Seek + Read> ValueReader<R> {
1673    pub(crate) fn read_directory(&mut self, ptr: IfdPointer) -> Result<Directory, TiffError> {
1674        Self::read_ifd(&mut self.reader, self.bigtiff, ptr)
1675    }
1676
1677    /// Reads a IFD entry.
1678    // An IFD entry has four fields:
1679    //
1680    // Tag   2 bytes
1681    // Type  2 bytes
1682    // Count 4 bytes
1683    // Value 4 bytes either a pointer the value itself
1684    fn read_entry(
1685        reader: &mut EndianReader<R>,
1686        bigtiff: bool,
1687    ) -> TiffResult<Option<(Tag, ifd::Entry)>> {
1688        let tag = Tag::from_u16_exhaustive(reader.read_u16()?);
1689        let type_ = match Type::from_u16(reader.read_u16()?) {
1690            Some(t) => t,
1691            None => {
1692                // Unknown type. Skip this entry according to spec.
1693                reader.read_u32()?;
1694                reader.read_u32()?;
1695                return Ok(None);
1696            }
1697        };
1698        let entry = if bigtiff {
1699            let mut offset = [0; 8];
1700
1701            let count = reader.read_u64()?;
1702            reader.inner().read_exact(&mut offset)?;
1703            ifd::Entry::new_u64(type_, count, offset)
1704        } else {
1705            let mut offset = [0; 4];
1706
1707            let count = reader.read_u32()?;
1708            reader.inner().read_exact(&mut offset)?;
1709            ifd::Entry::new(type_, count, offset)
1710        };
1711        Ok(Some((tag, entry)))
1712    }
1713
1714    /// Reads the IFD starting at the indicated location.
1715    fn read_ifd(
1716        reader: &mut EndianReader<R>,
1717        bigtiff: bool,
1718        ifd_location: IfdPointer,
1719    ) -> TiffResult<Directory> {
1720        reader.goto_offset(ifd_location.0)?;
1721
1722        let mut entries: BTreeMap<_, _> = BTreeMap::new();
1723
1724        let num_tags = if bigtiff {
1725            reader.read_u64()?
1726        } else {
1727            reader.read_u16()?.into()
1728        };
1729
1730        for _ in 0..num_tags {
1731            let (tag, entry) = match Self::read_entry(reader, bigtiff)? {
1732                Some(val) => val,
1733                None => {
1734                    continue;
1735                } // Unknown data type in tag, skip
1736            };
1737
1738            entries.insert(tag.to_u16(), entry);
1739        }
1740
1741        let next_ifd = if bigtiff {
1742            reader.read_u64()?
1743        } else {
1744            reader.read_u32()?.into()
1745        };
1746
1747        let next_ifd = core::num::NonZeroU64::new(next_ifd);
1748
1749        Ok(Directory { entries, next_ifd })
1750    }
1751}
1752
1753impl IfdDecoder<'_> {
1754    /// Retrieve the IFD entry for a given tag, if it exists.
1755    ///
1756    /// The entry contains the metadata of the value, that is its type and count from which we can
1757    /// calculate a total byte size.
1758    pub fn find_entry(&self, tag: Tag) -> Option<ifd::Entry> {
1759        self.inner.ifd.get(tag).cloned()
1760    }
1761
1762    /// Tries to retrieve a tag.
1763    /// Return `Ok(None)` if the tag is not present.
1764    pub fn find_tag(&mut self, tag: Tag) -> TiffResult<Option<ifd::Value>> {
1765        self.inner.find_tag(tag)
1766    }
1767
1768    /// Retrieve a tag and reproduce its bytes into the provided buffer.
1769    ///
1770    /// The buffer is unmodified if the tag is not present.
1771    pub fn find_tag_buf(
1772        &mut self,
1773        tag: Tag,
1774        buf: &mut ValueBuffer,
1775    ) -> TiffResult<Option<ifd::Entry>> {
1776        self.inner.find_tag_buf(tag, buf)
1777    }
1778
1779    /// Read bytes of a tag's value into a byte buffer.
1780    pub fn find_tag_bytes(
1781        &mut self,
1782        tag: Tag,
1783        buf: &mut [u8],
1784        offset: u64,
1785    ) -> TiffResult<Option<usize>> {
1786        self.inner.find_tag_raw(tag, buf, offset)
1787    }
1788
1789    /// Tries to retrieve a tag and convert it to the desired unsigned type.
1790    pub fn find_tag_unsigned<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<Option<T>> {
1791        self.find_tag(tag)?
1792            .map(|v| v.into_u64())
1793            .transpose()?
1794            .map(|value| {
1795                T::try_from(value).map_err(|_| TiffFormatError::InvalidTagValueType(tag).into())
1796            })
1797            .transpose()
1798    }
1799
1800    /// Tries to retrieve a vector of all a tag's values and convert them to
1801    /// the desired unsigned type.
1802    pub fn find_tag_unsigned_vec<T: TryFrom<u64>>(
1803        &mut self,
1804        tag: Tag,
1805    ) -> TiffResult<Option<Vec<T>>> {
1806        self.find_tag(tag)?
1807            .map(|v| v.into_u64_vec())
1808            .transpose()?
1809            .map(|v| {
1810                v.into_iter()
1811                    .map(|u| {
1812                        T::try_from(u).map_err(|_| TiffFormatError::InvalidTagValueType(tag).into())
1813                    })
1814                    .collect()
1815            })
1816            .transpose()
1817    }
1818
1819    /// Tries to retrieve a tag and convert it to the desired unsigned type.
1820    /// Returns an error if the tag is not present.
1821    pub fn get_tag_unsigned<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<T> {
1822        self.find_tag_unsigned(tag)?
1823            .ok_or_else(|| TiffFormatError::RequiredTagNotFound(tag).into())
1824    }
1825
1826    /// Tries to retrieve a tag.
1827    /// Returns an error if the tag is not present
1828    pub fn get_tag(&mut self, tag: Tag) -> TiffResult<ifd::Value> {
1829        match self.find_tag(tag)? {
1830            Some(val) => Ok(val),
1831            None => Err(TiffError::FormatError(
1832                TiffFormatError::RequiredTagNotFound(tag),
1833            )),
1834        }
1835    }
1836
1837    /// Tries to retrieve a tag and convert it to the desired type.
1838    pub fn get_tag_u32(&mut self, tag: Tag) -> TiffResult<u32> {
1839        self.get_tag(tag)?.into_u32()
1840    }
1841
1842    pub fn get_tag_u64(&mut self, tag: Tag) -> TiffResult<u64> {
1843        self.get_tag(tag)?.into_u64()
1844    }
1845
1846    /// Tries to retrieve a tag and convert it to the desired type.
1847    pub fn get_tag_f32(&mut self, tag: Tag) -> TiffResult<f32> {
1848        self.get_tag(tag)?.into_f32()
1849    }
1850
1851    /// Tries to retrieve a tag and convert it to the desired type.
1852    pub fn get_tag_f64(&mut self, tag: Tag) -> TiffResult<f64> {
1853        self.get_tag(tag)?.into_f64()
1854    }
1855
1856    /// Tries to retrieve a tag and convert it to the desired type.
1857    pub fn get_tag_u32_vec(&mut self, tag: Tag) -> TiffResult<Vec<u32>> {
1858        self.get_tag(tag)?.into_u32_vec()
1859    }
1860
1861    pub fn get_tag_u16_vec(&mut self, tag: Tag) -> TiffResult<Vec<u16>> {
1862        self.get_tag(tag)?.into_u16_vec()
1863    }
1864
1865    pub fn get_tag_u64_vec(&mut self, tag: Tag) -> TiffResult<Vec<u64>> {
1866        self.get_tag(tag)?.into_u64_vec()
1867    }
1868
1869    /// Tries to retrieve a tag and convert it to the desired type.
1870    pub fn get_tag_f32_vec(&mut self, tag: Tag) -> TiffResult<Vec<f32>> {
1871        self.get_tag(tag)?.into_f32_vec()
1872    }
1873
1874    /// Tries to retrieve a tag and convert it to the desired type.
1875    pub fn get_tag_f64_vec(&mut self, tag: Tag) -> TiffResult<Vec<f64>> {
1876        self.get_tag(tag)?.into_f64_vec()
1877    }
1878
1879    /// Tries to retrieve a tag and convert it to a 8bit vector.
1880    pub fn get_tag_u8_vec(&mut self, tag: Tag) -> TiffResult<Vec<u8>> {
1881        self.get_tag(tag)?.into_u8_vec()
1882    }
1883
1884    /// Tries to retrieve a tag and convert it to a ascii vector.
1885    pub fn get_tag_ascii_string(&mut self, tag: Tag) -> TiffResult<String> {
1886        self.get_tag(tag)?.into_string()
1887    }
1888
1889    /// Inspect the raw underlying directory.
1890    pub fn directory(&self) -> &Directory {
1891        self.inner.ifd
1892    }
1893}
1894
1895impl<'l> IfdDecoder<'l> {
1896    /// Returns an iterator over all tags in the current image, along with their values.
1897    pub fn tag_iter(self) -> impl Iterator<Item = TiffResult<(Tag, ifd::Value)>> + 'l {
1898        self.inner
1899            .ifd
1900            .iter()
1901            .map(|(tag, entry)| match self.inner.decoder.entry_val(entry) {
1902                Ok(value) => Ok((tag, value)),
1903                Err(err) => Err(err),
1904            })
1905    }
1906}
1907
1908#[cfg(test)]
1909mod tests {
1910    use super::Decoder;
1911    use crate::{
1912        bytecast,
1913        tags::{ByteOrder, Tag, ValueBuffer},
1914    };
1915
1916    #[test]
1917    fn equivalence_of_tag_readers() {
1918        let file = std::fs::File::open(concat!(
1919            env!("CARGO_MANIFEST_DIR"),
1920            "/tests/images/int8_rgb.tif"
1921        ))
1922        .unwrap();
1923
1924        let mut decoder = Decoder::new(file).unwrap();
1925        let file_bo = decoder.byte_order();
1926        let mut ifd = decoder.image_ifd();
1927
1928        {
1929            let value = ifd
1930                .find_tag(Tag::BitsPerSample)
1931                .unwrap()
1932                .expect("must have BitsPerSample");
1933
1934            let samples = value.into_u16_vec().unwrap();
1935            assert_eq!(samples.as_slice(), [8, 8, 8]);
1936        }
1937
1938        {
1939            let mut value = ValueBuffer::from_value(&[0u16; 4]);
1940            let _entry = ifd
1941                .find_tag_buf(Tag::BitsPerSample, &mut value)
1942                .unwrap()
1943                .expect("must have BitsPerSample");
1944
1945            value.set_byte_order(ByteOrder::native());
1946            assert_eq!(value.as_bytes(), bytecast::u16_as_ne_bytes(&[8, 8, 8]));
1947        }
1948
1949        {
1950            let mut by_bytes = [0u16; 4];
1951            let entry = ifd
1952                .find_entry(Tag::BitsPerSample)
1953                .expect("must have BitsPerSample");
1954
1955            let byte_len = ifd
1956                .find_tag_bytes(
1957                    Tag::BitsPerSample,
1958                    bytecast::u16_as_ne_mut_bytes(&mut by_bytes),
1959                    0,
1960                )
1961                .unwrap()
1962                .expect("must have BitsPerSample");
1963            assert_eq!(byte_len, 3 * std::mem::size_of::<u16>());
1964
1965            file_bo.convert(
1966                entry.field_type(),
1967                bytecast::u16_as_ne_mut_bytes(&mut by_bytes[..3]),
1968                ByteOrder::native(),
1969            );
1970            assert_eq!(&by_bytes[..3], &[8, 8, 8]);
1971        }
1972    }
1973}