1
1
use std:: collections:: HashMap ;
2
+ use std:: fmt:: Debug ;
2
3
use std:: ops:: Range ;
4
+ use std:: sync:: Arc ;
3
5
4
6
use bytes:: Bytes ;
5
7
use num_enum:: TryFromPrimitive ;
@@ -17,6 +19,48 @@ use crate::tile::Tile;
17
19
18
20
const DOCUMENT_NAME : u16 = 269 ;
19
21
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
+
20
64
/// An ImageFileDirectory representing Image content
21
65
// The ordering of these tags matches the sorted order in TIFF spec Appendix A
22
66
#[ allow( dead_code) ]
@@ -133,6 +177,8 @@ pub struct ImageFileDirectory {
133
177
134
178
pub ( crate ) copyright : Option < String > ,
135
179
180
+ pub ( crate ) extra_tags : ExtraTagsRegistry ,
181
+
136
182
// Geospatial tags
137
183
pub ( crate ) geo_key_directory : Option < GeoKeyDirectory > ,
138
184
pub ( crate ) model_pixel_scale : Option < Vec < f64 > > ,
@@ -149,6 +195,7 @@ impl ImageFileDirectory {
149
195
pub fn from_tags (
150
196
tag_data : HashMap < Tag , Value > ,
151
197
endianness : Endianness ,
198
+ extra_tags_registry : ExtraTagsRegistry
152
199
) -> AsyncTiffResult < Self > {
153
200
let mut new_subfile_type = None ;
154
201
let mut image_width = None ;
@@ -398,6 +445,7 @@ impl ImageFileDirectory {
398
445
geo_key_directory,
399
446
model_pixel_scale,
400
447
model_tiepoint,
448
+ extra_tags : extra_tags_registry,
401
449
other_tags,
402
450
} )
403
451
}
0 commit comments