diff options
18 files changed, 507 insertions, 0 deletions
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 142028e8d4d..cd67a41a701 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -542,6 +542,7 @@ compositor_node_categories = [ NodeItem("CompositorNodeSepYCCA"), NodeItem("CompositorNodeCombYCCA"), NodeItem("CompositorNodeSwitchView"), + NodeItem("CompositorNodeConvertColorSpace"), ]), CompositorNodeCategory("CMP_OP_FILTER", "Filter", items=[ NodeItem("CompositorNodeBlur"), 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); +} |