Skip to content

Commit 7e86454

Browse files
committed
Changed to use integer math instead of f32 method. Adjusted to use iterators instead of array indexing.
1 parent 2204f18 commit 7e86454

1 file changed

Lines changed: 18 additions & 34 deletions

File tree

openh264/src/formats/rgb2yuv.rs

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -58,46 +58,30 @@ 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();
64+
// let rgb8_data = rgb.rgb8_data().as_chunks::<3>().0;
65+
// let rgb8_data = rgb.rgb8_data().chunks_exact(3);
6466

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-
};
67+
for (pix, y) in rgb8_data.chunks_exact(3).zip(y_buf.iter_mut()) {
68+
// let [r, g, b] = *pix else { unreachable!() };
69+
*y = (((66 * u32::from(pix[0]) + 129 * u32::from(pix[1]) + 25 * u32::from(pix[2])) >> 8) + 16) as u8;
70+
}
7571

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-
};
72+
let r1 = rgb8_data.chunks_exact(dimensions_padded.0 * 3).step_by(2);
73+
let r2 = rgb8_data.chunks_exact(dimensions_padded.0 * 3).skip(1).step_by(2);
8074

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-
];
75+
let u_rows = u_buf.chunks_exact_mut(half_width);
76+
let v_rows = v_buf.chunks_exact_mut(half_width);
77+
for (((r1, r2), u), v) in r1.zip(r2).zip(u_rows).zip(v_rows) {
78+
for (((pix0, pix1), u), v) in r1.chunks_exact(2 * 3).zip(r2.chunks_exact(2 * 3)).zip(u).zip(v) {
79+
let r = (i16::from(pix0[0]) + i16::from(pix0[3]) + i16::from(pix1[0]) + i16::from(pix1[3]) + 2) / 4;
80+
let g = (i16::from(pix0[1]) + i16::from(pix0[4]) + i16::from(pix1[1]) + i16::from(pix1[4]) + 2) / 4;
81+
let b = (i16::from(pix0[2]) + i16::from(pix0[5]) + i16::from(pix1[2]) + i16::from(pix1[5]) + 2) / 4;
9482

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);
83+
*u = (((-38 * r + 112 * b - 74 * g) >> 8) + 128) as u8;
84+
*v = (((112 * r - 18 * b - 94 * g) >> 8) + 128) as u8;
10185
}
10286
}
10387
}

0 commit comments

Comments
 (0)