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