1use crate::kernel::{self, SobelKernel};
2use bumpalo::Bump;
3use std::time::Instant;
4
5impl std::fmt::Debug for CannyWorkspace {
6 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7 f.debug_struct("CannyWorkspace")
8 .field("width", &self.width)
9 .field("height", &self.height)
10 .field("capacity", &self.capacity)
11 .finish_non_exhaustive()
12 }
13}
14
15pub struct CannyWorkspace {
16 pub width: usize,
17 pub height: usize,
18 pub capacity: usize,
19 pub buffer_a: Vec<f32>, pub buffer_b: Vec<f32>, pub dir_map: Vec<u8>, pub edge_map: Vec<u8>, pub arena: Bump,
24 pub(crate) kernel: Box<dyn SobelKernel>,
25}
26
27impl CannyWorkspace {
28 pub fn new(width: usize, height: usize) -> Result<Self, crate::CannyError> {
29 if width < 3 || height < 3 {
30 return Err(crate::CannyError::InvalidDimensions { width, height });
31 }
32 let t0 = Instant::now();
33 let capacity = width * height;
34 let arena_bytes = (capacity / 20) * std::mem::size_of::<usize>();
35 let ws = Self {
36 width,
37 height,
38 capacity,
39 buffer_a: vec![0.0f32; capacity],
40 buffer_b: vec![0.0f32; capacity],
41 dir_map: vec![0u8; capacity],
42 edge_map: vec![0u8; capacity],
43 arena: Bump::with_capacity(arena_bytes),
44 kernel: kernel::detect(),
45 };
46 log::info!(
47 "[CannyWorkspace::new] {}x{}, ~{} KB, {:?}",
48 width,
49 height,
50 (capacity * 10 + arena_bytes) / 1024,
51 t0.elapsed()
52 );
53 Ok(ws)
54 }
55
56 #[inline(always)]
58 pub fn reset(&mut self) {
59 self.arena.reset();
60 self.edge_map.fill(0);
61 }
62
63 #[inline(always)]
64 pub(crate) fn kernel(&self) -> &dyn SobelKernel {
65 self.kernel.as_ref()
66 }
67}