80 lines
2.5 KiB
Rust
80 lines
2.5 KiB
Rust
use super::*;
|
|
use crate::Arena;
|
|
use crate::core::film::{CreateFilmBase, PixelSensor};
|
|
use crate::utils::containers::Array2D;
|
|
use anyhow::Result;
|
|
use shared::core::camera::CameraTransform;
|
|
use shared::core::film::{Film, FilmBase, RGBFilm, RGBPixel};
|
|
use shared::core::filter::FilterTrait;
|
|
use shared::spectra::RGBColorSpace;
|
|
|
|
struct RGBFilmStorage {
|
|
pixels: Array2D<RGBPixel>,
|
|
}
|
|
|
|
pub struct RGBFilmHost {
|
|
pub device: RGBFilm,
|
|
storage: RGBFilmStorage,
|
|
}
|
|
|
|
impl RGBFilmHost {
|
|
pub fn new(
|
|
base: FilmBase,
|
|
colorspace: &RGBColorSpace,
|
|
max_component_value: Float,
|
|
write_fp16: bool,
|
|
) -> Self {
|
|
let sensor_ptr = base.sensor;
|
|
if sensor_ptr.is_null() {
|
|
panic!("Film must have a sensor");
|
|
}
|
|
let sensor = &*sensor_ptr;
|
|
let filter_integral = base.filter.integral();
|
|
let sensor_matrix = sensor.xyz_from_sensor_rgb;
|
|
let output_rgbf_from_sensor_rgb = colorspace.rgb_from_xyz * sensor_matrix;
|
|
|
|
let width = base.pixel_bounds.p_max.x() - base.pixel_bounds.p_min.x();
|
|
let height = base.pixel_bounds.p_max.y() - base.pixel_bounds.p_min.y();
|
|
let count = (width * height) as usize;
|
|
|
|
let mut pixel_vec = Vec::with_capacity(count);
|
|
for _ in 0..count {
|
|
pixel_vec.push(RGBPixel::default());
|
|
}
|
|
|
|
let pixels: Array2D<RGBPixel> = Array2D::new(base.pixel_bounds);
|
|
|
|
let device_pixels = pixels.device.clone();
|
|
let storage = RGBFilmStorage { pixels };
|
|
|
|
let device = RGBFilm {
|
|
base,
|
|
max_component_value,
|
|
write_fp16,
|
|
filter_integral,
|
|
output_rgbf_from_sensor_rgb,
|
|
pixels: device_pixels,
|
|
};
|
|
|
|
Self { device, storage }
|
|
}
|
|
}
|
|
|
|
impl CreateFilm for RGBFilm {
|
|
fn create(
|
|
params: &ParameterDictionary,
|
|
exposure_time: Float,
|
|
filter: Filter,
|
|
_camera_transform: Option<CameraTransform>,
|
|
loc: &FileLoc,
|
|
_arena: &Arena,
|
|
) -> Result<Film> {
|
|
let colorspace = params.color_space.as_ref().unwrap();
|
|
let max_component_value = params.get_one_float("maxcomponentvalue", Float::INFINITY);
|
|
let write_fp16 = params.get_one_bool("savefp16", true);
|
|
let sensor = PixelSensor::create(params, colorspace.clone(), exposure_time, loc)?;
|
|
let film_base = FilmBase::create(params, filter, Some(&sensor.device()), loc);
|
|
let film = RGBFilmHost::new(film_base, &colorspace, max_component_value, write_fp16);
|
|
Ok(Film::RGB(film.device))
|
|
}
|
|
}
|