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}
46