image icon indicating copy to clipboard operation
image copied to clipboard

add support for block pixel enum in ImageBuffer

Open bfraboni opened this issue 2 years ago • 0 comments

Hey team,

I'm very new to Rust, and very new to using the Image-rs crate -- so please forgive the potential mistakes I could write/say.

I'm trying to add a block enumerator for incoherent ImagBuffer access. This is usually faster than regular pixel enum when we want to perform a column-major operation on a image, even though the memory layout is row-major. Basically the following code:

fn transpose_enum<P, Container>(input: &ImageBuffer<P, Container>, output: &mut ImageBuffer<P, Container>)
where 
   P: Pixel, 
   Container: Deref<Target = [P::Subpixel]> + DerefMut
{
   for (x, y, pix) in input.enumerate_pixels() {
       output.put_pixel(y, x, *pix);
   }
}

can be outperformed by the PR modified version:

fn transpose_enum_blocks<P, Container>(input: &ImageBuffer<P, Container>, output: &mut ImageBuffer<P, Container>, block_size: u32)
where 
    P: Pixel, 
    Container: Deref<Target = [P::Subpixel]> + DerefMut
{
    for (x, y, pix) in input.enumerate_pixels_blocks(block_size) {
        output.put_pixel(y, x, *pix);
    }
}

On my old 2016 laptop I get between 1.3x to 2x perf improvements for some adequate block sizes when tranposing 2K - 4K and 8K images. I still didn't properly becnhmarked on my desktop machine though (Ryzen 7 5800x) but will soon do.

Let me know if that's of interest for the image crate, and please let me know of any dumb mistake I could have done in the code. Note that I randomly chose function and variable names, but we can completely change that, and I can also make a mutable version of the enumerator.

I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to choose either at their option.

bfraboni avatar Apr 30 '23 05:04 bfraboni