### Windows Installation Step 11 Source: https://github.com/imazen/fast-ssim2/blob/main/ssimulacra2_bin/README.md Installing ssimulacra2_rs using Cargo on Windows. ```powershell cargo install ssimulacra2_rs ``` -------------------------------- ### Windows Installation Step 13 Source: https://github.com/imazen/fast-ssim2/blob/main/ssimulacra2_bin/README.md Verifying ssimulacra2_rs installation on Windows. ```powershell ssimulacra2_rs -h ``` -------------------------------- ### Runnable Rust examples Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/INDEX.md Example of how to use the compute_ssimulacra2 function in Rust. ```rust // Runnable Rust examples use fast_ssim2::compute_ssimulacra2; let score = compute_ssimulacra2(&source, &distorted)?; ``` -------------------------------- ### compute_ssimulacra2_with_config Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-main.md Example usage of compute_ssimulacra2_with_config to force scalar or SIMD backends. ```rust use fast_ssim2::{compute_ssimulacra2_with_config, Ssimulacra2Config}; // Force scalar (slowest, baseline) let score_scalar = compute_ssimulacra2_with_config( source, distorted, Ssimulacra2Config::scalar(), )?; // Force SIMD (default, auto-detects AVX2/NEON/WASM128) let score_simd = compute_ssimulacra2_with_config( source, distorted, Ssimulacra2Config::simd(), )?; ``` -------------------------------- ### Example usage of compute_ssimulacra2_strip_with_config Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-strip.md Example usage of compute_ssimulacra2_strip_with_config with custom configuration. ```rust use fast_ssim2::{compute_ssimulacra2_strip_with_config, Ssimulacra2StripConfig}; let config = Ssimulacra2StripConfig::with_halo_rows(48) .with_inner(/* custom SIMD config */); let score = compute_ssimulacra2_strip_with_config( &source, &distorted, 128, config, )?; ``` -------------------------------- ### compute_ssimulacra2 Example (yuvxyb) Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-main.md Example usage of compute_ssimulacra2 with yuvxyb types. ```rust use fast_ssim2::compute_ssimulacra2; use yuvxyb::{Rgb, TransferCharacteristic, ColorPrimaries}; use std::num::NonZeroUsize; let data1: Vec<[f32; 3]> = vec![[0.5, 0.5, 0.5]; 64 * 64]; let data2: Vec<[f32; 3]> = vec![[0.51, 0.50, 0.49]; 64 * 64]; let w = NonZeroUsize::new(64).unwrap(); let h = NonZeroUsize::new(64).unwrap(); let source = Rgb::new( data1, w, h, TransferCharacteristic::SRGB, ColorPrimaries::BT709, )?; let distorted = Rgb::new( data2, w, h, TransferCharacteristic::SRGB, ColorPrimaries::BT709, )?; let score = compute_ssimulacra2(source, distorted)?; ``` -------------------------------- ### Quick Start - Dependencies Source: https://github.com/imazen/fast-ssim2/blob/main/README.md Add fast-ssim2 to your Cargo.toml with the 'imgref' feature. ```toml [dependencies] fast-ssim2 = { version = "0.8", features = ["imgref"] } ``` -------------------------------- ### Ssimulacra2Reference::new Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-precompute.md Example of creating a Ssimulacra2Reference from a source image. ```rust use fast_ssim2::Ssimulacra2Reference; use imgref::ImgVec; let source: ImgVec<[u8; 3]> = /* load reference image */; let reference = Ssimulacra2Reference::new(&source)?; // Now compare multiple distorted images efficiently ``` -------------------------------- ### Blur::new Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-blur.md Example of creating a new Blur instance with the default SIMD implementation. ```rust use fast_ssim2::Blur; let mut blur = Blur::new(512, 512); ``` -------------------------------- ### Blur::with_simd_impl Examples Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-blur.md Examples of creating a Blur instance with explicit SIMD implementation selection. ```rust use fast_ssim2::{Blur, SimdImpl}; // Force scalar (for testing/debugging) let mut blur = Blur::with_simd_impl(512, 512, SimdImpl::Scalar); // Use SIMD (default) let mut blur = Blur::with_simd_impl(512, 512, SimdImpl::Simd); ``` -------------------------------- ### Usage Examples Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/configuration.md Demonstrates different ways to use `compute_ssimulacra2_strip_with_config` with varying halo sizes and SIMD/scalar configurations. ```rust use fast_ssim2::{compute_ssimulacra2_strip_with_config, Ssimulacra2StripConfig, Ssimulacra2Config}; // Default: 96 halo, SIMD let score = compute_ssimulacra2_strip_with_config( &source, &distorted, 256, // strip height Ssimulacra2StripConfig::default(), )?; // Custom: 48 halo for speed, SIMD let score = compute_ssimulacra2_strip_with_config( &source, &distorted, 256, Ssimulacra2StripConfig::with_halo_rows(48), )?; // Custom: 192 halo, scalar for reproducibility let score = compute_ssimulacra2_strip_with_config( &source, &distorted, 256, Ssimulacra2StripConfig::with_halo_rows(192) .with_inner(Ssimulacra2Config::scalar()), ?; ``` -------------------------------- ### LinearRgbConversionFailed Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/errors.md Example of how to handle the LinearRgbConversionFailed error when computing SSIMULACRA2. ```rust use fast_ssim2::{compute_ssimulacra2, Ssimulacra2Error}; match compute_ssimulacra2(&invalid_image, &valid_image) { Err(Ssimulacra2Error::LinearRgbConversionFailed) => { eprintln!("Input image format unsupported"); } _ => {} } ``` -------------------------------- ### Windows Installation Step 10 Source: https://github.com/imazen/fast-ssim2/blob/main/ssimulacra2_bin/README.md Setting the LIB environment variable for VapourSynth SDK on Windows. ```powershell $env:LIB="C:\Path\to\VapourSynth\sdk\lib64;$env:LIB" ``` -------------------------------- ### compute_ssimulacra2 Example (imgref) Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-main.md Example usage of compute_ssimulacra2 with imgref types. ```rust use fast_ssim2::compute_ssimulacra2; use imgref::ImgVec; // With imgref (feature: "imgref") let source: ImgVec<[u8; 3]> = /* load sRGB PNG */; let distorted: ImgVec<[u8; 3]> = /* load sRGB PNG */; let score = compute_ssimulacra2(&source, &distorted)?; println!("Score: {:.2}", score); // e.g., "Score: 87.45" ``` -------------------------------- ### Custom Type Implementation Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-input.md Example demonstrating how to implement the ToLinearRgb trait for a custom image struct. ```rust use fast_ssim2::{ToLinearRgb, LinearRgbImage, srgb_u8_to_linear}; struct MyImage { pixels: Vec<[u8; 3]>, width: usize, height: usize, } impl ToLinearRgb for MyImage { fn to_linear_rgb(&self) -> LinearRgbImage { let data: Vec<[f32; 3]> = self.pixels.iter() .map(|&[r, g, b]| [ srgb_u8_to_linear(r), srgb_u8_to_linear(g), srgb_u8_to_linear(b), ]) .collect(); LinearRgbImage::new(data, self.width, self.height) } fn into_linear_rgb(self) -> LinearRgbImage { // Zero-copy if you can convert in-place let data: Vec<[f32; 3]> = self.pixels.into_iter() .map(|[r, g, b]| [ srgb_u8_to_linear(r), srgb_u8_to_linear(g), srgb_u8_to_linear(b), ]) .collect(); LinearRgbImage::new(data, self.width, self.height) } } ``` -------------------------------- ### Using compute_ssimulacra2_with_config with Ssimulacra2Config Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/configuration.md Example demonstrating how to use compute_ssimulacra2_with_config with different Ssimulacra2Config options. ```rust use fast_ssim2::{compute_ssimulacra2_with_config, Ssimulacra2Config}; // Default: SIMD let score = compute_ssimulacra2_with_config( &source, &distorted, Ssimulacra2Config::default(), // == Ssimulacra2Config::simd() )?; // Scalar for debugging let score_scalar = compute_ssimulacra2_with_config( &source, &distorted, Ssimulacra2Config::scalar(), ?); ``` -------------------------------- ### Example: 40 MP Image Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-strip.md Example usage of compute_ssimulacra2_strip for a large image. ```rust use fast_ssim2::compute_ssimulacra2_strip; let source: ImgVec<[u8; 3]> = /* load 7700×5200 image */; let distorted: ImgVec<[u8; 3]> = /* load 7700×5200 image */; // Process in 256-row strips (~256×7700 per strip) // Peak working memory: ~24 × 7700 × (256+96) × 4 B ≈ 220 MiB // vs. full image: ~7 GiB let score = compute_ssimulacra2_strip(&source, &distorted, 256)?; println!("Score: {:.2}", score); ``` -------------------------------- ### Build Configuration - Profile Settings Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/configuration.md Example Cargo.toml profile settings for release, dev, and dev.package. ```toml [profile.release] lto = "thin" # Thin LTO for smaller binary, faster compile than full LTO codegen-units = 1 # Necessary for optimization [profile.dev] opt-level = 2 # Keep debug mode reasonably fast [profile.dev.package."*"] opt-level = 1 # Dependencies don't need to be hyper-optimized in debug ``` -------------------------------- ### Ssimulacra2Reference::compare_context Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-precompute.md Example of creating and using a CompareContext for batch comparisons. ```rust use fast_ssim2::Ssimulacra2Reference; let reference = Ssimulacra2Reference::new(&source)?; let mut ctx = reference.compare_context(); for distorted in variants { // Zero Vec allocations on subsequent calls let score = reference.compare_with(&mut ctx, &distorted)?; } ``` -------------------------------- ### Batch Optimization Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/configuration.md Demonstrates how to optimize SSIMulacra2 calculations for a large number of images using parallel processing with Rayon. ```rust use fast_ssim2::Ssimulacra2Reference; use rayon::prelude::*; let reference = Ssimulacra2Reference::new(&source)?; let scores: Vec = images .par_iter() .map(|distorted| { let mut ctx = reference.compare_context(); // Thread-local reference.compare_with(&mut ctx, distorted).unwrap_or(0.0) }) .collect(); ``` -------------------------------- ### Arch Linux Installation Source: https://github.com/imazen/fast-ssim2/blob/main/ssimulacra2_bin/README.md Required packages for video support on Arch Linux. ```bash sudo pacman -S vapoursynth vapoursynth-plugin-lsmashsource gcc make cmake pkg-config ttf-bitstream-vera # Keep install dependencies ``` -------------------------------- ### srgb_to_linear example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-input.md Example usage of the srgb_to_linear function. ```rust let srgb_val = 128.0 / 255.0; // sRGB 128 normalized let linear = srgb_to_linear(srgb_val); // ~0.2158 ``` -------------------------------- ### NonMatchingImageDimensions Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/errors.md Example of how to handle the NonMatchingImageDimensions error when computing SSIMULACRA2. ```rust use fast_ssim2::{compute_ssimulacra2, Ssimulacra2Error}; match compute_ssimulacra2(&source, &distorted) { Err(Ssimulacra2Error::NonMatchingImageDimensions) => { eprintln!("Image sizes differ: {}x{} vs {}x{}", source.width(), source.height(), distorted.width(), distorted.height()); } _ => {} } ``` -------------------------------- ### InvalidImageSize Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/errors.md Example of how to handle the InvalidImageSize error when computing SSIMULACRA2. ```rust use fast_ssim2::{compute_ssimulacra2, Ssimulacra2Error}; let score = match compute_ssimulacra2(&src, &dist) { Ok(s) => s, Err(Ssimulacra2Error::InvalidImageSize) => { eprintln!("Image too small: minimum is 8×8 pixels"); return; } Err(e) => { eprintln!("Error: {}", e); return; } }; ``` -------------------------------- ### srgb_u16_to_linear example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-input.md Example usage of the srgb_u16_to_linear function. ```rust let linear_0 = srgb_u16_to_linear(0); // 0.0 let linear_32768 = srgb_u16_to_linear(32768); // ~0.2158 let linear_65535 = srgb_u16_to_linear(65535); // 1.0 ``` -------------------------------- ### srgb_u8_to_linear example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-input.md Example usage of the srgb_u8_to_linear function. ```rust let linear_0 = srgb_u8_to_linear(0); // 0.0 let linear_128 = srgb_u8_to_linear(128); // ~0.2158 let linear_255 = srgb_u8_to_linear(255); // 1.0 ``` -------------------------------- ### Public API Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-blur.md Example demonstrating how to use the Blur struct and SimdImpl enum in Rust. ```rust use fast_ssim2::{Blur, SimdImpl}; let mut blur = Blur::with_simd_impl(512, 512, SimdImpl::Simd); // Create test data let input_r = vec![0.5; 512 * 512]; let input_g = vec![0.5; 512 * 512]; let input_b = vec![0.5; 512 * 512]; let input = [input_r, input_g, input_b]; // Blur and collect results let blurred = blur.blur(&input); println!("Mean of blurred R: {}", blurred[0][0]); // Or reuse buffers for multiple blurs let mut output = [vec![0.0; 512*512]; 3]; blur.blur_into(&input, &mut output); ``` -------------------------------- ### Blur::blur Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-blur.md Example of blurring an image using the blur method, which allocates new output buffers. ```rust use fast_ssim2::Blur; let mut blur = Blur::new(256, 256); let input_r = vec![0.5; 256 * 256]; let input_g = vec![0.5; 256 * 256]; let input_b = vec![0.5; 256 * 256]; let input = [input_r, input_g, input_b]; let output = blur.blur(&input); // output[0], output[1], output[2] are blurred R, G, B ``` -------------------------------- ### Example usage of with_inner Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-strip.md Example demonstrating how to force the scalar backend using with_inner. ```rust use fast_ssim2::{Ssimulacra2StripConfig, Ssimulacra2Config}; let config = Ssimulacra2StripConfig::with_halo_rows(64) .with_inner(Ssimulacra2Config::scalar()); // Force scalar ``` -------------------------------- ### API Usage Source: https://github.com/imazen/fast-ssim2/blob/main/BENCHMARKS.md Examples of how to use the SSIMULACRA2 API with default and explicit configurations. ```rust use ssimulacra2::{compute_frame_ssimulacra2, Ssimulacra2Config}; // Default (safe SIMD) let score = compute_frame_ssimulacra2(source, distorted)?; // Explicit configuration let score = compute_frame_ssimulacra2_with_config( source, distorted, Ssimulacra2Config::unsafe_simd() // or ::simd() or ::scalar() )?; ``` -------------------------------- ### Ssimulacra2Error Usage Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/types.md Example demonstrating how to handle Ssimulacra2Error using a match statement. ```rust use fast_ssim2::{compute_ssimulacra2, Ssimulacra2Error}; match compute_ssimulacra2(&source, &distorted) { Ok(score) => println!("Score: {:.2}", score), Err(Ssimulacra2Error::InvalidImageSize) => eprintln!("Image too small"), Err(Ssimulacra2Error::ImageTooLarge { actual }) => { eprintln!("Image exceeds limit: {} pixels", actual) } Err(e) => eprintln!("Error: {}", e), } ``` -------------------------------- ### CompareContext Usage Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/types.md Demonstrates how to obtain and use a CompareContext for multiple comparisons. ```rust let reference = Ssimulacra2Reference::new(&source)?; let mut ctx = reference.compare_context(); for distorted in variants { reference.compare_with(&mut ctx, &distorted)?; } ``` -------------------------------- ### Using imgref with compute_ssimulacra2 Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/configuration.md Example demonstrating the use of ImgVec from the imgref crate with the compute_ssimulacra2 function. ```rust use fast_ssim2::compute_ssimulacra2; use imgref::ImgVec; let source: ImgVec<[u8; 3]> = /* load PNG */; let distorted: ImgVec<[u8; 3]> = /* load PNG */; let score = compute_ssimulacra2(&source, &distorted)?; ``` -------------------------------- ### Example Usage Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-precompute.md Demonstrates how to use Ssimulacra2Reference to compare multiple distorted images against a precomputed reference, optimizing by reusing a CompareContext. ```rust use fast_ssim2::Ssimulacra2Reference; let reference = Ssimulacra2Reference::new(&source)?; let mut ctx = reference.compare_context(); // Allocate once // Process batch (no allocations) for distorted in variants { let score = reference.compare_with(&mut ctx, &distorted)?; println!("Score: {:.2}", score); } ``` -------------------------------- ### Custom Image Type Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/API-OVERVIEW.md Example demonstrating how to implement the `ToLinearRgb` trait for a custom image type. ```rust use fast_ssim2::{ToLinearRgb, LinearRgbImage, srgb_u8_to_linear}; struct MyImage { pixels: Vec, width: usize, height: usize, } impl ToLinearRgb for MyImage { fn to_linear_rgb(&self) -> LinearRgbImage { let data: Vec<[f32; 3]> = self.pixels.chunks_exact(3) .map(|c| [ srgb_u8_to_linear(c[0]), srgb_u8_to_linear(c[1]), srgb_u8_to_linear(c[2]), ]) .collect(); LinearRgbImage::new(data, self.width, self.height) } } let my_img: MyImage = /* ... */; let score = compute_ssimulacra2(&my_img, &distorted)?; ``` -------------------------------- ### Blur::blur_into Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-blur.md Example of blurring an image into pre-allocated output buffers using blur_into, avoiding allocations after construction. ```rust use fast_ssim2::Blur; let mut blur = Blur::new(256, 256); let input = [vec![0.5; 256*256]; 3]; let mut output = [vec![0.0; 256*256]; 3]; // First call allocates output blur.blur_into(&input, &mut output); // Subsequent calls reuse output (no allocation) blur.blur_into(&input, &mut output); ``` -------------------------------- ### Simple One-Off Comparison Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/API-OVERVIEW.md Example of computing the SSIMULACRA2 score between two images. ```rust use fast_ssim2::compute_ssimulacra2; let source = load_image("original.png"); let distorted = load_image("compressed.png"); let score = compute_ssimulacra2(&source, &distorted)?; println!("SSIMULACRA2 score: {:.2}", score); ``` -------------------------------- ### Running Reference Tests Source: https://github.com/imazen/fast-ssim2/blob/main/REFERENCE_TESTING.md Command to run reference parity tests and an example of the expected output. ```bash # Run reference parity tests (with detailed variance report) cargo test --release --test reference_parity -- --nocapture # Expected output: # All 66 reference tests passed! Max error: 0.954936 ``` -------------------------------- ### Using yuvxyb Types Directly Source: https://github.com/imazen/fast-ssim2/blob/main/README.md Example of using yuvxyb types directly with fast-ssim2. ```rust use fast_ssim2::compute_ssimulacra2; use yuvxyb::{Rgb, TransferCharacteristic, ColorPrimaries}; let source = Rgb::new( pixel_data, width, height, TransferCharacteristic::SRGB, ColorPrimaries::BT709, )?; let score = compute_ssimulacra2(source, distorted)?; ``` -------------------------------- ### Encoder Tuning (Batch, Same Reference) Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/API-OVERVIEW.md Example of tuning an encoder by comparing multiple encoded versions against a single reference image. ```rust use fast_ssim2::Ssimulacra2Reference; let original = load_image("original.png"); let reference = Ssimulacra2Reference::new(&original)?; let mut results = Vec::new(); for quality in 0..100 { let encoded = encode_with_quality(quality); let score = reference.compare(&encoded)?; results.push((quality, score)); } results.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap()); println!("Best quality: {}", results[0].0); ``` -------------------------------- ### Example: Multiple Input Types Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-input.md Demonstrates how to use compute_ssimulacra2 with various input image types, including 8-bit sRGB, 16-bit sRGB, linear f32, and yuvxyb::Rgb. ```rust use fast_ssim2::compute_ssimulacra2; use imgref::ImgVec; use yuvxyb::{Rgb, TransferCharacteristic, ColorPrimaries}; // Path 1: 8-bit sRGB (PNG) let png_src: ImgVec<[u8; 3]> = /* ... */; let png_dist: ImgVec<[u8; 3]> = /* ... */; let score1 = compute_ssimulacra2(&png_src, &png_dist)?; // Path 2: 16-bit sRGB (HDR capture) let hdr_src: ImgVec<[u16; 3]> = /* ... */; let hdr_dist: ImgVec<[u16; 3]> = /* ... */; let score2 = compute_ssimulacra2(&hdr_src, &hdr_dist)?; // Path 3: Linear f32 (processed data) let linear_src: ImgVec<[f32; 3]> = /* ... */; let linear_dist: ImgVec<[f32; 3]> = /* ... */; let score3 = compute_ssimulacra2(&linear_src, &linear_dist)?; // Path 4: yuvxyb::Rgb (explicit color space) use std::num::NonZeroUsize; let data: Vec<[f32; 3]> = vec![[0.5; 3]; 64 * 64]; let rgb = Rgb::new( data, NonZeroUsize::new(64).unwrap(), NonZeroUsize::new(64).unwrap(), TransferCharacteristic::SRGB, ColorPrimaries::BT709, )?; let score4 = compute_ssimulacra2(&rgb, &rgb)?; ``` -------------------------------- ### Quick Start - Usage Source: https://github.com/imazen/fast-ssim2/blob/main/README.md Compute the SSIMULACRA2 score between two images using the compute_ssimulacra2 function. ```rust use fast_ssim2::compute_ssimulacra2; use imgref::ImgVec; let source: ImgVec<[u8; 3]> = /* your source image */; let distorted: ImgVec<[u8; 3]> = /* compressed/modified version */; let score = compute_ssimulacra2(source.as_ref(), distorted.as_ref())?; // 100 = identical, 90+ = imperceptible, <50 = significant degradation ``` -------------------------------- ### Very Large Image Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/API-OVERVIEW.md Example of using `compute_ssimulacra2_strip` for processing very large images efficiently. ```rust use fast_ssim2::compute_ssimulacra2_strip; let source = load_image_40mp("huge.jpg"); let distorted = load_image_40mp("huge_compressed.jpg"); // Process in 256-row strips, ~220 MiB peak memory let score = compute_ssimulacra2_strip(&source, &distorted, 256)?; ``` -------------------------------- ### Parallel Batch Processing Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/API-OVERVIEW.md Example of using Rayon for parallel processing of multiple images against a single reference. ```rust use fast_ssim2::Ssimulacra2Reference; use rayon::prelude::*; let reference = Ssimulacra2Reference::new(&original)?; let scores: Vec = images .par_iter() .map(|img| { let mut ctx = reference.compare_context(); reference.compare_with(&mut ctx, img).unwrap_or(0.0) }) .collect(); ``` -------------------------------- ### CompareContext Example: Parallel Batch Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-precompute.md Illustrates using a thread-local CompareContext for parallel batch processing of distorted images against a precomputed reference. ```rust use fast_ssim2::Ssimulacra2Reference; use rayon::prelude::*; let reference = Ssimulacra2Reference::new(&source)?; let scores: Vec = variants .par_iter() .map(|distorted| { let mut ctx = reference.compare_context(); // Thread-local context reference.compare_with(&mut ctx, distorted).unwrap_or(0.0) }) .collect(); ``` -------------------------------- ### Error Handling Best Practice: Validate Inputs Before Calling Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/errors.md A comprehensive example demonstrating input validation before calling `compute_ssimulacra2`, covering dimension checks, matching dimensions, and size limits. ```rust use fast_ssim2::{compute_ssimulacra2, MAX_IMAGE_PIXELS}; fn compute_with_validation(source: &ImgRef<[u8; 3]>, distorted: &ImgRef<[u8; 3]>) -> Result { // Validate dimensions if source.width() < 8 || source.height() < 8 { return Err("Source image too small".to_string()); } if distorted.width() < 8 || distorted.height() < 8 { return Err("Distorted image too small".to_string()); } // Validate matching if source.width() != distorted.width() || source.height() != distorted.height() { return Err("Image dimensions don't match".to_string()); } // Check size limit let pixels = (source.width() as u64) * (source.height() as u64); if pixels > MAX_IMAGE_PIXELS as u64 { return Err(format!("Image {} pixels exceeds limit", pixels)); } // Now compute compute_ssimulacra2(source, distorted) .map_err(|e| format!("Computation failed: {}", e)) } ``` -------------------------------- ### Example of DataLengthMismatch error Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/errors.md Illustrates the `DataLengthMismatch` error for `LinearRgbImage`, showing a successful case and a failing case with an assertion. ```rust use fast_ssim2::{LinearRgbImage, LinearRgbImageError}; let data = vec![[0.5, 0.5, 0.5]; 100]; // 100 pixels let result = LinearRgbImage::try_new(data, 10, 10); // 10×10 = 100 ✓ let data = vec![[0.5, 0.5, 0.5]; 99]; // 99 pixels let result = LinearRgbImage::try_new(data, 10, 10); // 10×10 = 100 ✗ assert!(matches!(result, Err(LinearRgbImageError::DataLengthMismatch { expected: 100, actual: 99 }))); ``` -------------------------------- ### Integration with Precomputed Reference Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-strip.md Example of using Ssimulacra2Reference with strip-wise processing for multiple distorted images against a single reference. ```rust use fast_ssim2::Ssimulacra2Reference; let reference = Ssimulacra2Reference::new(&source)?; for distorted in variants { // Precompute handles reference, strip bounds distortion memory let score = reference.compare(&distorted)?; // Allocates // or let mut ctx = reference.compare_context(); let score = reference.compare_with(&mut ctx, &distorted)?; // Zero-alloc } ``` -------------------------------- ### GitHub Actions Workflow for Reference Parity Tests Source: https://github.com/imazen/fast-ssim2/blob/main/REFERENCE_TESTING.md This YAML configuration defines a GitHub Actions workflow that checks out code, installs C++ dependencies, builds ssimulacra2, captures reference data, and runs parity tests. ```yaml name: Reference Parity Tests on: [push, pull_request] jobs: parity: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install C++ dependencies run: | sudo apt-get update sudo apt-get install -y cmake build-essential libhwy-dev libjpeg-dev libpng-dev - name: Build C++ ssimulacra2 run: | git clone https://github.com/libjxl/libjxl.git /tmp/libjxl cd /tmp/libjxl cmake -B build -DCMAKE_BUILD_TYPE=Release -DJPEGXL_ENABLE_DEVTOOLS=ON cmake --build build --target ssimulacra2 -j$(nproc) - name: Capture reference data run: | export SSIMULACRA2_BIN=/tmp/libjxl/build/tools/ssimulacra2 cargo run --release --example capture_cpp_reference - name: Run parity tests run: cargo test --release --test reference_parity ``` -------------------------------- ### Example Reference Parity Test Output Source: https://github.com/imazen/fast-ssim2/blob/main/REFERENCE_TESTING.md This output shows a detailed breakdown of test results, including top errors, error percentiles, and error distribution by pattern type. ```text ================================== REFERENCE PARITY TEST RESULTS =================================== All 66 reference tests passed! Max error: 0.954936 Error percentiles: p50=0.0000, p90=0.2836, p95=0.4164, p99=0.9549 Errors >0.1: 14, >0.5: 2, >1.0: 0 -------------------------------------- Top 10 Largest Errors --------------------------------------- Test Case Expected Actual Error ---------------------------------------------------------------------------------------------------- uniform_shift_5_32x32 98.808274 97.853338 0.954936 uniform_shift_1_32x32 97.749214 98.363460 0.614246 ... --------------------------------- Error Breakdown by Pattern Type ---------------------------------- Pattern Count Max Error Mean Error P95 Error -------------------------------------------------------------------------------- uniform_shift 20 0.954936 0.229443 0.954936 distortions 4 0.120631 0.064514 0.120631 synthetic_vs 2 0.001332 0.000936 0.001332 perfect_match 4 0.000000 0.000000 0.000000 ``` -------------------------------- ### Performance - Benchmarking Command Source: https://github.com/imazen/fast-ssim2/blob/main/README.md Run your own benchmarks using cargo bench. ```bash cargo bench -p fast-ssim2 ``` -------------------------------- ### Build Commands Source: https://github.com/imazen/fast-ssim2/blob/main/BENCHMARKS.md Commands for building the SSIMULACRA2 project with different feature flag combinations. ```bash # Default (simd + unsafe-simd) car go build --release # SIMD only (no unsafe) car go build --release --no-default-features --features simd # With Rayon parallelism car go build --release --features rayon ``` -------------------------------- ### Build C++ SSIMULACRA2 Source: https://github.com/imazen/fast-ssim2/blob/main/REFERENCE_TESTING.md Instructions to clone the libjxl repository, build it with devtools enabled, and verify the ssimulacra2 binary. ```bash # If you don't have libjxl cloned: git clone https://github.com/libjxl/libjxl.git cd libjxl # Build with DEVTOOLS enabled to get ssimulacra2 cmake -B build -DCMAKE_BUILD_TYPE=Release -DJPEGXL_ENABLE_DEVTOOLS=ON cmake --build build --target ssimulacra2 -j$(nproc) # Verify binary works ./build/tools/ssimulacra2 --help ``` -------------------------------- ### Ssimulacra2Reference::compare Example Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-precompute.md Example of comparing a single distorted image against the precomputed reference. ```rust use fast_ssim2::Ssimulacra2Reference; let reference = Ssimulacra2Reference::new(&source)?; // Compare single distorted image let score = reference.compare(&distorted)?; println!("Score: {:.2}", score); ``` -------------------------------- ### Recommended Configurations - Archival/Quality Assessment (Accuracy Priority) Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/configuration.md Configuration for prioritizing accuracy in archival or quality assessment scenarios. ```rust use fast_ssim2::compute_ssimulacra2; let score = compute_ssimulacra2(&source, &distorted)?; // Full image, default SIMD ``` -------------------------------- ### Recommended Configurations - Web/Streaming (Speed Priority) Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/configuration.md Configuration for prioritizing speed in web or streaming applications. ```rust use fast_ssim2::{compute_ssimulacra2_strip_with_config, Ssimulacra2StripConfig}; let config = Ssimulacra2StripConfig::with_halo_rows(24); // Fast let score = compute_ssimulacra2_strip_with_config(&source, &distorted, 128, config)?; ``` -------------------------------- ### Recommended Configurations - Scientific/Reproducible Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/configuration.md Configuration for scientific use cases requiring bit-identical reproducibility. ```rust use fast_ssim2::{compute_ssimulacra2_with_config, Ssimulacra2Config}; let config = Ssimulacra2Config::scalar(); // Deterministic f64 IIR let score = compute_ssimulacra2_with_config(&source, &distorted, config)?; ``` -------------------------------- ### Recommended Configurations - Video Codec Tuning (Balanced) Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/configuration.md Configuration for balanced performance suitable for video codec tuning. ```rust use fast_ssim2::Ssimulacra2Reference; let reference = Ssimulacra2Reference::new(&source)?; let mut ctx = reference.compare_context(); for variant in variants { let score = reference.compare_with(&mut ctx, &variant)?; } ``` -------------------------------- ### LinearRgbImage::new Constructor Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-input.md Creates a new LinearRgbImage, panicking on invalid input. ```rust pub fn new( data: Vec<[f32; 3]>, width: usize, height: usize, ) -> Self ``` -------------------------------- ### Build Configuration - Compile Flags Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/configuration.md Standard Cargo build commands for debug and release profiles. ```bash # Debug build (opt-level=2 for perf) cargo build # Release (LTO thin, codegen-units=1) cargo build --release # Bench (same as release) cargo bench -p fast-ssim2 ``` -------------------------------- ### Batch Comparisons Source: https://github.com/imazen/fast-ssim2/blob/main/README.md Precompute the reference image for faster batch comparisons. ```rust use fast_ssim2::Ssimulacra2Reference; let reference = Ssimulacra2Reference::new(source.as_ref())?; for distorted in compressed_variants { let score = reference.compare(distorted.as_ref())?; } ``` -------------------------------- ### Handling GaussianBlurError Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/errors.md An example of how to catch and handle the `GaussianBlurError` specifically, including checks for invalid pixel values. ```rust use fast_ssim2::{compute_ssimulacra2, Ssimulacra2Error}; match compute_ssimulacra2(&source, &distorted) { Err(Ssimulacra2Error::GaussianBlurError) => { eprintln!("Internal blur failed; check image data validity"); // Validate: no NaN, Inf, or negative values in linear RGB for pixel in source.data() { if !pixel.iter().all(|v| v.is_finite() && *v >= 0.0 && *v <= 1.0) { eprintln!("Invalid pixel value detected"); break; } } } _ => {} } ``` -------------------------------- ### Enable rayon feature in Cargo.toml Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/configuration.md Example of how to enable the 'rayon' Cargo feature for parallel computation support. ```toml [dependencies] fast-ssim2 = { version = "0.8", features = ["rayon"] } ``` -------------------------------- ### Add imgref feature for image types Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/API-OVERVIEW.md Example of how to add the `imgref` feature to your `Cargo.toml` to enable support for various image types. ```toml fast-ssim2 = { version = "0.8", features = ["imgref"] } ``` -------------------------------- ### Benchmark Allocations Source: https://github.com/imazen/fast-ssim2/blob/main/BENCHMARKS.md Runs the benchmark for memory allocations. ```bash cargo run --release --example benchmark_allocations --features unsafe-simd ``` -------------------------------- ### SHA256 Hash Mismatch Error Example Source: https://github.com/imazen/fast-ssim2/blob/main/REFERENCE_TESTING.md This error message indicates that the SHA256 hash of a generated image does not match the expected hash, suggesting a change in the image generation algorithm. ```text ERROR: Source image hash mismatch for gradient_h_64x64! Expected: abc123... Got: def456... This indicates the image generation algorithm changed. ``` -------------------------------- ### Harness details Source: https://github.com/imazen/fast-ssim2/blob/main/benchmarks/ssim2_perf/2026-05-21_kanetaka_lossless.md The harness used for benchmarking involves precomputing and timing different paths of the SSIMULACRA2 computation. ```rust examples/precompute_benchmark.rs ``` -------------------------------- ### Feature Benchmark Source: https://github.com/imazen/fast-ssim2/blob/main/BENCHMARKS.md Runs a benchmark for specific features. ```bash cargo run --release --example feature_benchmark --features unsafe-simd ``` -------------------------------- ### Handle Large Images Gracefully Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/errors.md Demonstrates how to conditionally use full-image SSIMULACRA2 computation for smaller images and strip-wise computation for larger images to manage memory usage. ```rust use fast_ssim2::{compute_ssimulacra2, compute_ssimulacra2_strip}; fn compute_any_size(source: &ImgRef<[u8; 3]>, distorted: &ImgRef<[u8; 3]>) -> Result { let pixels = (source.width() as u64) * (source.height() as u64); if pixels <= 33_000_000 { // ~6K // Full-image computation compute_ssimulacra2(source, distorted) .map_err(|e| format!("Error: {}", e)) } else { // Strip-wise for large images compute_ssimulacra2_strip(source, distorted, 256) .map_err(|e| format!("Error: {}", e)) } } ``` -------------------------------- ### Ssimulacra2Config::new constructor Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/configuration.md Constructor method for Ssimulacra2Config to create a config with a specified backend. ```rust pub fn new(impl_type: SimdImpl) -> Self ``` -------------------------------- ### LinearRgbImage::try_new Constructor Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/api-reference-input.md A fallible constructor for LinearRgbImage that returns a Result. ```rust pub fn try_new( data: Vec<[f32; 3]>, width: usize, height: usize, ) -> Result ``` -------------------------------- ### Ssimulacra2Config Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/API-OVERVIEW.md Configuration for the SSIMULACRA2 algorithm, allowing selection between SIMD and Scalar implementations. ```rust pub struct Ssimulacra2Config { pub impl_type: SimdImpl, // Scalar or Simd (default) } ``` -------------------------------- ### Ssimulacra2StripConfig::with_halo_rows constructor Source: https://github.com/imazen/fast-ssim2/blob/main/_autodocs/configuration.md Constructor for Ssimulacra2StripConfig with a custom halo row count and default SIMD backend. ```rust pub fn with_halo_rows(halo_rows: usize) -> Self ```