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#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
27pub struct TiffCodingUnit(pub u32);
28
29#[derive(Debug)]
31pub enum DecodingResult {
32 U8(Vec<u8>),
34 U16(Vec<u16>),
36 U32(Vec<u32>),
38 U64(Vec<u64>),
40 F16(Vec<f16>),
42 F32(Vec<f32>),
44 F64(Vec<f64>),
46 I8(Vec<i8>),
48 I16(Vec<i16>),
50 I32(Vec<i32>),
52 I64(Vec<i64>),
54}
55
56impl DecodingResult {
57 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 *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 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
155pub enum DecodingBuffer<'a> {
157 U8(&'a mut [u8]),
159 U16(&'a mut [u16]),
161 U32(&'a mut [u32]),
163 U64(&'a mut [u64]),
165 F16(&'a mut [f16]),
167 F32(&'a mut [f32]),
169 F64(&'a mut [f64]),
171 I8(&'a mut [i8]),
173 I16(&'a mut [i16]),
175 I32(&'a mut [i32]),
177 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#[non_exhaustive]
258#[derive(Debug, Clone)]
259pub struct BufferLayoutPreference {
260 pub len: usize,
262 pub sample_format: SampleFormat,
268 pub sample_type: Option<DecodingSampleType>,
271 pub row_stride: Option<NonZeroUsize>,
273 pub planes: usize,
275 pub plane_stride: Option<NonZeroUsize>,
277 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 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 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#[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)]
457pub enum ChunkType {
459 Strip,
460 Tile,
461}
462
463#[derive(Clone, Debug)]
465#[non_exhaustive]
466pub struct Limits {
467 pub decoding_buffer_size: usize,
472 pub ifd_value_size: usize,
475 pub intermediate_buffer_size: usize,
478}
479
480impl Limits {
481 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#[derive(Debug)]
511pub struct Decoder<R>
512where
513 R: Read + Seek,
514{
515 value_reader: ValueReader<R>,
518 current_ifd: Option<IfdPointer>,
519 next_ifd: Option<IfdPointer>,
520 ifd_offsets: Vec<IfdPointer>,
522 seen_ifds: cycles::IfdCycles,
524 image: Image,
525}
526
527#[derive(Debug)]
531struct ValueReader<R> {
532 reader: EndianReader<R>,
533 bigtiff: bool,
534 limits: Limits,
535}
536
537pub 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 (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 (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 (ColorType::Gray(1 | 2 | 4 | 8), SampleFormat::Uint) => {
721 for x in buf {
722 *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
771fn 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 if reader.read_u16()? != 8 {
805 return Err(TiffError::FormatError(
806 TiffFormatError::TiffSignatureNotFound,
807 ));
808 }
809 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 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 pub fn seek_to_image(&mut self, ifd_index: usize) -> TiffResult<()> {
894 if ifd_index >= self.ifd_offsets.len() {
896 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 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 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 self.seen_ifds.insert_next(next_ifd, ifd.next())?;
945
946 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 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 pub fn more_images(&self) -> bool {
968 self.next_ifd.is_some()
969 }
970
971 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 pub fn inner(&mut self) -> &mut R {
992 self.value_reader.reader.inner()
993 }
994
995 #[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 #[inline]
1005 pub fn read_short(&mut self) -> Result<u16, io::Error> {
1006 self.value_reader.reader.read_u16()
1007 }
1008
1009 #[inline]
1011 pub fn read_sshort(&mut self) -> Result<i16, io::Error> {
1012 self.value_reader.reader.read_i16()
1013 }
1014
1015 #[inline]
1017 pub fn read_long(&mut self) -> Result<u32, io::Error> {
1018 self.value_reader.reader.read_u32()
1019 }
1020
1021 #[inline]
1023 pub fn read_slong(&mut self) -> Result<i32, io::Error> {
1024 self.value_reader.reader.read_i32()
1025 }
1026
1027 #[inline]
1029 pub fn read_float(&mut self) -> Result<f32, io::Error> {
1030 self.value_reader.reader.read_f32()
1031 }
1032
1033 #[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 #[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 if let Some(first) = out.iter().position(|&b| b == 0) {
1056 out.truncate(first);
1057 }
1058 Ok(String::from_utf8(out)?)
1059 }
1060
1061 #[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 #[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 #[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 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 pub fn get_chunk_type(&self) -> ChunkType {
1129 self.image().chunk_type
1130 }
1131
1132 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 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 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 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 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 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 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 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 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 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 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 pub fn chunk_dimensions(&self) -> (u32, u32) {
1361 self.image().chunk_dimensions().unwrap()
1362 }
1363
1364 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 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 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 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 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 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 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 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 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 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 pub fn find_tag(&mut self, tag: Tag) -> TiffResult<Option<ifd::Value>> {
1586 self.image_ifd().find_tag(tag)
1587 }
1588
1589 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 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 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 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 pub fn get_tag_f32(&mut self, tag: Tag) -> TiffResult<f32> {
1626 self.get_tag(tag)?.into_f32()
1627 }
1628
1629 pub fn get_tag_f64(&mut self, tag: Tag) -> TiffResult<f64> {
1631 self.get_tag(tag)?.into_f64()
1632 }
1633
1634 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 pub fn get_tag_f32_vec(&mut self, tag: Tag) -> TiffResult<Vec<f32>> {
1649 self.get_tag(tag)?.into_f32_vec()
1650 }
1651
1652 pub fn get_tag_f64_vec(&mut self, tag: Tag) -> TiffResult<Vec<f64>> {
1654 self.get_tag(tag)?.into_f64_vec()
1655 }
1656
1657 pub fn get_tag_u8_vec(&mut self, tag: Tag) -> TiffResult<Vec<u8>> {
1659 self.get_tag(tag)?.into_u8_vec()
1660 }
1661
1662 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 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 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 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 } };
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 pub fn find_entry(&self, tag: Tag) -> Option<ifd::Entry> {
1759 self.inner.ifd.get(tag).cloned()
1760 }
1761
1762 pub fn find_tag(&mut self, tag: Tag) -> TiffResult<Option<ifd::Value>> {
1765 self.inner.find_tag(tag)
1766 }
1767
1768 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 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 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 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 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 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 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 pub fn get_tag_f32(&mut self, tag: Tag) -> TiffResult<f32> {
1848 self.get_tag(tag)?.into_f32()
1849 }
1850
1851 pub fn get_tag_f64(&mut self, tag: Tag) -> TiffResult<f64> {
1853 self.get_tag(tag)?.into_f64()
1854 }
1855
1856 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 pub fn get_tag_f32_vec(&mut self, tag: Tag) -> TiffResult<Vec<f32>> {
1871 self.get_tag(tag)?.into_f32_vec()
1872 }
1873
1874 pub fn get_tag_f64_vec(&mut self, tag: Tag) -> TiffResult<Vec<f64>> {
1876 self.get_tag(tag)?.into_f64_vec()
1877 }
1878
1879 pub fn get_tag_u8_vec(&mut self, tag: Tag) -> TiffResult<Vec<u8>> {
1881 self.get_tag(tag)?.into_u8_vec()
1882 }
1883
1884 pub fn get_tag_ascii_string(&mut self, tag: Tag) -> TiffResult<String> {
1886 self.get_tag(tag)?.into_string()
1887 }
1888
1889 pub fn directory(&self) -> &Directory {
1891 self.inner.ifd
1892 }
1893}
1894
1895impl<'l> IfdDecoder<'l> {
1896 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}