use crate::errors::CodecError;
use alloc::vec::Vec;
use half::f16;
#[must_use]
pub fn compute_residual(original: &[f32], reconstructed: &[f32]) -> Vec<u8> {
debug_assert_eq!(original.len(), reconstructed.len());
let mut out = Vec::with_capacity(original.len() * 2);
for (o, r) in original.iter().zip(reconstructed.iter()) {
let diff = f16::from_f32(*o - *r);
out.extend_from_slice(&diff.to_le_bytes());
}
out
}
pub fn apply_residual_into(values: &mut [f32], residual: &[u8]) -> Result<(), CodecError> {
let expected = values.len() * 2;
if residual.len() != expected {
return Err(CodecError::LengthMismatch {
left: residual.len(),
right: expected,
});
}
#[allow(clippy::indexing_slicing)]
for (v, chunk) in values.iter_mut().zip(residual.chunks_exact(2)) {
let bits = u16::from_le_bytes([chunk[0], chunk[1]]);
*v += f16::from_bits(bits).to_f32();
}
Ok(())
}