mirror of
https://github.com/Cykooz/fast_image_resize.git
synced 2026-10-08 01:11:09 +00:00
Added some doc-string for couple structs and methods
This commit is contained in:
@@ -4,10 +4,15 @@ Rust library for fast image resizing with using of SIMD instructions.
|
||||
|
||||
[CHANGELOG](https://github.com/Cykooz/fast_image_resize/blob/master/CHANGELOG.md)
|
||||
|
||||
Supported optimisations:
|
||||
- native Rust-code without forced SIMD
|
||||
- with using SSE4.1
|
||||
- with using AVX2
|
||||
Supported pixel formats and available optimisations:
|
||||
- `U8x4` - four `u8` components per pixel:
|
||||
- native Rust-code without forced SIMD
|
||||
- SSE4.1
|
||||
- AVX2
|
||||
- `I32` - one `i32` component per pixel:
|
||||
- native Rust-code without forced SIMD
|
||||
- `F32` - one `f32` component per pixel:
|
||||
- native Rust-code without forced SIMD
|
||||
|
||||
## Benchmarks
|
||||
|
||||
@@ -30,6 +35,10 @@ Resize algorithms:
|
||||
|
||||
### Resize RGB image 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
`src_image => resize => dst_image`
|
||||
|
||||
- Source image [nasa-4928x3279.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279.png)
|
||||
- Numbers in table is time of image resizing in milliseconds.
|
||||
|
||||
@@ -41,7 +50,7 @@ Resize algorithms:
|
||||
| fir sse4.1 | - | 12.143 | 18.662 | 26.334 |
|
||||
| fir avx2 | - | 9.346 | 13.342 | 18.934 |
|
||||
|
||||
`rustflags = ["-C", "target-cpu=native"]`
|
||||
Compiled with `rustflags = ["-C", "target-cpu=native"]`
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
@@ -53,6 +62,10 @@ Resize algorithms:
|
||||
|
||||
### Resize RGBA image 4928x3279 => 852x567
|
||||
|
||||
Pipeline:
|
||||
|
||||
`src_image => multiply by alpha => resize => divide by alpha => dst_image`
|
||||
|
||||
- Source image [nasa-4928x3279.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279.png)
|
||||
- Numbers in table is time of image resizing in milliseconds.
|
||||
|
||||
@@ -64,7 +77,7 @@ Resize algorithms:
|
||||
| fir sse4.1 | 12.03 | 23.721 | 30.266 | 37.874 |
|
||||
| fir avx2 | 6.949 | 15.873 | 19.956 | 25.527 |
|
||||
|
||||
`rustflags = ["-C", "target-cpu=native"]`
|
||||
Compiled with `rustflags = ["-C", "target-cpu=native"]`
|
||||
|
||||
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
|
||||
|------------|:-------:|:--------:|:----------:|:--------:|
|
||||
|
||||
@@ -26,6 +26,24 @@ pub enum MulDivImageError {
|
||||
|
||||
/// Methods of this structure used to multiplies or divides RGB-channels
|
||||
/// by alpha-channel.
|
||||
///
|
||||
/// By default instance of `MulDiv` created with best CPU-extensions provided by your CPU.
|
||||
/// You can change this by use method [MulDiv::set_cpu_extensions].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::num::NonZeroU32;
|
||||
/// use fast_image_resize::{ImageData, MulDiv, PixelType};
|
||||
///
|
||||
/// let width = NonZeroU32::new(10).unwrap();
|
||||
/// let height = NonZeroU32::new(7).unwrap();
|
||||
/// let src_image = ImageData::new_owned(width, height, PixelType::U8x4);
|
||||
/// let mut dst_image = ImageData::new_owned(width, height, PixelType::U8x4);
|
||||
///
|
||||
/// let mul_div = MulDiv::default();
|
||||
/// mul_div.multiply_alpha(&src_image.src_view(), &mut dst_image.dst_view()).unwrap();
|
||||
/// ```
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct MulDiv {
|
||||
cpu_extensions: CpuExtensions,
|
||||
|
||||
+10
-9
@@ -1,6 +1,9 @@
|
||||
use std::slice;
|
||||
|
||||
/* Handles values form -640 to 639. */
|
||||
// This code is based on C-implementation from Pillow-SIMD package for Python
|
||||
// https://github.com/uploadcare/pillow-simd
|
||||
|
||||
// Handles values form -640 to 639.
|
||||
const CLIP8_LOOKUPS: [u8; 1280] = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
@@ -62,17 +65,15 @@ const CLIP8_LOOKUPS: [u8; 1280] = [
|
||||
// in the other it will be more than 1.0. That is why we need
|
||||
// two extra bits for overflow and i32 type.
|
||||
const PRECISION_BITS: u8 = 32 - 8 - 2;
|
||||
/* We use signed INT16 type to store coefficients. */
|
||||
// We use i16 type to store coefficients.
|
||||
const MAX_COEFS_PRECISION: u8 = 16 - 1;
|
||||
|
||||
/// The function must be used with the ``v`` and ``precision`` values
|
||||
/// such that the expression
|
||||
/// ```
|
||||
/// v >> precision
|
||||
/// ```
|
||||
/// produces a result in the range ``[-512, 511]``.
|
||||
/// # Safety
|
||||
/// The function must be used with the `v` and `precision` values
|
||||
/// such that the expression `v >> precision`
|
||||
/// produces a result in the range `[-512, 511]`.
|
||||
#[inline(always)]
|
||||
pub unsafe fn clip8(v: i32, precision: u8) -> u8 {
|
||||
pub(crate) unsafe fn clip8(v: i32, precision: u8) -> u8 {
|
||||
let index = (640 + (v >> precision)) as usize;
|
||||
// index must be in range [(640-512)..(640+511)]
|
||||
*CLIP8_LOOKUPS.get_unchecked(index)
|
||||
|
||||
@@ -55,6 +55,7 @@ impl Default for ResizeAlg {
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods of this structure used to resize images.
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct Resizer {
|
||||
pub algorithm: ResizeAlg,
|
||||
@@ -64,6 +65,10 @@ pub struct Resizer {
|
||||
}
|
||||
|
||||
impl Resizer {
|
||||
/// Creates instance of `Resizer`
|
||||
///
|
||||
/// By default instance of `Resizer` created with best CPU-extensions provided by your CPU.
|
||||
/// You can change this by use method [Resizer::set_cpu_extensions].
|
||||
pub fn new(algorithm: ResizeAlg) -> Self {
|
||||
Self {
|
||||
algorithm,
|
||||
@@ -71,6 +76,12 @@ impl Resizer {
|
||||
}
|
||||
}
|
||||
|
||||
/// Resize source image to the size of destination image and save
|
||||
/// the result to the latter's pixel buffer.
|
||||
///
|
||||
/// This method doesn't multiply source image and doesn't divide
|
||||
/// destination image by alpha channel.
|
||||
/// You must use [MulDiv](crate::MulDiv) for this actions.
|
||||
pub fn resize(&mut self, src_image: &SrcImageView, dst_image: &mut DstImageView) {
|
||||
match self.algorithm {
|
||||
ResizeAlg::Nearest => resample_nearest(&src_image, dst_image),
|
||||
|
||||
Reference in New Issue
Block a user