1 | use std::{borrow::Cow, io::Write, slice::from_ref}; |
2 | |
3 | use crate::{bytecast, tags::Type, TiffError, TiffFormatError, TiffResult}; |
4 | |
5 | use super::writer::TiffWriter; |
6 | |
7 | /// Trait for types that can be encoded in a tiff file |
8 | pub trait TiffValue { |
9 | const BYTE_LEN: u8; |
10 | const FIELD_TYPE: Type; |
11 | fn count(&self) -> usize; |
12 | fn bytes(&self) -> usize { |
13 | self.count() * usize::from(Self::BYTE_LEN) |
14 | } |
15 | |
16 | /// Access this value as an contiguous sequence of bytes. |
17 | /// If their is no trivial representation, allocate it on the heap. |
18 | fn data(&self) -> Cow<[u8]>; |
19 | |
20 | /// Write this value to a TiffWriter. |
21 | /// While the default implementation will work in all cases, it may require unnecessary allocations. |
22 | /// The written bytes of any custom implementation MUST be the same as yielded by `self.data()`. |
23 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
24 | writer.write_bytes(&self.data())?; |
25 | Ok(()) |
26 | } |
27 | } |
28 | |
29 | impl TiffValue for [u8] { |
30 | const BYTE_LEN: u8 = 1; |
31 | const FIELD_TYPE: Type = Type::BYTE; |
32 | |
33 | fn count(&self) -> usize { |
34 | self.len() |
35 | } |
36 | |
37 | fn data(&self) -> Cow<[u8]> { |
38 | Cow::Borrowed(self) |
39 | } |
40 | } |
41 | |
42 | impl TiffValue for [i8] { |
43 | const BYTE_LEN: u8 = 1; |
44 | const FIELD_TYPE: Type = Type::SBYTE; |
45 | |
46 | fn count(&self) -> usize { |
47 | self.len() |
48 | } |
49 | |
50 | fn data(&self) -> Cow<[u8]> { |
51 | Cow::Borrowed(bytecast::i8_as_ne_bytes(self)) |
52 | } |
53 | } |
54 | |
55 | impl TiffValue for [u16] { |
56 | const BYTE_LEN: u8 = 2; |
57 | const FIELD_TYPE: Type = Type::SHORT; |
58 | |
59 | fn count(&self) -> usize { |
60 | self.len() |
61 | } |
62 | |
63 | fn data(&self) -> Cow<[u8]> { |
64 | Cow::Borrowed(bytecast::u16_as_ne_bytes(self)) |
65 | } |
66 | } |
67 | |
68 | impl TiffValue for [i16] { |
69 | const BYTE_LEN: u8 = 2; |
70 | const FIELD_TYPE: Type = Type::SSHORT; |
71 | |
72 | fn count(&self) -> usize { |
73 | self.len() |
74 | } |
75 | |
76 | fn data(&self) -> Cow<[u8]> { |
77 | Cow::Borrowed(bytecast::i16_as_ne_bytes(self)) |
78 | } |
79 | } |
80 | |
81 | impl TiffValue for [u32] { |
82 | const BYTE_LEN: u8 = 4; |
83 | const FIELD_TYPE: Type = Type::LONG; |
84 | |
85 | fn count(&self) -> usize { |
86 | self.len() |
87 | } |
88 | |
89 | fn data(&self) -> Cow<[u8]> { |
90 | Cow::Borrowed(bytecast::u32_as_ne_bytes(self)) |
91 | } |
92 | } |
93 | |
94 | impl TiffValue for [i32] { |
95 | const BYTE_LEN: u8 = 4; |
96 | const FIELD_TYPE: Type = Type::SLONG; |
97 | |
98 | fn count(&self) -> usize { |
99 | self.len() |
100 | } |
101 | |
102 | fn data(&self) -> Cow<[u8]> { |
103 | Cow::Borrowed(bytecast::i32_as_ne_bytes(self)) |
104 | } |
105 | } |
106 | |
107 | impl TiffValue for [u64] { |
108 | const BYTE_LEN: u8 = 8; |
109 | const FIELD_TYPE: Type = Type::LONG8; |
110 | |
111 | fn count(&self) -> usize { |
112 | self.len() |
113 | } |
114 | |
115 | fn data(&self) -> Cow<[u8]> { |
116 | Cow::Borrowed(bytecast::u64_as_ne_bytes(self)) |
117 | } |
118 | } |
119 | |
120 | impl TiffValue for [i64] { |
121 | const BYTE_LEN: u8 = 8; |
122 | const FIELD_TYPE: Type = Type::SLONG8; |
123 | |
124 | fn count(&self) -> usize { |
125 | self.len() |
126 | } |
127 | |
128 | fn data(&self) -> Cow<[u8]> { |
129 | Cow::Borrowed(bytecast::i64_as_ne_bytes(self)) |
130 | } |
131 | } |
132 | |
133 | impl TiffValue for [f32] { |
134 | const BYTE_LEN: u8 = 4; |
135 | const FIELD_TYPE: Type = Type::FLOAT; |
136 | |
137 | fn count(&self) -> usize { |
138 | self.len() |
139 | } |
140 | |
141 | fn data(&self) -> Cow<[u8]> { |
142 | // We write using native endian so this should be safe |
143 | Cow::Borrowed(bytecast::f32_as_ne_bytes(self)) |
144 | } |
145 | } |
146 | |
147 | impl TiffValue for [f64] { |
148 | const BYTE_LEN: u8 = 8; |
149 | const FIELD_TYPE: Type = Type::DOUBLE; |
150 | |
151 | fn count(&self) -> usize { |
152 | self.len() |
153 | } |
154 | |
155 | fn data(&self) -> Cow<[u8]> { |
156 | // We write using native endian so this should be safe |
157 | Cow::Borrowed(bytecast::f64_as_ne_bytes(self)) |
158 | } |
159 | } |
160 | |
161 | impl TiffValue for u8 { |
162 | const BYTE_LEN: u8 = 1; |
163 | const FIELD_TYPE: Type = Type::BYTE; |
164 | |
165 | fn count(&self) -> usize { |
166 | 1 |
167 | } |
168 | |
169 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
170 | writer.write_u8(*self)?; |
171 | Ok(()) |
172 | } |
173 | |
174 | fn data(&self) -> Cow<[u8]> { |
175 | Cow::Borrowed(from_ref(self)) |
176 | } |
177 | } |
178 | |
179 | impl TiffValue for i8 { |
180 | const BYTE_LEN: u8 = 1; |
181 | const FIELD_TYPE: Type = Type::SBYTE; |
182 | |
183 | fn count(&self) -> usize { |
184 | 1 |
185 | } |
186 | |
187 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
188 | writer.write_i8(*self)?; |
189 | Ok(()) |
190 | } |
191 | |
192 | fn data(&self) -> Cow<[u8]> { |
193 | Cow::Borrowed(bytecast::i8_as_ne_bytes(slice:from_ref(self))) |
194 | } |
195 | } |
196 | |
197 | impl TiffValue for u16 { |
198 | const BYTE_LEN: u8 = 2; |
199 | const FIELD_TYPE: Type = Type::SHORT; |
200 | |
201 | fn count(&self) -> usize { |
202 | 1 |
203 | } |
204 | |
205 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
206 | writer.write_u16(*self)?; |
207 | Ok(()) |
208 | } |
209 | |
210 | fn data(&self) -> Cow<[u8]> { |
211 | Cow::Borrowed(bytecast::u16_as_ne_bytes(slice:from_ref(self))) |
212 | } |
213 | } |
214 | |
215 | impl TiffValue for i16 { |
216 | const BYTE_LEN: u8 = 2; |
217 | const FIELD_TYPE: Type = Type::SSHORT; |
218 | |
219 | fn count(&self) -> usize { |
220 | 1 |
221 | } |
222 | |
223 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
224 | writer.write_i16(*self)?; |
225 | Ok(()) |
226 | } |
227 | |
228 | fn data(&self) -> Cow<[u8]> { |
229 | Cow::Borrowed(bytecast::i16_as_ne_bytes(slice:from_ref(self))) |
230 | } |
231 | } |
232 | |
233 | impl TiffValue for u32 { |
234 | const BYTE_LEN: u8 = 4; |
235 | const FIELD_TYPE: Type = Type::LONG; |
236 | |
237 | fn count(&self) -> usize { |
238 | 1 |
239 | } |
240 | |
241 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
242 | writer.write_u32(*self)?; |
243 | Ok(()) |
244 | } |
245 | |
246 | fn data(&self) -> Cow<[u8]> { |
247 | Cow::Borrowed(bytecast::u32_as_ne_bytes(slice:from_ref(self))) |
248 | } |
249 | } |
250 | |
251 | impl TiffValue for i32 { |
252 | const BYTE_LEN: u8 = 4; |
253 | const FIELD_TYPE: Type = Type::SLONG; |
254 | |
255 | fn count(&self) -> usize { |
256 | 1 |
257 | } |
258 | |
259 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
260 | writer.write_i32(*self)?; |
261 | Ok(()) |
262 | } |
263 | |
264 | fn data(&self) -> Cow<[u8]> { |
265 | Cow::Borrowed(bytecast::i32_as_ne_bytes(slice:from_ref(self))) |
266 | } |
267 | } |
268 | |
269 | impl TiffValue for u64 { |
270 | const BYTE_LEN: u8 = 8; |
271 | const FIELD_TYPE: Type = Type::LONG8; |
272 | |
273 | fn count(&self) -> usize { |
274 | 1 |
275 | } |
276 | |
277 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
278 | writer.write_u64(*self)?; |
279 | Ok(()) |
280 | } |
281 | |
282 | fn data(&self) -> Cow<[u8]> { |
283 | Cow::Borrowed(bytecast::u64_as_ne_bytes(slice:from_ref(self))) |
284 | } |
285 | } |
286 | |
287 | impl TiffValue for i64 { |
288 | const BYTE_LEN: u8 = 8; |
289 | const FIELD_TYPE: Type = Type::SLONG8; |
290 | |
291 | fn count(&self) -> usize { |
292 | 1 |
293 | } |
294 | |
295 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
296 | writer.write_i64(*self)?; |
297 | Ok(()) |
298 | } |
299 | |
300 | fn data(&self) -> Cow<[u8]> { |
301 | Cow::Borrowed(bytecast::i64_as_ne_bytes(slice:from_ref(self))) |
302 | } |
303 | } |
304 | |
305 | impl TiffValue for f32 { |
306 | const BYTE_LEN: u8 = 4; |
307 | const FIELD_TYPE: Type = Type::FLOAT; |
308 | |
309 | fn count(&self) -> usize { |
310 | 1 |
311 | } |
312 | |
313 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
314 | writer.write_f32(*self)?; |
315 | Ok(()) |
316 | } |
317 | |
318 | fn data(&self) -> Cow<[u8]> { |
319 | Cow::Borrowed(bytecast::f32_as_ne_bytes(slice:from_ref(self))) |
320 | } |
321 | } |
322 | |
323 | impl TiffValue for f64 { |
324 | const BYTE_LEN: u8 = 8; |
325 | const FIELD_TYPE: Type = Type::DOUBLE; |
326 | |
327 | fn count(&self) -> usize { |
328 | 1 |
329 | } |
330 | |
331 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
332 | writer.write_f64(*self)?; |
333 | Ok(()) |
334 | } |
335 | |
336 | fn data(&self) -> Cow<[u8]> { |
337 | Cow::Borrowed(bytecast::f64_as_ne_bytes(slice:from_ref(self))) |
338 | } |
339 | } |
340 | |
341 | impl TiffValue for Ifd { |
342 | const BYTE_LEN: u8 = 4; |
343 | const FIELD_TYPE: Type = Type::IFD; |
344 | |
345 | fn count(&self) -> usize { |
346 | 1 |
347 | } |
348 | |
349 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
350 | writer.write_u32(self.0)?; |
351 | Ok(()) |
352 | } |
353 | |
354 | fn data(&self) -> Cow<[u8]> { |
355 | Cow::Borrowed(bytecast::u32_as_ne_bytes(slice:from_ref(&self.0))) |
356 | } |
357 | } |
358 | |
359 | impl TiffValue for Ifd8 { |
360 | const BYTE_LEN: u8 = 8; |
361 | const FIELD_TYPE: Type = Type::IFD8; |
362 | |
363 | fn count(&self) -> usize { |
364 | 1 |
365 | } |
366 | |
367 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
368 | writer.write_u64(self.0)?; |
369 | Ok(()) |
370 | } |
371 | |
372 | fn data(&self) -> Cow<[u8]> { |
373 | Cow::Borrowed(bytecast::u64_as_ne_bytes(slice:from_ref(&self.0))) |
374 | } |
375 | } |
376 | |
377 | impl TiffValue for Rational { |
378 | const BYTE_LEN: u8 = 8; |
379 | const FIELD_TYPE: Type = Type::RATIONAL; |
380 | |
381 | fn count(&self) -> usize { |
382 | 1 |
383 | } |
384 | |
385 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
386 | writer.write_u32(self.n)?; |
387 | writer.write_u32(self.d)?; |
388 | Ok(()) |
389 | } |
390 | |
391 | fn data(&self) -> Cow<[u8]> { |
392 | Cow::Owned({ |
393 | let first_dword: &[u8] = bytecast::u32_as_ne_bytes(slice:from_ref(&self.n)); |
394 | let second_dword: &[u8] = bytecast::u32_as_ne_bytes(slice:from_ref(&self.d)); |
395 | [first_dword, second_dword].concat() |
396 | }) |
397 | } |
398 | } |
399 | |
400 | impl TiffValue for SRational { |
401 | const BYTE_LEN: u8 = 8; |
402 | const FIELD_TYPE: Type = Type::SRATIONAL; |
403 | |
404 | fn count(&self) -> usize { |
405 | 1 |
406 | } |
407 | |
408 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
409 | writer.write_i32(self.n)?; |
410 | writer.write_i32(self.d)?; |
411 | Ok(()) |
412 | } |
413 | |
414 | fn data(&self) -> Cow<[u8]> { |
415 | Cow::Owned({ |
416 | let first_dword: &[u8] = bytecast::i32_as_ne_bytes(slice:from_ref(&self.n)); |
417 | let second_dword: &[u8] = bytecast::i32_as_ne_bytes(slice:from_ref(&self.d)); |
418 | [first_dword, second_dword].concat() |
419 | }) |
420 | } |
421 | } |
422 | |
423 | impl TiffValue for str { |
424 | const BYTE_LEN: u8 = 1; |
425 | const FIELD_TYPE: Type = Type::ASCII; |
426 | |
427 | fn count(&self) -> usize { |
428 | self.len() + 1 |
429 | } |
430 | |
431 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
432 | if self.is_ascii() && !self.bytes().any(|b| b == 0) { |
433 | writer.write_bytes(self.as_bytes())?; |
434 | writer.write_u8(0)?; |
435 | Ok(()) |
436 | } else { |
437 | Err(TiffError::FormatError(TiffFormatError::InvalidTag)) |
438 | } |
439 | } |
440 | |
441 | fn data(&self) -> Cow<[u8]> { |
442 | Cow::Owned({ |
443 | if self.is_ascii() && !self.bytes().any(|b| b == 0) { |
444 | let bytes: &[u8] = self.as_bytes(); |
445 | [bytes, &[0]].concat() |
446 | } else { |
447 | vec![] |
448 | } |
449 | }) |
450 | } |
451 | } |
452 | |
453 | impl<'a, T: TiffValue + ?Sized> TiffValue for &'a T { |
454 | const BYTE_LEN: u8 = T::BYTE_LEN; |
455 | const FIELD_TYPE: Type = T::FIELD_TYPE; |
456 | |
457 | fn count(&self) -> usize { |
458 | (*self).count() |
459 | } |
460 | |
461 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
462 | (*self).write(writer) |
463 | } |
464 | |
465 | fn data(&self) -> Cow<[u8]> { |
466 | T::data(self) |
467 | } |
468 | } |
469 | |
470 | macro_rules! impl_tiff_value_for_contiguous_sequence { |
471 | ($inner_type:ty; $bytes:expr; $field_type:expr) => { |
472 | impl $crate::encoder::TiffValue for [$inner_type] { |
473 | const BYTE_LEN: u8 = $bytes; |
474 | const FIELD_TYPE: Type = $field_type; |
475 | |
476 | fn count(&self) -> usize { |
477 | self.len() |
478 | } |
479 | |
480 | fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> { |
481 | for x in self { |
482 | x.write(writer)?; |
483 | } |
484 | Ok(()) |
485 | } |
486 | |
487 | fn data(&self) -> Cow<[u8]> { |
488 | let mut buf: Vec<u8> = Vec::with_capacity(Self::BYTE_LEN as usize * self.len()); |
489 | for x in self { |
490 | buf.extend_from_slice(&x.data()); |
491 | } |
492 | Cow::Owned(buf) |
493 | } |
494 | } |
495 | }; |
496 | } |
497 | |
498 | impl_tiff_value_for_contiguous_sequence!(Ifd; 4; Type::IFD); |
499 | impl_tiff_value_for_contiguous_sequence!(Ifd8; 8; Type::IFD8); |
500 | impl_tiff_value_for_contiguous_sequence!(Rational; 8; Type::RATIONAL); |
501 | impl_tiff_value_for_contiguous_sequence!(SRational; 8; Type::SRATIONAL); |
502 | |
503 | /// Type to represent tiff values of type `IFD` |
504 | #[derive (Clone)] |
505 | pub struct Ifd(pub u32); |
506 | |
507 | /// Type to represent tiff values of type `IFD8` |
508 | #[derive (Clone)] |
509 | pub struct Ifd8(pub u64); |
510 | |
511 | /// Type to represent tiff values of type `RATIONAL` |
512 | #[derive (Clone)] |
513 | pub struct Rational { |
514 | pub n: u32, |
515 | pub d: u32, |
516 | } |
517 | |
518 | /// Type to represent tiff values of type `SRATIONAL` |
519 | #[derive (Clone)] |
520 | pub struct SRational { |
521 | pub n: i32, |
522 | pub d: i32, |
523 | } |
524 | |