use std::os::raw::{c_int, c_uint};
use crate::error::{Error, Result};
#[repr(C)]
struct BaResult {
score: f64,
ok: c_int,
}
unsafe extern "C" {
fn iqa_butteraugli_rgb_f32(
orig_rgb: *const f32,
dist_rgb: *const f32,
width: c_uint,
height: c_uint,
intensity_target: f32,
hf_asymmetry: f32,
pnorm: f64,
) -> BaResult;
}
pub(super) fn compute(
orig: &[f32],
dist: &[f32],
width: u32,
height: u32,
intensity_target: f32,
hf_asymmetry: f32,
pnorm: f64,
) -> 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_butteraugli_rgb_f32(
orig.as_ptr(),
dist.as_ptr(),
width,
height,
intensity_target,
hf_asymmetry,
pnorm,
)
};
if result.ok != 0 {
Ok(result.score)
} else {
Err(Error::ButteraugliFailed)
}
}