robotics_signals/sensors/
image.rs1use crate::standard::HeaderFixedSize;
2use serde_derive::{Deserialize, Serialize};
3
4use cdds_derive::*;
5use cyclonedds_rs::*;
6use serde_big_array::BigArray;
7
8#[repr(C)]
58#[derive(Serialize, Deserialize, PartialEq)]
59pub enum Encoding {
60 Unknown,
61 RGB8,
62 RGBA8,
63 RGB16,
64 RGBA16,
65 BGR8,
66 BGRA8,
67 BGR16,
68 BGRA16,
69 MONO8,
70 MONO16,
71 Type8UC1,
72 Type8UC2,
73 Type8UC3,
74 Type8UC4,
75 Type8SC1,
76 Type8SC2,
77 Type8SC3,
78 Type8SC4,
79 Type16UC1,
80 Type16UC2,
81 Type16UC3,
82 Type16UC4,
83 Type16SC1,
84 Type16SC2,
85 Type16SC3,
86 Type16SC4,
87 Type32SC1,
88 Type32SC2,
89 Type32SC3,
90 Type32SC4,
91 Type32FC1,
92 Type32FC2,
93 Type32FC3,
94 Type32FC4,
95 Type64FC1,
96 Type64FC2,
97 Type64FC3,
98 Type64FC4,
99 BayerRGGB8,
100 BayerBGGR8,
101 BayerGBRG8,
102 BayerGRBG8,
103 BayerRGGB16,
104 BayerBGGR16,
105 BayerGBRG16,
106 BayerGrbg16,
107 YUV422,
108}
109
110impl Encoding {
111 pub const fn num_channels(&self) -> usize {
112 match self {
113 Self::MONO16 | Self::MONO8 => 1,
114 Self::BGR8 | Self::RGB8 | Self::BGR16 | Self::RGB16 => 3,
115 Self::BGRA8 | Self::RGBA8 | Self::BGRA16 | Self::RGBA16 => 4,
116 Self::BayerRGGB8
117 | Self::BayerBGGR8
118 | Self::BayerGBRG8
119 | Self::BayerGRBG8
120 | Self::BayerRGGB16
121 | Self::BayerBGGR16
122 | Self::BayerGBRG16
123 | Self::BayerGrbg16 => 1,
124 Self::Type16SC1
125 | Self::Type16UC1
126 | Self::Type32FC1
127 | Self::Type32SC1
128 | Self::Type64FC1
129 | Self::Type8SC1
130 | Self::Type8UC1 => 1,
131 Self::Type16SC2
132 | Self::Type16UC2
133 | Self::Type32FC2
134 | Self::Type32SC2
135 | Self::Type64FC2
136 | Self::Type8SC2
137 | Self::Type8UC2 => 2,
138 Self::Type16SC3
139 | Self::Type16UC3
140 | Self::Type32FC3
141 | Self::Type32SC3
142 | Self::Type64FC3
143 | Self::Type8SC3
144 | Self::Type8UC3 => 3,
145 Self::Type16SC4
146 | Self::Type16UC4
147 | Self::Type32FC4
148 | Self::Type32SC4
149 | Self::Type64FC4
150 | Self::Type8SC4
151 | Self::Type8UC4 => 4,
152 Self::YUV422 => 2,
153 Self::Unknown => 0,
154 }
155 }
156
157 pub fn is_mono(&self) -> bool {
158 *self == Self::MONO16 || *self == Self::MONO8
159 }
160
161 pub fn is_color(&self) -> bool {
162 *self == Self::RGB8
163 || *self == Self::BGR8
164 || *self == Self::RGBA8
165 || *self == Self::BGRA8
166 || *self == Self::RGB16
167 || *self == Self::BGR16
168 || *self == Self::RGBA16
169 || *self == Self::BGRA16
170 }
171
172 pub fn has_alpha(&self) -> bool {
173 *self == Self::RGBA8
174 || *self == Self::BGRA8
175 || *self == Self::RGBA16
176 || *self == Self::BGRA16
177 }
178
179 pub const fn bit_depth(&self) -> usize {
180 match self {
181 Self::MONO16 => 16,
182 Self::MONO8
183 | Self::BGR8
184 | Self::RGB8
185 | Self::BGRA8
186 | Self::RGBA8
187 | Self::BayerRGGB8
188 | Self::BayerBGGR8
189 | Self::BayerGBRG8
190 | Self::BayerGRBG8 => 8,
191 Self::BGR16
192 | Self::RGB16
193 | Self::BGRA16
194 | Self::RGBA16
195 | Self::BayerRGGB16
196 | Self::BayerBGGR16
197 | Self::BayerGBRG16
198 | Self::BayerGrbg16 => 16,
199 Self::YUV422 => 8,
200 Self::Type16SC1 | Self::Type16SC2 | Self::Type16SC3 | Self::Type16SC4 => 16,
201 Self::Type16UC1 | Self::Type16UC2 | Self::Type16UC3 | Self::Type16UC4 => 16,
202 Self::Type32SC1 | Self::Type32SC2 | Self::Type32SC3 | Self::Type32SC4 => 32,
203 Self::Type32FC1 | Self::Type32FC2 | Self::Type32FC3 | Self::Type32FC4 => 32,
204 Self::Type64FC1 | Self::Type64FC2 | Self::Type64FC3 | Self::Type64FC4 => 64,
205 Self::Type8SC1 | Self::Type8SC2 | Self::Type8SC3 | Self::Type8SC4 => 8,
206 Self::Type8UC1 | Self::Type8UC2 | Self::Type8UC3 | Self::Type8UC4 => 8,
207 Self::Unknown => 0,
208 }
209 }
210}
211
212macro_rules! make_image_type {
213 ( $resname:ident, $width:expr, $height:expr, $encoding_type:expr ) => {
214 #[repr(C)]
215 #[derive(Serialize, Deserialize, TopicFixedSize)]
216 pub struct $resname {
217 pub header: HeaderFixedSize,
218 pub width: u32,
219 pub height: u32,
220 pub encoding: Encoding,
221 pub stride: u32,
222 #[serde(with = "BigArray")]
223 pub data:
224 [u8; $width * $height * $encoding_type.num_channels() * $encoding_type.bit_depth()
225 / 8],
226 }
227
228 impl $resname {
229 pub fn set_resolution(&mut self) {
231 self.width = $width;
232 self.height = $height;
233 self.stride = $width;
234 }
235
236 pub fn initialize(&mut self) {
237 self.set_resolution();
238 self.encoding = $encoding_type;
239 }
240 }
241 };
242}
243
244make_image_type!(ImageQCIF4BPP, 176, 120, Encoding::RGBA8);
248make_image_type!(ImageCIF4BPP, 352, 240, Encoding::RGBA8);
249make_image_type!(Image3MP4BPP, 2048, 1536, Encoding::RGBA8);
250make_image_type!(Image1080p4BPP, 1920, 1080, Encoding::RGBA8);
251make_image_type!(Image1080pYUV422, 1920, 1080, Encoding::YUV422);