tiff/decoder/
tag_reader.rs

1use std::convert::TryFrom;
2use std::io::{Read, Seek};
3
4use crate::tags::Tag;
5use crate::{TiffError, TiffFormatError, TiffResult};
6
7use super::ifd::{Directory, Value};
8use super::stream::SmartReader;
9use super::Limits;
10
11pub(crate) struct TagReader<'a, R: Read + Seek> {
12    pub reader: &'a mut SmartReader<R>,
13    pub ifd: &'a Directory,
14    pub limits: &'a Limits,
15    pub bigtiff: bool,
16}
17impl<'a, R: Read + Seek> TagReader<'a, R> {
18    pub(crate) fn find_tag(&mut self, tag: Tag) -> TiffResult<Option<Value>> {
19        Ok(match self.ifd.get(&tag) {
20            Some(entry) => Some(entry.clone().val(self.limits, self.bigtiff, self.reader)?),
21            None => None,
22        })
23    }
24    pub(crate) fn require_tag(&mut self, tag: Tag) -> TiffResult<Value> {
25        match self.find_tag(tag)? {
26            Some(val) => Ok(val),
27            None => Err(TiffError::FormatError(
28                TiffFormatError::RequiredTagNotFound(tag),
29            )),
30        }
31    }
32    pub fn find_tag_uint_vec<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<Option<Vec<T>>> {
33        self.find_tag(tag)?
34            .map(|v| v.into_u64_vec())
35            .transpose()?
36            .map(|v| {
37                v.into_iter()
38                    .map(|u| {
39                        T::try_from(u).map_err(|_| TiffFormatError::InvalidTagValueType(tag).into())
40                    })
41                    .collect()
42            })
43            .transpose()
44    }
45}