Blender V5.0
node_composite_convert_color_space.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_string_utf8.h"
10
12#include "UI_resources.hh"
13
15
16#include "GPU_shader.hh"
17
18#include "COM_node_operation.hh"
20#include "COM_utilities.hh"
21
23
25
27
29{
30 b.add_input<decl::Color>("Image")
31 .default_value({1.0f, 1.0f, 1.0f, 1.0f})
32 .structure_type(StructureType::Dynamic);
33
34 b.add_output<decl::Color>("Image").structure_type(StructureType::Dynamic);
35}
36
38{
40 STRNCPY_UTF8(ncs->from_color_space, "scene_linear");
41 STRNCPY_UTF8(ncs->to_color_space, "scene_linear");
42 node->storage = ncs;
43}
44
46 bContext * /*C*/,
48{
49#ifndef WITH_OPENCOLORIO
50 layout->label(RPT_("Disabled, built without OpenColorIO"), ICON_ERROR);
51#endif
52
53 layout->prop(ptr, "from_color_space", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
54 layout->prop(ptr, "to_color_space", UI_ITEM_R_SPLIT_EMPTY_NAME, std::nullopt, ICON_NONE);
55}
56
57using namespace blender::compositor;
58
60 public:
62
63 void execute() override
64 {
65 const Result &input_image = this->get_input("Image");
66 if (this->is_identity()) {
67 Result &output_image = this->get_result("Image");
68 output_image.share_data(input_image);
69 return;
70 }
71
72 if (input_image.is_single_value()) {
74 return;
75 }
76 if (this->context().use_gpu()) {
78 }
79 else {
81 }
82 }
83
85 {
86 const char *source = node_storage(bnode()).from_color_space;
87 const char *target = node_storage(bnode()).to_color_space;
88
91 context(), source, target);
92
93 gpu::Shader *shader = ocio_shader.bind_shader_and_resources();
94
95 /* A null shader indicates that the conversion shader is just a stub implementation since OCIO
96 * is disabled at compile time, so pass the input through in that case. */
97 const Result &input_image = this->get_input("Image");
98 Result &output_image = this->get_result("Image");
99 if (!shader) {
100 output_image.share_data(input_image);
101 return;
102 }
103
104 input_image.bind_as_texture(shader, ocio_shader.input_sampler_name());
105
106 const Domain domain = compute_domain();
107 output_image.allocate_texture(domain);
108 output_image.bind_as_image(shader, ocio_shader.output_image_name());
109
111
112 input_image.unbind_as_texture();
113 output_image.unbind_as_image();
114 ocio_shader.unbind_shader_and_resources();
115 }
116
118 {
119 const char *source = node_storage(bnode()).from_color_space;
120 const char *target = node_storage(bnode()).to_color_space;
122 target);
123
124 Result &input_image = get_input("Image");
125
126 const Domain domain = compute_domain();
127 Result &output_image = get_result("Image");
128 output_image.allocate_texture(domain);
129
130 parallel_for(domain.size, [&](const int2 texel) {
131 output_image.store_pixel(texel, input_image.load_pixel<float4>(texel));
132 });
133
135 static_cast<float *>(output_image.cpu_data().data()),
136 domain.size.x,
137 domain.size.y,
138 input_image.channels_count(),
139 false);
140 IMB_colormanagement_processor_free(color_processor);
141 }
142
144 {
145 const char *source = node_storage(bnode()).from_color_space;
146 const char *target = node_storage(bnode()).to_color_space;
148 target);
149
150 Result &input_image = get_input("Image");
151 float4 color = input_image.get_single_value<float4>();
152
154 IMB_colormanagement_processor_free(color_processor);
155
156 Result &output_image = get_result("Image");
157 output_image.allocate_single_value();
158 output_image.set_single_value(color);
159 }
160
162 {
163 const char *source = node_storage(bnode()).from_color_space;
164 const char *target = node_storage(bnode()).to_color_space;
165
166 if (STREQ(source, target)) {
167 return true;
168 }
169
170 /* Data color spaces ignore any color transformation that gets applied to them. */
172 return true;
173 }
174
175 return false;
176 }
177};
178
180{
181 return new ConvertColorSpaceOperation(context, node);
182}
183
184} // namespace blender::nodes::node_composite_convert_color_space_cc
185
187{
189 static blender::bke::bNodeType ntype;
190
191 cmp_node_type_base(&ntype, "CompositorNodeConvertColorSpace", CMP_NODE_CONVERT_COLOR_SPACE);
192 ntype.ui_name = "Convert Colorspace";
193 ntype.ui_description = "Convert between color spaces";
194 ntype.enum_name_legacy = "CONVERT_COLORSPACE";
196 ntype.declare = file_ns::CMP_NODE_CONVERT_COLOR_SPACE_declare;
197 ntype.draw_buttons = file_ns::node_composit_buts_convert_colorspace;
199 ntype.initfunc = file_ns::node_composit_init_convert_colorspace;
201 ntype, "NodeConvertColorSpace", node_free_standard_storage, node_copy_standard_storage);
202 ntype.get_compositor_operation = file_ns::get_compositor_operation;
204
206}
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:453
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1240
constexpr int NODE_DEFAULT_MAX_WIDTH
Definition BKE_node.hh:1250
#define CMP_NODE_CONVERT_COLOR_SPACE
#define STRNCPY_UTF8(dst, src)
#define STREQ(a, b)
#define RPT_(msgid)
ColormanageProcessor * IMB_colormanagement_colorspace_processor_new(const char *from_colorspace, const char *to_colorspace)
bool IMB_colormanagement_space_name_is_data(const char *name)
void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, float *buffer, int width, int height, int channels, bool predivide)
void IMB_colormanagement_processor_free(ColormanageProcessor *cm_processor)
void IMB_colormanagement_processor_apply_pixel(ColormanageProcessor *cm_processor, float *pixel, int channels)
#define NOD_REGISTER_NODE(REGISTER_FUNC)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
const void * data() const
NodeOperation(Context &context, DNode node)
OCIOColorSpaceConversionShader & get(Context &context, std::string source, std::string target)
Result & get_result(StringRef identifier)
Definition operation.cc:39
Result & get_input(StringRef identifier) const
Definition operation.cc:138
virtual Domain compute_domain()
Definition operation.cc:56
void share_data(const Result &source)
Definition result.cc:523
void allocate_texture(const Domain domain, const bool from_pool=true, const std::optional< ResultStorageType > storage_type=std::nullopt)
Definition result.cc:389
void unbind_as_texture() const
Definition result.cc:511
void set_single_value(const T &value)
void bind_as_texture(gpu::Shader *shader, const char *texture_name) const
Definition result.cc:487
int64_t channels_count() const
void unbind_as_image() const
Definition result.cc:517
void bind_as_image(gpu::Shader *shader, const char *image_name, bool read=false) const
Definition result.cc:498
bool is_single_value() const
Definition result.cc:758
const T & get_single_value() const
OCIOColorSpaceConversionShaderContainer ocio_color_space_conversion_shaders
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void node_type_size(bNodeType &ntype, int width, int minwidth, int maxwidth)
Definition node.cc:5384
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
Definition node.cc:5414
void node_type_size_preset(bNodeType &ntype, eNodeSizePreset size)
Definition node.cc:5396
void compute_dispatch_threads_at_least(gpu::Shader *shader, int2 threads_range, int2 local_size=int2(16))
Definition utilities.cc:196
void parallel_for(const int2 range, const Function &function)
static NodeOperation * get_compositor_operation(Context &context, DNode node)
static void node_composit_buts_convert_colorspace(uiLayout *layout, bContext *, PointerRNA *ptr)
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
static void register_node_type_cmp_convert_color_space()
void cmp_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
void node_free_standard_storage(bNode *node)
Definition node_util.cc:42
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:54
void * storage
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
NodeGetCompositorOperationFunction get_compositor_operation
Definition BKE_node.hh:348
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:289
const char * enum_name_legacy
Definition BKE_node.hh:247
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:259
NodeDeclareFunction declare
Definition BKE_node.hh:362
void label(blender::StringRef name, int icon)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
PointerRNA * ptr
Definition wm_files.cc:4238