Skip to content

Commit 91a60b5

Browse files
Charlie-Zhengralfbiedert
authored andcommitted
Changed to use integer math instead of f32 method. Adjusted to use iterators instead of array indexing.
1 parent 5efb82b commit 91a60b5

1 file changed

Lines changed: 15 additions & 34 deletions

File tree

openh264/src/formats/rgb2yuv.rs

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -58,46 +58,27 @@ pub fn write_yuv_scalar(rgb: impl RGB8Source, dimensions: (usize, usize), y_buf:
5858

5959
let dimensions_padded = rgb.dimensions_padded();
6060
let width = dimensions.0;
61-
let height = dimensions.1;
61+
6262
let half_width = width / 2;
6363
let rgb8_data = rgb.rgb8_data();
6464

65-
// y is full size, u, v is quarter size
66-
let mut write_y = |x: usize, y: usize, rgb: &[u8]| {
67-
let (r, g, b) = (f32::from(rgb[0]), f32::from(rgb[1]), f32::from(rgb[2]));
68-
y_buf[x + y * width] = (0.09765625f32.mul_add(b, 0.2578125f32.mul_add(r, 0.50390625 * g)) + 16.0) as u8;
69-
};
70-
71-
let mut write_u = |x: usize, y: usize, rgb: &[u8]| {
72-
let (r, g, b) = (f32::from(rgb[0]), f32::from(rgb[1]), f32::from(rgb[2]));
73-
u_buf[x + y * half_width] = (0.4375f32.mul_add(b, (-0.1484375f32).mul_add(r, -0.2890625 * g)) + 128.0) as u8;
74-
};
65+
for (pix, y) in rgb8_data.chunks_exact(3).zip(y_buf.iter_mut()) {
66+
*y = (((66 * u32::from(pix[0]) + 129 * u32::from(pix[1]) + 25 * u32::from(pix[2])) >> 8) + 16) as u8;
67+
}
7568

76-
let mut write_v = |x: usize, y: usize, rgb: &[u8]| {
77-
let (r, g, b) = (f32::from(rgb[0]), f32::from(rgb[1]), f32::from(rgb[2]));
78-
v_buf[x + y * half_width] = ((-0.0703125f32).mul_add(b, 0.4375f32.mul_add(r, -0.3671875 * g)) + 128.0) as u8;
79-
};
69+
let r1 = rgb8_data.chunks_exact(dimensions_padded.0 * 3).step_by(2);
70+
let r2 = rgb8_data.chunks_exact(dimensions_padded.0 * 3).skip(1).step_by(2);
8071

81-
for i in 0..width / 2 {
82-
for j in 0..height / 2 {
83-
let px = i * 2;
84-
let py = j * 2;
85-
let pix0x0 = &rgb8_data[(px + py * dimensions_padded.0) * 3..][..3];
86-
let pix0x1 = &rgb8_data[(px + (py + 1) * dimensions_padded.0) * 3..][..3];
87-
let pix1x0 = &rgb8_data[(px + 1 + (py) * dimensions_padded.0) * 3..][..3];
88-
let pix1x1 = &rgb8_data[(px + 1 + (py + 1) * dimensions_padded.0) * 3..][..3];
89-
let avg_pix = [
90-
((u32::from(pix0x0[0]) + u32::from(pix0x1[0]) + u32::from(pix1x0[0]) + u32::from(pix1x1[0])) / 4) as u8,
91-
((u32::from(pix0x0[1]) + u32::from(pix0x1[1]) + u32::from(pix1x0[1]) + u32::from(pix1x1[1])) / 4) as u8,
92-
((u32::from(pix0x0[2]) + u32::from(pix0x1[2]) + u32::from(pix1x0[2]) + u32::from(pix1x1[2])) / 4) as u8,
93-
];
72+
let u_rows = u_buf.chunks_exact_mut(half_width);
73+
let v_rows = v_buf.chunks_exact_mut(half_width);
74+
for (((r1, r2), u), v) in r1.zip(r2).zip(u_rows).zip(v_rows) {
75+
for (((pix0, pix1), u), v) in r1.chunks_exact(2 * 3).zip(r2.chunks_exact(2 * 3)).zip(u).zip(v) {
76+
let r = (i16::from(pix0[0]) + i16::from(pix0[3]) + i16::from(pix1[0]) + i16::from(pix1[3]) + 2) / 4;
77+
let g = (i16::from(pix0[1]) + i16::from(pix0[4]) + i16::from(pix1[1]) + i16::from(pix1[4]) + 2) / 4;
78+
let b = (i16::from(pix0[2]) + i16::from(pix0[5]) + i16::from(pix1[2]) + i16::from(pix1[5]) + 2) / 4;
9479

95-
write_y(px, py, pix0x0);
96-
write_y(px, py + 1, pix0x1);
97-
write_y(px + 1, py, pix1x0);
98-
write_y(px + 1, py + 1, pix1x1);
99-
write_u(i, j, &avg_pix);
100-
write_v(i, j, &avg_pix);
80+
*u = (((-38 * r + 112 * b - 74 * g) >> 8) + 128) as u8;
81+
*v = (((112 * r - 18 * b - 94 * g) >> 8) + 128) as u8;
10182
}
10283
}
10384
}

0 commit comments

Comments
 (0)