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 70 71
//! A pixel mixer module.
use core::borrow::{Borrow, BorrowMut};
use crate::color::PixelRgb;
use crate::phase_amp::*;
/// Implementations of this trait should compute the vertical and horizontal intermediate data for a
/// [Mixer].
pub trait IntermediateCalculator<T> {
/// Computes an intermediate data for a given angle.
///
/// The input value is given in radians in the range: `[0, 2PI)`.
/// The output will be stored in the array of given types as defined by [Mixer::IntermediateH]
/// or [Mixer::IntermediateV]. The type should be a `f32` or a packed simd `f32x8` if a
/// "use-simd" crate feature is enabled.
fn calculate(&self, v: T) -> T;
}
/// Implementations of this trait should compute the color of each pixel based on an intermediate
/// data created by a [IntermediateCalculator].
///
/// The type `T` should be a `f32` or a packed simd `f32x8` if a "use-simd" crate feature is
/// enabled.
pub trait Mixer<T: Sized + Default + Copy> {
/// This type should be an array of the type T for an intermediate horizontal data.
type IntermediateH: Sized + Default + Copy + BorrowMut<[T]> + Borrow<[T]>;
/// This type should be an array of the type T for an intermediate vertical data.
type IntermediateV: Sized + Default + Copy + BorrowMut<[T]> + Borrow<[T]>;
/// Returns the number of intermediate horizontal values.
#[inline]
fn intermediate_h_len() -> usize { core::mem::size_of::<Self::IntermediateH>() / core::mem::size_of::<T>() }
/// Returns the number of intermediate vertical values.
#[inline]
fn intermediate_v_len() -> usize { core::mem::size_of::<Self::IntermediateV>() / core::mem::size_of::<T>() }
/// The implementors should compute a pixel and send it as an instance of [PixelRgb] to the
/// provided `next_pixel` function.
///
/// The computation should be based on the provided combination of intermediate data.
fn mix_pixels(vxp: &Self::IntermediateH, vyp: &Self::IntermediateV, next_pixel: &mut dyn FnMut(PixelRgb));
}
/// Implementations of this trait should produce an iterator of an [IntermediateCalculator] tool.
///
/// The type `T` should be a `f32` or a packed simd `f32x8` if a "use-simd" crate feature is
/// enabled.
pub trait IntermediateCalculatorProducer<'a, P, T>
where P: PhaseAmpsSelect<'a> + ?Sized,
T: Sized + Default + Copy
{
/// Provide an iterator implementation which produce [IntermediateCalculator] tools.
/// The iterator must be a [ExactSizeIterator] with exactly the same length as
/// the associated [Mixer::IntermediateH] array's number of elements.
type CalcIterH: ExactSizeIterator + Iterator<Item = Self::LineCalcH> + Sized;
/// Provide an iterator implementation which produce [IntermediateCalculator] tools.
/// The iterator must be a [ExactSizeIterator] with exactly the same length as
/// the associated [Mixer::IntermediateV] array's number of elements.
type CalcIterV: ExactSizeIterator + Iterator<Item = Self::LineCalcV> + Sized;
/// Provide an implementation of a [IntermediateCalculator] for horizontal intermediate data.
type LineCalcH: IntermediateCalculator<T> + Sized;
/// Provide an implementation of a [IntermediateCalculator] for vertical intermediate data.
type LineCalcV: IntermediateCalculator<T> + Sized;
/// Should return an instance of a [IntermediateCalculatorProducer::LineCalcH].
/// The input data references an implementation of [PhaseAmpsSelect] tool.
fn compose_h_iter(pa: &'a P) -> Self::CalcIterH;
/// Should return an instance of a [IntermediateCalculatorProducer::LineCalcV].
/// The input data references an implementation of [PhaseAmpsSelect] tool.
fn compose_v_iter(pa: &'a P) -> Self::CalcIterV;
}