1#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
3#[repr(u8)]
4pub enum TransformType {
5 Dct8 = 0,
6 Hornuss,
7 Dct2,
8 Dct4,
9 Dct16,
10 Dct32,
11 Dct16x8,
12 Dct8x16,
13 Dct32x8,
14 Dct8x32,
15 Dct32x16,
16 Dct16x32,
17 Dct4x8,
18 Dct8x4,
19 Afv0,
20 Afv1,
21 Afv2,
22 Afv3,
23 Dct64,
24 Dct64x32,
25 Dct32x64,
26 Dct128,
27 Dct128x64,
28 Dct64x128,
29 Dct256,
30 Dct256x128,
31 Dct128x256,
32}
33
34impl TryFrom<u8> for TransformType {
35 type Error = jxl_bitstream::Error;
36
37 fn try_from(value: u8) -> jxl_bitstream::Result<Self> {
38 if value <= TransformType::Dct128x256 as u8 {
39 Ok(unsafe { std::mem::transmute::<u8, Self>(value) })
41 } else {
42 Err(jxl_bitstream::Error::InvalidEnum {
43 name: "TransformType",
44 value: value as u32,
45 })
46 }
47 }
48}
49
50impl TransformType {
51 pub fn dct_select_size(self) -> (u32, u32) {
53 use TransformType::*;
54
55 match self {
56 Dct8 | Hornuss | Dct2 | Dct4 | Dct4x8 | Dct8x4 | Afv0 | Afv1 | Afv2 | Afv3 => (1, 1),
57 Dct16 => (2, 2),
58 Dct32 => (4, 4),
59 Dct16x8 => (1, 2),
60 Dct8x16 => (2, 1),
61 Dct32x8 => (1, 4),
62 Dct8x32 => (4, 1),
63 Dct32x16 => (2, 4),
64 Dct16x32 => (4, 2),
65 Dct64 => (8, 8),
66 Dct64x32 => (4, 8),
67 Dct32x64 => (8, 4),
68 Dct128 => (16, 16),
69 Dct128x64 => (8, 16),
70 Dct64x128 => (16, 8),
71 Dct256 => (32, 32),
72 Dct256x128 => (16, 32),
73 Dct128x256 => (32, 16),
74 }
75 }
76
77 pub(crate) fn dequant_matrix_param_index(self) -> u32 {
78 use TransformType::*;
79
80 match self {
81 Dct8 => 0,
82 Hornuss => 1,
83 Dct2 => 2,
84 Dct4 => 3,
85 Dct16 => 4,
86 Dct32 => 5,
87 Dct16x8 | Dct8x16 => 6,
88 Dct32x8 | Dct8x32 => 7,
89 Dct32x16 | Dct16x32 => 8,
90 Dct4x8 | Dct8x4 => 9,
91 Afv0 | Afv1 | Afv2 | Afv3 => 10,
92 Dct64 => 11,
93 Dct64x32 | Dct32x64 => 12,
94 Dct128 => 13,
95 Dct128x64 | Dct64x128 => 14,
96 Dct256 => 15,
97 Dct256x128 | Dct128x256 => 16,
98 }
99 }
100
101 pub(crate) fn dequant_matrix_size(self) -> (u32, u32) {
102 use TransformType::*;
103
104 match self {
105 Dct8 | Hornuss | Dct2 | Dct4 | Dct4x8 | Dct8x4 | Afv0 | Afv1 | Afv2 | Afv3 => (8, 8),
106 Dct16 => (16, 16),
107 Dct32 => (32, 32),
108 Dct16x8 | Dct8x16 => (16, 8),
109 Dct32x8 | Dct8x32 => (32, 8),
110 Dct32x16 | Dct16x32 => (32, 16),
111 Dct64 => (64, 64),
112 Dct64x32 | Dct32x64 => (64, 32),
113 Dct128 => (128, 128),
114 Dct128x64 | Dct64x128 => (128, 64),
115 Dct256 => (256, 256),
116 Dct256x128 | Dct128x256 => (256, 128),
117 }
118 }
119
120 pub(crate) fn order_id(self) -> u32 {
121 use TransformType::*;
122
123 match self {
124 Dct8 => 0,
125 Hornuss | Dct2 | Dct4 | Dct4x8 | Dct8x4 | Afv0 | Afv1 | Afv2 | Afv3 => 1,
126 Dct16 => 2,
127 Dct32 => 3,
128 Dct16x8 | Dct8x16 => 4,
129 Dct32x8 | Dct8x32 => 5,
130 Dct32x16 | Dct16x32 => 6,
131 Dct64 => 7,
132 Dct64x32 | Dct32x64 => 8,
133 Dct128 => 9,
134 Dct128x64 | Dct64x128 => 10,
135 Dct256 => 11,
136 Dct256x128 | Dct128x256 => 12,
137 }
138 }
139
140 #[inline]
142 pub fn need_transpose(&self) -> bool {
143 use TransformType::*;
144
145 if matches!(
146 self,
147 Hornuss | Dct2 | Dct4 | Dct4x8 | Dct8x4 | Afv0 | Afv1 | Afv2 | Afv3
148 ) {
149 false
150 } else {
151 let (w, h) = self.dct_select_size();
152 h >= w
153 }
154 }
155}