rawkit/tiff/
tags.rs

1use super::types::{Array, ConstArray, TagType, TypeByte, TypeIfd, TypeLong, TypeNumber, TypeOrientation, TypeSRational, TypeSShort, TypeShort, TypeSonyToneCurve, TypeString};
2use super::{Ifd, TagId, TiffError, TiffRead};
3
4use std::io::{Read, Seek};
5
6pub trait SimpleTag {
7	type Type: TagType;
8
9	const ID: TagId;
10	const NAME: &'static str;
11}
12
13pub struct ImageWidth;
14pub struct ImageLength;
15pub struct BitsPerSample;
16pub struct Compression;
17pub struct PhotometricInterpretation;
18pub struct Make;
19pub struct Model;
20pub struct StripOffsets;
21pub struct Orientation;
22pub struct SamplesPerPixel;
23pub struct RowsPerStrip;
24pub struct StripByteCounts;
25pub struct SubIfd;
26pub struct JpegOffset;
27pub struct JpegLength;
28pub struct SonyDataOffset;
29pub struct SonyToneCurve;
30pub struct BlackLevel;
31pub struct WhiteBalanceRggbLevels;
32pub struct CfaPatternDim;
33pub struct CfaPattern;
34pub struct ColorMatrix1;
35pub struct ColorMatrix2;
36
37impl SimpleTag for ImageWidth {
38	type Type = TypeNumber;
39
40	const ID: TagId = TagId::ImageWidth;
41	const NAME: &'static str = "Image Width";
42}
43
44impl SimpleTag for ImageLength {
45	type Type = TypeNumber;
46
47	const ID: TagId = TagId::ImageLength;
48	const NAME: &'static str = "Image Length";
49}
50
51impl SimpleTag for BitsPerSample {
52	type Type = TypeShort;
53
54	const ID: TagId = TagId::BitsPerSample;
55	const NAME: &'static str = "Bits per Sample";
56}
57
58impl SimpleTag for Compression {
59	type Type = TypeShort;
60
61	const ID: TagId = TagId::Compression;
62	const NAME: &'static str = "Compression";
63}
64
65impl SimpleTag for PhotometricInterpretation {
66	type Type = TypeShort;
67
68	const ID: TagId = TagId::PhotometricInterpretation;
69	const NAME: &'static str = "Photometric Interpretation";
70}
71
72impl SimpleTag for Make {
73	type Type = TypeString;
74
75	const ID: TagId = TagId::Make;
76	const NAME: &'static str = "Make";
77}
78
79impl SimpleTag for Model {
80	type Type = TypeString;
81
82	const ID: TagId = TagId::Model;
83	const NAME: &'static str = "Model";
84}
85
86impl SimpleTag for StripOffsets {
87	type Type = Array<TypeNumber>;
88
89	const ID: TagId = TagId::StripOffsets;
90	const NAME: &'static str = "Strip Offsets";
91}
92
93impl SimpleTag for Orientation {
94	type Type = TypeOrientation;
95
96	const ID: TagId = TagId::Orientation;
97	const NAME: &'static str = "Orientation";
98}
99
100impl SimpleTag for SamplesPerPixel {
101	type Type = TypeShort;
102
103	const ID: TagId = TagId::SamplesPerPixel;
104	const NAME: &'static str = "Samples per Pixel";
105}
106
107impl SimpleTag for RowsPerStrip {
108	type Type = TypeNumber;
109
110	const ID: TagId = TagId::RowsPerStrip;
111	const NAME: &'static str = "Rows per Strip";
112}
113
114impl SimpleTag for StripByteCounts {
115	type Type = Array<TypeNumber>;
116
117	const ID: TagId = TagId::StripByteCounts;
118	const NAME: &'static str = "Strip Byte Counts";
119}
120
121impl SimpleTag for SubIfd {
122	type Type = TypeIfd;
123
124	const ID: TagId = TagId::SubIfd;
125	const NAME: &'static str = "SubIFD";
126}
127
128impl SimpleTag for JpegOffset {
129	type Type = TypeLong;
130
131	const ID: TagId = TagId::JpegOffset;
132	const NAME: &'static str = "Jpeg Offset";
133}
134
135impl SimpleTag for JpegLength {
136	type Type = TypeLong;
137
138	const ID: TagId = TagId::JpegLength;
139	const NAME: &'static str = "Jpeg Length";
140}
141
142impl SimpleTag for CfaPatternDim {
143	type Type = ConstArray<TypeShort, 2>;
144
145	const ID: TagId = TagId::CfaPatternDim;
146	const NAME: &'static str = "CFA Pattern Dimension";
147}
148
149impl SimpleTag for CfaPattern {
150	type Type = Array<TypeByte>;
151
152	const ID: TagId = TagId::CfaPattern;
153	const NAME: &'static str = "CFA Pattern";
154}
155
156impl SimpleTag for ColorMatrix1 {
157	type Type = Array<TypeSRational>;
158
159	const ID: TagId = TagId::ColorMatrix1;
160	const NAME: &'static str = "Color Matrix 1";
161}
162
163impl SimpleTag for ColorMatrix2 {
164	type Type = Array<TypeSRational>;
165
166	const ID: TagId = TagId::ColorMatrix2;
167	const NAME: &'static str = "Color Matrix 2";
168}
169
170impl SimpleTag for SonyDataOffset {
171	type Type = TypeLong;
172
173	const ID: TagId = TagId::SubIfd;
174	const NAME: &'static str = "Sony Data Offset";
175}
176
177impl SimpleTag for SonyToneCurve {
178	type Type = TypeSonyToneCurve;
179
180	const ID: TagId = TagId::SonyToneCurve;
181	const NAME: &'static str = "Sony Tone Curve";
182}
183
184impl SimpleTag for BlackLevel {
185	type Type = ConstArray<TypeShort, 4>;
186
187	const ID: TagId = TagId::BlackLevel;
188	const NAME: &'static str = "Black Level";
189}
190
191impl SimpleTag for WhiteBalanceRggbLevels {
192	type Type = ConstArray<TypeSShort, 4>;
193
194	const ID: TagId = TagId::WhiteBalanceRggbLevels;
195	const NAME: &'static str = "White Balance Levels (RGGB)";
196}
197
198pub trait Tag {
199	type Output;
200
201	fn get<R: Read + Seek>(ifd: &Ifd, file: &mut TiffRead<R>) -> Result<Self::Output, TiffError>;
202}
203
204impl<T: SimpleTag> Tag for T {
205	type Output = <T::Type as TagType>::Output;
206
207	fn get<R: Read + Seek>(ifd: &Ifd, file: &mut TiffRead<R>) -> Result<Self::Output, TiffError> {
208		let tag_id = T::ID;
209		let index: u32 = ifd.iter().position(|x| x.tag == tag_id).ok_or(TiffError::MissingTag)?.try_into()?;
210
211		file.seek_from_start(ifd.current_ifd_offset + 2 + 12 * index + 2)?;
212		T::Type::read(file)
213	}
214}
215
216impl<T: Tag> Tag for Option<T> {
217	type Output = Option<T::Output>;
218
219	fn get<R: Read + Seek>(ifd: &Ifd, file: &mut TiffRead<R>) -> Result<Self::Output, TiffError> {
220		let result = T::get(ifd, file);
221
222		match result {
223			Err(TiffError::MissingTag) => Ok(None),
224			Ok(x) => Ok(Some(x)),
225			Err(x) => Err(x),
226		}
227	}
228}