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,
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(Debug)]
27pub enum DecodingResult {
28 U8(Vec<u8>),
30 U16(Vec<u16>),
32 U32(Vec<u32>),
34 U64(Vec<u64>),
36 F16(Vec<f16>),
38 F32(Vec<f32>),
40 F64(Vec<f64>),
42 I8(Vec<i8>),
44 I16(Vec<i16>),
46 I32(Vec<i32>),
48 I64(Vec<i64>),
50}
51
52impl DecodingResult {
53 fn new_u8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
54 if size > limits.decoding_buffer_size {
55 Err(TiffError::LimitsExceeded)
56 } else {
57 Ok(DecodingResult::U8(vec![0; size]))
58 }
59 }
60
61 fn new_u16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
62 if size > limits.decoding_buffer_size / 2 {
63 Err(TiffError::LimitsExceeded)
64 } else {
65 Ok(DecodingResult::U16(vec![0; size]))
66 }
67 }
68
69 fn new_u32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
70 if size > limits.decoding_buffer_size / 4 {
71 Err(TiffError::LimitsExceeded)
72 } else {
73 Ok(DecodingResult::U32(vec![0; size]))
74 }
75 }
76
77 fn new_u64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
78 if size > limits.decoding_buffer_size / 8 {
79 Err(TiffError::LimitsExceeded)
80 } else {
81 Ok(DecodingResult::U64(vec![0; size]))
82 }
83 }
84
85 fn new_f32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
86 if size > limits.decoding_buffer_size / std::mem::size_of::<f32>() {
87 Err(TiffError::LimitsExceeded)
88 } else {
89 Ok(DecodingResult::F32(vec![0.0; size]))
90 }
91 }
92
93 fn new_f64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
94 if size > limits.decoding_buffer_size / std::mem::size_of::<f64>() {
95 Err(TiffError::LimitsExceeded)
96 } else {
97 Ok(DecodingResult::F64(vec![0.0; size]))
98 }
99 }
100
101 fn new_f16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
102 if size > limits.decoding_buffer_size / std::mem::size_of::<u16>() {
103 Err(TiffError::LimitsExceeded)
104 } else {
105 Ok(DecodingResult::F16(vec![f16::ZERO; size]))
106 }
107 }
108
109 fn new_i8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
110 if size > limits.decoding_buffer_size / std::mem::size_of::<i8>() {
111 Err(TiffError::LimitsExceeded)
112 } else {
113 Ok(DecodingResult::I8(vec![0; size]))
114 }
115 }
116
117 fn new_i16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
118 if size > limits.decoding_buffer_size / 2 {
119 Err(TiffError::LimitsExceeded)
120 } else {
121 Ok(DecodingResult::I16(vec![0; size]))
122 }
123 }
124
125 fn new_i32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
126 if size > limits.decoding_buffer_size / 4 {
127 Err(TiffError::LimitsExceeded)
128 } else {
129 Ok(DecodingResult::I32(vec![0; size]))
130 }
131 }
132
133 fn new_i64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
134 if size > limits.decoding_buffer_size / 8 {
135 Err(TiffError::LimitsExceeded)
136 } else {
137 Ok(DecodingResult::I64(vec![0; size]))
138 }
139 }
140
141 pub fn as_buffer(&mut self, start: usize) -> DecodingBuffer<'_> {
142 match *self {
143 DecodingResult::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[start..]),
144 DecodingResult::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[start..]),
145 DecodingResult::U32(ref mut buf) => DecodingBuffer::U32(&mut buf[start..]),
146 DecodingResult::U64(ref mut buf) => DecodingBuffer::U64(&mut buf[start..]),
147 DecodingResult::F16(ref mut buf) => DecodingBuffer::F16(&mut buf[start..]),
148 DecodingResult::F32(ref mut buf) => DecodingBuffer::F32(&mut buf[start..]),
149 DecodingResult::F64(ref mut buf) => DecodingBuffer::F64(&mut buf[start..]),
150 DecodingResult::I8(ref mut buf) => DecodingBuffer::I8(&mut buf[start..]),
151 DecodingResult::I16(ref mut buf) => DecodingBuffer::I16(&mut buf[start..]),
152 DecodingResult::I32(ref mut buf) => DecodingBuffer::I32(&mut buf[start..]),
153 DecodingResult::I64(ref mut buf) => DecodingBuffer::I64(&mut buf[start..]),
154 }
155 }
156}
157
158pub enum DecodingBuffer<'a> {
160 U8(&'a mut [u8]),
162 U16(&'a mut [u16]),
164 U32(&'a mut [u32]),
166 U64(&'a mut [u64]),
168 F16(&'a mut [f16]),
170 F32(&'a mut [f32]),
172 F64(&'a mut [f64]),
174 I8(&'a mut [i8]),
176 I16(&'a mut [i16]),
178 I32(&'a mut [i32]),
180 I64(&'a mut [i64]),
182}
183
184impl<'a> DecodingBuffer<'a> {
185 fn as_bytes_mut(&mut self) -> &mut [u8] {
186 match self {
187 DecodingBuffer::U8(ref mut buf) => buf,
188 DecodingBuffer::I8(buf) => bytecast::i8_as_ne_mut_bytes(buf),
189 DecodingBuffer::U16(buf) => bytecast::u16_as_ne_mut_bytes(buf),
190 DecodingBuffer::I16(buf) => bytecast::i16_as_ne_mut_bytes(buf),
191 DecodingBuffer::U32(buf) => bytecast::u32_as_ne_mut_bytes(buf),
192 DecodingBuffer::I32(buf) => bytecast::i32_as_ne_mut_bytes(buf),
193 DecodingBuffer::U64(buf) => bytecast::u64_as_ne_mut_bytes(buf),
194 DecodingBuffer::I64(buf) => bytecast::i64_as_ne_mut_bytes(buf),
195 DecodingBuffer::F16(buf) => bytecast::f16_as_ne_mut_bytes(buf),
196 DecodingBuffer::F32(buf) => bytecast::f32_as_ne_mut_bytes(buf),
197 DecodingBuffer::F64(buf) => bytecast::f64_as_ne_mut_bytes(buf),
198 }
199 }
200}
201
202#[non_exhaustive]
208pub struct BufferLayoutPreference {
209 pub len: usize,
211 pub row_stride: Option<NonZeroUsize>,
213}
214
215#[derive(Clone)]
217enum DecodingExtent {
218 U8(usize),
219 U16(usize),
220 U32(usize),
221 U64(usize),
222 F16(usize),
223 F32(usize),
224 F64(usize),
225 I8(usize),
226 I16(usize),
227 I32(usize),
228 I64(usize),
229}
230
231impl DecodingExtent {
232 fn to_result_buffer(&self, limits: &Limits) -> TiffResult<DecodingResult> {
233 match *self {
234 DecodingExtent::U8(count) => DecodingResult::new_u8(count, limits),
235 DecodingExtent::U16(count) => DecodingResult::new_u16(count, limits),
236 DecodingExtent::U32(count) => DecodingResult::new_u32(count, limits),
237 DecodingExtent::U64(count) => DecodingResult::new_u64(count, limits),
238 DecodingExtent::F16(count) => DecodingResult::new_f16(count, limits),
239 DecodingExtent::F32(count) => DecodingResult::new_f32(count, limits),
240 DecodingExtent::F64(count) => DecodingResult::new_f64(count, limits),
241 DecodingExtent::I8(count) => DecodingResult::new_i8(count, limits),
242 DecodingExtent::I16(count) => DecodingResult::new_i16(count, limits),
243 DecodingExtent::I32(count) => DecodingResult::new_i32(count, limits),
244 DecodingExtent::I64(count) => DecodingResult::new_i64(count, limits),
245 }
246 }
247
248 fn preferred_layout(self) -> TiffResult<Layout> {
249 fn overflow(_: LayoutError) -> TiffError {
250 TiffError::LimitsExceeded
251 }
252
253 match self {
254 DecodingExtent::U8(count) => Layout::array::<u8>(count),
255 DecodingExtent::U16(count) => Layout::array::<u16>(count),
256 DecodingExtent::U32(count) => Layout::array::<u32>(count),
257 DecodingExtent::U64(count) => Layout::array::<u64>(count),
258 DecodingExtent::F16(count) => Layout::array::<f16>(count),
259 DecodingExtent::F32(count) => Layout::array::<f32>(count),
260 DecodingExtent::F64(count) => Layout::array::<f64>(count),
261 DecodingExtent::I8(count) => Layout::array::<i8>(count),
262 DecodingExtent::I16(count) => Layout::array::<i16>(count),
263 DecodingExtent::I32(count) => Layout::array::<i32>(count),
264 DecodingExtent::I64(count) => Layout::array::<i64>(count),
265 }
266 .map_err(overflow)
267 }
268
269 fn assert_layout(self, buffer: usize) -> TiffResult<()> {
270 let needed_bytes = self.preferred_layout()?.size();
271 if buffer < needed_bytes {
272 Err(TiffError::UsageError(
273 UsageError::InsufficientOutputBufferSize {
274 needed: needed_bytes,
275 provided: buffer,
276 },
277 ))
278 } else {
279 Ok(())
280 }
281 }
282}
283
284#[derive(Debug, Copy, Clone, PartialEq)]
285pub enum ChunkType {
287 Strip,
288 Tile,
289}
290
291#[derive(Clone, Debug)]
293#[non_exhaustive]
294pub struct Limits {
295 pub decoding_buffer_size: usize,
300 pub ifd_value_size: usize,
303 pub intermediate_buffer_size: usize,
306}
307
308impl Limits {
309 pub fn unlimited() -> Limits {
317 Limits {
318 decoding_buffer_size: usize::MAX,
319 ifd_value_size: usize::MAX,
320 intermediate_buffer_size: usize::MAX,
321 }
322 }
323}
324
325impl Default for Limits {
326 fn default() -> Limits {
327 Limits {
328 decoding_buffer_size: 256 * 1024 * 1024,
329 intermediate_buffer_size: 128 * 1024 * 1024,
330 ifd_value_size: 1024 * 1024,
331 }
332 }
333}
334
335#[derive(Debug)]
339pub struct Decoder<R>
340where
341 R: Read + Seek,
342{
343 value_reader: ValueReader<R>,
346 current_ifd: Option<IfdPointer>,
347 next_ifd: Option<IfdPointer>,
348 ifd_offsets: Vec<IfdPointer>,
350 seen_ifds: cycles::IfdCycles,
352 image: Image,
353}
354
355#[derive(Debug)]
359struct ValueReader<R> {
360 reader: EndianReader<R>,
361 bigtiff: bool,
362 limits: Limits,
363}
364
365pub struct IfdDecoder<'lt> {
367 inner: tag_reader::TagReader<'lt, dyn tag_reader::EntryDecoder + 'lt>,
368}
369
370fn rev_hpredict_nsamp(buf: &mut [u8], bit_depth: u8, samples: usize) {
371 match bit_depth {
372 0..=8 => {
373 for i in samples..buf.len() {
374 buf[i] = buf[i].wrapping_add(buf[i - samples]);
375 }
376 }
377 9..=16 => {
378 for i in (samples * 2..buf.len()).step_by(2) {
379 let v = u16::from_ne_bytes(buf[i..][..2].try_into().unwrap());
380 let p = u16::from_ne_bytes(buf[i - 2 * samples..][..2].try_into().unwrap());
381 buf[i..][..2].copy_from_slice(&(v.wrapping_add(p)).to_ne_bytes());
382 }
383 }
384 17..=32 => {
385 for i in (samples * 4..buf.len()).step_by(4) {
386 let v = u32::from_ne_bytes(buf[i..][..4].try_into().unwrap());
387 let p = u32::from_ne_bytes(buf[i - 4 * samples..][..4].try_into().unwrap());
388 buf[i..][..4].copy_from_slice(&(v.wrapping_add(p)).to_ne_bytes());
389 }
390 }
391 33..=64 => {
392 for i in (samples * 8..buf.len()).step_by(8) {
393 let v = u64::from_ne_bytes(buf[i..][..8].try_into().unwrap());
394 let p = u64::from_ne_bytes(buf[i - 8 * samples..][..8].try_into().unwrap());
395 buf[i..][..8].copy_from_slice(&(v.wrapping_add(p)).to_ne_bytes());
396 }
397 }
398 _ => {
399 unreachable!("Caller should have validated arguments. Please file a bug.")
400 }
401 }
402}
403
404fn predict_f32(input: &mut [u8], output: &mut [u8], samples: usize) {
405 for i in samples..input.len() {
406 input[i] = input[i].wrapping_add(input[i - samples]);
407 }
408
409 for (i, chunk) in output.chunks_mut(4).enumerate() {
410 chunk.copy_from_slice(&u32::to_ne_bytes(u32::from_be_bytes([
411 input[i],
412 input[input.len() / 4 + i],
413 input[input.len() / 4 * 2 + i],
414 input[input.len() / 4 * 3 + i],
415 ])));
416 }
417}
418
419fn predict_f16(input: &mut [u8], output: &mut [u8], samples: usize) {
420 for i in samples..input.len() {
421 input[i] = input[i].wrapping_add(input[i - samples]);
422 }
423
424 for (i, chunk) in output.chunks_mut(2).enumerate() {
425 chunk.copy_from_slice(&u16::to_ne_bytes(u16::from_be_bytes([
426 input[i],
427 input[input.len() / 2 + i],
428 ])));
429 }
430}
431
432fn predict_f64(input: &mut [u8], output: &mut [u8], samples: usize) {
433 for i in samples..input.len() {
434 input[i] = input[i].wrapping_add(input[i - samples]);
435 }
436
437 for (i, chunk) in output.chunks_mut(8).enumerate() {
438 chunk.copy_from_slice(&u64::to_ne_bytes(u64::from_be_bytes([
439 input[i],
440 input[input.len() / 8 + i],
441 input[input.len() / 8 * 2 + i],
442 input[input.len() / 8 * 3 + i],
443 input[input.len() / 8 * 4 + i],
444 input[input.len() / 8 * 5 + i],
445 input[input.len() / 8 * 6 + i],
446 input[input.len() / 8 * 7 + i],
447 ])));
448 }
449}
450
451fn fix_endianness_and_predict(
452 buf: &mut [u8],
453 bit_depth: u8,
454 samples: usize,
455 byte_order: ByteOrder,
456 predictor: Predictor,
457) {
458 match predictor {
459 Predictor::None => {
460 fix_endianness(buf, byte_order, bit_depth);
461 }
462 Predictor::Horizontal => {
463 fix_endianness(buf, byte_order, bit_depth);
464 rev_hpredict_nsamp(buf, bit_depth, samples);
465 }
466 Predictor::FloatingPoint => {
467 let mut buffer_copy = buf.to_vec();
468 match bit_depth {
469 16 => predict_f16(&mut buffer_copy, buf, samples),
470 32 => predict_f32(&mut buffer_copy, buf, samples),
471 64 => predict_f64(&mut buffer_copy, buf, samples),
472 _ => unreachable!("Caller should have validated arguments. Please file a bug."),
473 }
474 }
475 }
476}
477
478fn invert_colors(
479 buf: &mut [u8],
480 color_type: ColorType,
481 sample_format: SampleFormat,
482) -> TiffResult<()> {
483 match (color_type, sample_format) {
484 (ColorType::Gray(1 | 2 | 4 | 8), SampleFormat::Uint) => {
486 for x in buf {
487 *x = !*x;
494 }
495 }
496 (ColorType::Gray(16), SampleFormat::Uint) => {
497 for x in buf.chunks_mut(2) {
498 let v = u16::from_ne_bytes(x.try_into().unwrap());
499 x.copy_from_slice(&(0xffff - v).to_ne_bytes());
500 }
501 }
502 (ColorType::Gray(32), SampleFormat::Uint) => {
503 for x in buf.chunks_mut(4) {
504 let v = u32::from_ne_bytes(x.try_into().unwrap());
505 x.copy_from_slice(&(0xffff_ffff - v).to_ne_bytes());
506 }
507 }
508 (ColorType::Gray(64), SampleFormat::Uint) => {
509 for x in buf.chunks_mut(8) {
510 let v = u64::from_ne_bytes(x.try_into().unwrap());
511 x.copy_from_slice(&(0xffff_ffff_ffff_ffff - v).to_ne_bytes());
512 }
513 }
514 (ColorType::Gray(32), SampleFormat::IEEEFP) => {
515 for x in buf.chunks_mut(4) {
516 let v = f32::from_ne_bytes(x.try_into().unwrap());
517 x.copy_from_slice(&(1.0 - v).to_ne_bytes());
518 }
519 }
520 (ColorType::Gray(64), SampleFormat::IEEEFP) => {
521 for x in buf.chunks_mut(8) {
522 let v = f64::from_ne_bytes(x.try_into().unwrap());
523 x.copy_from_slice(&(1.0 - v).to_ne_bytes());
524 }
525 }
526 _ => {
527 return Err(TiffError::UnsupportedError(
528 TiffUnsupportedError::UnknownInterpretation,
529 ))
530 }
531 }
532
533 Ok(())
534}
535
536fn fix_endianness(buf: &mut [u8], byte_order: ByteOrder, bit_depth: u8) {
538 match byte_order {
539 ByteOrder::LittleEndian => match bit_depth {
540 0..=8 => {}
541 9..=16 => buf.chunks_exact_mut(2).for_each(|v| {
542 v.copy_from_slice(&u16::from_le_bytes((*v).try_into().unwrap()).to_ne_bytes())
543 }),
544 17..=32 => buf.chunks_exact_mut(4).for_each(|v| {
545 v.copy_from_slice(&u32::from_le_bytes((*v).try_into().unwrap()).to_ne_bytes())
546 }),
547 _ => buf.chunks_exact_mut(8).for_each(|v| {
548 v.copy_from_slice(&u64::from_le_bytes((*v).try_into().unwrap()).to_ne_bytes())
549 }),
550 },
551 ByteOrder::BigEndian => match bit_depth {
552 0..=8 => {}
553 9..=16 => buf.chunks_exact_mut(2).for_each(|v| {
554 v.copy_from_slice(&u16::from_be_bytes((*v).try_into().unwrap()).to_ne_bytes())
555 }),
556 17..=32 => buf.chunks_exact_mut(4).for_each(|v| {
557 v.copy_from_slice(&u32::from_be_bytes((*v).try_into().unwrap()).to_ne_bytes())
558 }),
559 _ => buf.chunks_exact_mut(8).for_each(|v| {
560 v.copy_from_slice(&u64::from_be_bytes((*v).try_into().unwrap()).to_ne_bytes())
561 }),
562 },
563 };
564}
565
566impl<R: Read + Seek> Decoder<R> {
567 pub fn new(mut r: R) -> TiffResult<Decoder<R>> {
568 let mut endianess = Vec::with_capacity(2);
569 (&mut r).take(2).read_to_end(&mut endianess)?;
570 let byte_order = match &*endianess {
571 b"II" => ByteOrder::LittleEndian,
572 b"MM" => ByteOrder::BigEndian,
573 _ => {
574 return Err(TiffError::FormatError(
575 TiffFormatError::TiffSignatureNotFound,
576 ))
577 }
578 };
579 let mut reader = EndianReader::new(r, byte_order);
580
581 let bigtiff = match reader.read_u16()? {
582 42 => false,
583 43 => {
584 if reader.read_u16()? != 8 {
586 return Err(TiffError::FormatError(
587 TiffFormatError::TiffSignatureNotFound,
588 ));
589 }
590 if reader.read_u16()? != 0 {
592 return Err(TiffError::FormatError(
593 TiffFormatError::TiffSignatureNotFound,
594 ));
595 }
596 true
597 }
598 _ => {
599 return Err(TiffError::FormatError(
600 TiffFormatError::TiffSignatureInvalid,
601 ))
602 }
603 };
604
605 let next_ifd = if bigtiff {
606 Some(reader.read_u64()?)
607 } else {
608 Some(u64::from(reader.read_u32()?))
609 }
610 .map(IfdPointer);
611
612 let current_ifd = *next_ifd.as_ref().unwrap();
613 let ifd_offsets = vec![current_ifd];
614
615 let mut decoder = Decoder {
616 value_reader: ValueReader {
617 reader,
618 bigtiff,
619 limits: Default::default(),
620 },
621 next_ifd,
622 ifd_offsets,
623 current_ifd: None,
624 seen_ifds: cycles::IfdCycles::new(),
625 image: Image {
626 ifd: None,
627 width: 0,
628 height: 0,
629 bits_per_sample: 1,
630 samples: 1,
631 sample_format: SampleFormat::Uint,
632 photometric_interpretation: PhotometricInterpretation::BlackIsZero,
633 compression_method: CompressionMethod::None,
634 jpeg_tables: None,
635 predictor: Predictor::None,
636 chunk_type: ChunkType::Strip,
637 planar_config: PlanarConfiguration::Chunky,
638 strip_decoder: None,
639 tile_attributes: None,
640 chunk_offsets: Vec::new(),
641 chunk_bytes: Vec::new(),
642 },
643 };
644 decoder.next_image()?;
645 Ok(decoder)
646 }
647
648 pub fn with_limits(mut self, limits: Limits) -> Decoder<R> {
649 self.value_reader.limits = limits;
650 self
651 }
652
653 pub fn dimensions(&mut self) -> TiffResult<(u32, u32)> {
654 Ok((self.image().width, self.image().height))
655 }
656
657 pub fn colortype(&mut self) -> TiffResult<ColorType> {
658 self.image().colortype()
659 }
660
661 pub fn ifd_pointer(&mut self) -> Option<IfdPointer> {
663 self.current_ifd
664 }
665
666 fn image(&self) -> &Image {
667 &self.image
668 }
669
670 pub fn seek_to_image(&mut self, ifd_index: usize) -> TiffResult<()> {
672 if ifd_index >= self.ifd_offsets.len() {
674 if self.next_ifd.is_none() {
676 self.current_ifd = None;
677
678 return Err(TiffError::FormatError(
679 TiffFormatError::ImageFileDirectoryNotFound,
680 ));
681 }
682
683 loop {
684 let ifd = self.next_ifd()?;
686
687 if ifd.next().is_none() {
688 break;
689 }
690
691 if ifd_index < self.ifd_offsets.len() {
692 break;
693 }
694 }
695 }
696
697 if let Some(ifd_offset) = self.ifd_offsets.get(ifd_index) {
699 let ifd = self.value_reader.read_directory(*ifd_offset)?;
700 self.next_ifd = ifd.next();
701 self.current_ifd = Some(*ifd_offset);
702 self.image = Image::from_reader(&mut self.value_reader, ifd)?;
703
704 Ok(())
705 } else {
706 Err(TiffError::FormatError(
707 TiffFormatError::ImageFileDirectoryNotFound,
708 ))
709 }
710 }
711
712 fn next_ifd(&mut self) -> TiffResult<Directory> {
713 let Some(next_ifd) = self.next_ifd.take() else {
714 return Err(TiffError::FormatError(
715 TiffFormatError::ImageFileDirectoryNotFound,
716 ));
717 };
718
719 let ifd = self.value_reader.read_directory(next_ifd)?;
720
721 self.seen_ifds.insert_next(next_ifd, ifd.next())?;
723
724 if self.ifd_offsets.last().copied() == self.current_ifd {
726 self.ifd_offsets.push(next_ifd);
727 }
728
729 self.current_ifd = Some(next_ifd);
730 self.next_ifd = ifd.next();
731
732 Ok(ifd)
733 }
734
735 pub fn next_image(&mut self) -> TiffResult<()> {
739 let ifd = self.next_ifd()?;
740 self.image = Image::from_reader(&mut self.value_reader, ifd)?;
741 Ok(())
742 }
743
744 pub fn more_images(&self) -> bool {
746 self.next_ifd.is_some()
747 }
748
749 pub fn byte_order(&self) -> ByteOrder {
751 self.value_reader.reader.byte_order
752 }
753
754 #[inline]
755 pub fn read_ifd_offset(&mut self) -> Result<u64, io::Error> {
756 if self.value_reader.bigtiff {
757 self.read_long8()
758 } else {
759 self.read_long().map(u64::from)
760 }
761 }
762
763 pub fn inner(&mut self) -> &mut R {
765 self.value_reader.reader.inner()
766 }
767
768 #[inline]
770 pub fn read_byte(&mut self) -> Result<u8, io::Error> {
771 let mut buf = [0; 1];
772 self.value_reader.reader.inner().read_exact(&mut buf)?;
773 Ok(buf[0])
774 }
775
776 #[inline]
778 pub fn read_short(&mut self) -> Result<u16, io::Error> {
779 self.value_reader.reader.read_u16()
780 }
781
782 #[inline]
784 pub fn read_sshort(&mut self) -> Result<i16, io::Error> {
785 self.value_reader.reader.read_i16()
786 }
787
788 #[inline]
790 pub fn read_long(&mut self) -> Result<u32, io::Error> {
791 self.value_reader.reader.read_u32()
792 }
793
794 #[inline]
796 pub fn read_slong(&mut self) -> Result<i32, io::Error> {
797 self.value_reader.reader.read_i32()
798 }
799
800 #[inline]
802 pub fn read_float(&mut self) -> Result<f32, io::Error> {
803 self.value_reader.reader.read_f32()
804 }
805
806 #[inline]
808 pub fn read_double(&mut self) -> Result<f64, io::Error> {
809 self.value_reader.reader.read_f64()
810 }
811
812 #[inline]
813 pub fn read_long8(&mut self) -> Result<u64, io::Error> {
814 self.value_reader.reader.read_u64()
815 }
816
817 #[inline]
818 pub fn read_slong8(&mut self) -> Result<i64, io::Error> {
819 self.value_reader.reader.read_i64()
820 }
821
822 #[inline]
824 pub fn read_string(&mut self, length: usize) -> TiffResult<String> {
825 let mut out = vec![0; length];
826 self.value_reader.reader.inner().read_exact(&mut out)?;
827 if let Some(first) = out.iter().position(|&b| b == 0) {
829 out.truncate(first);
830 }
831 Ok(String::from_utf8(out)?)
832 }
833
834 #[inline]
836 pub fn read_offset(&mut self) -> TiffResult<[u8; 4]> {
837 if self.value_reader.bigtiff {
838 return Err(TiffError::FormatError(
839 TiffFormatError::InconsistentSizesEncountered,
840 ));
841 }
842 let mut val = [0; 4];
843 self.value_reader.reader.inner().read_exact(&mut val)?;
844 Ok(val)
845 }
846
847 #[inline]
849 pub fn read_offset_u64(&mut self) -> Result<[u8; 8], io::Error> {
850 let mut val = [0; 8];
851 self.value_reader.reader.inner().read_exact(&mut val)?;
852 Ok(val)
853 }
854
855 #[inline]
857 pub fn goto_offset(&mut self, offset: u32) -> io::Result<()> {
858 self.goto_offset_u64(offset.into())
859 }
860
861 #[inline]
862 pub fn goto_offset_u64(&mut self, offset: u64) -> io::Result<()> {
863 self.value_reader.reader.goto_offset(offset)
864 }
865
866 pub fn read_directory(&mut self, ptr: IfdPointer) -> TiffResult<Directory> {
886 self.value_reader.read_directory(ptr)
887 }
888
889 fn check_chunk_type(&self, expected: ChunkType) -> TiffResult<()> {
890 if expected != self.image().chunk_type {
891 return Err(TiffError::UsageError(UsageError::InvalidChunkType(
892 expected,
893 self.image().chunk_type,
894 )));
895 }
896
897 Ok(())
898 }
899
900 pub fn get_chunk_type(&self) -> ChunkType {
902 self.image().chunk_type
903 }
904
905 pub fn strip_count(&mut self) -> TiffResult<u32> {
907 self.check_chunk_type(ChunkType::Strip)?;
908 let rows_per_strip = self.image().strip_decoder.as_ref().unwrap().rows_per_strip;
909
910 if rows_per_strip == 0 {
911 return Ok(0);
912 }
913
914 let height = match self.image().height.checked_add(rows_per_strip - 1) {
916 Some(h) => h,
917 None => return Err(TiffError::IntSizeError),
918 };
919
920 let strips = match self.image().planar_config {
921 PlanarConfiguration::Chunky => height / rows_per_strip,
922 PlanarConfiguration::Planar => height / rows_per_strip * self.image().samples as u32,
923 };
924
925 Ok(strips)
926 }
927
928 pub fn tile_count(&mut self) -> TiffResult<u32> {
930 self.check_chunk_type(ChunkType::Tile)?;
931 Ok(u32::try_from(self.image().chunk_offsets.len())?)
932 }
933
934 pub fn read_chunk_to_buffer(
935 &mut self,
936 mut buffer: DecodingBuffer,
937 chunk_index: u32,
938 output_width: usize,
939 ) -> TiffResult<()> {
940 let output_row_stride = (output_width as u64)
941 .saturating_mul(self.image.samples_per_pixel() as u64)
942 .saturating_mul(self.image.bits_per_sample as u64)
943 .div_ceil(8);
944
945 self.read_chunk_to_bytes(buffer.as_bytes_mut(), chunk_index, output_row_stride)
946 }
947
948 fn read_chunk_to_bytes(
949 &mut self,
950 buffer: &mut [u8],
951 chunk_index: u32,
952 output_row_stride: u64,
953 ) -> TiffResult<()> {
954 let offset = self.image.chunk_file_range(chunk_index)?.0;
955 self.goto_offset_u64(offset)?;
956
957 self.image.expand_chunk(
958 &mut self.value_reader,
959 buffer,
960 output_row_stride.try_into()?,
961 chunk_index,
962 )?;
963
964 Ok(())
965 }
966
967 fn result_buffer(&self, width: usize, height: usize) -> TiffResult<DecodingResult> {
968 self.result_extent(width, height)?
969 .to_result_buffer(&self.value_reader.limits)
970 }
971
972 fn result_extent(&self, width: usize, height: usize) -> TiffResult<DecodingExtent> {
976 let bits_per_sample = self.image.bits_per_sample;
977
978 let row_samples = if bits_per_sample >= 8 {
983 width
984 } else {
985 ((width as u64) * bits_per_sample as u64)
986 .div_ceil(8)
987 .try_into()
988 .map_err(|_| TiffError::LimitsExceeded)?
989 };
990
991 let buffer_size = row_samples
992 .checked_mul(height)
993 .and_then(|x| x.checked_mul(self.image.samples_per_pixel()))
994 .ok_or(TiffError::LimitsExceeded)?;
995
996 Ok(match self.image().sample_format {
997 SampleFormat::Uint => match bits_per_sample {
998 n if n <= 8 => DecodingExtent::U8(buffer_size),
999 n if n <= 16 => DecodingExtent::U16(buffer_size),
1000 n if n <= 32 => DecodingExtent::U32(buffer_size),
1001 n if n <= 64 => DecodingExtent::U64(buffer_size),
1002 n => {
1003 return Err(TiffError::UnsupportedError(
1004 TiffUnsupportedError::UnsupportedBitsPerChannel(n),
1005 ))
1006 }
1007 },
1008 SampleFormat::IEEEFP => match bits_per_sample {
1009 16 => DecodingExtent::F16(buffer_size),
1010 32 => DecodingExtent::F32(buffer_size),
1011 64 => DecodingExtent::F64(buffer_size),
1012 n => {
1013 return Err(TiffError::UnsupportedError(
1014 TiffUnsupportedError::UnsupportedBitsPerChannel(n),
1015 ))
1016 }
1017 },
1018 SampleFormat::Int => match bits_per_sample {
1019 n if n <= 8 => DecodingExtent::I8(buffer_size),
1020 n if n <= 16 => DecodingExtent::I16(buffer_size),
1021 n if n <= 32 => DecodingExtent::I32(buffer_size),
1022 n if n <= 64 => DecodingExtent::I64(buffer_size),
1023 n => {
1024 return Err(TiffError::UnsupportedError(
1025 TiffUnsupportedError::UnsupportedBitsPerChannel(n),
1026 ))
1027 }
1028 },
1029 format => {
1030 return Err(TiffUnsupportedError::UnsupportedSampleFormat(vec![format]).into())
1031 }
1032 })
1033 }
1034
1035 pub fn image_chunk_buffer_layout(
1049 &mut self,
1050 chunk_index: u32,
1051 ) -> TiffResult<BufferLayoutPreference> {
1052 let data_dims = self.image().chunk_data_dimensions(chunk_index)?;
1053 let layout = self
1054 .result_extent(data_dims.0 as usize, data_dims.1 as usize)?
1055 .preferred_layout()?;
1056
1057 let row_stride = self.image.minimum_row_stride(data_dims);
1058
1059 Ok(BufferLayoutPreference {
1060 len: layout.size(),
1061 row_stride,
1062 })
1063 }
1064
1065 pub fn read_chunk(&mut self, chunk_index: u32) -> TiffResult<DecodingResult> {
1072 let data_dims = self.image().chunk_data_dimensions(chunk_index)?;
1073
1074 let mut result = self.result_buffer(data_dims.0 as usize, data_dims.1 as usize)?;
1075
1076 self.read_chunk_to_buffer(result.as_buffer(0), chunk_index, data_dims.0 as usize)?;
1077
1078 Ok(result)
1079 }
1080
1081 pub fn read_chunk_bytes(&mut self, chunk_index: u32, buffer: &mut [u8]) -> TiffResult<()> {
1092 let data_dims = self.image().chunk_data_dimensions(chunk_index)?;
1093
1094 let extent = self.result_extent(data_dims.0 as usize, data_dims.1 as usize)?;
1095 extent.assert_layout(buffer.len())?;
1096
1097 let output_row_stride = u64::from(data_dims.0)
1098 .saturating_mul(self.image.samples_per_pixel() as u64)
1099 .saturating_mul(self.image.bits_per_sample as u64)
1100 .div_ceil(8);
1101
1102 self.read_chunk_to_bytes(buffer, chunk_index, output_row_stride)?;
1103
1104 Ok(())
1105 }
1106
1107 pub fn chunk_dimensions(&self) -> (u32, u32) {
1110 self.image().chunk_dimensions().unwrap()
1111 }
1112
1113 pub fn chunk_data_dimensions(&self, chunk_index: u32) -> (u32, u32) {
1116 self.image()
1117 .chunk_data_dimensions(chunk_index)
1118 .expect("invalid chunk_index")
1119 }
1120
1121 pub fn image_buffer_layout(&mut self) -> TiffResult<BufferLayoutPreference> {
1135 let data_dims @ (width, height) = (self.image.width, self.image.height);
1136
1137 let layout = self
1138 .result_extent(width as usize, height as usize)?
1139 .preferred_layout()?;
1140
1141 let row_stride = self.image.minimum_row_stride(data_dims);
1142
1143 Ok(BufferLayoutPreference {
1144 len: layout.size(),
1145 row_stride,
1146 })
1147 }
1148
1149 pub fn read_image(&mut self) -> TiffResult<DecodingResult> {
1156 let width = self.image().width;
1157 let height = self.image().height;
1158
1159 let mut result = self.result_buffer(width as usize, height as usize)?;
1160 self.read_image_bytes(result.as_buffer(0).as_bytes_mut())?;
1161
1162 Ok(result)
1163 }
1164
1165 pub fn read_image_bytes(&mut self, buffer: &mut [u8]) -> TiffResult<()> {
1176 let width = self.image().width;
1177 let height = self.image().height;
1178
1179 let extent = self.result_extent(width as usize, height as usize)?;
1180 extent.assert_layout(buffer.len())?;
1181
1182 if width == 0 || height == 0 {
1183 return Ok(());
1184 }
1185
1186 let chunk_dimensions = self.image().chunk_dimensions()?;
1187 let chunk_dimensions = (
1188 chunk_dimensions.0.min(width),
1189 chunk_dimensions.1.min(height),
1190 );
1191 if chunk_dimensions.0 == 0 || chunk_dimensions.1 == 0 {
1192 return Err(TiffError::FormatError(
1193 TiffFormatError::InconsistentSizesEncountered,
1194 ));
1195 }
1196
1197 let samples = self.image().samples_per_pixel();
1198 if samples == 0 {
1199 return Err(TiffError::FormatError(
1200 TiffFormatError::InconsistentSizesEncountered,
1201 ));
1202 }
1203
1204 let output_row_bits = (width as u64 * self.image.bits_per_sample as u64)
1205 .checked_mul(samples as u64)
1206 .ok_or(TiffError::LimitsExceeded)?;
1207 let output_row_stride: usize = output_row_bits.div_ceil(8).try_into()?;
1208
1209 let chunk_row_bits = (chunk_dimensions.0 as u64 * self.image.bits_per_sample as u64)
1210 .checked_mul(samples as u64)
1211 .ok_or(TiffError::LimitsExceeded)?;
1212 let chunk_row_bytes: usize = chunk_row_bits.div_ceil(8).try_into()?;
1213
1214 let chunks_across = ((width - 1) / chunk_dimensions.0 + 1) as usize;
1215
1216 if chunks_across > 1 && chunk_row_bits % 8 != 0 {
1217 return Err(TiffError::UnsupportedError(
1218 TiffUnsupportedError::MisalignedTileBoundaries,
1219 ));
1220 }
1221
1222 let image_chunks = self.image().chunk_offsets.len() / self.image().strips_per_pixel();
1223 for chunk in 0..image_chunks {
1228 self.goto_offset_u64(self.image().chunk_offsets[chunk])?;
1229
1230 let x = chunk % chunks_across;
1231 let y = chunk / chunks_across;
1232 let buffer_offset =
1233 y * output_row_stride * chunk_dimensions.1 as usize + x * chunk_row_bytes;
1234 self.image.expand_chunk(
1235 &mut self.value_reader,
1236 &mut buffer[buffer_offset..],
1237 output_row_stride,
1238 chunk as u32,
1239 )?;
1240 }
1241
1242 Ok(())
1243 }
1244
1245 fn image_ifd(&mut self) -> IfdDecoder<'_> {
1247 IfdDecoder {
1248 inner: tag_reader::TagReader {
1249 decoder: &mut self.value_reader,
1250 ifd: self.image.ifd.as_ref().unwrap(),
1251 },
1252 }
1253 }
1254
1255 pub fn read_directory_tags<'ifd>(&'ifd mut self, ifd: &'ifd Directory) -> IfdDecoder<'ifd> {
1280 IfdDecoder {
1281 inner: tag_reader::TagReader {
1282 decoder: &mut self.value_reader,
1283 ifd,
1284 },
1285 }
1286 }
1287
1288 pub fn find_tag(&mut self, tag: Tag) -> TiffResult<Option<ifd::Value>> {
1291 self.image_ifd().find_tag(tag)
1292 }
1293
1294 pub fn find_tag_unsigned<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<Option<T>> {
1297 self.image_ifd().find_tag_unsigned(tag)
1298 }
1299
1300 pub fn find_tag_unsigned_vec<T: TryFrom<u64>>(
1303 &mut self,
1304 tag: Tag,
1305 ) -> TiffResult<Option<Vec<T>>> {
1306 self.image_ifd().find_tag_unsigned_vec(tag)
1307 }
1308
1309 pub fn get_tag_unsigned<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<T> {
1312 self.image_ifd().get_tag_unsigned(tag)
1313 }
1314
1315 pub fn get_tag(&mut self, tag: Tag) -> TiffResult<ifd::Value> {
1318 self.image_ifd().get_tag(tag)
1319 }
1320
1321 pub fn get_tag_u32(&mut self, tag: Tag) -> TiffResult<u32> {
1322 self.get_tag(tag)?.into_u32()
1323 }
1324
1325 pub fn get_tag_u64(&mut self, tag: Tag) -> TiffResult<u64> {
1326 self.get_tag(tag)?.into_u64()
1327 }
1328
1329 pub fn get_tag_f32(&mut self, tag: Tag) -> TiffResult<f32> {
1331 self.get_tag(tag)?.into_f32()
1332 }
1333
1334 pub fn get_tag_f64(&mut self, tag: Tag) -> TiffResult<f64> {
1336 self.get_tag(tag)?.into_f64()
1337 }
1338
1339 pub fn get_tag_u32_vec(&mut self, tag: Tag) -> TiffResult<Vec<u32>> {
1341 self.get_tag(tag)?.into_u32_vec()
1342 }
1343
1344 pub fn get_tag_u16_vec(&mut self, tag: Tag) -> TiffResult<Vec<u16>> {
1345 self.get_tag(tag)?.into_u16_vec()
1346 }
1347
1348 pub fn get_tag_u64_vec(&mut self, tag: Tag) -> TiffResult<Vec<u64>> {
1349 self.get_tag(tag)?.into_u64_vec()
1350 }
1351
1352 pub fn get_tag_f32_vec(&mut self, tag: Tag) -> TiffResult<Vec<f32>> {
1354 self.get_tag(tag)?.into_f32_vec()
1355 }
1356
1357 pub fn get_tag_f64_vec(&mut self, tag: Tag) -> TiffResult<Vec<f64>> {
1359 self.get_tag(tag)?.into_f64_vec()
1360 }
1361
1362 pub fn get_tag_u8_vec(&mut self, tag: Tag) -> TiffResult<Vec<u8>> {
1364 self.get_tag(tag)?.into_u8_vec()
1365 }
1366
1367 pub fn get_tag_ascii_string(&mut self, tag: Tag) -> TiffResult<String> {
1369 self.get_tag(tag)?.into_string()
1370 }
1371
1372 pub fn tag_iter(&mut self) -> impl Iterator<Item = TiffResult<(Tag, ifd::Value)>> + '_ {
1373 self.image_ifd().tag_iter()
1374 }
1375}
1376
1377impl<R: Seek + Read> ValueReader<R> {
1378 pub(crate) fn read_directory(&mut self, ptr: IfdPointer) -> Result<Directory, TiffError> {
1379 Self::read_ifd(&mut self.reader, self.bigtiff, ptr)
1380 }
1381
1382 fn read_entry(
1390 reader: &mut EndianReader<R>,
1391 bigtiff: bool,
1392 ) -> TiffResult<Option<(Tag, ifd::Entry)>> {
1393 let tag = Tag::from_u16_exhaustive(reader.read_u16()?);
1394 let type_ = match Type::from_u16(reader.read_u16()?) {
1395 Some(t) => t,
1396 None => {
1397 reader.read_u32()?;
1399 reader.read_u32()?;
1400 return Ok(None);
1401 }
1402 };
1403 let entry = if bigtiff {
1404 let mut offset = [0; 8];
1405
1406 let count = reader.read_u64()?;
1407 reader.inner().read_exact(&mut offset)?;
1408 ifd::Entry::new_u64(type_, count, offset)
1409 } else {
1410 let mut offset = [0; 4];
1411
1412 let count = reader.read_u32()?;
1413 reader.inner().read_exact(&mut offset)?;
1414 ifd::Entry::new(type_, count, offset)
1415 };
1416 Ok(Some((tag, entry)))
1417 }
1418
1419 fn read_ifd(
1421 reader: &mut EndianReader<R>,
1422 bigtiff: bool,
1423 ifd_location: IfdPointer,
1424 ) -> TiffResult<Directory> {
1425 reader.goto_offset(ifd_location.0)?;
1426
1427 let mut entries: BTreeMap<_, _> = BTreeMap::new();
1428
1429 let num_tags = if bigtiff {
1430 reader.read_u64()?
1431 } else {
1432 reader.read_u16()?.into()
1433 };
1434
1435 for _ in 0..num_tags {
1436 let (tag, entry) = match Self::read_entry(reader, bigtiff)? {
1437 Some(val) => val,
1438 None => {
1439 continue;
1440 } };
1442
1443 entries.insert(tag.to_u16(), entry);
1444 }
1445
1446 let next_ifd = if bigtiff {
1447 reader.read_u64()?
1448 } else {
1449 reader.read_u32()?.into()
1450 };
1451
1452 let next_ifd = core::num::NonZeroU64::new(next_ifd);
1453
1454 Ok(Directory { entries, next_ifd })
1455 }
1456}
1457
1458impl IfdDecoder<'_> {
1459 pub fn find_tag(&mut self, tag: Tag) -> TiffResult<Option<ifd::Value>> {
1462 self.inner.find_tag(tag)
1463 }
1464
1465 pub fn find_tag_unsigned<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<Option<T>> {
1467 self.find_tag(tag)?
1468 .map(|v| v.into_u64())
1469 .transpose()?
1470 .map(|value| {
1471 T::try_from(value).map_err(|_| TiffFormatError::InvalidTagValueType(tag).into())
1472 })
1473 .transpose()
1474 }
1475
1476 pub fn find_tag_unsigned_vec<T: TryFrom<u64>>(
1479 &mut self,
1480 tag: Tag,
1481 ) -> TiffResult<Option<Vec<T>>> {
1482 self.find_tag(tag)?
1483 .map(|v| v.into_u64_vec())
1484 .transpose()?
1485 .map(|v| {
1486 v.into_iter()
1487 .map(|u| {
1488 T::try_from(u).map_err(|_| TiffFormatError::InvalidTagValueType(tag).into())
1489 })
1490 .collect()
1491 })
1492 .transpose()
1493 }
1494
1495 pub fn get_tag_unsigned<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<T> {
1498 self.find_tag_unsigned(tag)?
1499 .ok_or_else(|| TiffFormatError::RequiredTagNotFound(tag).into())
1500 }
1501
1502 pub fn get_tag(&mut self, tag: Tag) -> TiffResult<ifd::Value> {
1505 match self.find_tag(tag)? {
1506 Some(val) => Ok(val),
1507 None => Err(TiffError::FormatError(
1508 TiffFormatError::RequiredTagNotFound(tag),
1509 )),
1510 }
1511 }
1512
1513 pub fn get_tag_u32(&mut self, tag: Tag) -> TiffResult<u32> {
1515 self.get_tag(tag)?.into_u32()
1516 }
1517
1518 pub fn get_tag_u64(&mut self, tag: Tag) -> TiffResult<u64> {
1519 self.get_tag(tag)?.into_u64()
1520 }
1521
1522 pub fn get_tag_f32(&mut self, tag: Tag) -> TiffResult<f32> {
1524 self.get_tag(tag)?.into_f32()
1525 }
1526
1527 pub fn get_tag_f64(&mut self, tag: Tag) -> TiffResult<f64> {
1529 self.get_tag(tag)?.into_f64()
1530 }
1531
1532 pub fn get_tag_u32_vec(&mut self, tag: Tag) -> TiffResult<Vec<u32>> {
1534 self.get_tag(tag)?.into_u32_vec()
1535 }
1536
1537 pub fn get_tag_u16_vec(&mut self, tag: Tag) -> TiffResult<Vec<u16>> {
1538 self.get_tag(tag)?.into_u16_vec()
1539 }
1540
1541 pub fn get_tag_u64_vec(&mut self, tag: Tag) -> TiffResult<Vec<u64>> {
1542 self.get_tag(tag)?.into_u64_vec()
1543 }
1544
1545 pub fn get_tag_f32_vec(&mut self, tag: Tag) -> TiffResult<Vec<f32>> {
1547 self.get_tag(tag)?.into_f32_vec()
1548 }
1549
1550 pub fn get_tag_f64_vec(&mut self, tag: Tag) -> TiffResult<Vec<f64>> {
1552 self.get_tag(tag)?.into_f64_vec()
1553 }
1554
1555 pub fn get_tag_u8_vec(&mut self, tag: Tag) -> TiffResult<Vec<u8>> {
1557 self.get_tag(tag)?.into_u8_vec()
1558 }
1559
1560 pub fn get_tag_ascii_string(&mut self, tag: Tag) -> TiffResult<String> {
1562 self.get_tag(tag)?.into_string()
1563 }
1564}
1565
1566impl<'l> IfdDecoder<'l> {
1567 pub fn tag_iter(self) -> impl Iterator<Item = TiffResult<(Tag, ifd::Value)>> + 'l {
1569 self.inner
1570 .ifd
1571 .iter()
1572 .map(|(tag, entry)| match self.inner.decoder.entry_val(entry) {
1573 Ok(value) => Ok((tag, value)),
1574 Err(err) => Err(err),
1575 })
1576 }
1577}