use ndarray::Array2;
pub fn adjust_contrast(image_data: Vec<f64>, offset: f64, min: f64, max: f64) -> Vec<f64> {
let val_range: f64 = 256f64 / (max - min);
let rescaled_data: Vec<f64> = image_data.iter().step_by(4)
.map(|val| (val - min + offset) * val_range).collect();
let rescaled_rgba = luminance_to_rgba(rescaled_data);
return rescaled_rgba
}
pub fn array_to_luminance(image: Array2<f64>) -> Vec<f64> {
image.into_raw_vec()
}
pub fn luminance_to_rgba(luminance: Vec<f64>) -> Vec<f64>{
let mut rgba: Vec<f64> = vec![0f64; luminance.len()*4];
for i in 0..luminance.len() {
rgba[i*4 ] = luminance[i]; rgba[i*4 + 1] = luminance[i]; rgba[i*4 + 2] = luminance[i]; rgba[i*4 + 3] = 255f64; }
return rgba
}
#[cfg(test)]
mod tests {
use crate::utilities::adjust_contrast;
#[test]
fn max_100() {
let data: Vec<f64> = vec![0., 0., 0., 10.,
12., 12., 12., 10.,
1.2, 1.2, 1.2, 10.];
let adjusted_data = adjust_contrast(data, 0. ,0., 100.);
let max = adjusted_data.iter().cloned().fold(0./0., f64::max);
let pixel_2 = adjusted_data[4];
assert_eq!( pixel_2, 12. * 256. / (100. - 0.));
}
#[test]
fn min_100() {
let data: Vec<f64> = vec![0., 0., 0., 10.,
12., 12., 12., 10.,
1.2, 1.2, 1.2, 10.];
let adjusted_data = adjust_contrast(data, 0. ,0., 100.);
let min = adjusted_data.iter().cloned().fold(0./0., f64::min);
let pixel_3 = adjusted_data[8];
assert_eq!( pixel_3, 1.2 * 256. / (100. - 0.));
}
#[test]
fn alpha() {
let data: Vec<f64> = vec![0., 0., 0., 10.,
12., 12., 12., 10.,
-8.2, -8.2, -8.2, 10.];
let adjusted_data = adjust_contrast(data, 0. ,-8.2, 12.);
let alpha = adjusted_data[adjusted_data.len()-1];
assert_eq!( alpha, 255.);
}
#[test]
fn offset() {
let val = 25.;
let offset = 50.;
let data: Vec<f64> = vec![val, val, val, 10.];
let adjusted_data = adjust_contrast(data, offset ,0., 256.);
let pixel = adjusted_data[0];
assert_eq!( pixel, val + offset );
}
}