tiff/encoder/
tiff_value.rs1use std::{borrow::Cow, io::Write, slice::from_ref};
2
3use crate::{bytecast, tags, tags::Type, TiffError, TiffFormatError, TiffResult};
4
5use super::writer::TiffWriter;
6
7#[diagnostic::on_unimplemented(
9 message = "the type `{Self}` does not implement `TiffValue`",
10 note = "the trait is implemented for primitive types (`u8`, `i16`, `f32`, etc.)",
11 note = "the trait is implemented for shared references to values",
12 note = "the trait is implemented for slices, pass them by reference (e.g. `&[u8]`)",
13 note = "the trait is implemented for arrays if it is implemented for a slice",
14 note = "values in a `Vec` or `Box` should be dereferenced, e.g. `&vec[..]`"
15)]
16pub trait TiffValue {
17 const BYTE_LEN: u8;
18 const FIELD_TYPE: Type;
19
20 fn count(&self) -> usize;
24
25 fn bytes(&self) -> usize {
26 self.count() * usize::from(Self::BYTE_LEN)
27 }
28
29 fn data(&self) -> Cow<'_, [u8]>;
32
33 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
37 writer.write_bytes(&self.data())?;
38 Ok(())
39 }
40}
41
42impl TiffValue for [u8] {
43 const BYTE_LEN: u8 = 1;
44 const FIELD_TYPE: Type = Type::BYTE;
45
46 fn count(&self) -> usize {
47 self.len()
48 }
49
50 fn data(&self) -> Cow<'_, [u8]> {
51 Cow::Borrowed(self)
52 }
53}
54
55impl TiffValue for [i8] {
56 const BYTE_LEN: u8 = 1;
57 const FIELD_TYPE: Type = Type::SBYTE;
58
59 fn count(&self) -> usize {
60 self.len()
61 }
62
63 fn data(&self) -> Cow<'_, [u8]> {
64 Cow::Borrowed(bytecast::i8_as_ne_bytes(self))
65 }
66}
67
68impl TiffValue for [u16] {
69 const BYTE_LEN: u8 = 2;
70 const FIELD_TYPE: Type = Type::SHORT;
71
72 fn count(&self) -> usize {
73 self.len()
74 }
75
76 fn data(&self) -> Cow<'_, [u8]> {
77 Cow::Borrowed(bytecast::u16_as_ne_bytes(self))
78 }
79}
80
81impl TiffValue for [i16] {
82 const BYTE_LEN: u8 = 2;
83 const FIELD_TYPE: Type = Type::SSHORT;
84
85 fn count(&self) -> usize {
86 self.len()
87 }
88
89 fn data(&self) -> Cow<'_, [u8]> {
90 Cow::Borrowed(bytecast::i16_as_ne_bytes(self))
91 }
92}
93
94impl TiffValue for [u32] {
95 const BYTE_LEN: u8 = 4;
96 const FIELD_TYPE: Type = Type::LONG;
97
98 fn count(&self) -> usize {
99 self.len()
100 }
101
102 fn data(&self) -> Cow<'_, [u8]> {
103 Cow::Borrowed(bytecast::u32_as_ne_bytes(self))
104 }
105}
106
107impl TiffValue for [i32] {
108 const BYTE_LEN: u8 = 4;
109 const FIELD_TYPE: Type = Type::SLONG;
110
111 fn count(&self) -> usize {
112 self.len()
113 }
114
115 fn data(&self) -> Cow<'_, [u8]> {
116 Cow::Borrowed(bytecast::i32_as_ne_bytes(self))
117 }
118}
119
120impl TiffValue for [u64] {
121 const BYTE_LEN: u8 = 8;
122 const FIELD_TYPE: Type = Type::LONG8;
123
124 fn count(&self) -> usize {
125 self.len()
126 }
127
128 fn data(&self) -> Cow<'_, [u8]> {
129 Cow::Borrowed(bytecast::u64_as_ne_bytes(self))
130 }
131}
132
133impl TiffValue for [i64] {
134 const BYTE_LEN: u8 = 8;
135 const FIELD_TYPE: Type = Type::SLONG8;
136
137 fn count(&self) -> usize {
138 self.len()
139 }
140
141 fn data(&self) -> Cow<'_, [u8]> {
142 Cow::Borrowed(bytecast::i64_as_ne_bytes(self))
143 }
144}
145
146impl TiffValue for [f32] {
147 const BYTE_LEN: u8 = 4;
148 const FIELD_TYPE: Type = Type::FLOAT;
149
150 fn count(&self) -> usize {
151 self.len()
152 }
153
154 fn data(&self) -> Cow<'_, [u8]> {
155 Cow::Borrowed(bytecast::f32_as_ne_bytes(self))
157 }
158}
159
160impl TiffValue for [f64] {
161 const BYTE_LEN: u8 = 8;
162 const FIELD_TYPE: Type = Type::DOUBLE;
163
164 fn count(&self) -> usize {
165 self.len()
166 }
167
168 fn data(&self) -> Cow<'_, [u8]> {
169 Cow::Borrowed(bytecast::f64_as_ne_bytes(self))
171 }
172}
173
174impl TiffValue for u8 {
175 const BYTE_LEN: u8 = 1;
176 const FIELD_TYPE: Type = Type::BYTE;
177
178 fn count(&self) -> usize {
179 1
180 }
181
182 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
183 writer.write_u8(*self)?;
184 Ok(())
185 }
186
187 fn data(&self) -> Cow<'_, [u8]> {
188 Cow::Borrowed(from_ref(self))
189 }
190}
191
192impl TiffValue for i8 {
193 const BYTE_LEN: u8 = 1;
194 const FIELD_TYPE: Type = Type::SBYTE;
195
196 fn count(&self) -> usize {
197 1
198 }
199
200 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
201 writer.write_i8(*self)?;
202 Ok(())
203 }
204
205 fn data(&self) -> Cow<'_, [u8]> {
206 Cow::Borrowed(bytecast::i8_as_ne_bytes(from_ref(self)))
207 }
208}
209
210impl TiffValue for u16 {
211 const BYTE_LEN: u8 = 2;
212 const FIELD_TYPE: Type = Type::SHORT;
213
214 fn count(&self) -> usize {
215 1
216 }
217
218 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
219 writer.write_u16(*self)?;
220 Ok(())
221 }
222
223 fn data(&self) -> Cow<'_, [u8]> {
224 Cow::Borrowed(bytecast::u16_as_ne_bytes(from_ref(self)))
225 }
226}
227
228impl TiffValue for i16 {
229 const BYTE_LEN: u8 = 2;
230 const FIELD_TYPE: Type = Type::SSHORT;
231
232 fn count(&self) -> usize {
233 1
234 }
235
236 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
237 writer.write_i16(*self)?;
238 Ok(())
239 }
240
241 fn data(&self) -> Cow<'_, [u8]> {
242 Cow::Borrowed(bytecast::i16_as_ne_bytes(from_ref(self)))
243 }
244}
245
246impl TiffValue for u32 {
247 const BYTE_LEN: u8 = 4;
248 const FIELD_TYPE: Type = Type::LONG;
249
250 fn count(&self) -> usize {
251 1
252 }
253
254 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
255 writer.write_u32(*self)?;
256 Ok(())
257 }
258
259 fn data(&self) -> Cow<'_, [u8]> {
260 Cow::Borrowed(bytecast::u32_as_ne_bytes(from_ref(self)))
261 }
262}
263
264impl TiffValue for i32 {
265 const BYTE_LEN: u8 = 4;
266 const FIELD_TYPE: Type = Type::SLONG;
267
268 fn count(&self) -> usize {
269 1
270 }
271
272 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
273 writer.write_i32(*self)?;
274 Ok(())
275 }
276
277 fn data(&self) -> Cow<'_, [u8]> {
278 Cow::Borrowed(bytecast::i32_as_ne_bytes(from_ref(self)))
279 }
280}
281
282impl TiffValue for u64 {
283 const BYTE_LEN: u8 = 8;
284 const FIELD_TYPE: Type = Type::LONG8;
285
286 fn count(&self) -> usize {
287 1
288 }
289
290 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
291 writer.write_u64(*self)?;
292 Ok(())
293 }
294
295 fn data(&self) -> Cow<'_, [u8]> {
296 Cow::Borrowed(bytecast::u64_as_ne_bytes(from_ref(self)))
297 }
298}
299
300impl TiffValue for i64 {
301 const BYTE_LEN: u8 = 8;
302 const FIELD_TYPE: Type = Type::SLONG8;
303
304 fn count(&self) -> usize {
305 1
306 }
307
308 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
309 writer.write_i64(*self)?;
310 Ok(())
311 }
312
313 fn data(&self) -> Cow<'_, [u8]> {
314 Cow::Borrowed(bytecast::i64_as_ne_bytes(from_ref(self)))
315 }
316}
317
318impl TiffValue for f32 {
319 const BYTE_LEN: u8 = 4;
320 const FIELD_TYPE: Type = Type::FLOAT;
321
322 fn count(&self) -> usize {
323 1
324 }
325
326 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
327 writer.write_f32(*self)?;
328 Ok(())
329 }
330
331 fn data(&self) -> Cow<'_, [u8]> {
332 Cow::Borrowed(bytecast::f32_as_ne_bytes(from_ref(self)))
333 }
334}
335
336impl TiffValue for f64 {
337 const BYTE_LEN: u8 = 8;
338 const FIELD_TYPE: Type = Type::DOUBLE;
339
340 fn count(&self) -> usize {
341 1
342 }
343
344 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
345 writer.write_f64(*self)?;
346 Ok(())
347 }
348
349 fn data(&self) -> Cow<'_, [u8]> {
350 Cow::Borrowed(bytecast::f64_as_ne_bytes(from_ref(self)))
351 }
352}
353
354impl TiffValue for Ifd {
355 const BYTE_LEN: u8 = 4;
356 const FIELD_TYPE: Type = Type::IFD;
357
358 fn count(&self) -> usize {
359 1
360 }
361
362 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
363 writer.write_u32(self.0)?;
364 Ok(())
365 }
366
367 fn data(&self) -> Cow<'_, [u8]> {
368 Cow::Borrowed(bytecast::u32_as_ne_bytes(from_ref(&self.0)))
369 }
370}
371
372impl TiffValue for Ifd8 {
373 const BYTE_LEN: u8 = 8;
374 const FIELD_TYPE: Type = Type::IFD8;
375
376 fn count(&self) -> usize {
377 1
378 }
379
380 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
381 writer.write_u64(self.0)?;
382 Ok(())
383 }
384
385 fn data(&self) -> Cow<'_, [u8]> {
386 Cow::Borrowed(bytecast::u64_as_ne_bytes(from_ref(&self.0)))
387 }
388}
389
390impl TiffValue for Rational {
391 const BYTE_LEN: u8 = 8;
392 const FIELD_TYPE: Type = Type::RATIONAL;
393
394 fn count(&self) -> usize {
395 1
396 }
397
398 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
399 writer.write_u32(self.n)?;
400 writer.write_u32(self.d)?;
401 Ok(())
402 }
403
404 fn data(&self) -> Cow<'_, [u8]> {
405 Cow::Owned({
406 let first_dword = bytecast::u32_as_ne_bytes(from_ref(&self.n));
407 let second_dword = bytecast::u32_as_ne_bytes(from_ref(&self.d));
408 [first_dword, second_dword].concat()
409 })
410 }
411}
412
413impl TiffValue for SRational {
414 const BYTE_LEN: u8 = 8;
415 const FIELD_TYPE: Type = Type::SRATIONAL;
416
417 fn count(&self) -> usize {
418 1
419 }
420
421 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
422 writer.write_i32(self.n)?;
423 writer.write_i32(self.d)?;
424 Ok(())
425 }
426
427 fn data(&self) -> Cow<'_, [u8]> {
428 Cow::Owned({
429 let first_dword = bytecast::i32_as_ne_bytes(from_ref(&self.n));
430 let second_dword = bytecast::i32_as_ne_bytes(from_ref(&self.d));
431 [first_dword, second_dword].concat()
432 })
433 }
434}
435
436impl TiffValue for str {
437 const BYTE_LEN: u8 = 1;
438 const FIELD_TYPE: Type = Type::ASCII;
439
440 fn count(&self) -> usize {
441 self.len() + 1
442 }
443
444 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
445 if self.is_ascii() && !self.bytes().any(|b| b == 0) {
446 writer.write_bytes(self.as_bytes())?;
447 writer.write_u8(0)?;
448 Ok(())
449 } else {
450 Err(TiffError::FormatError(TiffFormatError::InvalidTag))
451 }
452 }
453
454 fn data(&self) -> Cow<'_, [u8]> {
455 Cow::Owned({
456 if self.is_ascii() && !self.bytes().any(|b| b == 0) {
457 let bytes: &[u8] = self.as_bytes();
458 [bytes, &[0]].concat()
459 } else {
460 vec![]
461 }
462 })
463 }
464}
465
466impl TiffValue for tags::CompressionMethod {
479 const BYTE_LEN: u8 = <u16 as TiffValue>::BYTE_LEN;
480 const FIELD_TYPE: Type = Type::SHORT;
481
482 fn count(&self) -> usize {
483 1
484 }
485
486 fn data(&self) -> Cow<'_, [u8]> {
487 let bytes = self.to_u16().to_ne_bytes();
488 Cow::Owned(bytes.to_vec())
489 }
490}
491
492impl TiffValue for tags::PhotometricInterpretation {
493 const BYTE_LEN: u8 = <u16 as TiffValue>::BYTE_LEN;
494 const FIELD_TYPE: Type = Type::SHORT;
495
496 fn count(&self) -> usize {
497 1
498 }
499
500 fn data(&self) -> Cow<'_, [u8]> {
501 self.to_u16().to_ne_bytes().to_vec().into()
502 }
503}
504
505impl TiffValue for tags::PlanarConfiguration {
506 const BYTE_LEN: u8 = 2;
507 const FIELD_TYPE: Type = Type::SHORT;
508
509 fn count(&self) -> usize {
510 1
511 }
512
513 fn data(&self) -> Cow<'_, [u8]> {
514 self.to_u16().to_ne_bytes().to_vec().into()
515 }
516}
517
518impl TiffValue for tags::Predictor {
519 const BYTE_LEN: u8 = <u16 as TiffValue>::BYTE_LEN;
520 const FIELD_TYPE: Type = Type::SHORT;
521
522 fn count(&self) -> usize {
523 1
524 }
525
526 fn data(&self) -> Cow<'_, [u8]> {
527 self.to_u16().to_ne_bytes().to_vec().into()
528 }
529}
530
531impl TiffValue for tags::ResolutionUnit {
532 const BYTE_LEN: u8 = <u16 as TiffValue>::BYTE_LEN;
533 const FIELD_TYPE: Type = Type::SHORT;
534
535 fn count(&self) -> usize {
536 1
537 }
538
539 fn data(&self) -> Cow<'_, [u8]> {
540 self.to_u16().to_ne_bytes().to_vec().into()
541 }
542}
543
544impl TiffValue for [tags::SampleFormat] {
550 const BYTE_LEN: u8 = <u16 as TiffValue>::BYTE_LEN;
551 const FIELD_TYPE: Type = Type::SHORT;
552
553 fn count(&self) -> usize {
554 self.len()
555 }
556
557 fn data(&self) -> Cow<'_, [u8]> {
558 let mut buf: Vec<u8> = Vec::with_capacity(self.len() * 2);
559 for x in self {
560 buf.extend_from_slice(&x.to_u16().to_ne_bytes());
561 }
562 Cow::Owned(buf)
563 }
564}
565
566impl TiffValue for [tags::ExtraSamples] {
572 const BYTE_LEN: u8 = <u16 as TiffValue>::BYTE_LEN;
573 const FIELD_TYPE: Type = Type::SHORT;
574
575 fn count(&self) -> usize {
576 self.len()
577 }
578
579 fn data(&self) -> Cow<'_, [u8]> {
580 let mut buf: Vec<u8> = Vec::with_capacity(self.len() * 2);
581 for x in self {
582 buf.extend_from_slice(&x.to_u16().to_ne_bytes());
583 }
584 Cow::Owned(buf)
585 }
586}
587
588#[diagnostic::do_not_recommend]
596impl<T: TiffValue + ?Sized> TiffValue for &'_ T {
597 const BYTE_LEN: u8 = T::BYTE_LEN;
598 const FIELD_TYPE: Type = T::FIELD_TYPE;
599
600 fn count(&self) -> usize {
601 (*self).count()
602 }
603
604 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
605 (*self).write(writer)
606 }
607
608 fn data(&self) -> Cow<'_, [u8]> {
609 T::data(self)
610 }
611}
612
613impl<T, const N: usize> TiffValue for [T; N]
615where
616 [T]: TiffValue,
617{
618 const BYTE_LEN: u8 = <[T]>::BYTE_LEN;
619 const FIELD_TYPE: Type = <[T]>::FIELD_TYPE;
620
621 fn count(&self) -> usize {
622 self.as_slice().count()
623 }
624
625 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
626 self.as_slice().write(writer)
627 }
628
629 fn data(&self) -> Cow<'_, [u8]> {
630 self.as_slice().data()
631 }
632}
633
634macro_rules! impl_tiff_value_for_contiguous_sequence {
635 ($inner_type:ty; $bytes:expr; $field_type:expr) => {
636 impl $crate::encoder::TiffValue for [$inner_type] {
637 const BYTE_LEN: u8 = $bytes;
638 const FIELD_TYPE: Type = $field_type;
639
640 fn count(&self) -> usize {
641 self.len()
642 }
643
644 fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
645 for x in self {
646 x.write(writer)?;
647 }
648 Ok(())
649 }
650
651 fn data(&self) -> Cow<'_, [u8]> {
652 let mut buf: Vec<u8> = Vec::with_capacity(Self::BYTE_LEN as usize * self.len());
653 for x in self {
654 buf.extend_from_slice(&x.data());
655 }
656 Cow::Owned(buf)
657 }
658 }
659 };
660}
661
662impl_tiff_value_for_contiguous_sequence!(Ifd; 4; Type::IFD);
663impl_tiff_value_for_contiguous_sequence!(Ifd8; 8; Type::IFD8);
664impl_tiff_value_for_contiguous_sequence!(Rational; 8; Type::RATIONAL);
665impl_tiff_value_for_contiguous_sequence!(SRational; 8; Type::SRATIONAL);
666
667#[derive(Clone)]
669pub struct Ifd(pub u32);
670
671#[derive(Clone)]
673pub struct Ifd8(pub u64);
674
675#[derive(Clone)]
677pub struct Rational {
678 pub n: u32,
679 pub d: u32,
680}
681
682#[derive(Clone)]
684pub struct SRational {
685 pub n: i32,
686 pub d: i32,
687}