1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
use crate::co::plugin::numeric_helpers::*;
use crate::co::prelude::*;
/// The Transformer Trait
///
/// Gets implemented for all Transformable Data Types.
/// Allows all Transformable Data Types to get transformed into a `Blob`.
pub trait Transformer {
/// Transforms non-numeric data into a numeric `SharedTensor`
///
/// The shape attribute is used to control the dimensions/shape of the Blob.
/// It returns an Error, when the expected capacity (defined by the shape) differs from the
/// observed one.
fn transform(&self, shape: &[usize]) -> Result<SharedTensor<f32>, TransformerError> {
let native_backend = Backend::<Native>::default().unwrap();
let mut tensor = SharedTensor::<f32>::new(&shape);
{
let mut native_tensor = tensor.write_only(native_backend.device()).unwrap();
Self::write_to_memory(&mut native_tensor, &self.transform_to_vec())?;
}
Ok(tensor)
}
/// Transforms the non-numeric data into a numeric `Vec`
fn transform_to_vec(&self) -> Vec<f32>;
/// Write into a native Coaster Memory.
fn write_to_memory<T: NumCast + ::std::marker::Copy>(
mem: &mut FlatBox,
data: &[T],
) -> Result<(), TransformerError> {
Self::write_to_memory_offset(mem, data, 0)
}
/// Write into a native Coaster Memory with a offset.
fn write_to_memory_offset<T: NumCast + ::std::marker::Copy>(
mem: &mut FlatBox,
data: &[T],
offset: usize,
) -> Result<(), TransformerError> {
let mem_buffer = mem.as_mut_slice::<f32>();
if offset == 0 && mem_buffer.len() != data.len() {
return Err(TransformerError::InvalidShape);
}
for (index, datum) in data.iter().enumerate() {
let old_val = mem_buffer
.get_mut(index + offset)
.ok_or(TransformerError::InvalidShape)?;
*old_val = cast(*datum).unwrap();
}
Ok(())
}
}
#[derive(Debug, Copy, Clone)]
/// The Transformer Errors
pub enum TransformerError {
/// When the speficied shape capacitiy differs from the actual capacity of the numeric Vec
InvalidShape,
/// When The Image Pixel Buffer can't be converted to a RGB Image
InvalidRgbPixels,
/// When The Image Pixel Buffer can't be converted to a RGBA Image
InvalidRgbaPixels,
/// When The Image Pixel Buffer can't be converted to a greyscale Image
InvalidLumaPixels,
/// When The Image Pixel Buffer can't be converted to a greyscale Alpha Image
InvalidLumaAlphaPixels,
}