Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <jeroen@blender.org>2022-01-10 10:57:53 +0300
committerJeroen Bakker <jeroen@blender.org>2022-01-10 10:59:00 +0300
commit6beaa297918b24de00d26886e981312b041748b0 (patch)
treec81515e9f1c9e65dbb789e56c1032624db167fca /source/blender
parenteb7333e772bd9313bf3530eb02e0d036563efe90 (diff)
Compositing Convert color space node
Compositor node to convert between color spaces. Conversion is skipped when converting between the same color spaces or to or from data spaces. Implementation done for tiled and full frame compositor. Reviewed By: Blendify, jbakker Differential Revision: https://developer.blender.org/D12481
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/intern/node.cc1
-rw-r--r--source/blender/compositor/CMakeLists.txt5
-rw-r--r--source/blender/compositor/intern/COM_Converter.cc4
-rw-r--r--source/blender/compositor/intern/COM_MemoryBuffer.cc17
-rw-r--r--source/blender/compositor/intern/COM_MemoryBuffer.h7
-rw-r--r--source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc100
-rw-r--r--source/blender/compositor/nodes/COM_ConvertColorSpaceNode.h46
-rw-r--r--source/blender/compositor/operations/COM_ConvertColorSpaceOperation.cc91
-rw-r--r--source/blender/compositor/operations/COM_ConvertColorSpaceOperation.h57
-rw-r--r--source/blender/makesdna/DNA_node_types.h5
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c86
-rw-r--r--source/blender/nodes/NOD_composite.h1
-rw-r--r--source/blender/nodes/NOD_static_types.h1
-rw-r--r--source/blender/nodes/composite/CMakeLists.txt1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc82
17 files changed, 506 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index ed1b1397219..f58094bf77e 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1318,6 +1318,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *localtree,
#define CMP_NODE_EXPOSURE 325
#define CMP_NODE_CRYPTOMATTE 326
#define CMP_NODE_POSTERIZE 327
+#define CMP_NODE_CONVERT_COLOR_SPACE 328
/* channel toggles */
#define CMP_CHAN_RGB 1
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 51fc7b99fce..c84d43b2a39 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -4582,6 +4582,7 @@ static void registerCompositNodes()
register_node_type_cmp_denoise();
register_node_type_cmp_antialiasing();
+ register_node_type_cmp_convert_color_space();
register_node_type_cmp_valtorgb();
register_node_type_cmp_rgbtobw();
register_node_type_cmp_setalpha();
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index 10e385e0187..f59fd885871 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -39,6 +39,7 @@ set(INC
../../../extern/clew/include
../../../intern/atomic
../../../intern/guardedalloc
+ ../../../intern/clog
)
set(INC_SYS
@@ -242,6 +243,8 @@ set(SRC
nodes/COM_ColorToBWNode.h
nodes/COM_ConvertAlphaNode.cc
nodes/COM_ConvertAlphaNode.h
+ nodes/COM_ConvertColorSpaceNode.cc
+ nodes/COM_ConvertColorSpaceNode.h
nodes/COM_GammaNode.cc
nodes/COM_GammaNode.h
nodes/COM_HueSaturationValueCorrectNode.cc
@@ -567,6 +570,8 @@ set(SRC
operations/COM_DotproductOperation.cc
operations/COM_DotproductOperation.h
+ operations/COM_ConvertColorSpaceOperation.cc
+ operations/COM_ConvertColorSpaceOperation.h
# Matte operation
operations/COM_BoxMaskOperation.cc
diff --git a/source/blender/compositor/intern/COM_Converter.cc b/source/blender/compositor/intern/COM_Converter.cc
index 0af4ff7d98d..1b98a04cf96 100644
--- a/source/blender/compositor/intern/COM_Converter.cc
+++ b/source/blender/compositor/intern/COM_Converter.cc
@@ -46,6 +46,7 @@
#include "COM_CombineColorNode.h"
#include "COM_CompositorNode.h"
#include "COM_ConvertAlphaNode.h"
+#include "COM_ConvertColorSpaceNode.h"
#include "COM_ConvertOperation.h"
#include "COM_Converter.h"
#include "COM_CornerPinNode.h"
@@ -426,6 +427,9 @@ Node *COM_convert_bnode(bNode *b_node)
case CMP_NODE_POSTERIZE:
node = new PosterizeNode(b_node);
break;
+ case CMP_NODE_CONVERT_COLOR_SPACE:
+ node = new ConvertColorSpaceNode(b_node);
+ break;
}
return node;
}
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cc b/source/blender/compositor/intern/COM_MemoryBuffer.cc
index ae925f796ee..dcc279e3b88 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.cc
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.cc
@@ -289,6 +289,23 @@ void MemoryBuffer::copy_from(const uchar *src,
}
}
+void MemoryBuffer::apply_processor(ColormanageProcessor &processor, const rcti area)
+{
+ const int width = BLI_rcti_size_x(&area);
+ const int height = BLI_rcti_size_y(&area);
+ float *out = get_elem(area.xmin, area.ymin);
+ /* If area allows continuous memory do conversion in one step. Otherwise per row. */
+ if (get_width() == width) {
+ IMB_colormanagement_processor_apply(&processor, out, width, height, get_num_channels(), false);
+ }
+ else {
+ for (int y = 0; y < height; y++) {
+ IMB_colormanagement_processor_apply(&processor, out, width, 1, get_num_channels(), false);
+ out += row_stride;
+ }
+ }
+}
+
static void colorspace_to_scene_linear(MemoryBuffer *buf, const rcti &area, ColorSpace *colorspace)
{
const int width = BLI_rcti_size_x(&area);
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h
index dd18a7403da..1765fb93035 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.h
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.h
@@ -26,6 +26,8 @@
#include "BLI_math_interp.h"
#include "BLI_rect.h"
+#include "IMB_colormanagement.h"
+
struct ImBuf;
namespace blender::compositor {
@@ -578,6 +580,11 @@ class MemoryBuffer {
return state_ == MemoryBufferState::Temporary;
}
+ /**
+ * \brief Apply a color processor on the given area.
+ */
+ void apply_processor(ColormanageProcessor &processor, const rcti area);
+
void copy_from(const MemoryBuffer *src, const rcti &area);
void copy_from(const MemoryBuffer *src, const rcti &area, int to_x, int to_y);
void copy_from(const MemoryBuffer *src,
diff --git a/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc b/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc
new file mode 100644
index 00000000000..4e7bbefc22d
--- /dev/null
+++ b/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc
@@ -0,0 +1,100 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2021, Blender Foundation.
+ */
+
+#include "COM_ConvertColorSpaceNode.h"
+
+#include "BKE_node.h"
+
+#include "BLI_utildefines.h"
+
+#include "COM_ConvertColorSpaceOperation.h"
+#include "COM_ConvertOperation.h"
+#include "COM_ExecutionSystem.h"
+#include "COM_ImageOperation.h"
+#include "COM_MultilayerImageOperation.h"
+
+#include "CLG_log.h"
+
+static CLG_LogRef LOG = {"compositor"};
+
+namespace blender::compositor {
+
+ConvertColorSpaceNode::ConvertColorSpaceNode(bNode *editorNode) : Node(editorNode)
+{
+ /* pass */
+}
+
+void ConvertColorSpaceNode::convert_to_operations(NodeConverter &converter,
+ const CompositorContext &UNUSED(context)) const
+{
+ bNode *b_node = get_bnode();
+
+ NodeInput *inputSocketImage = this->get_input_socket(0);
+ NodeOutput *outputSocketImage = this->get_output_socket(0);
+
+ NodeConvertColorSpace *settings = static_cast<NodeConvertColorSpace *>(b_node->storage);
+
+ if (!performs_conversion(*settings)) {
+ converter.map_output_socket(get_output_socket(0),
+ converter.add_input_proxy(get_input_socket(0), false));
+ return;
+ }
+
+ ConvertColorSpaceOperation *operation = new ConvertColorSpaceOperation();
+ operation->set_settings((NodeConvertColorSpace *)b_node->storage);
+ converter.add_operation(operation);
+
+ converter.map_input_socket(inputSocketImage, operation->get_input_socket(0));
+ converter.map_output_socket(outputSocketImage, operation->get_output_socket());
+}
+
+bool ConvertColorSpaceNode::performs_conversion(NodeConvertColorSpace &settings) const
+{
+ bNode *b_node = get_bnode();
+
+ if (IMB_colormanagement_space_name_is_data(settings.from_color_space)) {
+ CLOG_INFO(&LOG,
+ 2,
+ "Color space conversion bypassed for node: %s. From color space is data: %s.",
+ b_node->name,
+ settings.from_color_space);
+ return false;
+ }
+
+ if (IMB_colormanagement_space_name_is_data(settings.to_color_space)) {
+ CLOG_INFO(&LOG,
+ 2,
+ "Color space conversion bypassed for node: %s. To color space is data: %s.",
+ b_node->name,
+ settings.to_color_space);
+ return false;
+ }
+
+ if (STREQLEN(
+ settings.from_color_space, settings.to_color_space, sizeof(settings.from_color_space))) {
+ CLOG_INFO(&LOG,
+ 2,
+ "Color space conversion bypassed for node: %s. To and from are the same: %s.",
+ b_node->name,
+ settings.from_color_space);
+ return false;
+ }
+ return true;
+}
+
+} // namespace blender::compositor
diff --git a/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.h b/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.h
new file mode 100644
index 00000000000..b3460abea27
--- /dev/null
+++ b/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.h
@@ -0,0 +1,46 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2021, Blender Foundation.
+ */
+
+#pragma once
+
+#include "COM_Node.h"
+#include "COM_defines.h"
+#include "DNA_image_types.h"
+#include "DNA_node_types.h"
+
+#include "RE_engine.h"
+#include "RE_pipeline.h"
+
+namespace blender::compositor {
+
+/**
+ * \brief ImageNode
+ * \ingroup Node
+ */
+class ConvertColorSpaceNode : public Node {
+ public:
+ ConvertColorSpaceNode(bNode *editorNode);
+ void convert_to_operations(NodeConverter &converter,
+ const CompositorContext &context) const override;
+
+ private:
+ /** \brief check if the given settings changes color space. */
+ bool performs_conversion(NodeConvertColorSpace &settings) const;
+};
+
+} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_ConvertColorSpaceOperation.cc b/source/blender/compositor/operations/COM_ConvertColorSpaceOperation.cc
new file mode 100644
index 00000000000..5b1dfb4a02c
--- /dev/null
+++ b/source/blender/compositor/operations/COM_ConvertColorSpaceOperation.cc
@@ -0,0 +1,91 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2021, Blender Foundation.
+ */
+
+#include "COM_ConvertColorSpaceOperation.h"
+
+namespace blender::compositor {
+
+ConvertColorSpaceOperation::ConvertColorSpaceOperation()
+{
+ this->add_input_socket(DataType::Color);
+ this->add_output_socket(DataType::Color);
+ this->input_program_ = nullptr;
+ color_processor_ = nullptr;
+}
+
+void ConvertColorSpaceOperation::set_settings(NodeConvertColorSpace *node_color_space)
+{
+ this->settings_ = node_color_space;
+}
+
+void ConvertColorSpaceOperation::init_execution()
+{
+ if (BLI_strnlen(settings_->from_color_space, sizeof(settings_->from_color_space)) == 0 ||
+ BLI_strnlen(settings_->to_color_space, sizeof(settings_->to_color_space)) == 0) {
+ return;
+ }
+
+ int in_colorspace_index = IMB_colormanagement_colorspace_get_named_index(
+ settings_->from_color_space);
+ int out_colorspace_index = IMB_colormanagement_colorspace_get_named_index(
+ settings_->to_color_space);
+
+ if (in_colorspace_index == 0 || out_colorspace_index == 0) {
+ return;
+ }
+
+ this->input_program_ = this->get_input_socket_reader(0);
+
+ color_processor_ = IMB_colormanagement_colorspace_processor_new(settings_->from_color_space,
+ settings_->to_color_space);
+}
+
+void ConvertColorSpaceOperation::execute_pixel_sampled(float output[4],
+ float x,
+ float y,
+ PixelSampler sampler)
+{
+ this->input_program_->read_sampled(output, x, y, sampler);
+ if (color_processor_ != nullptr) {
+ IMB_colormanagement_processor_apply_pixel(color_processor_, output, 3);
+ }
+}
+
+void ConvertColorSpaceOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+ copy_v4_v4(it.out, it.in(0));
+ }
+
+ if (color_processor_ != nullptr) {
+ output->apply_processor(*color_processor_, area);
+ }
+}
+
+void ConvertColorSpaceOperation::deinit_execution()
+{
+ if (color_processor_ != nullptr) {
+ IMB_colormanagement_processor_free(color_processor_);
+ }
+ this->input_program_ = nullptr;
+ this->color_processor_ = nullptr;
+}
+
+} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_ConvertColorSpaceOperation.h b/source/blender/compositor/operations/COM_ConvertColorSpaceOperation.h
new file mode 100644
index 00000000000..c065224eadc
--- /dev/null
+++ b/source/blender/compositor/operations/COM_ConvertColorSpaceOperation.h
@@ -0,0 +1,57 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2021, Blender Foundation.
+ */
+
+#pragma once
+
+#include "COM_ConvertColorSpaceNode.h"
+#include "COM_MultiThreadedOperation.h"
+#include "IMB_colormanagement.h"
+
+namespace blender::compositor {
+
+class ConvertColorSpaceOperation : public MultiThreadedOperation {
+ private:
+ SocketReader *input_program_;
+ NodeConvertColorSpace *settings_;
+ ColormanageProcessor *color_processor_;
+
+ public:
+ ConvertColorSpaceOperation();
+
+ void set_settings(NodeConvertColorSpace *node_color_space);
+ /**
+ * The inner loop of this operation.
+ */
+ void execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) override;
+
+ /**
+ * Initialize the execution
+ */
+ void init_execution() override;
+
+ /**
+ * Deinitialize the execution
+ */
+ void deinit_execution() override;
+
+ void update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs) override;
+};
+
+} // namespace blender::compositor
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index becc2d290f7..a2b8546f623 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -923,6 +923,11 @@ typedef struct NodeColorspill {
float uspillr, uspillg, uspillb;
} NodeColorspill;
+typedef struct NodeConvertColorSpace {
+ char from_color_space[64];
+ char to_color_space[64];
+} NodeConvertColorSpace;
+
typedef struct NodeDilateErode {
char falloff;
} NodeDilateErode;
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 92e2e426262..20f77626e49 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -137,6 +137,7 @@ extern StructRNA RNA_CompositorNodeChannelMatte;
extern StructRNA RNA_CompositorNodeChromaMatte;
extern StructRNA RNA_CompositorNodeColorMatte;
extern StructRNA RNA_CompositorNodeColorSpill;
+extern StructRNA RNA_CompositorNodeConvertColorSpace;
extern StructRNA RNA_CompositorNodeCombHSVA;
extern StructRNA RNA_CompositorNodeCombRGBA;
extern StructRNA RNA_CompositorNodeCombYCCA;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 98de40ead93..d7da36295c1 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -52,6 +52,7 @@
#include "rna_internal.h"
#include "rna_internal_types.h"
+#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -4666,6 +4667,55 @@ bool rna_NodeSocketMaterial_default_value_poll(PointerRNA *UNUSED(ptr), PointerR
return ma->gp_style == NULL;
}
+static int rna_NodeConvertColorSpace_from_color_space_get(struct PointerRNA *ptr)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeConvertColorSpace *node_storage = node->storage;
+ return IMB_colormanagement_colorspace_get_named_index(node_storage->from_color_space);
+}
+
+static void rna_NodeConvertColorSpace_from_color_space_set(struct PointerRNA *ptr, int value)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeConvertColorSpace *node_storage = node->storage;
+ const char *name = IMB_colormanagement_colorspace_get_indexed_name(value);
+
+ if (name && name[0]) {
+ BLI_strncpy(node_storage->from_color_space, name, sizeof(node_storage->from_color_space));
+ }
+}
+static int rna_NodeConvertColorSpace_to_color_space_get(struct PointerRNA *ptr)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeConvertColorSpace *node_storage = node->storage;
+ return IMB_colormanagement_colorspace_get_named_index(node_storage->to_color_space);
+}
+
+static void rna_NodeConvertColorSpace_to_color_space_set(struct PointerRNA *ptr, int value)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeConvertColorSpace *node_storage = node->storage;
+ const char *name = IMB_colormanagement_colorspace_get_indexed_name(value);
+
+ if (name && name[0]) {
+ BLI_strncpy(node_storage->to_color_space, name, sizeof(node_storage->to_color_space));
+ }
+}
+
+static const EnumPropertyItem *rna_NodeConvertColorSpace_color_space_itemf(
+ bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ EnumPropertyItem *items = NULL;
+ int totitem = 0;
+
+ IMB_colormanagement_colorspace_items_add(&items, &totitem);
+ RNA_enum_item_end(&items, &totitem);
+
+ *r_free = true;
+
+ return items;
+}
+
#else
static const EnumPropertyItem prop_image_layer_items[] = {
@@ -7313,6 +7363,42 @@ static void def_cmp_distance_matte(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_cmp_convert_color_space(StructRNA *srna)
+{
+ PropertyRNA *prop;
+ RNA_def_struct_sdna_from(srna, "NodeConvertColorSpace", "storage");
+
+ static const EnumPropertyItem color_space_items[] = {
+ {0,
+ "NONE",
+ 0,
+ "None",
+ "Do not perform any color transform on load, treat colors as in scene linear space "
+ "already"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ prop = RNA_def_property(srna, "from_color_space", PROP_ENUM, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
+ RNA_def_property_enum_items(prop, color_space_items);
+ RNA_def_property_enum_funcs(prop,
+ "rna_NodeConvertColorSpace_from_color_space_get",
+ "rna_NodeConvertColorSpace_from_color_space_set",
+ "rna_NodeConvertColorSpace_color_space_itemf");
+ RNA_def_property_ui_text(prop, "From", "Color space of the input image");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "to_color_space", PROP_ENUM, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
+ RNA_def_property_enum_items(prop, color_space_items);
+ RNA_def_property_enum_funcs(prop,
+ "rna_NodeConvertColorSpace_to_color_space_get",
+ "rna_NodeConvertColorSpace_to_color_space_set",
+ "rna_NodeConvertColorSpace_color_space_itemf");
+ RNA_def_property_ui_text(prop, "To", "Color space of the output image");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+}
+
static void def_cmp_color_spill(StructRNA *srna)
{
PropertyRNA *prop;
diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h
index d243577f68d..72539f6081e 100644
--- a/source/blender/nodes/NOD_composite.h
+++ b/source/blender/nodes/NOD_composite.h
@@ -62,6 +62,7 @@ void register_node_type_cmp_alphaover(void);
void register_node_type_cmp_zcombine(void);
void register_node_type_cmp_colorbalance(void);
void register_node_type_cmp_huecorrect(void);
+void register_node_type_cmp_convert_color_space(void);
void register_node_type_cmp_normal(void);
void register_node_type_cmp_curve_vec(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 74f1531bd90..07a29677b72 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -227,6 +227,7 @@ DefNode(CompositorNode, CMP_NODE_DENOISE, def_cmp_denoise, "DENOIS
DefNode(CompositorNode, CMP_NODE_EXPOSURE, 0, "EXPOSURE", Exposure, "Exposure", "" )
DefNode(CompositorNode, CMP_NODE_ANTIALIASING, def_cmp_antialiasing, "ANTIALIASING", AntiAliasing, "Anti-Aliasing", "" )
DefNode(CompositorNode, CMP_NODE_POSTERIZE, 0, "POSTERIZE", Posterize, "Posterize", "" )
+DefNode(CompositorNode, CMP_NODE_CONVERT_COLOR_SPACE,def_cmp_convert_color_space, "CONVERT_COLORSPACE", ConvertColorSpace, "Color Space","" )
DefNode(TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" )
DefNode(TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )
diff --git a/source/blender/nodes/composite/CMakeLists.txt b/source/blender/nodes/composite/CMakeLists.txt
index 41bcaba22bf..20a7fcc9826 100644
--- a/source/blender/nodes/composite/CMakeLists.txt
+++ b/source/blender/nodes/composite/CMakeLists.txt
@@ -51,6 +51,7 @@ set(SRC
nodes/node_composite_color_spill.cc
nodes/node_composite_colorbalance.cc
nodes/node_composite_colorcorrection.cc
+ nodes/node_composite_convert_color_space.cc
nodes/node_composite_common.cc
nodes/node_composite_composite.cc
nodes/node_composite_cornerpin.cc
diff --git a/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc b/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc
new file mode 100644
index 00000000000..2aa0b74aa11
--- /dev/null
+++ b/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc
@@ -0,0 +1,82 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2021 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup cmpnodes
+ */
+
+#include "node_composite_util.hh"
+
+#include "RNA_access.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "IMB_colormanagement.h"
+
+namespace blender::nodes {
+
+static void CMP_NODE_CONVERT_COLOR_SPACE_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Color>(N_("Image")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
+ b.add_output<decl::Color>(N_("Image"));
+}
+
+} // namespace blender::nodes
+
+static void node_composit_init_convert_colorspace(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeConvertColorSpace *ncs = static_cast<NodeConvertColorSpace *>(
+ MEM_callocN(sizeof(NodeConvertColorSpace), "node colorspace"));
+ const char *first_colorspace = IMB_colormanagement_role_colorspace_name_get(
+ COLOR_ROLE_SCENE_LINEAR);
+ if (first_colorspace && first_colorspace[0]) {
+ STRNCPY(ncs->from_color_space, first_colorspace);
+ STRNCPY(ncs->to_color_space, first_colorspace);
+ }
+ else {
+ ncs->from_color_space[0] = 0;
+ ncs->to_color_space[0] = 0;
+ }
+ node->storage = ncs;
+}
+
+static void node_composit_buts_convert_colorspace(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "from_color_space", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "to_color_space", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
+}
+
+void register_node_type_cmp_convert_color_space(void)
+{
+ static bNodeType ntype;
+
+ cmp_node_type_base(
+ &ntype, CMP_NODE_CONVERT_COLOR_SPACE, "Convert Colorspace", NODE_CLASS_CONVERTER);
+ ntype.declare = blender::nodes::CMP_NODE_CONVERT_COLOR_SPACE_declare;
+ ntype.draw_buttons = node_composit_buts_convert_colorspace;
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ node_type_init(&ntype, node_composit_init_convert_colorspace);
+ node_type_storage(
+ &ntype, "NodeConvertColorSpace", node_free_standard_storage, node_copy_standard_storage);
+
+ nodeRegisterType(&ntype);
+}