mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-26 02:57:34 -06:00
QA: frame scores refuse NaN samples and mismatched buffers (#427 follow-up)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiAJeFttZp83Fh7YuzAR5f
This commit is contained in:
@@ -2,17 +2,21 @@
|
||||
|
||||
use effectcraft_raster::Image;
|
||||
|
||||
/// How far a rendered frame is from its reference.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct FrameScore {
|
||||
/// Pixels compared (the frames' width × height).
|
||||
pub compared_pixels: usize,
|
||||
/// Mean absolute difference over every channel sample.
|
||||
pub mean_absolute_error: f64,
|
||||
/// Largest absolute difference of any channel sample.
|
||||
pub max_error: f32,
|
||||
}
|
||||
|
||||
/// Compare two premultiplied rendered frames. A size mismatch is reported as an error instead of
|
||||
/// silently producing a misleading score.
|
||||
pub fn compare_frames(actual: &Image, reference: &Image) -> Result<FrameScore, String> {
|
||||
if actual.width != reference.width || actual.height != reference.height {
|
||||
if actual.width != reference.width || actual.height != reference.height || actual.data.len() != reference.data.len() {
|
||||
return Err(format!("frame size mismatch: {}x{} vs {}x{}", actual.width, actual.height, reference.width, reference.height));
|
||||
}
|
||||
let mut sum = 0.0f64;
|
||||
@@ -20,6 +24,10 @@ pub fn compare_frames(actual: &Image, reference: &Image) -> Result<FrameScore, S
|
||||
for (a, b) in actual.data.iter().zip(&reference.data) {
|
||||
for (&x, &y) in a.iter().zip(b) {
|
||||
let error = (x - y).abs();
|
||||
// A NaN would make the mean NaN, which a `mean > tolerance` check reads as a pass.
|
||||
if !error.is_finite() {
|
||||
return Err("frame has a non-finite sample".into());
|
||||
}
|
||||
sum += f64::from(error);
|
||||
max = max.max(error);
|
||||
}
|
||||
@@ -43,5 +51,7 @@ mod tests {
|
||||
assert!((score.mean_absolute_error - 0.0625).abs() < f64::EPSILON);
|
||||
assert_eq!(score.max_error, 0.5);
|
||||
assert!(compare_frames(&actual, &Image::new(1, 1)).is_err());
|
||||
actual.data[0][1] = f32::NAN;
|
||||
assert!(compare_frames(&actual, &reference).is_err(), "NaN is an error, not a pass");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,12 @@ mod color2;
|
||||
mod color3;
|
||||
mod color_fx;
|
||||
pub mod controls;
|
||||
pub mod fidelity;
|
||||
mod distort;
|
||||
mod distort2;
|
||||
mod distort3;
|
||||
pub mod distort4;
|
||||
pub mod face_track;
|
||||
pub mod fidelity;
|
||||
mod generate;
|
||||
mod generate2;
|
||||
mod generate3;
|
||||
|
||||
Reference in New Issue
Block a user