atmos/os_lib/web_engine/
blur_box.rs1extern crate alloc;
32
33use alloc::vec::Vec;
34
35pub fn window_bounds(i: usize, r: usize, n: usize) -> (usize, usize) {
41 if n == 0 {
42 return (0, 0);
43 }
44 let lo = i.saturating_sub(r);
45 let hi = core::cmp::min(i + r, n - 1);
46 (lo, hi)
47}
48
49pub fn box_blur_rgb(src: &[u32], w: usize, h: usize, radius: usize) -> Vec<u32> {
58 if radius == 0 || w == 0 || h == 0 || src.len() < w * h {
59 return src.to_vec();
60 }
61
62 let mut pre_r: Vec<u32> = alloc::vec![0u32; (w + 1) * h];
65 let mut pre_g: Vec<u32> = alloc::vec![0u32; (w + 1) * h];
66 let mut pre_b: Vec<u32> = alloc::vec![0u32; (w + 1) * h];
67 for y in 0..h {
68 let base = y * (w + 1);
69 for x in 0..w {
70 let c = src[y * w + x];
71 pre_r[base + x + 1] = pre_r[base + x] + ((c >> 16) & 0xFF);
72 pre_g[base + x + 1] = pre_g[base + x] + ((c >> 8) & 0xFF);
73 pre_b[base + x + 1] = pre_b[base + x] + (c & 0xFF);
74 }
75 }
76
77 let mut hr: Vec<u32> = alloc::vec![0u32; w * h];
80 let mut hg: Vec<u32> = alloc::vec![0u32; w * h];
81 let mut hb: Vec<u32> = alloc::vec![0u32; w * h];
82 for y in 0..h {
83 let rbase = y * (w + 1);
84 for x in 0..w {
85 let (x_lo, x_hi) = window_bounds(x, radius, w);
86 let i = y * w + x;
87 hr[i] = pre_r[rbase + x_hi + 1] - pre_r[rbase + x_lo];
88 hg[i] = pre_g[rbase + x_hi + 1] - pre_g[rbase + x_lo];
89 hb[i] = pre_b[rbase + x_hi + 1] - pre_b[rbase + x_lo];
90 }
91 }
92
93 let mut cr: Vec<u32> = alloc::vec![0u32; w * (h + 1)];
96 let mut cg: Vec<u32> = alloc::vec![0u32; w * (h + 1)];
97 let mut cb: Vec<u32> = alloc::vec![0u32; w * (h + 1)];
98 for y in 0..h {
99 for x in 0..w {
100 let i = y * w + x;
101 cr[(y + 1) * w + x] = cr[y * w + x] + hr[i];
102 cg[(y + 1) * w + x] = cg[y * w + x] + hg[i];
103 cb[(y + 1) * w + x] = cb[y * w + x] + hb[i];
104 }
105 }
106
107 let mut out: Vec<u32> = alloc::vec![0u32; w * h];
109 for y in 0..h {
110 let (y_lo, y_hi) = window_bounds(y, radius, h);
111 let ny = (y_hi - y_lo + 1) as u32;
112 for x in 0..w {
113 let (x_lo, x_hi) = window_bounds(x, radius, w);
114 let nx = (x_hi - x_lo + 1) as u32;
115 let n = nx * ny;
116
117 let sr = cr[(y_hi + 1) * w + x] - cr[y_lo * w + x];
118 let sg = cg[(y_hi + 1) * w + x] - cg[y_lo * w + x];
119 let sb = cb[(y_hi + 1) * w + x] - cb[y_lo * w + x];
120
121 out[y * w + x] = 0xFF00_0000 | ((sr / n) << 16) | ((sg / n) << 8) | (sb / n);
122 }
123 }
124 out
125}