diff --git a/src/metadata/fetch.rs b/src/metadata/fetch.rs index 90050f83..1f06e90f 100644 --- a/src/metadata/fetch.rs +++ b/src/metadata/fetch.rs @@ -28,13 +28,16 @@ impl MetadataFetch for T { } } -pub(crate) struct MetadataCursor<'a, F: MetadataFetch> { +/// An endian-aware cursor into the tiff +#[derive(Debug)] +pub struct MetadataCursor<'a, F: MetadataFetch> { fetch: &'a F, offset: u64, endianness: Endianness, } impl<'a, F: MetadataFetch> MetadataCursor<'a, F> { + /// Create a new MetadataCursor pointing at the start of the tiff pub fn new(fetch: &'a F, endianness: Endianness) -> Self { Self { fetch, @@ -43,6 +46,7 @@ impl<'a, F: MetadataFetch> MetadataCursor<'a, F> { } } + /// Create a new Metadata cursor at the specified offset pub fn new_with_offset(fetch: &'a F, endianness: Endianness, offset: u64) -> Self { Self { fetch, @@ -51,11 +55,18 @@ impl<'a, F: MetadataFetch> MetadataCursor<'a, F> { } } + /// set the offset on this cursor + /// + /// ```ignore + /// use async_tiff::metadata::MetadataCursor; + /// let cursor = MetadataCursor::new().with_offset(42); + /// ``` pub fn with_offset(mut self, offset: u64) -> Self { self.offset = offset; self } + /// seek to a pre-determined offset in the tiff pub fn seek(&mut self, offset: u64) { self.offset = offset; } @@ -84,7 +95,7 @@ impl<'a, F: MetadataFetch> MetadataCursor<'a, F> { } /// Read a u16 from the cursor, advancing the internal state by 2 bytes. - pub(crate) async fn read_u16(&mut self) -> AsyncTiffResult { + pub async fn read_u16(&mut self) -> AsyncTiffResult { self.read(2).await?.read_u16() } @@ -94,7 +105,7 @@ impl<'a, F: MetadataFetch> MetadataCursor<'a, F> { } /// Read a u32 from the cursor, advancing the internal state by 4 bytes. - pub(crate) async fn read_u32(&mut self) -> AsyncTiffResult { + pub async fn read_u32(&mut self) -> AsyncTiffResult { self.read(4).await?.read_u32() } @@ -104,7 +115,7 @@ impl<'a, F: MetadataFetch> MetadataCursor<'a, F> { } /// Read a u64 from the cursor, advancing the internal state by 8 bytes. - pub(crate) async fn read_u64(&mut self) -> AsyncTiffResult { + pub async fn read_u64(&mut self) -> AsyncTiffResult { self.read(8).await?.read_u64() } diff --git a/src/metadata/mod.rs b/src/metadata/mod.rs index 79498140..78055033 100644 --- a/src/metadata/mod.rs +++ b/src/metadata/mod.rs @@ -61,5 +61,5 @@ pub mod cache; mod fetch; mod reader; -pub use fetch::MetadataFetch; +pub use fetch::{MetadataCursor, MetadataFetch}; pub use reader::{ImageFileDirectoryReader, TiffMetadataReader}; diff --git a/src/metadata/reader.rs b/src/metadata/reader.rs index 9488f1f6..e26db6a9 100644 --- a/src/metadata/reader.rs +++ b/src/metadata/reader.rs @@ -215,8 +215,7 @@ impl ImageFileDirectoryReader { tag_idx: u64, ) -> AsyncTiffResult<(Tag, TagValue)> { assert!(tag_idx < self.tag_count); - let tag_offset = - self.ifd_start_offset + self.tag_count_byte_size + (self.ifd_entry_byte_size * tag_idx); + let tag_offset = self.tag_offset(tag_idx); let (tag_name, tag_value) = read_tag(fetch, tag_offset, self.endianness, self.bigtiff).await?; Ok((tag_name, tag_value)) @@ -257,6 +256,16 @@ impl ImageFileDirectoryReader { Ok(Some(next_ifd_offset)) } } + + /// The number of tags in this IFD + pub fn tag_count(&self) -> u64 { + self.tag_count + } + + /// The offset of the nth IFD tag in the tiff + pub fn tag_offset(&self, tag_idx: u64) -> u64 { + self.ifd_start_offset + self.tag_count_byte_size + (self.ifd_entry_byte_size * tag_idx) + } } /// Read a single tag from the cursor