use crate::core::color::{RGB, RGBSigmoidPolynomial, RGBToSpectrumTable, XYZ}; use crate::core::geometry::Point2f; use crate::core::pbrt::Float; use crate::spectra::{DenselySampledSpectrum, SampledSpectrum}; use crate::utils::math::SquareMatrix3f; use crate::utils::ptr::DevicePtr; use std::cmp::{Eq, PartialEq}; #[repr(C)] #[derive(Copy, Debug, Clone)] pub struct StandardColorSpaces { pub srgb: DevicePtr, pub dci_p3: DevicePtr, pub rec2020: DevicePtr, pub aces2065_1: DevicePtr, } #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct RGBColorSpace { pub r: Point2f, pub g: Point2f, pub b: Point2f, pub w: Point2f, pub illuminant: DenselySampledSpectrum, pub rgb_to_spectrum_table: DevicePtr, pub xyz_from_rgb: SquareMatrix3f, pub rgb_from_xyz: SquareMatrix3f, } unsafe impl Send for RGBColorSpace {} unsafe impl Sync for RGBColorSpace {} impl RGBColorSpace { pub fn to_xyz(&self, rgb: RGB) -> XYZ { self.xyz_from_rgb * rgb } pub fn to_rgb(&self, xyz: XYZ) -> RGB { self.rgb_from_xyz * xyz } pub fn to_rgb_coeffs(&self, rgb: RGB) -> RGBSigmoidPolynomial { self.rgb_to_spectrum_table.to_polynomial(rgb) } pub fn convert_colorspace(&self, other: &RGBColorSpace) -> SquareMatrix3f { if self == other { return SquareMatrix3f::default(); } self.rgb_from_xyz * other.xyz_from_rgb } pub fn luminance_vector(&self) -> RGB { RGB::new( self.xyz_from_rgb[1][0], self.xyz_from_rgb[1][1], self.xyz_from_rgb[1][2], ) } } impl PartialEq for RGBColorSpace { fn eq(&self, other: &Self) -> bool { self.r == other.r && self.g == other.g && self.b == other.b && self.w == other.w && self.rgb_to_spectrum_table == other.rgb_to_spectrum_table } }