mindustry logic execution, map- and schematic- parsing and rendering
move image out
| -rw-r--r-- | Cargo.toml | 6 | ||||
| -rw-r--r-- | src/data/renderer.rs | 2 | ||||
| -rw-r--r-- | src/utils/image/affine.rs | 186 | ||||
| -rw-r--r-- | src/utils/image/holder.rs | 10 | ||||
| -rw-r--r-- | src/utils/image/mod.rs | 259 | ||||
| -rw-r--r-- | src/utils/image/overlay.rs | 231 | ||||
| -rw-r--r-- | src/utils/mod.rs | 2 |
7 files changed, 10 insertions, 686 deletions
@@ -1,6 +1,6 @@ [package] name = "mindus" -version = "4.0.15" +version = "4.0.17" edition = "2021" description = "A library for working with mindustry data formats (eg schematics and maps) (fork of plandustry)" authors = [ @@ -19,7 +19,6 @@ base64 = "0.21" paste = "1.0" strconv = "0.1" amap = "0.1" -png = { version = "0.17", features = ["unstable"], optional = true } color-hex = "0.2" thiserror = "1.0" bobbin-bits = "0.1" @@ -27,9 +26,10 @@ blurslice = { version = "0.1" } enum_dispatch = "0.3" fast_image_resize = "2.7" phf = { version = "0.11", features = ["macros"] } +fimg = { version = "0.2", default-features = false } [features] -bin = ["png"] +bin = ["fimg/save"] default = ["bin"] [build-dependencies] diff --git a/src/data/renderer.rs b/src/data/renderer.rs index 62c5fcd..e070022 100644 --- a/src/data/renderer.rs +++ b/src/data/renderer.rs @@ -3,7 +3,7 @@ pub(crate) use super::autotile::*; use super::schematic::Schematic; use super::GridPos; use crate::block::Rotation; -pub(crate) use crate::utils::{Image, ImageHolder, ImageUtils, Overlay, OverlayAt, Repeat}; +pub(crate) use crate::utils::*; use crate::Map; include!(concat!(env!("OUT_DIR"), "/full.rs")); include!(concat!(env!("OUT_DIR"), "/quar.rs")); diff --git a/src/utils/image/affine.rs b/src/utils/image/affine.rs deleted file mode 100644 index f2b23bf..0000000 --- a/src/utils/image/affine.rs +++ /dev/null @@ -1,186 +0,0 @@ -use super::Image; - -/// Rotate a image 180 degrees clockwise. -pub fn rot_180<const CHANNELS: usize>(img: &mut Image<&mut [u8], CHANNELS>) { - for y in 0..img.height() / 2 { - for x in 0..img.width() { - let p = unsafe { img.pixel(x, y) }; - let x2 = img.width() - x - 1; - let y2 = img.height() - y - 1; - let p2 = unsafe { img.pixel(x2, y2) }; - unsafe { img.set_pixel(x, y, p2) }; - unsafe { img.set_pixel(x2, y2, p) }; - } - } - - if img.height() % 2 != 0 { - let middle = img.height() / 2; - - for x in 0..img.width() / 2 { - let p = unsafe { img.pixel(x, middle) }; - let x2 = img.width() - x - 1; - let p2 = unsafe { img.pixel(x2, middle) }; - unsafe { img.set_pixel(x, middle, p2) }; - unsafe { img.set_pixel(x2, middle, p) }; - } - } -} - -/// # Safety -/// -/// UB if supplied image rectangular -unsafe fn transpose<const CHANNELS: usize>(img: &mut Image<&mut [u8], CHANNELS>) { - debug_assert_eq!(img.width(), img.height()); - let size = img.width(); - for i in 0..size { - for j in i..size { - for c in 0..CHANNELS { - // SAFETY: caller gurantees rectangularity - unsafe { - img.buffer.swap_unchecked( - (i * size + j) as usize * CHANNELS + c, - (j * size + i) as usize * CHANNELS + c, - ) - }; - } - } - } -} - -/// Rotate a image 90 degrees clockwise. -/// This is done by first [flipping vertically](flip_v), then [transposing](transpose) the image, to save allocations. -/// -/// # Safety -/// -/// UB if the image is not square -#[inline] -pub unsafe fn rot_90<const CHANNELS: usize>(img: &mut Image<&mut [u8], CHANNELS>) { - flip_v(img); - // SAFETY: caller ensures rectangularity - unsafe { transpose(img) }; -} - -/// Rotate a image 270 degrees clockwise, or 90 degrees anti clockwise. -/// [horizontal flip](flip_h), then [transpose]. -/// -/// # Safety -/// -/// UB if the image is not square -#[inline] -pub unsafe fn rot_270<const CHANNELS: usize>(img: &mut Image<&mut [u8], CHANNELS>) { - flip_h(img); - // SAFETY: caller ensures rectangularity - unsafe { transpose(img) }; -} - -/// Flip a image vertically. -pub fn flip_v<const CHANNELS: usize>(img: &mut Image<&mut [u8], CHANNELS>) { - for y in 0..img.height() / 2 { - for x in 0..img.width() { - let y2 = img.height() - y - 1; - // SAFETY: within bounds - let p2 = unsafe { img.pixel(x, y2) }; - let p = unsafe { img.pixel(x, y) }; - unsafe { img.set_pixel(x, y2, p) }; - unsafe { img.set_pixel(x, y, p2) }; - } - } -} - -/// Flip a image horizontally. -pub fn flip_h<const CHANNELS: usize>(img: &mut Image<&mut [u8], CHANNELS>) { - for y in 0..img.height() { - for x in 0..img.width() / 2 { - let x2 = img.width() - x - 1; - let p2 = unsafe { img.pixel(x2, y) }; - let p = unsafe { img.pixel(x, y) }; - unsafe { img.set_pixel(x2, y, p) }; - unsafe { img.set_pixel(x, y, p2) }; - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::utils::image::img; - - #[test] - fn rotate_90() { - let mut from = img![ - [00, 01] - [02, 10] - ]; - unsafe { rot_90(&mut from.as_mut()) }; - assert_eq!( - from, - img![ - [02, 00] - [10, 01] - ] - ); - } - - #[test] - fn rotate_180() { - let mut from = img![ - [00, 01] - [02, 10] - ]; - rot_180(&mut from.as_mut()); - assert_eq!( - from, - img![ - [10, 02] - [01, 00] - ] - ); - } - - #[test] - fn rotate_270() { - let mut from = img![ - [00, 01] - [20, 10] - ]; - unsafe { rot_270(&mut from.as_mut()) }; - assert_eq!( - from, - img![ - [01, 10] - [00, 20] - ] - ); - } - - #[test] - fn flip_vertical() { - let mut from = img![ - [90, 01] - [21, 42] - ]; - flip_v(&mut from.as_mut()); - assert_eq!( - from, - img![ - [21, 42] - [90, 01] - ] - ) - } - #[test] - fn flip_horizontal() { - let mut from = img![ - [90, 01] - [21, 42] - ]; - flip_h(&mut from.as_mut()); - assert_eq!( - from, - img![ - [01, 90] - [42, 21] - ] - ) - } -} diff --git a/src/utils/image/holder.rs b/src/utils/image/holder.rs index 4c1b6a5..e905f48 100644 --- a/src/utils/image/holder.rs +++ b/src/utils/image/holder.rs @@ -68,16 +68,6 @@ impl ImageUtils for ImageHolder<4> { self } - fn flip_h(&mut self) -> &mut Self { - self.borrow_mut().flip_h(); - self - } - - fn flip_v(&mut self) -> &mut Self { - self.borrow_mut().flip_v(); - self - } - fn shadow(&mut self) -> &mut Self { self.borrow_mut().shadow(); self diff --git a/src/utils/image/mod.rs b/src/utils/image/mod.rs index 02c1a43..9d853b6 100644 --- a/src/utils/image/mod.rs +++ b/src/utils/image/mod.rs @@ -1,21 +1,8 @@ use fast_image_resize as fr; -use std::{num::NonZeroU32, slice::SliceIndex}; +pub use fimg::*; -mod affine; -use affine::*; mod holder; -mod overlay; -pub use holder::*; -pub use overlay::*; - -pub trait RepeatNew { - type Output; - /// Repeat self till it fills a new image of size x, y - /// # Safety - /// - /// UB if self's width is not a multiple of x, or self's height is not a multiple of y - unsafe fn repeated(&self, x: u32, y: u32) -> Self::Output; -} +pub use holder::ImageHolder; pub trait ImageUtils { /// Tint this image with the color @@ -25,51 +12,18 @@ pub trait ImageUtils { /// /// UB if image is not square unsafe fn rotate(&mut self, times: u8) -> &mut Self; - /// flip along the horizontal axis - fn flip_h(&mut self) -> &mut Self; - /// flip along the vertical axis - fn flip_v(&mut self) -> &mut Self; /// shadow fn shadow(&mut self) -> &mut Self; /// scale a image fn scale(self, to: u32) -> Image<Vec<u8>, 4>; } -macro_rules! assert_unchecked { - ($cond:expr) => {{ - if !$cond { - #[cfg(debug_assertions)] - let _ = ::core::ptr::NonNull::<()>::dangling().as_ref(); // force unsafe wrapping block - #[cfg(debug_assertions)] - panic!("assertion failed: {} returned false", stringify!($cond)); - #[cfg(not(debug_assertions))] - std::hint::unreachable_unchecked() - } - }}; -} -use assert_unchecked; - -impl RepeatNew for Image<&[u8], 3> { - type Output = Image<Vec<u8>, 3>; - unsafe fn repeated(&self, x: u32, y: u32) -> Self::Output { - let mut img = Image::alloc(x, y); // could probably optimize this a ton but eh - for x in 0..(x / self.width()) { - for y in 0..(y / self.height()) { - let a: &mut Image<&mut [u8], 3> = &mut img.as_mut(); - // SAFETY: caller upholds - unsafe { a.overlay_at(self, x * self.width(), y * self.height()) }; - } - } - img - } -} - impl ImageUtils for Image<&mut [u8], 4> { unsafe fn rotate(&mut self, times: u8) -> &mut Self { match times { - 2 => rot_180(self), - 1 => unsafe { rot_90(self) }, - 3 => unsafe { rot_270(self) }, + 2 => self.rot_180(), + 1 => unsafe { self.rot_90() }, + 3 => unsafe { self.rot_270() }, _ => {} } self @@ -126,209 +80,6 @@ impl ImageUtils for Image<&mut [u8], 4> { } self } - - #[inline] - fn flip_h(&mut self) -> &mut Self { - flip_h(self); - self - } - - #[inline(always)] - fn flip_v(&mut self) -> &mut Self { - flip_v(self); - self - } -} - -#[inline] -unsafe fn really_unsafe_index(x: u32, y: u32, w: u32) -> usize { - // y * w + x - let tmp = unsafe { (y as usize).unchecked_mul(w as usize) }; - unsafe { tmp.unchecked_add(x as usize) } -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct Image<T, const CHANNELS: usize> { - pub buffer: T, - pub width: NonZeroU32, - pub height: NonZeroU32, -} - -impl<const CHANNELS: usize> Default for Image<&'static [u8], CHANNELS> { - fn default() -> Self { - Self { - buffer: &[0; CHANNELS], - width: NonZeroU32::new(1).unwrap(), - height: NonZeroU32::new(1).unwrap(), - } - } -} - -impl<T, const CHANNELS: usize> Image<T, CHANNELS> { - #[inline] - pub fn height(&self) -> u32 { - self.height.into() - } - - #[inline] - pub fn width(&self) -> u32 { - self.width.into() - } - - #[inline] - pub const fn new(width: NonZeroU32, height: NonZeroU32, buffer: T) -> Self { - Image { - width, - height, - buffer, - } - } -} - -impl<const CHANNELS: usize> Image<&[u8], CHANNELS> { - #[inline] - pub const fn copy(&self) -> Self { - Self { - width: self.width, - height: self.height, - buffer: self.buffer, - } - } -} - -impl<T: std::ops::Deref<Target = [u8]>, const CHANNELS: usize> Image<T, CHANNELS> { - /// # Safety - /// - /// - UB if x, y is out of bounds - /// - UB if buffer is too small - #[inline] - pub unsafe fn slice(&self, x: u32, y: u32) -> impl SliceIndex<[u8], Output = [u8]> { - debug_assert!(x < self.width(), "x out of bounds"); - debug_assert!(y < self.height(), "y out of bounds"); - let index = unsafe { really_unsafe_index(x, y, self.width()) }; - let index = unsafe { index.unchecked_mul(CHANNELS) }; - debug_assert!(self.buffer.len() > index); - index..unsafe { index.unchecked_add(CHANNELS) } - } - - #[inline] - pub fn chunked(&self) -> impl Iterator<Item = &[u8; CHANNELS]> { - // SAFETY: 0 sized images illegal - unsafe { assert_unchecked!(self.buffer.len() > CHANNELS) }; - // SAFETY: no half pixels! - unsafe { assert_unchecked!(self.buffer.len() % CHANNELS == 0) }; - self.buffer.array_chunks::<CHANNELS>() - } - - /// Return a pixel at (x, y). - /// # Safety - /// - /// Refer to [`slice`] - #[inline] - pub unsafe fn pixel(&self, x: u32, y: u32) -> [u8; CHANNELS] { - let idx = unsafe { self.slice(x, y) }; - let ptr = unsafe { self.buffer.get_unchecked(idx).as_ptr().cast() }; - unsafe { *ptr } - } -} - -impl<T: std::ops::DerefMut<Target = [u8]>, const CHANNELS: usize> Image<T, CHANNELS> { - /// Return a mutable reference to a pixel at (x, y). - /// # Safety - /// - /// Refer to [`slice`] - #[inline] - pub unsafe fn pixel_mut(&mut self, x: u32, y: u32) -> &mut [u8] { - let idx = unsafe { self.slice(x, y) }; - unsafe { self.buffer.get_unchecked_mut(idx) } - } - - #[inline] - pub fn chunked_mut(&mut self) -> impl Iterator<Item = &mut [u8; CHANNELS]> { - // SAFETY: 0 sized images are not allowed - unsafe { assert_unchecked!(self.buffer.len() > CHANNELS) }; - // SAFETY: buffer cannot have half pixels - unsafe { assert_unchecked!(self.buffer.len() % CHANNELS == 0) }; - self.buffer.array_chunks_mut::<CHANNELS>() - } - - /// Set the pixel at x, y - /// - /// # Safety - /// - /// UB if x, y is out of bounds. - #[inline] - pub unsafe fn set_pixel(&mut self, x: u32, y: u32, px: [u8; CHANNELS]) { - // SAFETY: Caller says that x, y is in bounds - let out = unsafe { self.pixel_mut(x, y) }; - // SAFETY: px must be CHANNELS long - unsafe { std::ptr::copy_nonoverlapping(px.as_ptr(), out.as_mut_ptr(), CHANNELS) }; - } -} - -impl<const CHANNELS: usize> Image<Vec<u8>, CHANNELS> { - pub fn alloc(width: u32, height: u32) -> Self { - Image { - width: width.try_into().unwrap(), - height: height.try_into().unwrap(), - buffer: vec![0; CHANNELS * width as usize * height as usize], - } - } - - pub fn as_ref(&self) -> Image<&[u8], CHANNELS> { - Image::new(self.width, self.height, &self.buffer) - } - - pub fn as_mut(&mut self) -> Image<&mut [u8], CHANNELS> { - Image::new(self.width, self.height, &mut self.buffer) - } -} - -impl Image<Vec<u8>, 3> { - #[cfg(feature = "bin")] - pub fn save(&self, f: impl AsRef<std::path::Path>) { - let p = std::fs::File::create(f).unwrap(); - let w = &mut std::io::BufWriter::new(p); - let mut enc = png::Encoder::new(w, self.width(), self.height()); - enc.set_color(png::ColorType::Rgb); - enc.set_depth(png::BitDepth::Eight); - enc.set_source_gamma(png::ScaledFloat::new(1.0 / 2.2)); - enc.set_source_chromaticities(png::SourceChromaticities::new( - (0.31270, 0.32900), - (0.64000, 0.33000), - (0.30000, 0.60000), - (0.15000, 0.06000), - )); - let mut writer = enc.write_header().unwrap(); - writer.write_image_data(&self.buffer).unwrap(); - } -} - -#[cfg(test)] -macro_rules! img { - [[$($v:literal),+] [$($v2:literal),+]] => {{ - let from: Image<Vec<u8>, 1> = Image::new( - 2.try_into().unwrap(), - 2.try_into().unwrap(), - vec![$($v,)+ $($v2,)+] - ); - from - }} -} -#[cfg(test)] -pub(self) use img; - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn scale() { - let mut from = Image::alloc(6, 6); - unsafe { from.set_pixel(3, 3, [255, 255, 255, 255]) }; - let from = from.as_mut().scale(12); - assert_eq!(unsafe { from.pixel(6, 6) }, [255, 255, 255, 255]); - } } pub fn blend(bg: &mut [u8; 4], fg: [u8; 4]) { diff --git a/src/utils/image/overlay.rs b/src/utils/image/overlay.rs deleted file mode 100644 index 3b6745b..0000000 --- a/src/utils/image/overlay.rs +++ /dev/null @@ -1,231 +0,0 @@ -use super::{assert_unchecked, really_unsafe_index, Image}; -use std::simd::SimdInt; -use std::simd::SimdPartialOrd; -use std::simd::{simd_swizzle, Simd}; - -pub trait OverlayAt<W> { - /// Overlay with => self at coordinates x, y, without blending - /// # Safety - /// - /// UB if x, y is out of bounds - unsafe fn overlay_at(&mut self, with: &W, x: u32, y: u32) -> &mut Self; -} - -pub trait Overlay<W> { - /// Overlay with => self (does not blend) - /// # Safety - /// - /// UB if a.width != b.width || a.height != b.height - unsafe fn overlay(&mut self, with: &W) -> &mut Self; -} - -#[inline] -pub unsafe fn blit(rgb: &mut [u8], rgba: &[u8]) { - const LAST4: Simd<u8, 16> = Simd::from_array([ - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, - ]); - - let mut srci = 0; - let mut dsti = 0; - while dsti + 16 <= rgb.len() { - let old: Simd<u8, 16> = Simd::from_slice(unsafe { rgb.get_unchecked(dsti..dsti + 16) }); - let new: Simd<u8, 16> = Simd::from_slice(unsafe { rgba.get_unchecked(srci..srci + 16) }); - - let threshold = new.simd_ge(Simd::splat(128)).to_int().cast::<u8>(); - let mut mask = simd_swizzle!( - threshold, - [3, 3, 3, 7, 7, 7, 11, 11, 11, 15, 15, 15, 0, 0, 0, 0] - ); - mask &= LAST4; - - let new_rgb = simd_swizzle!(new, [0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 0, 0, 0, 0]); - let blended = (new_rgb & mask) | (old & !mask); - blended.copy_to_slice(unsafe { rgb.get_unchecked_mut(dsti..dsti + 16) }); - - srci += 16; - dsti += 12; - } - - while dsti + 3 <= rgb.len() { - if unsafe { *rgba.get_unchecked(srci + 3) } >= 128 { - let src = unsafe { rgba.get_unchecked(srci..srci + 3) }; - let end = unsafe { rgb.get_unchecked_mut(dsti..dsti + 3) }; - unsafe { std::ptr::copy_nonoverlapping(src.as_ptr(), end.as_mut_ptr(), 3) }; - } - - srci += 4; - dsti += 3; - } -} - -impl Overlay<Image<&[u8], 4>> for Image<&mut [u8], 4> { - #[inline] - unsafe fn overlay(&mut self, with: &Image<&[u8], 4>) -> &mut Self { - debug_assert!(self.width() == with.width()); - debug_assert!(self.height() == with.height()); - for (i, other_pixels) in with.chunked().enumerate() { - if other_pixels[3] >= 128 { - let idx_begin = unsafe { i.unchecked_mul(4) }; - let idx_end = unsafe { idx_begin.unchecked_add(4) }; - let own_pixels = unsafe { self.buffer.get_unchecked_mut(idx_begin..idx_end) }; - unsafe { - std::ptr::copy_nonoverlapping(other_pixels.as_ptr(), own_pixels.as_mut_ptr(), 4) - }; - } - } - self - } -} - -impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 3> { - #[inline] - unsafe fn overlay_at(&mut self, with: &Image<&[u8], 4>, x: u32, y: u32) -> &mut Self { - // SAFETY: caller upholds these - unsafe { assert_unchecked!(x + with.width() <= self.width()) }; - unsafe { assert_unchecked!(y + with.height() <= self.height()) }; - for j in 0..with.height() { - let i_x = j as usize * with.width() as usize * 4 - ..(j as usize + 1) * with.width() as usize * 4; - let o_x = ((j as usize + y as usize) * self.width() as usize + x as usize) * 3 - ..((j as usize + y as usize) * self.width() as usize - + x as usize - + with.width() as usize) - * 3; - let rgb = unsafe { self.buffer.get_unchecked_mut(o_x) }; - let rgba = unsafe { with.buffer.get_unchecked(i_x) }; - unsafe { blit(rgb, rgba) } - } - self - } -} - -impl OverlayAt<Image<&[u8], 3>> for Image<&mut [u8], 3> { - #[inline] - unsafe fn overlay_at(&mut self, with: &Image<&[u8], 3>, x: u32, y: u32) -> &mut Self { - macro_rules! o3x3 { - ($n:expr) => {{ - for j in 0..($n as usize) { - let i_x = j * ($n as usize) * 3..(j + 1) * ($n as usize) * 3; - let o_x = ((j + y as usize) * self.width() as usize + x as usize) * 3 - ..((j + y as usize) * self.width() as usize + x as usize + ($n as usize)) - * 3; - let a = unsafe { self.buffer.get_unchecked_mut(o_x) }; - let b = unsafe { with.buffer.get_unchecked(i_x) }; - a.copy_from_slice(b); - } - }}; - } - // let it unroll - match with.width() { - 8 => o3x3!(8), - 16 => o3x3!(16), // this branch makes 8x8 0.16 times slower; but 16x16 0.2 times faster. - _ => o3x3!(with.width()), - } - self - } -} - -impl Overlay<Image<&[u8], 4>> for Image<&mut [u8], 3> { - #[inline] - unsafe fn overlay(&mut self, with: &Image<&[u8], 4>) -> &mut Self { - debug_assert!(self.width() == with.width()); - debug_assert!(self.height() == with.height()); - for (i, chunk) in with - .buffer - .chunks_exact(with.width() as usize * 4) - .enumerate() - { - let rgb = unsafe { - self.buffer.get_unchecked_mut( - i * with.width() as usize * 3..(i + 1) * with.width() as usize * 3, - ) - }; - unsafe { blit(rgb, chunk) }; - } - self - } -} - -impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 4> { - #[inline] - unsafe fn overlay_at(&mut self, with: &Image<&[u8], 4>, x: u32, y: u32) -> &mut Self { - for j in 0..with.height() { - for i in 0..with.width() { - let index = unsafe { really_unsafe_index(i, j, with.width()) }; - let their_px = unsafe { with.buffer.get_unchecked(index * 4..index * 4 + 4) }; - if unsafe { *their_px.get_unchecked(3) } >= 128 { - let x = unsafe { i.unchecked_add(x) }; - let y = unsafe { j.unchecked_add(y) }; - let index = unsafe { really_unsafe_index(x, y, self.width()) }; - let our_px = unsafe { self.buffer.get_unchecked_mut(index * 4..index * 4 + 4) }; - our_px.copy_from_slice(their_px); - } - } - } - - self - } -} - -#[cfg(test)] -mod bench { - extern crate test; - use test::{black_box, Bencher}; - - use super::*; - use crate::{data::renderer::Scale, load}; - - #[bench] - fn overlay_3on3at(bench: &mut Bencher) { - let mut v = vec![0u8; 3 * 64 * 64]; - let mut a: Image<_, 3> = Image::new( - 64.try_into().unwrap(), - 64.try_into().unwrap(), - v.as_mut_slice(), - ); - let b = load!("darksand", Scale::Eigth); - bench.iter(|| unsafe { - for x in 0..16 { - for y in 0..16 { - black_box(a.overlay_at(&b.borrow(), x, y)); - } - } - }); - } - - #[bench] - fn overlay_4on3at(bench: &mut Bencher) { - let mut v = vec![0u8; 3 * 64 * 64]; - let mut a: Image<_, 3> = Image::new( - 64.try_into().unwrap(), - 64.try_into().unwrap(), - v.as_mut_slice(), - ); - let b = load!("salt-wall", Scale::Eigth); - bench.iter(|| unsafe { - for x in 0..16 { - for y in 0..16 { - black_box(a.overlay_at(&b.borrow(), x, y)); - } - } - }); - } - - #[bench] - fn overlay_4on4at(bench: &mut Bencher) { - let mut v = vec![0u8; 4 * 64 * 64]; - let mut a: Image<_, 4> = Image::new( - 64.try_into().unwrap(), - 64.try_into().unwrap(), - v.as_mut_slice(), - ); - let b = load!("salt-wall", Scale::Eigth); - bench.iter(|| unsafe { - for x in 0..16 { - for y in 0..16 { - black_box(a.overlay_at(&b.borrow(), x, y)); - } - } - }); - } -} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 4518839..3e12541 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,3 +1,3 @@ pub mod array; pub mod image; -pub use self::image::{Image, ImageHolder, ImageUtils, Overlay, OverlayAt, RepeatNew as Repeat}; +pub use self::image::{Image, ImageHolder, ImageUtils, Overlay, OverlayAt}; |