Skip to content

Commit

Permalink
New interpolation functions, SSE fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
awxkee committed Jun 4, 2024
1 parent 81fec25 commit adc785d
Show file tree
Hide file tree
Showing 16 changed files with 968 additions and 50 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ documentation = "https://github.com/awxkee/pic-scale"
categories = ["multimedia::images", "multimedia::video"]
homepage = "https://github.com/awxkee/pic-scale"
repository = "https://github.com/awxkee/pic-scale"
exclude = ["*.jpg"]
exclude = ["*.jpg", "/assets"]

[dependencies]
colorutils-rs = "0.2.9"
Expand Down
135 changes: 135 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Image scaling library in Rust

Rust image scale in different color spaces using SIMD and multithreading.

Supported only NEON and SSE.

### Colorspace

This library provides for you some conveniences to scale in different color spaces.

### Performance

Faster or comparable to `fast-image-resize`, when implemented equal SIMD and pixel type.

Example comparison time for downscale RGB 4928x3279 image in two times for x86_64 SSE.

| | Lanczos3 |
|-----------|:--------:|
| pic-scale | 26.13 |
| fir sse | 26.84 |

Example comparison time for downscale RGBA 4928x3279 image in two times for x86_64 SSE with premultiplying alpha.

| | Lanczos3 |
|-----------|:--------:|
| pic-scale | 42.35 |
| fir sse | 42.96 |

Example comparison time for downscale RGBA 4928x3279 image in two times for x86_64 SSE without premultiplying alpha.

| | Lanczos3 |
|-----------|:--------:|
| pic-scale | 26.92 |
| fir sse | 38.30 |

#### Example integration with `image` crate

```rust
let img = ImageReader::open("./assets/asset.png")
.unwrap()
.decode()
.unwrap();
let dimensions = img.dimensions();
let mut bytes = Vec::from(img.as_bytes());

let mut scaler = LinearScaler::new(ResamplingFunction::Lanczos3);
scaler.set_threading_policy(ThreadingPolicy::Adaptive);
let store =
ImageStore::<u8, 4>::from_slice(&mut bytes, dimensions.0 as usize, dimensions.1 as usize);
let resized = scaler.resize_rgba(
ImageSize::new(dimensions.0 as usize / 2, dimensions.1 as usize / 2),
store,
true
);
```

#### Example in sRGB

In common, you should not downsize an image in sRGB colorspace, however if speed is more preferable than more proper scale you may omit linearizing

```rust
let mut scaler = Scaler::new(ResamplingFunction::Hermite);
scaler.set_threading_policy(ThreadingPolicy::Single);
let store =
ImageStore::<u8, 4>::from_slice(&mut bytes, width, height);
let resized = scaler.resize_rgba(
ImageSize::new(new_width, new_height),
store,
true
);
```

#### Example in linear

At the moment only sRGB transfer function is supported. This is also good optimized path so it is reasonably fast.

```rust
let mut scaler = LinearScaler::new(ResamplingFunction::Lanczos3);
scaler.set_threading_policy(ThreadingPolicy::Single);
let store =
ImageStore::<u8, 4>::from_slice(&mut bytes, width, height);
let resized = scaler.resize_rgba(
ImageSize::new(new_width, new_height),
store,
true
);
```

#### Example in CIE L\*a\*b
```rust
let mut scaler = LabScaler::new(ResamplingFunction::Hermite);
scaler.set_threading_policy(ThreadingPolicy::Single);
let store =
ImageStore::<u8, 4>::from_slice(&mut bytes, width, height);
let resized = scaler.resize_rgba(
ImageSize::new(new_width, new_height),
store,
true
);
```

#### Example in CIE L\*u\*v
```rust
let mut scaler = LuvScaler::new(ResamplingFunction::Hermite);
scaler.set_threading_policy(ThreadingPolicy::Single);
let store =
ImageStore::<u8, 4>::from_slice(&mut bytes, width, height);
let resized = scaler.resize_rgba(
ImageSize::new(new_width, new_height),
store,
true
);
```

#### Resampling filters

Over 30 resampling filters is supported.

```rust
Bilinear,
Nearest,
Cubic,
MitchellNetravalli,
CatmullRom,
Hermite,
BSpline,
Hann,
Bicubic,
Hamming,
Hanning,
EwaHanning,
Blackman,
EwaBlackman,
```
And others
18 changes: 7 additions & 11 deletions app/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,21 @@ use fast_image_resize::{
use image::io::Reader as ImageReader;
use image::{EncodableLayout, GenericImageView};

use pic_scale::{ImageSize, ImageStore, LinearScaler, LuvScaler, ResamplingFunction, Scaler, Scaling, ThreadingPolicy};
use pic_scale::{ImageSize, ImageStore, LabScaler, LinearScaler, LuvScaler, ResamplingFunction, Scaler, Scaling, ThreadingPolicy};

fn main() {
// test_fast_image();
test_fast_image();

let img = ImageReader::open("./assets/asset_middle.jpg")
let img = ImageReader::open("./assets/nasa-4928x3279.png")
.unwrap()
.decode()
.unwrap();
let dimensions = img.dimensions();
println!("dimensions {:?}", img.dimensions());

println!("{:?}", img.color());

let mut bytes = Vec::from(img.as_bytes());

let start_time = Instant::now();

let mut scaler = LinearScaler::new(ResamplingFunction::Lanczos4);
let mut scaler = Scaler::new(ResamplingFunction::Lanczos3);
scaler.set_threading_policy(ThreadingPolicy::Single);
let store =
ImageStore::<u8, 3>::from_slice(&mut bytes, dimensions.0 as usize, dimensions.1 as usize);
Expand Down Expand Up @@ -61,7 +57,7 @@ fn main() {
}

fn test_fast_image() {
let img = ImageReader::open("./assets/asset_5.png")
let img = ImageReader::open("./assets/nasa-4928x3279.png")
.unwrap()
.decode()
.unwrap();
Expand All @@ -71,7 +67,7 @@ fn test_fast_image() {

let start_time = Instant::now();

let pixel_type: PixelType = PixelType::U8x4;
let pixel_type: PixelType = PixelType::U8x3;

let src_image = Image::from_slice_u8(dimensions.0, dimensions.1, &mut vc, pixel_type).unwrap();

Expand All @@ -90,7 +86,7 @@ fn test_fast_image() {
.resize(
&src_image,
&mut dst_image,
&ResizeOptions::new().resize_alg(ResizeAlg::Convolution(Lanczos3)),
&ResizeOptions::new().resize_alg(ResizeAlg::Convolution(Lanczos3)).use_alpha(true),
)
.unwrap();

Expand Down
Loading

0 comments on commit adc785d

Please sign in to comment.