use crate::data::{AnyDataArray, DataArray, ImageData};
pub fn image_pad(
input: &ImageData,
scalars: &str,
pad: [usize; 3],
fill_value: f64,
) -> ImageData {
let arr = match input.point_data().get_array(scalars) {
Some(a) => a,
None => return input.clone(),
};
let dims = input.dimensions();
let nx = dims[0] as usize;
let ny = dims[1] as usize;
let nz = dims[2] as usize;
let origin = input.origin();
let spacing = input.spacing();
let new_nx = nx + 2 * pad[0];
let new_ny = ny + 2 * pad[1];
let new_nz = nz + 2 * pad[2];
let new_origin = [
origin[0] - pad[0] as f64 * spacing[0],
origin[1] - pad[1] as f64 * spacing[1],
origin[2] - pad[2] as f64 * spacing[2],
];
let new_n = new_nx * new_ny * new_nz;
let mut values = vec![fill_value; new_n];
let mut buf = [0.0f64];
for k in 0..nz {
for j in 0..ny {
for i in 0..nx {
arr.tuple_as_f64(k * ny * nx + j * nx + i, &mut buf);
let di = i + pad[0];
let dj = j + pad[1];
let dk = k + pad[2];
values[dk * new_ny * new_nx + dj * new_nx + di] = buf[0];
}
}
}
let mut img = ImageData::with_dimensions(new_nx, new_ny, new_nz);
img.set_origin(new_origin);
img.set_spacing(spacing);
img.point_data_mut().add_array(AnyDataArray::F64(
DataArray::from_vec(scalars, values, 1),
));
img
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pad_1_each_side() {
let mut img = ImageData::with_dimensions(3, 3, 1);
let values: Vec<f64> = (1..=9).map(|i| i as f64).collect();
img.point_data_mut().add_array(AnyDataArray::F64(
DataArray::from_vec("v", values, 1),
));
let result = image_pad(&img, "v", [1, 1, 0], 0.0);
assert_eq!(result.dimensions(), [5, 5, 1]);
let arr = result.point_data().get_array("v").unwrap();
let mut buf = [0.0f64];
arr.tuple_as_f64(0, &mut buf);
assert_eq!(buf[0], 0.0);
arr.tuple_as_f64(12, &mut buf);
assert_eq!(buf[0], 5.0); }
#[test]
fn zero_pad() {
let mut img = ImageData::with_dimensions(2, 2, 1);
img.point_data_mut().add_array(AnyDataArray::F64(
DataArray::from_vec("v", vec![1.0, 2.0, 3.0, 4.0], 1),
));
let result = image_pad(&img, "v", [0, 0, 0], 0.0);
assert_eq!(result.dimensions(), [2, 2, 1]);
}
#[test]
fn missing_array() {
let img = ImageData::with_dimensions(2, 2, 1);
let result = image_pad(&img, "nope", [1, 1, 1], 0.0);
assert_eq!(result.dimensions(), [2, 2, 1]);
}
}