fast-ssim2

Crates.iofast-ssim2
lib.rsfast-ssim2
version0.6.5
created_at2026-01-05 12:44:27.788303+00
updated_at2026-01-10 10:44:52.230713+00
descriptionFast SSIMULACRA2 image quality metric with SIMD acceleration
homepagehttps://github.com/imazen/ssimulacra2
repositoryhttps://github.com/imazen/ssimulacra2
max_upload_size
id2023759
size327,810
Lilith River (lilith)

documentation

https://docs.rs/fast-ssim2

README

fast-ssim2

docs.rs Crates.io LICENSE

Rust implementation of the SSIMULACRA2 perceptual image quality metric.

Attribution

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.

What's different

The upstream crate provides a correct, readable scalar implementation. This fork experiments with SIMD acceleration and adds some API conveniences:

  • SIMD-accelerated blur and XYB conversion (via wide crate and x86 intrinsics)
  • Precomputed reference API for batch comparisons (Ssimulacra2Reference)
  • imgref type support via ToLinearRgb trait

These 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.

Contributing back

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.

Benchmarks

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

Installation

[dependencies]
fast-ssim2 = "0.6"

Features

  • simd (default): Safe SIMD via the wide crate
  • unsafe-simd (default): x86_64 intrinsics (faster on supported hardware)
  • imgref: Support for imgref image types
  • rayon: Parallel computation

Usage

With imgref

use 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

With yuvxyb types

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)?;

Precomputed reference (for batch comparisons)

use fast_ssim2::Ssimulacra2Reference;

let reference = Ssimulacra2Reference::new(source)?;

for distorted in variants {
    let score = reference.compare(distorted)?;
}

Score interpretation

Score Meaning
100 Identical
90+ Imperceptible difference
70-90 Minor difference
50-70 Noticeable
< 50 Significant degradation

License

BSD-2-Clause (same as upstream)

Notes

Developed with assistance from Claude (Anthropic). Tested against the C++ reference implementation.

Commit count: 113

cargo fmt