use std::os::raw::{c_int, c_uint};
use crate::error::{Error, Result};
#[repr(C)]
struct S2Result {
score: f64,
ok: c_int,
}
unsafe extern "C" {
fn iqa_ssimulacra2_rgb_f32(
orig_rgb: *const f32,
dist_rgb: *const f32,
width: c_uint,
height: c_uint,
) -> S2Result;
}
pub(super) fn compute(orig: &[f32], dist: &[f32], width: u32, height: u32) -> Result<f64> {
let expected = width as usize * height as usize * 3;
assert_eq!(orig.len(), expected, "orig buffer length");
assert_eq!(dist.len(), expected, "dist buffer length");
let result = unsafe { iqa_ssimulacra2_rgb_f32(orig.as_ptr(), dist.as_ptr(), width, height) };
if result.ok != 0 {
Ok(result.score)
} else {
Err(Error::Ssimulacra2Failed)
}
}