Skip to main content

tiff_core/
sample.rs

1use crate::layout::RasterLayout;
2
3/// Types that can be read directly from a decoded TIFF raster.
4pub trait TiffSample: Clone + 'static {
5    fn matches_layout(layout: &RasterLayout) -> bool;
6    fn decode_many(bytes: &[u8]) -> Vec<Self>;
7    fn type_name() -> &'static str;
8}
9
10macro_rules! impl_tiff_sample {
11    ($ty:ty, $format:expr, $bits:expr, $chunk:expr, $from_ne:expr) => {
12        impl TiffSample for $ty {
13            fn matches_layout(layout: &RasterLayout) -> bool {
14                layout.sample_format == $format && layout.bits_per_sample == $bits
15            }
16
17            fn decode_many(bytes: &[u8]) -> Vec<Self> {
18                bytes.chunks_exact($chunk).map($from_ne).collect()
19            }
20
21            fn type_name() -> &'static str {
22                stringify!($ty)
23            }
24        }
25    };
26}
27
28impl TiffSample for u8 {
29    fn matches_layout(layout: &RasterLayout) -> bool {
30        layout.sample_format == 1 && layout.bits_per_sample <= 8
31    }
32
33    fn decode_many(bytes: &[u8]) -> Vec<Self> {
34        bytes.to_vec()
35    }
36
37    fn type_name() -> &'static str {
38        "u8"
39    }
40}
41
42impl_tiff_sample!(i8, 2, 8, 1, |chunk: &[u8]| chunk[0] as i8);
43impl_tiff_sample!(u16, 1, 16, 2, |chunk: &[u8]| u16::from_ne_bytes(
44    chunk.try_into().unwrap()
45));
46impl_tiff_sample!(i16, 2, 16, 2, |chunk: &[u8]| i16::from_ne_bytes(
47    chunk.try_into().unwrap()
48));
49impl_tiff_sample!(u32, 1, 32, 4, |chunk: &[u8]| u32::from_ne_bytes(
50    chunk.try_into().unwrap()
51));
52impl_tiff_sample!(i32, 2, 32, 4, |chunk: &[u8]| i32::from_ne_bytes(
53    chunk.try_into().unwrap()
54));
55impl_tiff_sample!(f32, 3, 32, 4, |chunk: &[u8]| f32::from_ne_bytes(
56    chunk.try_into().unwrap()
57));
58impl_tiff_sample!(u64, 1, 64, 8, |chunk: &[u8]| u64::from_ne_bytes(
59    chunk.try_into().unwrap()
60));
61impl_tiff_sample!(i64, 2, 64, 8, |chunk: &[u8]| i64::from_ne_bytes(
62    chunk.try_into().unwrap()
63));
64impl_tiff_sample!(f64, 3, 64, 8, |chunk: &[u8]| f64::from_ne_bytes(
65    chunk.try_into().unwrap()
66));