Skip to content

Commit dddbfe2

Browse files
committed
refactor: Use u16 for image width and height
1 parent 8a21f1d commit dddbfe2

File tree

5 files changed

+62
-76
lines changed

5 files changed

+62
-76
lines changed

benches/reducer.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ use hyperion::{
88
models::{ClassicLedConfig, Color16, Leds, ToLeds},
99
};
1010

11-
fn random_image(width: u32, height: u32) -> RawImage {
12-
let mut data = vec![0u8; (width * height * RawImage::CHANNELS) as usize];
11+
fn random_image(width: u16, height: u16) -> RawImage {
12+
let mut data = vec![0u8; width as usize * height as usize * RawImage::CHANNELS as usize];
1313

1414
let mut rng = rand::thread_rng();
1515
rng.fill_bytes(&mut data);
1616

17-
RawImage::try_from((data, width, height)).unwrap()
17+
RawImage::try_from((data, width as u32, height as u32)).unwrap()
1818
}
1919

2020
fn classic_led_config(leds: u32) -> Leds {

src/image.rs

+39-52
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ pub use reducer::*;
99

1010
pub trait Image: Sized {
1111
/// Get the width of the image, in pixels
12-
fn width(&self) -> u32;
12+
fn width(&self) -> u16;
1313

1414
/// Get the height of the image, in pixels
15-
fn height(&self) -> u32;
15+
fn height(&self) -> u16;
1616

1717
/// Get the color at the given coordinates
18-
fn color_at(&self, x: u32, y: u32) -> Option<Color>;
18+
fn color_at(&self, x: u16, y: u16) -> Option<Color>;
1919

2020
/// Get the color at the given coordinates skipping bound checks
21-
unsafe fn color_at_unchecked(&self, x: u32, y: u32) -> Color;
21+
unsafe fn color_at_unchecked(&self, x: u16, y: u16) -> Color;
2222

2323
/// Convert this image trait object to a raw image
2424
fn to_raw_image(&self) -> RawImage;
@@ -53,12 +53,12 @@ pub enum RawImageError {
5353
#[derive(Clone)]
5454
pub struct RawImage {
5555
data: Vec<u8>,
56-
width: u32,
57-
height: u32,
56+
width: u16,
57+
height: u16,
5858
}
5959

6060
impl RawImage {
61-
pub const CHANNELS: u32 = 3;
61+
pub const CHANNELS: u16 = 3;
6262

6363
pub fn write_to_kitty(&self, out: &mut dyn std::io::Write) -> Result<(), RawImageError> {
6464
// Buffer for raw PNG data
@@ -68,8 +68,8 @@ impl RawImage {
6868
// Write PNG to buffer
6969
encoder.encode(
7070
&self.data[..],
71-
self.width,
72-
self.height,
71+
self.width as _,
72+
self.height as _,
7373
image::ColorType::Rgb8,
7474
)?;
7575
// Encode to base64
@@ -105,45 +105,28 @@ impl RawImage {
105105
}
106106

107107
impl Image for RawImage {
108-
fn width(&self) -> u32 {
108+
fn width(&self) -> u16 {
109109
self.width
110110
}
111111

112-
fn height(&self) -> u32 {
112+
fn height(&self) -> u16 {
113113
self.height
114114
}
115115

116-
fn color_at(&self, x: u32, y: u32) -> Option<Color> {
116+
fn color_at(&self, x: u16, y: u16) -> Option<Color> {
117117
if x < self.width && y < self.height {
118-
unsafe {
119-
Some(Color::new(
120-
*self
121-
.data
122-
.get_unchecked(((y * self.width + x) * Self::CHANNELS) as usize),
123-
*self
124-
.data
125-
.get_unchecked(((y * self.width + x) * Self::CHANNELS + 1) as usize),
126-
*self
127-
.data
128-
.get_unchecked(((y * self.width + x) * Self::CHANNELS + 2) as usize),
129-
))
130-
}
118+
unsafe { Some(self.color_at_unchecked(x, y)) }
131119
} else {
132120
None
133121
}
134122
}
135123

136-
unsafe fn color_at_unchecked(&self, x: u32, y: u32) -> Color {
124+
unsafe fn color_at_unchecked(&self, x: u16, y: u16) -> Color {
125+
let idx = (y as usize * self.width as usize + x as usize) * Self::CHANNELS as usize;
137126
Color::new(
138-
*self
139-
.data
140-
.get_unchecked(((y * self.width + x) * Self::CHANNELS) as usize),
141-
*self
142-
.data
143-
.get_unchecked(((y * self.width + x) * Self::CHANNELS + 1) as usize),
144-
*self
145-
.data
146-
.get_unchecked(((y * self.width + x) * Self::CHANNELS + 2) as usize),
127+
*self.data.get_unchecked(idx),
128+
*self.data.get_unchecked(idx + 1),
129+
*self.data.get_unchecked(idx + 2),
147130
)
148131
}
149132

@@ -173,59 +156,63 @@ impl TryFrom<(Vec<u8>, u32, u32)> for RawImage {
173156
type Error = RawImageError;
174157

175158
fn try_from((data, width, height): (Vec<u8>, u32, u32)) -> Result<Self, Self::Error> {
176-
let expected = (width * height * Self::CHANNELS) as usize;
159+
let expected = width as usize * height as usize * Self::CHANNELS as usize;
177160

178161
if data.len() != expected {
179162
return Err(RawImageError::InvalidData {
180163
data: data.len(),
181164
width,
182165
height,
183-
channels: Self::CHANNELS,
166+
channels: Self::CHANNELS as _,
184167
expected,
185168
});
186169
} else if width == 0 {
187170
return Err(RawImageError::ZeroWidth);
188171
} else if height == 0 {
189172
return Err(RawImageError::ZeroHeight);
173+
} else if width >= u16::MAX as _ {
174+
return Err(RawImageError::InvalidWidth);
175+
} else if height >= u16::MAX as _ {
176+
return Err(RawImageError::InvalidHeight);
190177
}
191178

192179
Ok(Self {
193180
data,
194-
width,
195-
height,
181+
width: width as _,
182+
height: height as _,
196183
})
197184
}
198185
}
199186

200187
pub struct ImageView<'i, T: Image> {
201188
inner: &'i T,
202-
xmin: u32,
203-
xmax: u32,
204-
ymin: u32,
205-
ymax: u32,
189+
xmin: u16,
190+
xmax: u16,
191+
ymin: u16,
192+
ymax: u16,
206193
}
207194

208195
impl<'i, T: Image> Image for ImageView<'i, T> {
209-
fn width(&self) -> u32 {
196+
fn width(&self) -> u16 {
210197
self.xmax - self.xmin
211198
}
212199

213-
fn height(&self) -> u32 {
200+
fn height(&self) -> u16 {
214201
self.ymax - self.ymin
215202
}
216203

217-
fn color_at(&self, x: u32, y: u32) -> Option<Color> {
204+
fn color_at(&self, x: u16, y: u16) -> Option<Color> {
218205
self.inner.color_at(x + self.xmin, y + self.ymin)
219206
}
220207

221-
unsafe fn color_at_unchecked(&self, x: u32, y: u32) -> Color {
208+
unsafe fn color_at_unchecked(&self, x: u16, y: u16) -> Color {
222209
self.inner.color_at_unchecked(x + self.xmin, y + self.ymin)
223210
}
224211

225212
fn to_raw_image(&self) -> RawImage {
226213
let w = self.width();
227214
let h = self.height();
228-
let mut data = Vec::with_capacity((w * h * RawImage::CHANNELS) as usize);
215+
let mut data = Vec::with_capacity(w as usize * h as usize * RawImage::CHANNELS as usize);
229216

230217
unsafe {
231218
for y in 0..h {
@@ -240,18 +227,18 @@ impl<'i, T: Image> Image for ImageView<'i, T> {
240227

241228
RawImage {
242229
data,
243-
width: w as _,
244-
height: h as _,
230+
width: w,
231+
height: h,
245232
}
246233
}
247234
}
248235

249236
pub trait ImageViewExt: Image {
250-
fn wrap(&self, x: std::ops::Range<u32>, y: std::ops::Range<u32>) -> ImageView<Self>;
237+
fn wrap(&self, x: std::ops::Range<u16>, y: std::ops::Range<u16>) -> ImageView<Self>;
251238
}
252239

253240
impl<T: Image> ImageViewExt for T {
254-
fn wrap(&self, x: std::ops::Range<u32>, y: std::ops::Range<u32>) -> ImageView<Self> {
241+
fn wrap(&self, x: std::ops::Range<u16>, y: std::ops::Range<u16>) -> ImageView<Self> {
255242
ImageView {
256243
inner: self,
257244
xmin: x.start,

src/image/reducer.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use super::Image;
55
#[derive(Debug, Default)]
66
pub struct Reducer {
77
spec: Vec<LedSpec>,
8-
spec_width: u32,
9-
spec_height: u32,
8+
spec_width: u16,
9+
spec_height: u16,
1010
}
1111

1212
#[derive(Debug)]
@@ -19,41 +19,40 @@ struct LedSpec {
1919
}
2020

2121
impl LedSpec {
22-
pub fn new(spec: &Led, width: u32, height: u32, fwidth: f32, fheight: f32) -> Self {
22+
pub fn new(spec: &Led, width: u16, height: u16, fwidth: f32, fheight: f32) -> Self {
2323
let lxmin = spec.hmin * fwidth;
2424
let lxmax = spec.hmax * fwidth;
2525
let lymin = spec.vmin * fheight;
2626
let lymax = spec.vmax * fheight;
2727

2828
let x_area = if lxmin.floor() < lxmin {
29-
(255. * (1. - lxmin.fract())) as u32
29+
(255. * (1. - lxmin.fract())) as u16
3030
} else if (lxmax.ceil() + 1.) > lxmax {
31-
(255. * lxmax.fract()) as u32
31+
(255. * lxmax.fract()) as u16
3232
} else {
3333
255
3434
};
3535

3636
let y_area = if lxmin.floor() < lxmin {
37-
(255. * (1. - lymin.fract())) as u32
37+
(255. * (1. - lymin.fract())) as u16
3838
} else if (lymax.ceil() + 1.) > lxmax {
39-
(255. * lymax.fract()) as u32
39+
(255. * lymax.fract()) as u16
4040
} else {
4141
255
4242
};
4343

44-
// TODO: Add width/height limit to RawImage
4544
Self {
4645
lxmin: lxmin.floor() as u16,
47-
lxmax: (lxmax.ceil() as u16).min((width - 1) as u16),
46+
lxmax: (lxmax.ceil() as u16).min(width - 1),
4847
lymin: lymin.floor() as u16,
49-
lymax: (lymax.ceil() as u16).min((height - 1) as u16),
48+
lymax: (lymax.ceil() as u16).min(height - 1),
5049
area: (x_area * y_area / 255) as u8,
5150
}
5251
}
5352
}
5453

5554
impl Reducer {
56-
pub fn reset(&mut self, width: u32, height: u32, leds: &[Led]) {
55+
pub fn reset(&mut self, width: u16, height: u16, leds: &[Led]) {
5756
self.spec_width = width;
5857
self.spec_height = height;
5958

src/instance/black_border_detector.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use crate::{image::Image, models};
33
#[derive(Debug, Clone, Copy, PartialEq)]
44
pub struct BlackBorder {
55
pub unknown: bool,
6-
pub horizontal_size: u32,
7-
pub vertical_size: u32,
6+
pub horizontal_size: u16,
7+
pub vertical_size: u16,
88
threshold: u8,
99
}
1010

@@ -22,7 +22,7 @@ impl BlackBorder {
2222
color.red < self.threshold && color.green < self.threshold && color.blue < self.threshold
2323
}
2424

25-
fn update(&mut self, xy: (Option<u32>, Option<u32>)) {
25+
fn update(&mut self, xy: (Option<u16>, Option<u16>)) {
2626
if let (Some(x), Some(y)) = xy {
2727
self.unknown = false;
2828
self.horizontal_size = y;
@@ -121,12 +121,12 @@ impl BlackBorder {
121121
if first_non_black_x < 0 {
122122
None
123123
} else {
124-
Some(first_non_black_x as u32)
124+
Some(first_non_black_x as _)
125125
},
126126
if first_non_black_y < 0 {
127127
None
128128
} else {
129-
Some(first_non_black_y as u32)
129+
Some(first_non_black_y as _)
130130
},
131131
));
132132
}
@@ -203,7 +203,7 @@ impl BlackBorder {
203203
}
204204
}
205205

206-
pub fn blur(&mut self, blur: u32) {
206+
pub fn blur(&mut self, blur: u16) {
207207
if self.horizontal_size > 0 {
208208
self.horizontal_size += blur;
209209
}
@@ -215,9 +215,9 @@ impl BlackBorder {
215215

216216
pub fn get_ranges(
217217
&self,
218-
width: u32,
219-
height: u32,
220-
) -> (std::ops::Range<u32>, std::ops::Range<u32>) {
218+
width: u16,
219+
height: u16,
220+
) -> (std::ops::Range<u16>, std::ops::Range<u16>) {
221221
if self.unknown {
222222
(0..width, 0..height)
223223
} else {

src/models.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ pub struct BlackBorderDetector {
114114
pub unknown_frame_cnt: u32,
115115
pub border_frame_cnt: u32,
116116
pub max_inconsistent_cnt: u32,
117-
pub blur_remove_cnt: u32,
117+
pub blur_remove_cnt: u16,
118118
pub mode: BlackBorderDetectorMode,
119119
}
120120

0 commit comments

Comments
 (0)