optimize Image::repeat

also removes some unsafe
This commit is contained in:
bendn 2023-10-02 12:39:58 +07:00
parent ac3f07c797
commit 43da761a4e
No known key found for this signature in database
GPG key ID: 0D9D3A2A3B2A93D6
5 changed files with 100 additions and 74 deletions

View file

@ -1,6 +1,6 @@
[package]
name = "fimg"
version = "0.4.11"
version = "0.4.12"
authors = ["bend-n <bend.n@outlook.com>"]
license = "MIT"
edition = "2021"
@ -12,7 +12,8 @@ exclude = ["tdata", "benches/", ".gitignore"]
png = { version = "0.17", features = ["unstable"], optional = true }
[dev-dependencies]
iai = { version = "0.1.1", features = [], git = "https://github.com/bend-n/iai/" }
iai = { version = "0.1.1", features = [
], git = "https://github.com/bend-n/iai/" }
[[bench]]
name = "overlays"
@ -24,6 +25,11 @@ name = "affine_transformations"
path = "benches/affine_transformations.rs"
harness = false
[[bench]]
name = "tile"
path = "benches/tile.rs"
harness = false
[features]
save = ["png"]
default = ["save"]

View file

@ -7,10 +7,12 @@ quick simple image operations
- [x] overlay
- [x] rotation
- [x] flipping
- [x] image tiling
- [x] nearest neighbor scaling
- [x] triangle drawing
- [x] simple line drawing
- [x] box drawing
- [ ] thick box drawing
- [ ] thick line drawing
- [ ] polygon drawing
- [x] thick box drawing
- [x] thick line drawing
- [x] polygon drawing
- [x] circle drawing

6
benches/tile.rs Normal file
View file

@ -0,0 +1,6 @@
use fimg::*;
fn repeat() {
let x: Image<&[u8], 3> = Image::build(8, 8).buf(include_bytes!("3_8x8.imgbuf"));
let _ = unsafe { x.repeated(128, 128) }; // repeat 16 times
}
iai::main!(repeat);

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,7 @@
//! Handles image overlay
use crate::cloner::ImageCloner;
use super::{assert_unchecked, really_unsafe_index, Image};
use super::{assert_unchecked, Image};
use std::ops::{Deref, DerefMut};
use std::simd::{simd_swizzle, Simd, SimdInt, SimdPartialOrd};
@ -242,27 +242,14 @@ impl<T: DerefMut<Target = [u8]>, U: Deref<Target = [u8]>> OverlayAt<Image<U, 4>>
///
/// # Safety
/// - UB if x, y is out of bounds
/// - UB if x + with.width() > [`u32::MAX`]
/// - UB if y + with.height() > [`u32::MAX`]
unsafe fn overlay_at(&mut self, with: &Image<U, 4>, x: u32, y: u32) -> &mut Self {
for j in 0..with.height() {
for i in 0..with.width() {
// SAFETY: i, j is in bounds.
let index = unsafe { really_unsafe_index(i, j, with.width()) };
// SAFETY: using .pixel() results in horrible asm (+5k ns/iter)
let their_px = unsafe { with.buffer.get_unchecked(index * 4..index * 4 + 4) };
// SAFETY: must be sized right
if unsafe { *their_px.get_unchecked(3) } >= 128 {
// SAFETY:
// they said it cant go over.
// i dont know why, but this has performance importance™
let x = unsafe { i.unchecked_add(x) };
// SAFETY: caller gurantees this cannot overflow.
let y = unsafe { j.unchecked_add(y) };
// SAFETY: compute the offset index.
let index = unsafe { really_unsafe_index(x, y, self.width()) };
let their_px = unsafe { &with.pixel(i, j) };
if their_px[3] >= 128 {
// SAFETY: if everything else goes well, this is fine
let our_px = unsafe { self.buffer.get_unchecked_mut(index * 4..index * 4 + 4) };
let our_px = unsafe { self.pixel_mut(i + x, j + y) };
our_px.copy_from_slice(their_px);
}
}