use super::buffer::with_capacity;
use super::{Image, Layout};
use crate::{error::Result, transform::Transform};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ToFloat {
scale: bool,
}
impl ToFloat {
pub fn new(scale: bool) -> Self {
Self { scale }
}
}
impl Default for ToFloat {
fn default() -> Self {
Self::new(true)
}
}
impl<L: Layout> Transform<Image<u8, L>> for ToFloat {
type Output = Image<f32, L>;
fn apply(&self, _index: usize, image: Image<u8, L>) -> Result<Image<f32, L>> {
let mut data = with_capacity(image.data().len())?;
match self.scale {
true => data.extend(image.data().iter().map(|&v| f32::from(v) / 255.0)),
false => data.extend(image.data().iter().map(|&v| f32::from(v))),
}
Image::new(image.width(), image.height(), image.channels(), data)
}
}
#[cfg(test)]
mod tests {
use super::ToFloat;
use crate::image::{Chw, Image};
use crate::transform::Transform;
#[test]
fn scaled_and_not() {
let image = Image::<u8, Chw>::new(3, 1, 1, vec![0, 51, 255]).unwrap();
let scaled = ToFloat::default().apply(0, image.clone()).unwrap();
assert_eq!(scaled.data(), [0.0, 0.2, 1.0]);
assert_eq!(scaled.shape(), [1, 1, 3]);
let plain = ToFloat::new(false).apply(0, image).unwrap();
assert_eq!(plain.data(), [0.0, 51.0, 255.0]);
}
}