chess_corners_core/
imageview.rs1#[derive(Copy, Clone, Debug)]
3pub struct ImageView<'a> {
4 pub data: &'a [u8],
5 pub width: usize,
6 pub height: usize,
7 pub origin: [i32; 2],
9}
10
11impl<'a> ImageView<'a> {
12 pub fn from_u8_slice(width: usize, height: usize, data: &'a [u8]) -> Option<Self> {
13 if width.checked_mul(height)? != data.len() {
14 return None;
15 }
16 Some(Self {
17 data,
18 width,
19 height,
20 origin: [0, 0],
21 })
22 }
23
24 pub fn with_origin(
25 width: usize,
26 height: usize,
27 data: &'a [u8],
28 origin: [i32; 2],
29 ) -> Option<Self> {
30 Self::from_u8_slice(width, height, data).map(|mut view| {
31 view.origin = origin;
32 view
33 })
34 }
35
36 #[inline]
37 pub fn supports_patch(&self, cx: i32, cy: i32, radius: i32) -> bool {
38 if self.width == 0 || self.height == 0 {
39 return false;
40 }
41
42 let gx = cx + self.origin[0];
43 let gy = cy + self.origin[1];
44 let min_x = 0;
45 let min_y = 0;
46 let max_x = self.width as i32 - 1;
47 let max_y = self.height as i32 - 1;
48 gx - radius >= min_x && gy - radius >= min_y && gx + radius <= max_x && gy + radius <= max_y
49 }
50
51 #[inline]
52 pub fn sample(&self, gx: i32, gy: i32) -> f32 {
53 if self.width == 0 || self.height == 0 {
54 return 0.0;
55 }
56 let gx = gx + self.origin[0];
57 let gy = gy + self.origin[1];
58 let lx = gx.clamp(0, self.width.saturating_sub(1) as i32) as usize;
59 let ly = gy.clamp(0, self.height.saturating_sub(1) as i32) as usize;
60 self.data[ly * self.width + lx] as f32
61 }
62}