zoomvtools 1.1.0

Video motion vector analysis utilities in pure Rust
Documentation
#[cfg(test)]
mod tests;

use std::cmp::{max, min};

/// Port of C's `nearbyintf` function which rounds `.5` values to the nearest even number.
/// Why on earth IEEE 754 decided this should be the standard, I will never know.
#[must_use]
#[inline(always)]
pub fn round_ties_to_even(x: f32) -> f32 {
    let truncated = x.trunc();
    let fractional = x - truncated;

    match fractional.abs() {
        f if f < 0.5 => truncated,
        f if f > 0.5 => truncated + x.signum(),
        _ => {
            // Exactly 0.5 - round to even
            if truncated as i32 % 2 == 0 {
                truncated
            } else {
                truncated + x.signum()
            }
        }
    }
}

/// find the median between a, b and c
#[must_use]
#[inline(always)]
pub fn median<T: Ord + Copy>(a: T, b: T, c: T) -> T {
    max(min(a, b), min(max(a, b), c))
}

#[must_use]
#[inline(always)]
const fn gcd_u64(mut x: u64, mut y: u64) -> u64 {
    while y != 0 {
        let t = x % y;
        x = y;
        y = t;
    }
    x
}

#[must_use]
#[inline(always)]
pub const fn reduce_fraction(num: u64, den: u64) -> (u64, u64) {
    let gcd = gcd_u64(num, den);
    (num / gcd, den / gcd)
}