use convolve_nd::exports::ndarray::Array1;
use crate::aggregate::Aggregate;
use crate::decompose::WaveletDecompose;
use crate::kernels::Kernel;
use crate::layer::{WaveletLayer, WaveletLayerBuffer};
#[derive(Copy, Clone)]
pub struct Scale {
min: f32,
#[allow(unused)]
max: f32,
scaling_ratio: f32,
}
impl Scale {
pub fn new(min: f32, max: f32) -> Self {
Self {
min,
max,
scaling_ratio: max - min,
}
}
#[inline]
pub fn apply(&self, value: f32) -> f32 {
(value - self.min) / self.scaling_ratio
}
}
#[derive(Clone)]
struct ATrousTransformInput {
data: Array1<f32>,
}
impl Aggregate for ATrousTransformInput {
fn min(&self) -> f32 {
self.data.min()
}
fn max(&self) -> f32 {
self.data.max()
}
}
#[derive(Clone)]
pub struct ATrousTransform {
input: ATrousTransformInput,
levels: usize,
kernel: Kernel,
current_level: usize,
}
impl ATrousTransform {
pub fn new(input: Vec<f32>, levels: usize, kernel: Kernel) -> Self {
let data = input.into();
Self {
input: ATrousTransformInput { data },
levels,
kernel,
current_level: 0,
}
}
pub fn linear(input: Vec<f32>, levels: usize) -> Self {
ATrousTransform::new(input, levels, Kernel::LinearInterpolationKernel)
}
pub fn low_scale(input: Vec<f32>, levels: usize) -> Self {
ATrousTransform::new(input, levels, Kernel::LowScaleKernel)
}
pub fn b_spline(input: Vec<f32>, levels: usize) -> Self {
ATrousTransform::new(input, levels, Kernel::B3SplineKernel)
}
}
impl Iterator for ATrousTransform {
type Item = WaveletLayer;
fn next(&mut self) -> Option<Self::Item> {
let pixel_scale = self.current_level;
self.current_level += 1;
if pixel_scale > self.levels {
return None;
}
if pixel_scale == self.levels {
return Some(WaveletLayer {
buffer: WaveletLayerBuffer {
data: self.input.data.clone(),
},
pixel_scale: None,
});
}
let kernel = self.kernel;
let layer_buffer = self.input.data.wavelet_decompose(kernel, pixel_scale);
Some(WaveletLayer {
pixel_scale: Some(pixel_scale),
buffer: layer_buffer,
})
}
}