Skip to main content

video_sys/
pixel.rs

1pub fn nv12_to_rgba_strided(
2    width: u32,
3    height: u32,
4    y_stride: usize,
5    uv_stride: usize,
6    y_plane: &[u8],
7    uv_plane: &[u8],
8) -> Vec<u8> {
9    let w = width as usize;
10    let h = height as usize;
11
12    let mut out = vec![0u8; w * h * 4];
13
14    for y in 0..h {
15        let y_row = &y_plane[y * y_stride..y * y_stride + w];
16        let uv_row = &uv_plane[(y / 2) * uv_stride..(y / 2) * uv_stride + w];
17
18        for x in 0..w {
19            let yy = y_row[x] as i32;
20            let uu = uv_row[x & !1] as i32;
21            let vv = uv_row[(x & !1) + 1] as i32;
22
23            let c = yy - 16;
24            let d = uu - 128;
25            let e = vv - 128;
26
27            let r = (298 * c + 409 * e + 128) >> 8;
28            let g = (298 * c - 100 * d - 208 * e + 128) >> 8;
29            let b = (298 * c + 516 * d + 128) >> 8;
30
31            let r = r.clamp(0, 255) as u8;
32            let g = g.clamp(0, 255) as u8;
33            let b = b.clamp(0, 255) as u8;
34
35            let o = (y * w + x) * 4;
36            out[o] = r;
37            out[o + 1] = g;
38            out[o + 2] = b;
39            out[o + 3] = 255;
40        }
41    }
42
43    out
44}
45
46pub fn bgra_to_rgba_inplace(pixels: &mut [u8]) {
47    for px in pixels.chunks_exact_mut(4) {
48        let b = px[0];
49        let r = px[2];
50        px[0] = r;
51        px[2] = b;
52    }
53}
54
55
56/// Convert a YUV_420_888 style 3-plane image into RGBA.
57pub fn yuv420_888_to_rgba(
58    width: u32,
59    height: u32,
60    y_row_stride: usize,
61    u_row_stride: usize,
62    v_row_stride: usize,
63    u_pixel_stride: usize,
64    v_pixel_stride: usize,
65    y_plane: &[u8],
66    u_plane: &[u8],
67    v_plane: &[u8],
68) -> Vec<u8> {
69    let w = width as usize;
70    let h = height as usize;
71
72    let mut out = vec![0u8; w * h * 4];
73
74    for y in 0..h {
75        let y_off = y * y_row_stride;
76        let uv_y = y / 2;
77
78        for x in 0..w {
79            let uv_x = x / 2;
80
81            let yy = y_plane[y_off + x] as i32;
82            let u_idx = uv_y * u_row_stride + uv_x * u_pixel_stride;
83            let v_idx = uv_y * v_row_stride + uv_x * v_pixel_stride;
84
85            let uu = u_plane.get(u_idx).copied().unwrap_or(128) as i32;
86            let vv = v_plane.get(v_idx).copied().unwrap_or(128) as i32;
87
88            let c = yy - 16;
89            let d = uu - 128;
90            let e = vv - 128;
91
92            let r = (298 * c + 409 * e + 128) >> 8;
93            let g = (298 * c - 100 * d - 208 * e + 128) >> 8;
94            let b = (298 * c + 516 * d + 128) >> 8;
95
96            let r = r.clamp(0, 255) as u8;
97            let g = g.clamp(0, 255) as u8;
98            let b = b.clamp(0, 255) as u8;
99
100            let o = (y * w + x) * 4;
101            out[o] = r;
102            out[o + 1] = g;
103            out[o + 2] = b;
104            out[o + 3] = 255;
105        }
106    }
107
108    out
109}