zenjxl_decoder/image/
data_type.rs1use std::fmt::Debug;
7
8mod private {
9 pub trait Sealed {}
10}
11
12#[derive(Copy, Clone, PartialEq, Eq, Debug)]
13pub enum DataTypeTag {
14 U8,
15 U16,
16 U32,
17 F32,
18 I8,
19 I16,
20 I32,
21 F16,
22 F64,
23}
24
25impl DataTypeTag {
26 pub const fn size(&self) -> usize {
29 match self {
30 DataTypeTag::U8 | DataTypeTag::I8 => 1,
31 DataTypeTag::U16 | DataTypeTag::F16 | DataTypeTag::I16 => 2,
32 DataTypeTag::U32 | DataTypeTag::F32 | DataTypeTag::I32 => 4,
33 DataTypeTag::F64 => 8,
34 }
35 }
36}
37
38const _: () = {
39 assert!(std::mem::size_of::<i8>() == DataTypeTag::I8.size());
40 assert!(std::mem::size_of::<u8>() == DataTypeTag::U8.size());
41 assert!(std::mem::size_of::<i16>() == DataTypeTag::I16.size());
42 assert!(std::mem::size_of::<u16>() == DataTypeTag::U16.size());
43 assert!(std::mem::size_of::<crate::util::f16>() == DataTypeTag::F16.size());
44 assert!(std::mem::size_of::<i32>() == DataTypeTag::I32.size());
45 assert!(std::mem::size_of::<u32>() == DataTypeTag::U32.size());
46 assert!(std::mem::size_of::<f32>() == DataTypeTag::F32.size());
47 assert!(std::mem::size_of::<f64>() == DataTypeTag::F64.size());
48};
49
50pub trait ImageDataType:
53 private::Sealed + bytemuck::Pod + Copy + Default + 'static + Debug + PartialEq + Send + Sync
54{
55 const DATA_TYPE_ID: DataTypeTag;
57
58 fn from_f64(f: f64) -> Self;
59 fn to_f64(self) -> f64;
60 #[cfg(test)]
61 fn random<R: rand::Rng>(rng: &mut R) -> Self;
62}
63
64#[cfg(test)]
65macro_rules! type_min {
66 (f32) => {
67 0.0f32
68 };
69 (f64) => {
70 0.0f64
71 };
72 ($ty: ty) => {
73 <$ty>::MIN
74 };
75}
76
77#[cfg(test)]
78macro_rules! type_max {
79 (f32) => {
80 1.0f32
81 };
82 (f64) => {
83 1.0f64
84 };
85 ($ty: ty) => {
86 <$ty>::MAX
87 };
88}
89
90macro_rules! impl_image_data_type {
91 ($ty: ident, $id: ident) => {
92 impl private::Sealed for $ty {}
93 impl ImageDataType for $ty {
94 const DATA_TYPE_ID: DataTypeTag = DataTypeTag::$id;
95 fn from_f64(f: f64) -> $ty {
96 f as $ty
97 }
98 fn to_f64(self) -> f64 {
99 self as f64
100 }
101 #[cfg(test)]
102 fn random<R: rand::Rng>(rng: &mut R) -> Self {
103 use rand::distr::{Distribution, Uniform};
104 let min = type_min!($ty);
105 let max = type_max!($ty);
106 Uniform::new_inclusive(min, max).unwrap().sample(rng)
107 }
108 }
109 };
110}
111
112impl_image_data_type!(u8, U8);
113impl_image_data_type!(u16, U16);
114impl_image_data_type!(u32, U32);
115impl_image_data_type!(f32, F32);
116impl_image_data_type!(i8, I8);
117impl_image_data_type!(i16, I16);
118impl_image_data_type!(i32, I32);
119
120impl_image_data_type!(f64, F64);
123
124impl private::Sealed for crate::util::f16 {}
125impl ImageDataType for crate::util::f16 {
126 const DATA_TYPE_ID: DataTypeTag = DataTypeTag::F16;
127 fn from_f64(f: f64) -> crate::util::f16 {
128 crate::util::f16::from_f64(f)
129 }
130 fn to_f64(self) -> f64 {
131 crate::util::f16::to_f64(self)
132 }
133 #[cfg(test)]
134 fn random<R: rand::Rng>(rng: &mut R) -> Self {
135 use rand::distr::{Distribution, Uniform};
136 Self::from_f64(Uniform::new(0.0f32, 1.0f32).unwrap().sample(rng) as f64)
137 }
138}