Blender V4.5
libocio_display_processor.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7#if defined(WITH_OPENCOLORIO)
8
9# include "BLI_math_matrix.hh"
10
11# include "OCIO_config.hh"
12
13# include "error_handling.hh"
14# include "libocio_config.hh"
15
16# include "../white_point.hh"
17
18namespace blender::ocio {
19
20OCIO_NAMESPACE::ConstProcessorRcPtr create_ocio_display_processor(
21 const LibOCIOConfig &config, const DisplayParameters &display_parameters)
22{
23 using namespace OCIO_NAMESPACE;
24
25 const ConstConfigRcPtr &ocio_config = config.get_ocio_config();
26
27 GroupTransformRcPtr group = GroupTransform::Create();
28
29 const char *from_colorspace = display_parameters.from_colorspace.c_str();
30
31 /* Linear transforms. */
32 if (display_parameters.scale != 1.0f || display_parameters.use_white_balance) {
33 /* Always apply exposure and/or white balance in scene linear. */
34 ColorSpaceTransformRcPtr ct = ColorSpaceTransform::Create();
35 ct->setSrc(from_colorspace);
36 ct->setDst(ROLE_SCENE_LINEAR);
37 group->appendTransform(ct);
38
39 /* Make further transforms aware of the color space change. */
40 from_colorspace = ROLE_SCENE_LINEAR;
41
42 /* Apply scale. */
43 MatrixTransformRcPtr mt = MatrixTransform::Create();
44 float3x3 matrix = float3x3::identity() * display_parameters.scale;
45
46 /* Apply white balance. */
47 if (display_parameters.use_white_balance) {
49 config, display_parameters.temperature, display_parameters.tint);
50 }
51
52 mt->setMatrix(double4x4(math::transpose(matrix)).base_ptr());
53 group->appendTransform(mt);
54 }
55
56 /* Add look transform. */
57 bool use_look = (display_parameters.look != nullptr && display_parameters.look[0] != '\0');
58 if (use_look) {
59 const char *look_output = nullptr;
60
61 try {
62 look_output = LookTransform::GetLooksResultColorSpace(
63 ocio_config, ocio_config->getCurrentContext(), display_parameters.look.c_str());
64 }
65 catch (Exception &exception) {
66 report_exception(exception);
67 return nullptr;
68 }
69
70 if (look_output != nullptr && look_output[0] != 0) {
71 LookTransformRcPtr lt = LookTransform::Create();
72 lt->setSrc(from_colorspace);
73 lt->setDst(look_output);
74 lt->setLooks(display_parameters.look.c_str());
75 group->appendTransform(lt);
76
77 /* Make further transforms aware of the color space change. */
78 from_colorspace = look_output;
79 }
80 else {
81 /* For empty looks, no output color space is returned. */
82 use_look = false;
83 }
84 }
85
86 /* Add view and display transform. */
87 DisplayViewTransformRcPtr dvt = DisplayViewTransform::Create();
88 dvt->setSrc(from_colorspace);
89 dvt->setLooksBypass(use_look);
90 dvt->setView(display_parameters.view.c_str());
91 dvt->setDisplay(display_parameters.display.c_str());
92 group->appendTransform(dvt);
93
94 /* Gamma. */
95 if (display_parameters.exponent != 1.0f) {
96 ExponentTransformRcPtr et = ExponentTransform::Create();
97 const double value[4] = {display_parameters.exponent,
98 display_parameters.exponent,
99 display_parameters.exponent,
100 1.0};
101 et->setValue(value);
102 group->appendTransform(et);
103 }
104
105 if (display_parameters.inverse) {
106 group->setDirection(TRANSFORM_DIR_INVERSE);
107 }
108
109 /* Create processor from transform. This is the moment were OCIO validates the entire transform,
110 * no need to check for the validity of inputs above. */
111 ConstProcessorRcPtr p;
112 try {
113 p = ocio_config->getProcessor(group);
114 }
115 catch (Exception &exception) {
116 report_exception(exception);
117 return nullptr;
118 }
119
120 return p;
121}
122
123} // namespace blender::ocio
124
125#endif
MatBase< T, NumCol, NumRow > transpose(const MatBase< T, NumRow, NumCol > &mat)
float3x3 calculate_white_point_matrix(const Config &config, const float temperature, const float tint)
MatBase< float, 3, 3 > float3x3
MatBase< double, 4, 4 > double4x4