atmos/os_lib/web_engine/
bilinear.rs1use super::DecodedImage;
8
9pub fn sample_bilinear_rgba(img: &DecodedImage, u: f32, v: f32) -> (u8, u8, u8, u8) {
12 if img.width == 0 || img.height == 0 || img.rgba.len() < (img.width * img.height * 4) as usize {
13 return (0, 0, 0, 0);
14 }
15 let x = u.clamp(0.0, (img.width - 1) as f32);
16 let y = v.clamp(0.0, (img.height - 1) as f32);
17 let x0 = x as usize;
18 let y0 = y as usize;
19 let x1 = (x0 + 1).min(img.width as usize - 1);
20 let y1 = (y0 + 1).min(img.height as usize - 1);
21 let fx = x - (x0 as f32);
22 let fy = y - (y0 as f32);
23
24 let w = img.width as usize;
25 let row0_offset = (y0 * w) * 4;
26 let row1_offset = (y1 * w) * 4;
27 let p00_idx = row0_offset + x0 * 4;
28 let p10_idx = row0_offset + x1 * 4;
29 let p01_idx = row1_offset + x0 * 4;
30 let p11_idx = row1_offset + x1 * 4;
31
32 let p00_r = img.rgba[p00_idx] as f32;
33 let p00_g = img.rgba[p00_idx + 1] as f32;
34 let p00_b = img.rgba[p00_idx + 2] as f32;
35 let p00_a = img.rgba[p00_idx + 3] as f32;
36
37 let p10_r = img.rgba[p10_idx] as f32;
38 let p10_g = img.rgba[p10_idx + 1] as f32;
39 let p10_b = img.rgba[p10_idx + 2] as f32;
40 let p10_a = img.rgba[p10_idx + 3] as f32;
41
42 let p01_r = img.rgba[p01_idx] as f32;
43 let p01_g = img.rgba[p01_idx + 1] as f32;
44 let p01_b = img.rgba[p01_idx + 2] as f32;
45 let p01_a = img.rgba[p01_idx + 3] as f32;
46
47 let p11_r = img.rgba[p11_idx] as f32;
48 let p11_g = img.rgba[p11_idx + 1] as f32;
49 let p11_b = img.rgba[p11_idx + 2] as f32;
50 let p11_a = img.rgba[p11_idx + 3] as f32;
51
52 let w00 = (1.0 - fx) * (1.0 - fy);
53 let w10 = fx * (1.0 - fy);
54 let w01 = (1.0 - fx) * fy;
55 let w11 = fx * fy;
56
57 let r = (p00_r * w00 + p10_r * w10 + p01_r * w01 + p11_r * w11) as u8;
58 let g = (p00_g * w00 + p10_g * w10 + p01_g * w01 + p11_g * w11) as u8;
59 let b = (p00_b * w00 + p10_b * w10 + p01_b * w01 + p11_b * w11) as u8;
60 let a = (p00_a * w00 + p10_a * w10 + p01_a * w01 + p11_a * w11) as u8;
61 (r, g, b, a)
62}