Skip to content

Commit 418dbb3

Browse files
committed
preliminary commit
1 parent 86bf7aa commit 418dbb3

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

src/ifd.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::collections::HashMap;
2+
use std::fmt::Debug;
23
use std::ops::Range;
4+
use std::sync::Arc;
35

46
use bytes::Bytes;
57
use num_enum::TryFromPrimitive;
@@ -17,6 +19,48 @@ use crate::tile::Tile;
1719

1820
const DOCUMENT_NAME: u16 = 269;
1921

22+
/// Trait to implement for custom tags, such as Geo, EXIF, OME, etc
23+
pub trait ExtraTags: ExtraTagsCloneArc + std::any::Any + Debug {
24+
/// a list of tags this entry processes
25+
/// e.g. for Geo this would be [34735, 34736, 34737]
26+
fn tags(&self) -> &'static [Tag];
27+
/// process a single tag
28+
fn process_tag(&mut self, tag: u16, value: Value) -> AsyncTiffResult<()>;
29+
}
30+
31+
//
32+
pub trait ExtraTagsCloneArc {
33+
fn clone_arc(&self) -> Arc<dyn ExtraTags>;
34+
}
35+
36+
impl<T> ExtraTagsCloneArc for T
37+
where
38+
T: 'static + ExtraTags + Clone
39+
{
40+
fn clone_arc(&self) -> Arc<dyn ExtraTags> {
41+
Arc::new(self.clone())
42+
}
43+
}
44+
45+
#[derive(Debug, Clone)]
46+
pub struct ExtraTagsRegistry(HashMap<Tag, Arc<dyn ExtraTags>>);
47+
48+
impl ExtraTagsRegistry {
49+
pub fn register(&mut self, tags: Arc<dyn ExtraTags>) -> AsyncTiffResult<()> {
50+
// check for duplicates
51+
for tag in tags.tags() {
52+
if self.0.contains_key(tag) {
53+
return Err(AsyncTiffError::General(format!("Tag {tag:?} already registered in {self:?}!")));
54+
}
55+
}
56+
// add to self
57+
for tag in tags.tags() {
58+
self.0.insert(*tag, tags.clone());
59+
}
60+
Ok(())
61+
}
62+
}
63+
2064
/// An ImageFileDirectory representing Image content
2165
// The ordering of these tags matches the sorted order in TIFF spec Appendix A
2266
#[allow(dead_code)]
@@ -133,6 +177,8 @@ pub struct ImageFileDirectory {
133177

134178
pub(crate) copyright: Option<String>,
135179

180+
pub(crate) extra_tags: ExtraTagsRegistry,
181+
136182
// Geospatial tags
137183
pub(crate) geo_key_directory: Option<GeoKeyDirectory>,
138184
pub(crate) model_pixel_scale: Option<Vec<f64>>,
@@ -149,6 +195,7 @@ impl ImageFileDirectory {
149195
pub fn from_tags(
150196
tag_data: HashMap<Tag, Value>,
151197
endianness: Endianness,
198+
extra_tags_registry: ExtraTagsRegistry
152199
) -> AsyncTiffResult<Self> {
153200
let mut new_subfile_type = None;
154201
let mut image_width = None;
@@ -398,6 +445,7 @@ impl ImageFileDirectory {
398445
geo_key_directory,
399446
model_pixel_scale,
400447
model_tiepoint,
448+
extra_tags: extra_tags_registry,
401449
other_tags,
402450
})
403451
}

src/metadata/reader.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::io::Read;
44
use bytes::Bytes;
55

66
use crate::error::{AsyncTiffError, AsyncTiffResult};
7+
use crate::ifd::ExtraTagsRegistry;
78
use crate::metadata::fetch::MetadataCursor;
89
use crate::metadata::MetadataFetch;
910
use crate::reader::Endianness;
@@ -157,6 +158,8 @@ pub struct ImageFileDirectoryReader {
157158
ifd_entry_byte_size: u64,
158159
/// The number of bytes that the value for the number of tags takes up.
159160
tag_count_byte_size: u64,
161+
/// Registry for parsing extra tags
162+
extra_tags_registry: ExtraTagsRegistry,
160163
}
161164

162165
impl ImageFileDirectoryReader {
@@ -166,6 +169,7 @@ impl ImageFileDirectoryReader {
166169
ifd_start_offset: u64,
167170
bigtiff: bool,
168171
endianness: Endianness,
172+
extra_tags_registry: ExtraTagsRegistry,
169173
) -> AsyncTiffResult<Self> {
170174
let mut cursor = MetadataCursor::new_with_offset(fetch, endianness, ifd_start_offset);
171175

@@ -194,6 +198,7 @@ impl ImageFileDirectoryReader {
194198
tag_count,
195199
tag_count_byte_size,
196200
ifd_start_offset,
201+
extra_tags_registry,
197202
})
198203
}
199204

@@ -226,7 +231,7 @@ impl ImageFileDirectoryReader {
226231
let (tag, value) = self.read_tag(fetch, tag_idx).await?;
227232
tags.insert(tag, value);
228233
}
229-
ImageFileDirectory::from_tags(tags, self.endianness)
234+
ImageFileDirectory::from_tags(tags, self.endianness, self.extra_tags_registry)
230235
}
231236

232237
/// Finish this reader, reading the byte offset of the next IFD

0 commit comments

Comments
 (0)