mirror of
https://github.com/Cykooz/fast_image_resize.git
synced 2026-10-08 01:11:09 +00:00
- Fixed benchmarks for resizing images with alpha channel using the resizer crate.
- Removed `image` crate from benchmarks for resizing images with alpha. - Added method `Image::copy(&self) -> Image<'static>`.
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
## [Unreleased] - ReleaseDate
|
||||
|
||||
- Added support of new type of pixels `PixelType::U16x4`.
|
||||
- Fixed benchmarks for resizing images with alpha channel using
|
||||
the `resizer` crate.
|
||||
- Removed `image` crate from benchmarks for resizing images with alpha.
|
||||
- Added method `Image::copy(&self) -> Image<'static>`.
|
||||
|
||||
## [0.9.5] - 2022-06-22
|
||||
|
||||
|
||||
Generated
+15
-15
@@ -244,9 +244,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.9"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ff1f980957787286a554052d03c7aee98d99cc32e09f6d45f0a814133c87978"
|
||||
checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
@@ -386,11 +386,11 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||
|
||||
[[package]]
|
||||
name = "fallible_collections"
|
||||
version = "0.4.4"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52db5973b6a19247baf19b30f41c23a1bfffc2e9ce0a5db2f60e3cd5dc8895f7"
|
||||
checksum = "c195cf4b2285d3c993eb887b4dc56b0d5728bbe1d0f9a99c0ac6bec2da3e4d85"
|
||||
dependencies = [
|
||||
"hashbrown 0.11.2",
|
||||
"hashbrown 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -477,9 +477,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.11.3"
|
||||
version = "0.11.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b"
|
||||
checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06"
|
||||
dependencies = [
|
||||
"color_quant",
|
||||
"weezl",
|
||||
@@ -537,9 +537,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.11.2"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
|
||||
dependencies = [
|
||||
"ahash 0.7.6",
|
||||
]
|
||||
@@ -825,9 +825,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a"
|
||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
@@ -1134,9 +1134,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.8.0"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
||||
checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
@@ -1280,9 +1280,9 @@ checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.19"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
|
||||
checksum = "81dee68f85cab8cf68dec42158baf3a79a1cdc065a8b103025965d6ccb7f6cbd"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
@@ -16,17 +16,18 @@ about resizing with respect to color space._
|
||||
|
||||
Supported pixel formats and available optimisations:
|
||||
|
||||
| Format | Description | Native Rust | SSE4.1 | AVX2 |
|
||||
|:------:|:-------------------------------------------------------|:-----------:|:-------:|:----:|
|
||||
| U8 | One `u8` component per pixel (e.g. L) | + | partial | + |
|
||||
| U8x2 | Two `u8` components per pixel (e.g. LA) | + | + | + |
|
||||
| U8x3 | Three `u8` components per pixel (e.g. RGB) | + | partial | + |
|
||||
| U8x4 | Four `u8` components per pixel (e.g. RGBA, RGBx, CMYK) | + | + | + |
|
||||
| U16 | One `u16` components per pixel (e.g. L16) | + | + | + |
|
||||
| U16x2 | Two `u16` components per pixel (e.g. LA16) | + | + | + |
|
||||
| U16x3 | Three `u16` components per pixel (e.g. RGB16) | + | + | + |
|
||||
| I32 | One `i32` component per pixel | + | - | - |
|
||||
| F32 | One `f32` component per pixel | + | - | - |
|
||||
| Format | Description | Native Rust | SSE4.1 | AVX2 |
|
||||
|:------:|:--------------------------------------------------------------|:-----------:|:-------:|:----:|
|
||||
| U8 | One `u8` component per pixel (e.g. L) | + | partial | + |
|
||||
| U8x2 | Two `u8` components per pixel (e.g. LA) | + | + | + |
|
||||
| U8x3 | Three `u8` components per pixel (e.g. RGB) | + | partial | + |
|
||||
| U8x4 | Four `u8` components per pixel (e.g. RGBA, RGBx, CMYK) | + | + | + |
|
||||
| U16 | One `u16` components per pixel (e.g. L16) | + | + | + |
|
||||
| U16x2 | Two `u16` components per pixel (e.g. LA16) | + | + | + |
|
||||
| U16x3 | Three `u16` components per pixel (e.g. RGB16) | + | + | + |
|
||||
| U16x4 | Four `u16` components per pixel (e.g. RGBA16, RGBx16, CMYK16) | + | + | + |
|
||||
| I32 | One `i32` component per pixel | + | - | - |
|
||||
| F32 | One `f32` component per pixel | + | - | - |
|
||||
|
||||
## Some benchmarks
|
||||
|
||||
@@ -48,11 +49,11 @@ Pipeline:
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 19.44 | 83.01 | 153.17 | 208.82 |
|
||||
| resize | - | 52.13 | 103.37 | 154.10 |
|
||||
| fir rust | 0.28 | 43.00 | 79.52 | 117.41 |
|
||||
| fir sse4.1 | 0.28 | 27.79 | 42.97 | 58.16 |
|
||||
| fir avx2 | 0.28 | 7.30 | 9.50 | 13.59 |
|
||||
| image | 19.24 | 82.52 | 152.17 | 207.63 |
|
||||
| resize | - | 52.19 | 103.40 | 154.15 |
|
||||
| fir rust | 0.28 | 40.88 | 69.39 | 101.53 |
|
||||
| fir sse4.1 | 0.28 | 28.21 | 43.03 | 59.46 |
|
||||
| fir avx2 | 0.28 | 7.33 | 9.47 | 13.59 |
|
||||
|
||||
### Resize RGBA8 image (U8x4) 4928x3279 => 852x567
|
||||
|
||||
@@ -63,16 +64,16 @@ Pipeline:
|
||||
- Source image
|
||||
[nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 19.73 | 82.34 | 141.74 | 198.86 |
|
||||
| resize | - | 49.91 | 100.27 | 148.99 |
|
||||
| fir rust | 0.18 | 36.84 | 52.31 | 74.99 |
|
||||
| fir sse4.1 | 0.18 | 13.21 | 17.26 | 22.42 |
|
||||
| fir avx2 | 0.18 | 9.47 | 12.03 | 16.08 |
|
||||
| resize | - | 61.93 | 122.10 | 182.55 |
|
||||
| fir rust | 0.18 | 36.57 | 52.28 | 74.14 |
|
||||
| fir sse4.1 | 0.18 | 13.14 | 17.21 | 22.44 |
|
||||
| fir avx2 | 0.18 | 9.69 | 11.99 | 16.23 |
|
||||
|
||||
## Resize L8 (luma) image (U8) 4928x3279 => 852x567
|
||||
### Resize L8 (luma) image (U8) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
@@ -84,11 +85,11 @@ Pipeline:
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 15.21 | 44.78 | 71.92 | 100.91 |
|
||||
| resize | - | 17.53 | 36.20 | 61.10 |
|
||||
| fir rust | 0.15 | 14.08 | 16.38 | 23.73 |
|
||||
| fir sse4.1 | 0.16 | 11.92 | 12.28 | 17.79 |
|
||||
| fir avx2 | 0.16 | 6.48 | 4.77 | 7.85 |
|
||||
| image | 15.86 | 47.17 | 74.46 | 102.53 |
|
||||
| resize | - | 17.30 | 35.92 | 61.52 |
|
||||
| fir rust | 0.15 | 14.10 | 16.20 | 24.12 |
|
||||
| fir sse4.1 | 0.15 | 11.93 | 12.13 | 18.20 |
|
||||
| fir avx2 | 0.15 | 6.30 | 4.71 | 7.62 |
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
+21
-40
@@ -1,7 +1,6 @@
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use glassbench::*;
|
||||
use image::imageops;
|
||||
|
||||
use fast_image_resize::pixels::U8x2;
|
||||
use fast_image_resize::{CpuExtensions, FilterType, Image, MulDiv, PixelType, ResizeAlg, Resizer};
|
||||
@@ -10,29 +9,11 @@ use testing::PixelExt;
|
||||
mod utils;
|
||||
|
||||
pub fn bench_downscale_la(bench: &mut Bench) {
|
||||
let src_image = U8x2::load_big_image().to_luma_alpha8();
|
||||
let new_width = NonZeroU32::new(852).unwrap();
|
||||
let new_height = NonZeroU32::new(567).unwrap();
|
||||
|
||||
let alg_names = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
|
||||
// image crate
|
||||
// https://crates.io/crates/image
|
||||
for alg_name in alg_names {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => imageops::Nearest,
|
||||
"Bilinear" => imageops::Triangle,
|
||||
"CatmullRom" => imageops::CatmullRom,
|
||||
"Lanczos3" => imageops::Lanczos3,
|
||||
_ => continue,
|
||||
};
|
||||
bench.task(format!("image - {}", alg_name), |task| {
|
||||
task.iter(|| {
|
||||
imageops::resize(&src_image, new_width.get(), new_height.get(), filter);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// fast_image_resize crate;
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@@ -49,13 +30,10 @@ pub fn bench_downscale_la(bench: &mut Bench) {
|
||||
"Lanczos3" => ResizeAlg::Convolution(FilterType::Lanczos3),
|
||||
_ => return,
|
||||
};
|
||||
let src_image_data = U8x2::load_big_src_image();
|
||||
let src_view = src_image_data.view();
|
||||
let mut premultiplied_src_image = Image::new(
|
||||
NonZeroU32::new(src_image.width()).unwrap(),
|
||||
NonZeroU32::new(src_image.height()).unwrap(),
|
||||
src_view.pixel_type(),
|
||||
);
|
||||
let src_image = U8x2::load_big_src_image();
|
||||
let src_view = src_image.view();
|
||||
let mut premultiplied_src_image =
|
||||
Image::new(src_image.width(), src_image.height(), src_view.pixel_type());
|
||||
let mut dst_image = Image::new(new_width, new_height, PixelType::U8x2);
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
let mut mul_div = MulDiv::default();
|
||||
@@ -68,24 +46,27 @@ pub fn bench_downscale_la(bench: &mut Bench) {
|
||||
mul_div.set_cpu_extensions(cpu_ext);
|
||||
}
|
||||
|
||||
bench.task(format!("fir {} - {}", ext_name, alg_name), |task| {
|
||||
task.iter(|| match resize_alg {
|
||||
bench.task(
|
||||
format!("fir {} - {}", ext_name, alg_name),
|
||||
|task| match resize_alg {
|
||||
ResizeAlg::Nearest => {
|
||||
fast_resizer
|
||||
.resize(&premultiplied_src_image.view(), &mut dst_view)
|
||||
.unwrap();
|
||||
task.iter(|| {
|
||||
fast_resizer.resize(&src_view, &mut dst_view).unwrap();
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
mul_div
|
||||
.multiply_alpha(&src_view, &mut premultiplied_src_image.view_mut())
|
||||
.unwrap();
|
||||
fast_resizer
|
||||
.resize(&premultiplied_src_image.view(), &mut dst_view)
|
||||
.unwrap();
|
||||
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
|
||||
task.iter(|| {
|
||||
mul_div
|
||||
.multiply_alpha(&src_view, &mut premultiplied_src_image.view_mut())
|
||||
.unwrap();
|
||||
fast_resizer
|
||||
.resize(&premultiplied_src_image.view(), &mut dst_view)
|
||||
.unwrap();
|
||||
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use glassbench::*;
|
||||
use image::imageops;
|
||||
|
||||
use fast_image_resize::pixels::U16x2;
|
||||
use fast_image_resize::{CpuExtensions, FilterType, Image, MulDiv, PixelType, ResizeAlg, Resizer};
|
||||
@@ -10,29 +9,11 @@ use testing::PixelExt;
|
||||
mod utils;
|
||||
|
||||
pub fn bench_downscale_la16(bench: &mut Bench) {
|
||||
let src_image = U16x2::load_big_image().to_luma_alpha16();
|
||||
let new_width = NonZeroU32::new(852).unwrap();
|
||||
let new_height = NonZeroU32::new(567).unwrap();
|
||||
|
||||
let alg_names = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
|
||||
// image crate
|
||||
// https://crates.io/crates/image
|
||||
for alg_name in alg_names {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => imageops::Nearest,
|
||||
"Bilinear" => imageops::Triangle,
|
||||
"CatmullRom" => imageops::CatmullRom,
|
||||
"Lanczos3" => imageops::Lanczos3,
|
||||
_ => continue,
|
||||
};
|
||||
bench.task(format!("image - {}", alg_name), |task| {
|
||||
task.iter(|| {
|
||||
imageops::resize(&src_image, new_width.get(), new_height.get(), filter);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// fast_image_resize crate;
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@@ -49,12 +30,12 @@ pub fn bench_downscale_la16(bench: &mut Bench) {
|
||||
"Lanczos3" => ResizeAlg::Convolution(FilterType::Lanczos3),
|
||||
_ => return,
|
||||
};
|
||||
let src_image_data = U16x2::load_big_src_image();
|
||||
let src_view = src_image_data.view();
|
||||
let src_image = U16x2::load_big_src_image();
|
||||
let src_view = src_image.view();
|
||||
let mut premultiplied_src_image = Image::new(
|
||||
NonZeroU32::new(src_image.width()).unwrap(),
|
||||
NonZeroU32::new(src_image.height()).unwrap(),
|
||||
src_view.pixel_type(),
|
||||
src_image.width(),
|
||||
src_image.height(),
|
||||
src_image.pixel_type(),
|
||||
);
|
||||
let mut dst_image = Image::new(new_width, new_height, PixelType::U16x2);
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
@@ -71,9 +52,7 @@ pub fn bench_downscale_la16(bench: &mut Bench) {
|
||||
bench.task(format!("fir {} - {}", ext_name, alg_name), |task| {
|
||||
task.iter(|| match resize_alg {
|
||||
ResizeAlg::Nearest => {
|
||||
fast_resizer
|
||||
.resize(&premultiplied_src_image.view(), &mut dst_view)
|
||||
.unwrap();
|
||||
fast_resizer.resize(&src_view, &mut dst_view).unwrap();
|
||||
}
|
||||
_ => {
|
||||
mul_div
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use glassbench::*;
|
||||
use image::imageops;
|
||||
use resize::px::RGBA;
|
||||
use resize::Pixel::RGBA8;
|
||||
use resize::Pixel::RGBA8P;
|
||||
use rgb::FromSlice;
|
||||
|
||||
use fast_image_resize::pixels::U8x4;
|
||||
@@ -19,23 +18,6 @@ pub fn bench_downscale_rgba(bench: &mut Bench) {
|
||||
|
||||
let alg_names = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
|
||||
// image crate
|
||||
// https://crates.io/crates/image
|
||||
for alg_name in alg_names {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => imageops::Nearest,
|
||||
"Bilinear" => imageops::Triangle,
|
||||
"CatmullRom" => imageops::CatmullRom,
|
||||
"Lanczos3" => imageops::Lanczos3,
|
||||
_ => continue,
|
||||
};
|
||||
bench.task(format!("image - {}", alg_name), |task| {
|
||||
task.iter(|| {
|
||||
imageops::resize(&src_image, new_width.get(), new_height.get(), filter);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// resize crate
|
||||
// https://crates.io/crates/resize
|
||||
for alg_name in alg_names {
|
||||
@@ -58,7 +40,7 @@ pub fn bench_downscale_rgba(bench: &mut Bench) {
|
||||
src_image.height() as usize,
|
||||
new_width.get() as usize,
|
||||
new_height.get() as usize,
|
||||
RGBA8,
|
||||
RGBA8P,
|
||||
filter,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -106,9 +88,7 @@ pub fn bench_downscale_rgba(bench: &mut Bench) {
|
||||
bench.task(format!("fir {} - {}", ext_name, alg_name), |task| {
|
||||
task.iter(|| match resize_alg {
|
||||
ResizeAlg::Nearest => {
|
||||
fast_resizer
|
||||
.resize(&premultiplied_src_image.view(), &mut dst_view)
|
||||
.unwrap();
|
||||
fast_resizer.resize(&src_view, &mut dst_view).unwrap();
|
||||
}
|
||||
_ => {
|
||||
mul_div
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use glassbench::*;
|
||||
use image::imageops;
|
||||
use resize::px::RGBA;
|
||||
use resize::Pixel::RGBA16;
|
||||
use resize::Pixel::RGBA16P;
|
||||
use rgb::FromSlice;
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use fast_image_resize::pixels::U16x4;
|
||||
use fast_image_resize::{CpuExtensions, FilterType, Image, MulDiv, ResizeAlg, Resizer};
|
||||
@@ -13,31 +11,14 @@ use testing::PixelExt;
|
||||
mod utils;
|
||||
|
||||
pub fn bench_downscale_rgba16(bench: &mut Bench) {
|
||||
let src_image = U16x4::load_big_image().to_rgba16();
|
||||
let new_width = NonZeroU32::new(852).unwrap();
|
||||
let new_height = NonZeroU32::new(567).unwrap();
|
||||
|
||||
let alg_names = ["Nearest", "Bilinear", "CatmullRom", "Lanczos3"];
|
||||
|
||||
// image crate
|
||||
// https://crates.io/crates/image
|
||||
for alg_name in alg_names {
|
||||
let filter = match alg_name {
|
||||
"Nearest" => imageops::Nearest,
|
||||
"Bilinear" => imageops::Triangle,
|
||||
"CatmullRom" => imageops::CatmullRom,
|
||||
"Lanczos3" => imageops::Lanczos3,
|
||||
_ => continue,
|
||||
};
|
||||
bench.task(format!("image - {}", alg_name), |task| {
|
||||
task.iter(|| {
|
||||
imageops::resize(&src_image, new_width.get(), new_height.get(), filter);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// resize crate
|
||||
// https://crates.io/crates/resize
|
||||
let src_image = U16x4::load_big_image().to_rgba16();
|
||||
for alg_name in alg_names {
|
||||
let resize_src_image = src_image.as_raw().as_rgba();
|
||||
let mut dst =
|
||||
@@ -59,7 +40,7 @@ pub fn bench_downscale_rgba16(bench: &mut Bench) {
|
||||
src_image.height() as usize,
|
||||
new_width.get() as usize,
|
||||
new_height.get() as usize,
|
||||
RGBA16,
|
||||
RGBA16P,
|
||||
filter,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -70,7 +51,7 @@ pub fn bench_downscale_rgba16(bench: &mut Bench) {
|
||||
}
|
||||
|
||||
// fast_image_resize crate;
|
||||
let src_image_data = U16x4::load_big_src_image();
|
||||
let src_image = U16x4::load_big_src_image();
|
||||
let mut cpu_ext_and_name = vec![(CpuExtensions::None, "rust")];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
@@ -86,13 +67,7 @@ pub fn bench_downscale_rgba16(bench: &mut Bench) {
|
||||
"Lanczos3" => ResizeAlg::Convolution(FilterType::Lanczos3),
|
||||
_ => return,
|
||||
};
|
||||
let src_view = src_image_data.view();
|
||||
let mut premultiplied_src_image = Image::new(
|
||||
NonZeroU32::new(src_image.width()).unwrap(),
|
||||
NonZeroU32::new(src_image.height()).unwrap(),
|
||||
src_view.pixel_type(),
|
||||
);
|
||||
let mut dst_image = Image::new(new_width, new_height, src_view.pixel_type());
|
||||
let mut dst_image = Image::new(new_width, new_height, src_image.pixel_type());
|
||||
let mut dst_view = dst_image.view_mut();
|
||||
let mut mul_div = MulDiv::default();
|
||||
|
||||
@@ -104,24 +79,30 @@ pub fn bench_downscale_rgba16(bench: &mut Bench) {
|
||||
mul_div.set_cpu_extensions(cpu_ext);
|
||||
}
|
||||
|
||||
bench.task(format!("fir {} - {}", ext_name, alg_name), |task| {
|
||||
task.iter(|| match resize_alg {
|
||||
bench.task(
|
||||
format!("fir {} - {}", ext_name, alg_name),
|
||||
|task| match resize_alg {
|
||||
ResizeAlg::Nearest => {
|
||||
fast_resizer
|
||||
.resize(&premultiplied_src_image.view(), &mut dst_view)
|
||||
.unwrap();
|
||||
task.iter(|| {
|
||||
fast_resizer
|
||||
.resize(&src_image.view(), &mut dst_view)
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
mul_div
|
||||
.multiply_alpha(&src_view, &mut premultiplied_src_image.view_mut())
|
||||
.unwrap();
|
||||
fast_resizer
|
||||
.resize(&premultiplied_src_image.view(), &mut dst_view)
|
||||
.unwrap();
|
||||
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
|
||||
let mut work_image = src_image.copy();
|
||||
task.iter(|| {
|
||||
mul_div
|
||||
.multiply_alpha_inplace(&mut work_image.view_mut())
|
||||
.unwrap();
|
||||
fast_resizer
|
||||
.resize(&work_image.view(), &mut dst_view)
|
||||
.unwrap();
|
||||
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+59
-41
@@ -1,4 +1,4 @@
|
||||
# Benchmarks of fast_image_resize crate
|
||||
## Benchmarks of fast_image_resize crate
|
||||
|
||||
Environment:
|
||||
|
||||
@@ -21,7 +21,7 @@ Resize algorithms:
|
||||
- Convolution with CatmullRom filter
|
||||
- Convolution with Lanczos3 filter
|
||||
|
||||
## Resize RGB8 image (U8x3) 4928x3279 => 852x567
|
||||
### Resize RGB8 image (U8x3) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
@@ -32,13 +32,13 @@ Pipeline:
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 19.44 | 83.01 | 153.17 | 208.82 |
|
||||
| resize | - | 52.13 | 103.37 | 154.10 |
|
||||
| fir rust | 0.28 | 43.00 | 79.52 | 117.41 |
|
||||
| fir sse4.1 | 0.28 | 27.79 | 42.97 | 58.16 |
|
||||
| fir avx2 | 0.28 | 7.30 | 9.50 | 13.59 |
|
||||
| image | 19.24 | 82.52 | 152.17 | 207.63 |
|
||||
| resize | - | 52.19 | 103.40 | 154.15 |
|
||||
| fir rust | 0.28 | 40.88 | 69.39 | 101.53 |
|
||||
| fir sse4.1 | 0.28 | 28.21 | 43.03 | 59.46 |
|
||||
| fir avx2 | 0.28 | 7.33 | 9.47 | 13.59 |
|
||||
|
||||
## Resize RGBA8 image (U8x4) 4928x3279 => 852x567
|
||||
### Resize RGBA8 image (U8x4) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
@@ -47,16 +47,16 @@ Pipeline:
|
||||
- Source image
|
||||
[nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 19.73 | 82.34 | 141.74 | 198.86 |
|
||||
| resize | - | 49.91 | 100.27 | 148.99 |
|
||||
| fir rust | 0.18 | 36.84 | 52.31 | 74.99 |
|
||||
| fir sse4.1 | 0.18 | 13.21 | 17.26 | 22.42 |
|
||||
| fir avx2 | 0.18 | 9.47 | 12.03 | 16.08 |
|
||||
| resize | - | 61.93 | 122.10 | 182.55 |
|
||||
| fir rust | 0.18 | 36.57 | 52.28 | 74.14 |
|
||||
| fir sse4.1 | 0.18 | 13.14 | 17.21 | 22.44 |
|
||||
| fir avx2 | 0.18 | 9.69 | 11.99 | 16.23 |
|
||||
|
||||
## Resize L8 (luma) image (U8) 4928x3279 => 852x567
|
||||
### Resize L8 (luma) image (U8) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
@@ -68,13 +68,13 @@ Pipeline:
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 15.21 | 44.78 | 71.92 | 100.91 |
|
||||
| resize | - | 17.53 | 36.20 | 61.10 |
|
||||
| fir rust | 0.15 | 14.08 | 16.38 | 23.73 |
|
||||
| fir sse4.1 | 0.16 | 11.92 | 12.28 | 17.79 |
|
||||
| fir avx2 | 0.16 | 6.48 | 4.77 | 7.85 |
|
||||
| image | 15.86 | 47.17 | 74.46 | 102.53 |
|
||||
| resize | - | 17.30 | 35.92 | 61.52 |
|
||||
| fir rust | 0.15 | 14.10 | 16.20 | 24.12 |
|
||||
| fir sse4.1 | 0.15 | 11.93 | 12.13 | 18.20 |
|
||||
| fir avx2 | 0.15 | 6.30 | 4.71 | 7.62 |
|
||||
|
||||
## Resize LA8 (luma with alpha channel) image (U8x2) 4928x3279 => 852x567
|
||||
### Resize LA8 (luma with alpha channel) image (U8x2) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
@@ -84,16 +84,16 @@ Pipeline:
|
||||
[nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
|
||||
has converted into grayscale image with alpha channel (two bytes per pixel).
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
- The `resize` crate does not support this pixel format.
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 17.03 | 63.71 | 119.64 | 160.06 |
|
||||
| fir rust | 0.17 | 25.20 | 31.18 | 42.83 |
|
||||
| fir sse4.1 | 0.17 | 12.88 | 14.73 | 18.16 |
|
||||
| fir avx2 | 0.17 | 11.26 | 12.40 | 15.40 |
|
||||
| fir rust | 0.17 | 25.73 | 30.75 | 42.34 |
|
||||
| fir sse4.1 | 0.17 | 12.81 | 14.64 | 18.06 |
|
||||
| fir avx2 | 0.17 | 11.26 | 12.42 | 15.46 |
|
||||
|
||||
## Resize RGB16 image (U16x3) 4928x3279 => 852x567
|
||||
### Resize RGB16 image (U16x3) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
@@ -105,13 +105,31 @@ Pipeline:
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 17.79 | 74.65 | 133.43 | 185.33 |
|
||||
| resize | - | 54.94 | 107.17 | 159.07 |
|
||||
| fir rust | 0.32 | 43.85 | 80.21 | 117.04 |
|
||||
| fir sse4.1 | 0.32 | 24.46 | 39.49 | 56.00 |
|
||||
| fir avx2 | 0.32 | 20.56 | 30.36 | 36.07 |
|
||||
| image | 18.58 | 76.20 | 138.35 | 193.78 |
|
||||
| resize | - | 54.72 | 106.58 | 158.30 |
|
||||
| fir rust | 0.33 | 43.80 | 80.11 | 116.95 |
|
||||
| fir sse4.1 | 0.33 | 24.40 | 39.44 | 55.86 |
|
||||
| fir avx2 | 0.33 | 20.51 | 30.34 | 35.88 |
|
||||
|
||||
## Resize L16 image (U16) 4928x3279 => 852x567
|
||||
### Resize RGBA16 image (U16x4) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
`src_image => multiply by alpha => resize => divide by alpha => dst_image`
|
||||
|
||||
- Source image
|
||||
[nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| resize | - | 63.81 | 127.53 | 191.08 |
|
||||
| fir rust | 0.37 | 80.36 | 118.89 | 159.05 |
|
||||
| fir sse4.1 | 0.37 | 42.70 | 63.96 | 86.08 |
|
||||
| fir avx2 | 0.37 | 25.40 | 36.62 | 47.99 |
|
||||
|
||||
### Resize L16 image (U16) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
@@ -123,13 +141,13 @@ Pipeline:
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 15.38 | 46.00 | 74.00 | 102.80 |
|
||||
| resize | - | 15.48 | 32.07 | 57.20 |
|
||||
| fir rust | 0.17 | 19.20 | 28.51 | 37.54 |
|
||||
| fir sse4.1 | 0.17 | 7.74 | 13.16 | 19.11 |
|
||||
| fir avx2 | 0.17 | 7.06 | 9.55 | 14.82 |
|
||||
| image | 16.37 | 47.13 | 74.89 | 104.83 |
|
||||
| resize | - | 15.35 | 31.91 | 57.04 |
|
||||
| fir rust | 0.17 | 19.05 | 28.02 | 37.48 |
|
||||
| fir sse4.1 | 0.17 | 7.80 | 13.16 | 19.13 |
|
||||
| fir avx2 | 0.17 | 7.07 | 9.48 | 14.80 |
|
||||
|
||||
## Resize LA16 (luma with alpha channel) image (U16x2) 4928x3279 => 852x567
|
||||
### Resize LA16 (luma with alpha channel) image (U16x2) 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
@@ -139,11 +157,11 @@ Pipeline:
|
||||
[nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
|
||||
has converted into grayscale image with alpha channel (four bytes per pixel).
|
||||
- Numbers in table is mean duration of image resizing in milliseconds.
|
||||
- The `image` crate does not support multiplying and dividing by alpha channel.
|
||||
- The `resize` crate does not support this pixel format.
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
| image | 17.05 | 64.88 | 117.68 | 159.22 |
|
||||
| fir rust | 0.19 | 33.85 | 52.56 | 72.33 |
|
||||
| fir sse4.1 | 0.19 | 21.80 | 33.98 | 46.49 |
|
||||
| fir avx2 | 0.19 | 15.11 | 21.76 | 28.95 |
|
||||
| fir rust | 0.19 | 33.44 | 53.17 | 72.06 |
|
||||
| fir sse4.1 | 0.19 | 21.89 | 33.99 | 46.56 |
|
||||
| fir avx2 | 0.19 | 15.22 | 21.95 | 28.99 |
|
||||
|
||||
@@ -10,6 +10,15 @@ enum PixelsContainer<'a> {
|
||||
VecU8(Vec<u8>),
|
||||
}
|
||||
|
||||
impl<'a> PixelsContainer<'a> {
|
||||
fn as_vec(&self) -> Vec<u8> {
|
||||
match self {
|
||||
Self::MutU8(slice) => slice.to_vec(),
|
||||
Self::VecU8(vec) => vec.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Simple image container.
|
||||
#[derive(Debug)]
|
||||
pub struct Image<'a> {
|
||||
@@ -74,6 +83,16 @@ impl<'a> Image<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a copy of the image.
|
||||
pub fn copy(&self) -> Image<'static> {
|
||||
Image {
|
||||
width: self.width,
|
||||
height: self.height,
|
||||
pixels: PixelsContainer::VecU8(self.pixels.as_vec()),
|
||||
pixel_type: self.pixel_type,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn pixel_type(&self) -> PixelType {
|
||||
self.pixel_type
|
||||
|
||||
@@ -475,6 +475,32 @@ fn downscale_u16x4() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resizer_u16x4() {
|
||||
use resize::px::RGBA;
|
||||
use resize::Pixel::RGBA16P;
|
||||
use rgb::FromSlice;
|
||||
|
||||
let src_image = U16x4::load_big_image().to_rgba16();
|
||||
let new_width = NonZeroU32::new(852).unwrap();
|
||||
let new_height = NonZeroU32::new(567).unwrap();
|
||||
|
||||
let resize_src_image = src_image.as_raw().as_rgba();
|
||||
let mut dst =
|
||||
vec![RGBA::new(0u16, 0u16, 0u16, 0u16); (new_width.get() * new_height.get()) as usize];
|
||||
let filter = resize::Type::Triangle;
|
||||
let mut resize = resize::new(
|
||||
src_image.width() as usize,
|
||||
src_image.height() as usize,
|
||||
new_width.get() as usize,
|
||||
new_height.get() as usize,
|
||||
RGBA16P,
|
||||
filter,
|
||||
)
|
||||
.unwrap();
|
||||
resize.resize(resize_src_image, &mut dst).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn upscale_u16x4() {
|
||||
type P = U16x4;
|
||||
|
||||
Reference in New Issue
Block a user