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, } 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 = 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, loc: &FileLoc, _arena: &Arena, ) -> Result { 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)) } }