Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions src/image_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,40 @@ macro_rules! ycbcr_image {
fn fill_buffers(&self, y: u16, buffers: &mut [Vec<u8>; 4]) {
let line = get_line(self.0, y, self.width(), $num_colors);

for pixel in line.chunks_exact($num_colors) {
// Doing the convertion in chunks allows the compiler to vectorize the code
// A size of 16 seems optimal for SSE and AVX capable hardware
const CHUNK_SIZE:usize = 16;

let mut y_buffer = [0;CHUNK_SIZE];
let mut cb_buffer = [0;CHUNK_SIZE];
let mut cr_buffer = [0;CHUNK_SIZE];

for chuck in line.chunks_exact($num_colors*CHUNK_SIZE) {
for i in (0..CHUNK_SIZE) {
let (y, cb, cr) = rgb_to_ycbcr(
chuck[i * $num_colors + $o1],
chuck[i * $num_colors + $o2],
chuck[i * $num_colors + $o3],
);

y_buffer[i] = y;
cb_buffer[i] = cb;
cr_buffer[i] = cr;
}

buffers[0].extend_from_slice(&y_buffer);
buffers[1].extend_from_slice(&cb_buffer);
buffers[2].extend_from_slice(&cr_buffer);
}

// Add the remaining pixels in case the number of
// pixels is not a multiple of CHUNK_SIZE
let pixel = line.len() / $num_colors;
for i in pixel/CHUNK_SIZE*CHUNK_SIZE..pixel {
let (y, cb, cr) = rgb_to_ycbcr(
pixel[$o1],
pixel[$o2],
pixel[$o3],
line[i*$num_colors + $o1],
line[i*$num_colors + $o2],
line[i*$num_colors + $o3],
);

buffers[0].push(y);
Expand Down
Loading