Blender V4.3
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
9#include "BLI_string.h"
10
11#include "UI_interface.hh"
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 .compositor_domain_priority(0);
33 b.add_output<decl::Color>("Image");
34}
35
37{
38 NodeConvertColorSpace *ncs = static_cast<NodeConvertColorSpace *>(
39 MEM_callocN(sizeof(NodeConvertColorSpace), "node colorspace"));
40 const char *first_colorspace = IMB_colormanagement_role_colorspace_name_get(
42 if (first_colorspace && first_colorspace[0]) {
43 STRNCPY(ncs->from_color_space, first_colorspace);
44 STRNCPY(ncs->to_color_space, first_colorspace);
45 }
46 else {
47 ncs->from_color_space[0] = 0;
48 ncs->to_color_space[0] = 0;
49 }
50 node->storage = ncs;
51}
52
54 bContext * /*C*/,
56{
57#ifndef WITH_OCIO
58 uiItemL(layout, RPT_("Disabled, built without OpenColorIO"), ICON_ERROR);
59#endif
60
61 uiItemR(layout, ptr, "from_color_space", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
62 uiItemR(layout, ptr, "to_color_space", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
63}
64
65using namespace blender::realtime_compositor;
66
68 public:
70
71 void execute() override
72 {
73 Result &input_image = get_input("Image");
74 Result &output_image = get_result("Image");
75 if (is_identity()) {
76 input_image.pass_through(output_image);
77 return;
78 }
79
80 if (input_image.is_single_value()) {
82 return;
83 }
84
85 const char *source = node_storage(bnode()).from_color_space;
86 const char *target = node_storage(bnode()).to_color_space;
87
90 context(), source, target);
91
92 GPUShader *shader = ocio_shader.bind_shader_and_resources();
93
94 /* A null shader indicates that the conversion shader is just a stub implementation since OCIO
95 * is disabled at compile time, so pass the input through in that case. */
96 if (!shader) {
97 input_image.pass_through(output_image);
98 return;
99 }
100
101 input_image.bind_as_texture(shader, ocio_shader.input_sampler_name());
102
103 const Domain domain = compute_domain();
104 output_image.allocate_texture(domain);
105 output_image.bind_as_image(shader, ocio_shader.output_image_name());
106
107 compute_dispatch_threads_at_least(shader, domain.size);
108
109 input_image.unbind_as_texture();
110 output_image.unbind_as_image();
111 ocio_shader.unbind_shader_and_resources();
112 }
113
115 {
116 const char *source = node_storage(bnode()).from_color_space;
117 const char *target = node_storage(bnode()).to_color_space;
119 target);
120
121 Result &input_image = get_input("Image");
122 float4 color = input_image.get_color_value();
123
124 IMB_colormanagement_processor_apply_pixel(color_processor, color, 3);
125 IMB_colormanagement_processor_free(color_processor);
126
127 Result &output_image = get_result("Image");
128 output_image.allocate_single_value();
129 output_image.set_color_value(color);
130 }
131
133 {
134 const char *source = node_storage(bnode()).from_color_space;
135 const char *target = node_storage(bnode()).to_color_space;
136
137 if (STREQ(source, target)) {
138 return true;
139 }
140
141 /* Data color spaces ignore any color transformation that gets applied to them. */
143 return true;
144 }
145
146 return false;
147 }
148};
149
151{
152 return new ConvertColorSpaceOperation(context, node);
153}
154
155} // namespace blender::nodes::node_composite_convert_color_space_cc
156
158{
160 static blender::bke::bNodeType ntype;
161
163 &ntype, CMP_NODE_CONVERT_COLOR_SPACE, "Convert Colorspace", NODE_CLASS_CONVERTER);
164 ntype.declare = file_ns::CMP_NODE_CONVERT_COLOR_SPACE_declare;
165 ntype.draw_buttons = file_ns::node_composit_buts_convert_colorspace;
167 ntype.initfunc = file_ns::node_composit_init_convert_colorspace;
169 &ntype, "NodeConvertColorSpace", node_free_standard_storage, node_copy_standard_storage);
170 ntype.get_compositor_operation = file_ns::get_compositor_operation;
171
173}
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:410
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1799
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#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)
const char * IMB_colormanagement_role_colorspace_name_get(int role)
@ COLOR_ROLE_SCENE_LINEAR
void IMB_colormanagement_processor_free(ColormanageProcessor *cm_processor)
void IMB_colormanagement_processor_apply_pixel(ColormanageProcessor *cm_processor, float *pixel, int channels)
void uiItemL(uiLayout *layout, const char *name, int icon)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
struct GPUShader GPUShader
NodeOperation(Context &context, DNode node)
OCIOColorSpaceConversionShader & get(Context &context, std::string source, std::string target)
Result & get_input(StringRef identifier) const
Definition operation.cc:144
Result & get_result(StringRef identifier)
Definition operation.cc:46
void bind_as_image(GPUShader *shader, const char *image_name, bool read=false) const
Definition result.cc:264
void pass_through(Result &target)
Definition result.cc:289
void allocate_texture(Domain domain, bool from_pool=true)
Definition result.cc:204
void set_color_value(const float4 &value)
Definition result.cc:507
void bind_as_texture(GPUShader *shader, const char *texture_name) const
Definition result.cc:253
OCIOColorSpaceConversionShaderContainer ocio_color_space_conversion_shaders
local_group_size(16, 16) .push_constant(Type b
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void node_type_size_preset(bNodeType *ntype, eNodeSizePreset size)
Definition node.cc:4614
void node_type_storage(bNodeType *ntype, const char *storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
Definition node.cc:4632
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
static NodeOperation * get_compositor_operation(Context &context, DNode node)
static void node_composit_buts_convert_colorspace(uiLayout *layout, bContext *, PointerRNA *ptr)
void compute_dispatch_threads_at_least(GPUShader *shader, int2 threads_range, int2 local_size=int2(16))
Definition utilities.cc:131
void register_node_type_cmp_convert_color_space()
void cmp_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
void node_free_standard_storage(bNode *node)
Definition node_util.cc:46
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:58
Defines a node type.
Definition BKE_node.hh:218
NodeGetCompositorOperationFunction get_compositor_operation
Definition BKE_node.hh:324
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:267
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:238
NodeDeclareFunction declare
Definition BKE_node.hh:347
PointerRNA * ptr
Definition wm_files.cc:4126