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::Ptr; use core::cmp::{Eq, PartialEq}; #[repr(C)] #[derive(Copy, Debug, Clone)] pub struct DeviceStandardColorSpaces { pub srgb: Ptr, pub dci_p3: Ptr, pub rec2020: Ptr, pub aces2065_1: Ptr, } impl DeviceStandardColorSpaces { #[cfg(not(target_arch = "nvptx64"))] pub fn get_named(&self, name: &str) -> Option> { let lower = name.as_bytes(); match lower { b if b.eq_ignore_ascii_case(b"srgb") => Some(self.srgb), b if b.eq_ignore_ascii_case(b"dci-p3") => Some(self.dci_p3), b if b.eq_ignore_ascii_case(b"rec2020") => Some(self.rec2020), b if b.eq_ignore_ascii_case(b"aces2065-1") => Some(self.aces2065_1), _ => None, } } pub fn get_by_id(&self, id: ColorSpaceId) -> Ptr { match id { ColorSpaceId::SRGB => self.srgb, ColorSpaceId::DciP3 => self.dci_p3, ColorSpaceId::Rec2020 => self.rec2020, ColorSpaceId::Aces2065_1 => self.aces2065_1, } } } #[repr(u8)] #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum ColorSpaceId { SRGB = 0, DciP3 = 1, Rec2020 = 2, Aces2065_1 = 3, } impl ColorSpaceId { #[cfg(not(target_arch = "nvptx64"))] pub fn from_name(name: &str) -> Option { let lower = name.as_bytes(); match lower { b if b.eq_ignore_ascii_case(b"srgb") => Some(Self::SRGB), b if b.eq_ignore_ascii_case(b"dci-p3") => Some(Self::DciP3), b if b.eq_ignore_ascii_case(b"rec2020") => Some(Self::Rec2020), b if b.eq_ignore_ascii_case(b"aces2065-1") => Some(Self::Aces2065_1), _ => None, } } } #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct RGBColorSpace { pub r: Point2f, pub g: Point2f, pub b: Point2f, pub w: Point2f, pub xyz_from_rgb: SquareMatrix3f, pub rgb_from_xyz: SquareMatrix3f, pub illuminant: Ptr, pub rgb_to_spectrum_table: Ptr, } 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.evaluate(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 } }