9#if defined(WITH_OPENCOLORIO)
25static bool compare_floats(
float a,
float b,
float abs_diff,
int ulp_diff)
31 if (
fabsf(a -
b) < abs_diff) {
35 if ((a < 0.0f) != (
b < 0.0f)) {
39 return (
abs((*(
int *)&a) - (*(
int *)&
b)) < ulp_diff);
42static bool color_space_is_invertible(
const OCIO_NAMESPACE::ConstColorSpaceRcPtr &ocio_color_space)
44 const StringRefNull family = ocio_color_space->getFamily();
46 if (
ELEM(family,
"rrt",
"display")) {
52 if (ocio_color_space->isData()) {
57 if (ocio_color_space->getTransform(OCIO_NAMESPACE::COLORSPACE_DIR_TO_REFERENCE)) {
66static void color_space_is_builtin(
const OCIO_NAMESPACE::ConstConfigRcPtr &ocio_config,
67 const OCIO_NAMESPACE::ConstColorSpaceRcPtr &ocio_color_space,
68 bool &is_scene_linear,
71 OCIO_NAMESPACE::ConstProcessorRcPtr processor = create_ocio_processor_silent(
72 ocio_config, ocio_color_space->getName(), OCIO_NAMESPACE::ROLE_SCENE_LINEAR);
75 is_scene_linear =
false;
80 OCIO_NAMESPACE::ConstCPUProcessorRcPtr cpu_processor = processor->getDefaultCPUProcessor();
82 is_scene_linear =
true;
84 for (
int i = 0;
i < 256;
i++) {
87 float cR[3] = {
v, 0, 0};
88 float cG[3] = {0,
v, 0};
89 float cB[3] = {0, 0,
v};
90 float cW[3] = {
v,
v,
v};
91 cpu_processor->applyRGB(cR);
92 cpu_processor->applyRGB(cG);
93 cpu_processor->applyRGB(cB);
94 cpu_processor->applyRGB(cW);
97 if (
fabsf(cR[1]) > 1e-5f ||
fabsf(cR[2]) > 1e-5f ||
fabsf(cG[0]) > 1e-5f ||
100 is_scene_linear =
false;
108 is_scene_linear =
false;
114 is_scene_linear =
false;
119 float out_v = (cW[0] + cW[1] + cW[2]) * (1.0f / 3.0f);
121 is_scene_linear =
false;
129LibOCIOColorSpace::LibOCIOColorSpace(
const int index,
130 const OCIO_NAMESPACE::ConstConfigRcPtr &ocio_config,
131 const OCIO_NAMESPACE::ConstColorSpaceRcPtr &ocio_color_space)
132 : ocio_config_(ocio_config),
133 ocio_color_space_(ocio_color_space),
138 is_invertible_ = color_space_is_invertible(ocio_color_space);
143 const int num_aliases = ocio_color_space->getNumAliases();
144 for (
int i = 0;
i < num_aliases;
i++) {
146 if (alias ==
"srgb_display") {
147 interop_id_ =
"srgb_rec709_display";
149 else if (alias ==
"displayp3_display") {
150 interop_id_ =
"srgb_p3d65_display";
152 else if (alias ==
"displayp3_hdr_display") {
153 interop_id_ =
"srgbe_p3d65_display";
155 else if (alias ==
"p3d65_display") {
156 interop_id_ =
"g26_p3d65_display";
158 else if (alias ==
"rec1886_rec709_display") {
159 interop_id_ =
"g24_rec709_display";
161 else if (alias ==
"rec2100_pq_display") {
162 interop_id_ =
"pq_rec2020_display";
164 else if (alias ==
"rec2100_hlg_display") {
165 interop_id_ =
"hlg_rec2020_display";
167 else if (alias ==
"st2084_p3d65_display") {
168 interop_id_ =
"pq_p3d65_display";
170 else if (
ELEM(alias,
"lin_rec709_srgb",
"lin_rec709")) {
171 interop_id_ =
"lin_rec709_scene";
173 else if (alias ==
"lin_rec2020") {
174 interop_id_ =
"lin_rec2020_scene";
176 else if (
ELEM(alias,
"lin_p3d65",
"lin_displayp3")) {
177 interop_id_ =
"lin_p3d65_scene";
179 else if ((alias.startswith(
"lin_") || alias.startswith(
"srgb_") || alias.startswith(
"g18_") ||
180 alias.startswith(
"g22_") || alias.startswith(
"g24_") || alias.startswith(
"g26_") ||
181 alias.startswith(
"pq_") || alias.startswith(
"hlg_")) &&
182 (alias.endswith(
"_scene") || alias.endswith(
"_display")))
187 if (!interop_id_.is_empty()) {
193 if (interop_id_.is_empty()) {
194 const char *data_name = ocio_config->getRoleColorSpace(OCIO_NAMESPACE::ROLE_DATA);
195 if (data_name &&
STREQ(ocio_color_space->getName(), data_name)) {
196 interop_id_ =
"data";
201 "Add colorspace: %s (interop ID: %s)",
203 interop_id_.is_empty() ?
"<none>" : interop_id_.c_str());
206bool LibOCIOColorSpace::is_scene_linear()
const
208 ensure_srgb_scene_linear_info();
209 return is_scene_linear_;
212bool LibOCIOColorSpace::is_srgb()
const
214 ensure_srgb_scene_linear_info();
218const CPUProcessor *LibOCIOColorSpace::get_to_scene_linear_cpu_processor()
const
220 return to_scene_linear_cpu_processor_.get([&]() -> std::unique_ptr<CPUProcessor> {
221 OCIO_NAMESPACE::ConstProcessorRcPtr ocio_processor = create_ocio_processor(
222 ocio_config_, ocio_color_space_->getName(), OCIO_NAMESPACE::ROLE_SCENE_LINEAR);
223 if (!ocio_processor) {
226 return std::make_unique<LibOCIOCPUProcessor>(ocio_processor->getDefaultCPUProcessor());
230const CPUProcessor *LibOCIOColorSpace::get_from_scene_linear_cpu_processor()
const
232 return from_scene_linear_cpu_processor_.get([&]() -> std::unique_ptr<CPUProcessor> {
233 OCIO_NAMESPACE::ConstProcessorRcPtr ocio_processor = create_ocio_processor(
234 ocio_config_, OCIO_NAMESPACE::ROLE_SCENE_LINEAR, ocio_color_space_->getName());
235 if (!ocio_processor) {
238 return std::make_unique<LibOCIOCPUProcessor>(ocio_processor->getDefaultCPUProcessor());
242void LibOCIOColorSpace::ensure_srgb_scene_linear_info()
const
244 if (is_info_cached_) {
247 color_space_is_builtin(ocio_config_, ocio_color_space_, is_scene_linear_, is_srgb_);
248 is_info_cached_ =
true;
251void LibOCIOColorSpace::clear_caches()
253 from_scene_linear_cpu_processor_ = CPUProcessorCache();
254 to_scene_linear_cpu_processor_ = CPUProcessorCache();
255 is_info_cached_ =
false;
float srgb_to_linearrgb(float c)
#define CLOG_TRACE(clg_ref,...)
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device_inline bool compare_floats(const float a, const float b, float abs_diff, const int ulp_diff)
std::string cleanup_description(const StringRef description)