| Crates.io | fast-ssim2 |
| lib.rs | fast-ssim2 |
| version | 0.6.5 |
| created_at | 2026-01-05 12:44:27.788303+00 |
| updated_at | 2026-01-10 10:44:52.230713+00 |
| description | Fast SSIMULACRA2 image quality metric with SIMD acceleration |
| homepage | https://github.com/imazen/ssimulacra2 |
| repository | https://github.com/imazen/ssimulacra2 |
| max_upload_size | |
| id | 2023759 |
| size | 327,810 |
Rust implementation of the SSIMULACRA2 perceptual image quality metric.
This crate is a fork of rust-av/ssimulacra2. Thank you to the rust-av team for creating the original Rust implementation - their clean, well-structured code made it straightforward to build upon.
The upstream crate provides a correct, readable scalar implementation. This fork experiments with SIMD acceleration and adds some API conveniences:
wide crate and x86 intrinsics)Ssimulacra2Reference)imgref type support via ToLinearRgb traitThese changes come with trade-offs: higher MSRV (1.89.0 vs 1.65.0), more complex code, and platform-specific behavior. If you prefer simplicity and stability, the upstream crate may be a better fit.
We'd be happy to upstream any of these changes if the rust-av team is interested. The SIMD work is substantial and may not align with their goals, but we're open to collaboration.
Full SSIMULACRA2 computation (AMD Ryzen, x86_64):
| Resolution | Scalar | SIMD | Unsafe SIMD |
|---|---|---|---|
| 1920×1080 | 1083ms | 434ms (2.5×) | 370ms (2.9×) |
| 3840×2160 | 4256ms | 1612ms (2.6×) | 1422ms (3.0×) |
Run your own:
cargo run --release --features "simd unsafe-simd" --example benchmark_unsafe_simd
[dependencies]
fast-ssim2 = "0.6"
simd (default): Safe SIMD via the wide crateunsafe-simd (default): x86_64 intrinsics (faster on supported hardware)imgref: Support for imgref image typesrayon: Parallel computationuse fast_ssim2::compute_ssimulacra2;
use imgref::ImgVec;
let source: ImgVec<[u8; 3]> = /* your image */;
let distorted: ImgVec<[u8; 3]> = /* distorted version */;
let score = compute_ssimulacra2(source.as_ref(), distorted.as_ref())?;
// 100 = identical, lower = more different
use fast_ssim2::{compute_frame_ssimulacra2, Rgb, TransferCharacteristic, ColorPrimaries};
let source = Rgb::new(data, width, height,
TransferCharacteristic::SRGB, ColorPrimaries::BT709)?;
let distorted = Rgb::new(/* ... */)?;
let score = compute_frame_ssimulacra2(source, distorted)?;
use fast_ssim2::Ssimulacra2Reference;
let reference = Ssimulacra2Reference::new(source)?;
for distorted in variants {
let score = reference.compare(distorted)?;
}
| Score | Meaning |
|---|---|
| 100 | Identical |
| 90+ | Imperceptible difference |
| 70-90 | Minor difference |
| 50-70 | Noticeable |
| < 50 | Significant degradation |
BSD-2-Clause (same as upstream)
Developed with assistance from Claude (Anthropic). Tested against the C++ reference implementation.