Skip to content

DynamicImage::crop() is slow because to_image() is slow #2295

@Shnatsel

Description

@Shnatsel

In v0.25.2, the crop operation is implemented as:

dynamic_map!(*self, ref mut p => imageops::crop(p, x, y, width, height).to_image())

which obtains a view into an image, and then calls to_image() on it to turn it into a new image buffer. And to_image() shuffles pixels one by one in a purely scalar fashion and with bounds checks on every pixel:

image/src/image.rs

Lines 1131 to 1136 in e176cd4

for y in 0..self.inner.ystride {
for x in 0..self.inner.xstride {
let p = borrowed.get_pixel(x + self.inner.xoffset, y + self.inner.yoffset);
out.put_pixel(x, y, p);
}
}

A much better way would be iterating over the rows, and copying over entire rows with slice::copy_from_slice(). That would both leverage vector instructions and reduce the amount of bounds checks from n^2 to n.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind: APImissing or awkward public APIs, maintainer choicenext: breakingInformation tag for PRs and ideas that require an interface break

    Type

    No type

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions