1use tiff_core::ByteOrder;
4
5pub trait TiffWriteSample: tiff_core::TiffSample + Copy + Send + Sync {
7 const SAMPLE_FORMAT: u16;
9 const BITS_PER_SAMPLE: u16;
11 const BYTES_PER_SAMPLE: usize;
13
14 fn encode_slice(samples: &[Self], byte_order: ByteOrder) -> Vec<u8>;
16
17 fn lerc_encode_block(
23 samples: &[Self],
24 width: u32,
25 height: u32,
26 depth: u32,
27 max_z_error: f64,
28 index: usize,
29 ) -> crate::error::Result<Vec<u8>>;
30}
31
32macro_rules! impl_write_sample_8 {
35 ($ty:ty, $format:expr) => {
36 impl TiffWriteSample for $ty {
37 const SAMPLE_FORMAT: u16 = $format;
38 const BITS_PER_SAMPLE: u16 = 8;
39 const BYTES_PER_SAMPLE: usize = 1;
40
41 fn encode_slice(samples: &[Self], _byte_order: ByteOrder) -> Vec<u8> {
42 samples.iter().map(|&v| v as u8).collect()
43 }
44
45 fn lerc_encode_block(
46 samples: &[Self],
47 width: u32,
48 height: u32,
49 depth: u32,
50 max_z_error: f64,
51 index: usize,
52 ) -> crate::error::Result<Vec<u8>> {
53 crate::compress::lerc_encode(samples, width, height, depth, max_z_error, index)
54 }
55 }
56 };
57}
58
59macro_rules! impl_write_sample {
62 ($ty:ty, $format:expr, $bits:expr, $bytes:expr, $write_fn:ident) => {
63 impl TiffWriteSample for $ty {
64 const SAMPLE_FORMAT: u16 = $format;
65 const BITS_PER_SAMPLE: u16 = $bits;
66 const BYTES_PER_SAMPLE: usize = $bytes;
67
68 fn encode_slice(samples: &[Self], byte_order: ByteOrder) -> Vec<u8> {
69 let mut out = Vec::with_capacity(samples.len() * $bytes);
70 for &v in samples {
71 out.extend_from_slice(&byte_order.$write_fn(v));
72 }
73 out
74 }
75
76 fn lerc_encode_block(
77 samples: &[Self],
78 width: u32,
79 height: u32,
80 depth: u32,
81 max_z_error: f64,
82 index: usize,
83 ) -> crate::error::Result<Vec<u8>> {
84 crate::compress::lerc_encode(samples, width, height, depth, max_z_error, index)
85 }
86 }
87 };
88}
89
90macro_rules! impl_write_sample_no_lerc {
93 ($ty:ty, $format:expr, $bits:expr, $bytes:expr, $write_fn:ident) => {
94 impl TiffWriteSample for $ty {
95 const SAMPLE_FORMAT: u16 = $format;
96 const BITS_PER_SAMPLE: u16 = $bits;
97 const BYTES_PER_SAMPLE: usize = $bytes;
98
99 fn encode_slice(samples: &[Self], byte_order: ByteOrder) -> Vec<u8> {
100 let mut out = Vec::with_capacity(samples.len() * $bytes);
101 for &v in samples {
102 out.extend_from_slice(&byte_order.$write_fn(v));
103 }
104 out
105 }
106
107 fn lerc_encode_block(
108 _samples: &[Self],
109 _width: u32,
110 _height: u32,
111 _depth: u32,
112 _max_z_error: f64,
113 index: usize,
114 ) -> crate::error::Result<Vec<u8>> {
115 Err(crate::error::Error::CompressionFailed {
116 index,
117 reason: "LERC does not support 64-bit integer samples".into(),
118 })
119 }
120 }
121 };
122}
123
124impl_write_sample_8!(u8, 1);
125impl_write_sample_8!(i8, 2);
126impl_write_sample!(u16, 1, 16, 2, write_u16);
127impl_write_sample!(i16, 2, 16, 2, write_i16);
128impl_write_sample!(u32, 1, 32, 4, write_u32);
129impl_write_sample!(i32, 2, 32, 4, write_i32);
130impl_write_sample!(f32, 3, 32, 4, write_f32);
131impl_write_sample!(f64, 3, 64, 8, write_f64);
132impl_write_sample_no_lerc!(u64, 1, 64, 8, write_u64);
133impl_write_sample_no_lerc!(i64, 2, 64, 8, write_i64);