1 | use std::convert::TryFrom; |
2 | use std::io::{Read, Seek}; |
3 | |
4 | use crate::tags::Tag; |
5 | use crate::{TiffError, TiffFormatError, TiffResult}; |
6 | |
7 | use super::ifd::{Directory, Value}; |
8 | use super::stream::SmartReader; |
9 | use super::Limits; |
10 | |
11 | pub(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 | } |
17 | impl<'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 | |