Skip to main content

atmos/os_lib/web_engine/
bilinear.rs

1// arm/v1/src/os_lib/web_engine/bilinear.rs
2//! バイリニア画像サンプリング(描画パイプラインの純粋補間計算)。
3//!
4//! カーネル描画ドライバ(Screen等)に依存せず、画像バッファと座標から近傍4点ブレンドを行う純粋関数。
5//! ホスト単体テスト環境からも直接参照・検証可能。
6
7use super::DecodedImage;
8
9/// 計算量: **O(1)** — 近傍 4 点の読み出しと 2 段補間。
10/// 最近傍サンプリングの約 4 倍の定数倍。**毎ピクセル呼ばれる**。
11pub 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}