7#if defined(WITH_OPENCOLORIO)
12# include <fmt/format.h>
34std::unique_ptr<Config> LibOCIOConfig::create_from_environment()
37 OCIO_NAMESPACE::ConstConfigRcPtr ocio_config = OCIO_NAMESPACE::Config::CreateFromEnv();
42 return std::unique_ptr<LibOCIOConfig>(
new LibOCIOConfig(ocio_config));
44 catch (OCIO_NAMESPACE::Exception &exception) {
45 report_exception(exception);
51std::unique_ptr<Config> LibOCIOConfig::create_from_file(
const StringRefNull filename)
54 OCIO_NAMESPACE::ConstConfigRcPtr ocio_config = OCIO_NAMESPACE::Config::CreateFromFile(
60 return std::unique_ptr<LibOCIOConfig>(
new LibOCIOConfig(ocio_config));
62 catch (OCIO_NAMESPACE::Exception &exception) {
63 report_exception(exception);
69LibOCIOConfig::LibOCIOConfig(
const OCIO_NAMESPACE::ConstConfigRcPtr &ocio_config)
78 OCIO_NAMESPACE::SetCurrentConfig(ocio_config);
79 ocio_config_ = OCIO_NAMESPACE::GetCurrentConfig();
81 initialize_active_color_spaces();
82 initialize_inactive_color_spaces();
84 initialize_displays();
87LibOCIOConfig::~LibOCIOConfig() {}
89void LibOCIOConfig::initialize_active_color_spaces()
91 OCIO_NAMESPACE::ColorSpaceSetRcPtr ocio_color_spaces;
94 ocio_color_spaces = ocio_config_->getColorSpaces(
nullptr);
96 catch (OCIO_NAMESPACE::Exception &exception) {
97 report_exception(exception);
101 if (!ocio_color_spaces) {
102 report_error(
"Invalid OpenColorIO configuration: color spaces set is nullptr");
106 const int num_color_spaces = ocio_color_spaces->getNumColorSpaces();
107 if (num_color_spaces < 0) {
108 report_error(fmt::format(
109 "Invalid OpenColorIO configuration: invalid number of color spaces {}", num_color_spaces));
113 color_spaces_.reserve(num_color_spaces);
115 for (
const int i : IndexRange(num_color_spaces)) {
116 const OCIO_NAMESPACE::ConstColorSpaceRcPtr ocio_color_space =
117 ocio_color_spaces->getColorSpaceByIndex(
i);
118 color_spaces_.append_as(
i, ocio_config_, ocio_color_space);
122 sorted_color_space_index_.resize(num_color_spaces);
123 std::iota(sorted_color_space_index_.begin(), sorted_color_space_index_.end(), 0);
124 std::sort(sorted_color_space_index_.begin(), sorted_color_space_index_.end(), [&](
int a,
int b) {
125 return color_spaces_[a].name() < color_spaces_[b].name();
129void LibOCIOConfig::initialize_inactive_color_spaces()
131 const int num_inactive_color_spaces = ocio_config_->getNumColorSpaces(
132 OCIO_NAMESPACE::SEARCH_REFERENCE_SPACE_ALL, OCIO_NAMESPACE::COLORSPACE_INACTIVE);
133 if (num_inactive_color_spaces < 0) {
134 report_error(fmt::format(
135 "Invalid OpenColorIO configuration: invalid number of inactive color spaces {}",
136 num_inactive_color_spaces));
140 for (
const int i : IndexRange(num_inactive_color_spaces)) {
141 const char *colorspace_name = ocio_config_->getColorSpaceNameByIndex(
142 OCIO_NAMESPACE::SEARCH_REFERENCE_SPACE_ALL, OCIO_NAMESPACE::COLORSPACE_INACTIVE,
i);
144 OCIO_NAMESPACE::ConstColorSpaceRcPtr ocio_color_space;
146 ocio_color_space = ocio_config_->getColorSpace(colorspace_name);
148 catch (OCIO_NAMESPACE::Exception &exception) {
149 report_exception(exception);
153 inactive_color_spaces_.append_as(
i, ocio_config_, ocio_color_space);
157void LibOCIOConfig::initialize_looks()
159 const int num_looks = ocio_config_->getNumLooks();
161 looks_.reserve(num_looks + 1);
164 looks_.append_as(0,
nullptr);
166 for (
const int i : IndexRange(num_looks)) {
167 const StringRefNull view_name = ocio_config_->getLookNameByIndex(
i);
170 if (view_name ==
"None") {
174 const OCIO_NAMESPACE::ConstLookRcPtr ocio_look = ocio_config_->getLook(view_name.
c_str());
175 looks_.append_as(
i + 1, ocio_look);
179void LibOCIOConfig::initialize_displays()
181 const int num_displays = ocio_config_->getNumDisplays();
182 if (num_displays < 0) {
183 report_error(fmt::format(
"Invalid OpenColorIO configuration: invalid number of displays {}",
188 displays_.reserve(num_displays);
190 for (
const int i : IndexRange(num_displays)) {
191 displays_.append_as(
i, *
this);
201float3 LibOCIOConfig::get_default_luma_coefs()
const
204 double rgb_double[3];
205 ocio_config_->getDefaultLumaCoefs(rgb_double);
207 return float3(rgb_double[0], rgb_double[1], rgb_double[2]);
209 catch (OCIO_NAMESPACE::Exception &exception) {
210 report_exception(exception);
215 return float3(0.2126f, 0.7152f, 0.0722f);
218static bool to_scene_linear_matrix(
const OCIO_NAMESPACE::ConstConfigRcPtr &ocio_config,
219 const StringRefNull colorspace,
222 const OCIO_NAMESPACE::ConstProcessorRcPtr processor = create_ocio_processor(
223 ocio_config, colorspace.
c_str(), OCIO_NAMESPACE::ROLE_SCENE_LINEAR);
228 const OCIO_NAMESPACE::ConstCPUProcessorRcPtr cpu_processor = processor->getDefaultCPUProcessor();
230 cpu_processor->applyRGB(to_scene_linear[0]);
231 cpu_processor->applyRGB(to_scene_linear[1]);
232 cpu_processor->applyRGB(to_scene_linear[2]);
237float3x3 LibOCIOConfig::get_xyz_to_scene_linear_matrix()
const
244 if (!ocio_config_->hasRole(OCIO_NAMESPACE::ROLE_SCENE_LINEAR)) {
245 return xyz_to_scene_linear;
248 if (ocio_config_->hasRole(
"aces_interchange")) {
251 if (to_scene_linear_matrix(ocio_config_,
"aces_interchange", aces_to_scene_linear)) {
253 xyz_to_scene_linear = aces_to_scene_linear * xyz_to_aces;
256 else if (ocio_config_->hasRole(
"XYZ")) {
258 to_scene_linear_matrix(ocio_config_,
"XYZ", xyz_to_scene_linear);
261 return xyz_to_scene_linear;
264const char *LibOCIOConfig::get_color_space_from_filepath(
const char *filepath)
const
272 if (ocio_config_->filepathOnlyMatchesDefaultRule(filepath)) {
276 return ocio_config_->getColorSpaceFromFilepath(filepath);
285const ColorSpace *LibOCIOConfig::get_color_space(
const StringRefNull name)
const
287 OCIO_NAMESPACE::ConstColorSpaceRcPtr ocio_color_space;
291 ocio_color_space = ocio_config_->getColorSpace(name.
c_str());
293 catch (OCIO_NAMESPACE::Exception &exception) {
294 report_exception(exception);
298 if (!ocio_color_space) {
305 for (
const LibOCIOColorSpace &color_space : color_spaces_) {
306 if (color_space.name() == ocio_color_space->getName()) {
313 for (
const LibOCIOColorSpace &color_space : inactive_color_spaces_) {
314 if (color_space.name() == ocio_color_space->getName()) {
320 fmt::format(
"Invalid OpenColorIO configuration: color space {} not found on Blender side",
321 ocio_color_space->getName()));
326int LibOCIOConfig::get_num_color_spaces()
const
328 return color_spaces_.size();
331const ColorSpace *LibOCIOConfig::get_color_space_by_index(
int const index)
const
333 if (index < 0 || index >= color_spaces_.size()) {
336 return &color_spaces_[index];
339const ColorSpace *LibOCIOConfig::get_sorted_color_space_by_index(
const int index)
const
341 BLI_assert(color_spaces_.size() == sorted_color_space_index_.size());
342 if (index < 0 || index >= color_spaces_.size()) {
345 return get_color_space_by_index(sorted_color_space_index_[index]);
354const Display *LibOCIOConfig::get_default_display()
const
356 if (displays_.is_empty()) {
361 return &displays_[0];
364const Display *LibOCIOConfig::get_display_by_name(
const StringRefNull name)
const
367 for (
const LibOCIODisplay &display : displays_) {
368 if (display.name() == name) {
375int LibOCIOConfig::get_num_displays()
const
377 return displays_.size();
380const Display *LibOCIOConfig::get_display_by_index(
int index)
const
382 if (index < 0 || index >= displays_.size()) {
385 return &displays_[index];
394const ColorSpace *LibOCIOConfig::get_display_view_color_space(
const StringRefNull display,
395 const StringRefNull
view)
const
397 StringRefNull display_color_space;
400 display_color_space = ocio_config_->getDisplayViewColorSpaceName(display.
c_str(),
403 if (strcasecmp(display_color_space.
c_str(),
"<USE_DISPLAY_NAME>") == 0) {
404 display_color_space = display;
407 catch (OCIO_NAMESPACE::Exception &exception) {
408 report_exception(exception);
409 display_color_space = display;
412 return get_color_space(display_color_space);
421const Look *LibOCIOConfig::get_look_by_name(
const StringRefNull name)
const
424 for (
const LibOCIOLook &look : looks_) {
425 if (look.name() == name) {
432int LibOCIOConfig::get_num_looks()
const
434 return looks_.size();
437const Look *LibOCIOConfig::get_look_by_index(
const int index)
const
439 if (index < 0 || index >= looks_.size()) {
442 return &looks_[index];
451std::shared_ptr<const CPUProcessor> LibOCIOConfig::get_display_cpu_processor(
454 OCIO_NAMESPACE::ConstProcessorRcPtr processor = create_ocio_display_processor(
455 *
this, display_parameters);
459 return std::make_shared<LibOCIOCPUProcessor>(processor->getDefaultCPUProcessor());
462std::shared_ptr<const CPUProcessor> LibOCIOConfig::get_cpu_processor(
463 const StringRefNull from_colorspace,
const StringRefNull to_colorspace)
const
465 const OCIO_NAMESPACE::ConstProcessorRcPtr processor = create_ocio_processor(
466 ocio_config_, from_colorspace.
c_str(), to_colorspace.
c_str());
470 return std::make_shared<LibOCIOCPUProcessor>(processor->getDefaultCPUProcessor());
481 return gpu_shader_binder_;
constexpr const char * c_str() const
CartesianBasis invert(const CartesianBasis &basis)
static const float3x3 ACES_TO_XYZ
static const float3x3 XYZ_TO_REC709
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
static MatBase identity()