From 48eb27791bcd0b28b3fad384552009fa4b712d00 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Sun, 19 Aug 2012 03:05:38 +0000 Subject: The Distance Node in 2.49/2.5/2.6 pre-tiles has a different calculation for RGB and YCC. While RGB calculate the distance in 3d between R,G and B, the YCC only takes Cb and Cr into consideration. This commit makes COM_DistanceMatteOperation inheritable and expose the calculate distance function to be re-implemented for the YCC node operation. Thanks Troy Sobotka for the report over email. Patch incorporates review suggestions by Jeroen Bakker. --- source/blender/compositor/CMakeLists.txt | 6 +- .../compositor/nodes/COM_DistanceMatteNode.cpp | 33 ++++++-- .../operations/COM_DistanceMatteOperation.cpp | 90 --------------------- .../operations/COM_DistanceMatteOperation.h | 52 ------------ .../operations/COM_DistanceRGBMatteOperation.cpp | 94 ++++++++++++++++++++++ .../operations/COM_DistanceRGBMatteOperation.h | 55 +++++++++++++ .../operations/COM_DistanceYCCMatteOperation.cpp | 35 ++++++++ .../operations/COM_DistanceYCCMatteOperation.h | 43 ++++++++++ 8 files changed, 259 insertions(+), 149 deletions(-) delete mode 100644 source/blender/compositor/operations/COM_DistanceMatteOperation.cpp delete mode 100644 source/blender/compositor/operations/COM_DistanceMatteOperation.h create mode 100644 source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cpp create mode 100644 source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h create mode 100644 source/blender/compositor/operations/COM_DistanceYCCMatteOperation.cpp create mode 100644 source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h (limited to 'source/blender/compositor') diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index 65d46bf515a..c110d4f077e 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -473,8 +473,10 @@ set(SRC operations/COM_DifferenceMatteOperation.h operations/COM_LuminanceMatteOperation.cpp operations/COM_LuminanceMatteOperation.h - operations/COM_DistanceMatteOperation.cpp - operations/COM_DistanceMatteOperation.h + operations/COM_DistanceRGBMatteOperation.cpp + operations/COM_DistanceRGBMatteOperation.h + operations/COM_DistanceYCCMatteOperation.cpp + operations/COM_DistanceYCCMatteOperation.h operations/COM_ChromaMatteOperation.cpp operations/COM_ChromaMatteOperation.h operations/COM_ColorMatteOperation.cpp diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp b/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp index d6730ef6a00..87e7b9d0788 100644 --- a/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp +++ b/source/blender/compositor/nodes/COM_DistanceMatteNode.cpp @@ -21,8 +21,10 @@ #include "COM_DistanceMatteNode.h" #include "BKE_node.h" -#include "COM_DistanceMatteOperation.h" +#include "COM_DistanceRGBMatteOperation.h" +#include "COM_DistanceYCCMatteOperation.h" #include "COM_SetAlphaOperation.h" +#include "COM_ConvertRGBToYCCOperation.h" DistanceMatteNode::DistanceMatteNode(bNode *editorNode) : Node(editorNode) { @@ -36,12 +38,33 @@ void DistanceMatteNode::convertToOperations(ExecutionSystem *graph, CompositorCo OutputSocket *outputSocketImage = this->getOutputSocket(0); OutputSocket *outputSocketMatte = this->getOutputSocket(1); - DistanceMatteOperation *operation = new DistanceMatteOperation(); + NodeOperation *operation; bNode *editorsnode = getbNode(); - operation->setSettings((NodeChroma *)editorsnode->storage); + NodeChroma *storage = (NodeChroma *)editorsnode->storage; - inputSocketImage->relinkConnections(operation->getInputSocket(0), 0, graph); - inputSocketKey->relinkConnections(operation->getInputSocket(1), 1, graph); + /* work in RGB color space */ + if (storage->channel == 1) { + operation = new DistanceRGBMatteOperation(); + ((DistanceRGBMatteOperation *) operation)->setSettings(storage); + + inputSocketImage->relinkConnections(operation->getInputSocket(0), 0, graph); + inputSocketKey->relinkConnections(operation->getInputSocket(1), 1, graph); + } + /* work in YCbCr color space */ + else { + operation = new DistanceYCCMatteOperation(); + ((DistanceYCCMatteOperation *) operation)->setSettings(storage); + + ConvertRGBToYCCOperation *operationYCCImage = new ConvertRGBToYCCOperation(); + inputSocketImage->relinkConnections(operationYCCImage->getInputSocket(0), 0, graph); + addLink(graph, operationYCCImage->getOutputSocket(), operation->getInputSocket(0)); + graph->addOperation(operationYCCImage); + + ConvertRGBToYCCOperation *operationYCCMatte = new ConvertRGBToYCCOperation(); + inputSocketKey->relinkConnections(operationYCCMatte->getInputSocket(0), 1, graph); + addLink(graph, operationYCCMatte->getOutputSocket(), operation->getInputSocket(1)); + graph->addOperation(operationYCCMatte); + } if (outputSocketMatte->isConnected()) { outputSocketMatte->relinkConnections(operation->getOutputSocket()); diff --git a/source/blender/compositor/operations/COM_DistanceMatteOperation.cpp b/source/blender/compositor/operations/COM_DistanceMatteOperation.cpp deleted file mode 100644 index b65b5e0f224..00000000000 --- a/source/blender/compositor/operations/COM_DistanceMatteOperation.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2011, Blender Foundation. - * - * 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. - * - * Contributor: - * Dalai Felinto - */ - -#include "COM_DistanceMatteOperation.h" -#include "BLI_math.h" - -DistanceMatteOperation::DistanceMatteOperation() : NodeOperation() -{ - addInputSocket(COM_DT_COLOR); - addInputSocket(COM_DT_COLOR); - addOutputSocket(COM_DT_VALUE); - - this->m_inputImageProgram = NULL; - this->m_inputKeyProgram = NULL; -} - -void DistanceMatteOperation::initExecution() -{ - this->m_inputImageProgram = this->getInputSocketReader(0); - this->m_inputKeyProgram = this->getInputSocketReader(1); -} - -void DistanceMatteOperation::deinitExecution() -{ - this->m_inputImageProgram = NULL; - this->m_inputKeyProgram = NULL; -} - -void DistanceMatteOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) -{ - float inKey[4]; - float inImage[4]; - - const float tolerance = this->m_settings->t1; - const float falloff = this->m_settings->t2; - - float distance; - float alpha; - - this->m_inputKeyProgram->read(inKey, x, y, sampler); - this->m_inputImageProgram->read(inImage, x, y, sampler); - - distance = sqrt(pow((inKey[0] - inImage[0]), 2) + - pow((inKey[1] - inImage[1]), 2) + - pow((inKey[2] - inImage[2]), 2)); - - /* store matte(alpha) value in [0] to go with - * COM_SetAlphaOperation and the Value output - */ - - /*make 100% transparent */ - if (distance < tolerance) { - output[0] = 0.f; - } - /*in the falloff region, make partially transparent */ - else if (distance < falloff + tolerance) { - distance = distance - tolerance; - alpha = distance / falloff; - /*only change if more transparent than before */ - if (alpha < inImage[3]) { - output[0] = alpha; - } - else { /* leave as before */ - output[0] = inImage[3]; - } - } - else { - /* leave as before */ - output[0] = inImage[3]; - } -} - diff --git a/source/blender/compositor/operations/COM_DistanceMatteOperation.h b/source/blender/compositor/operations/COM_DistanceMatteOperation.h deleted file mode 100644 index a176e5da888..00000000000 --- a/source/blender/compositor/operations/COM_DistanceMatteOperation.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2011, Blender Foundation. - * - * 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. - * - * Contributor: - * Dalai Felinto - */ - -#ifndef _COM_DistanceMatteOperation_h -#define _COM_DistanceMatteOperation_h -#include "COM_MixBaseOperation.h" - - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class DistanceMatteOperation : public NodeOperation { -private: - NodeChroma *m_settings; - SocketReader *m_inputImageProgram; - SocketReader *m_inputKeyProgram; -public: - /** - * Default constructor - */ - DistanceMatteOperation(); - - /** - * the inner loop of this program - */ - void executePixel(float output[4], float x, float y, PixelSampler sampler); - - void initExecution(); - void deinitExecution(); - - void setSettings(NodeChroma *nodeChroma) { this->m_settings = nodeChroma; } -}; -#endif diff --git a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cpp b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cpp new file mode 100644 index 00000000000..df3809ba129 --- /dev/null +++ b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2011, Blender Foundation. + * + * 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. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_DistanceRGBMatteOperation.h" +#include "BLI_math.h" + +DistanceRGBMatteOperation::DistanceRGBMatteOperation() : NodeOperation() +{ + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_VALUE); + + this->m_inputImageProgram = NULL; + this->m_inputKeyProgram = NULL; +} + +void DistanceRGBMatteOperation::initExecution() +{ + this->m_inputImageProgram = this->getInputSocketReader(0); + this->m_inputKeyProgram = this->getInputSocketReader(1); +} + +void DistanceRGBMatteOperation::deinitExecution() +{ + this->m_inputImageProgram = NULL; + this->m_inputKeyProgram = NULL; +} + +float DistanceRGBMatteOperation::calculateDistance(float key[4], float image[4]) +{ + return sqrt(pow((key[0] - image[0]), 2) + + pow((key[1] - image[1]), 2) + + pow((key[2] - image[2]), 2)); +} + +void DistanceRGBMatteOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +{ + float inKey[4]; + float inImage[4]; + + const float tolerance = this->m_settings->t1; + const float falloff = this->m_settings->t2; + + float distance; + float alpha; + + this->m_inputKeyProgram->read(inKey, x, y, sampler); + this->m_inputImageProgram->read(inImage, x, y, sampler); + + distance = this->calculateDistance(inKey, inImage); + + /* store matte(alpha) value in [0] to go with + * COM_SetAlphaOperation and the Value output + */ + + /*make 100% transparent */ + if (distance < tolerance) { + output[0] = 0.f; + } + /*in the falloff region, make partially transparent */ + else if (distance < falloff + tolerance) { + distance = distance - tolerance; + alpha = distance / falloff; + /*only change if more transparent than before */ + if (alpha < inImage[3]) { + output[0] = alpha; + } + else { /* leave as before */ + output[0] = inImage[3]; + } + } + else { + /* leave as before */ + output[0] = inImage[3]; + } +} diff --git a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h new file mode 100644 index 00000000000..5a34135b1a4 --- /dev/null +++ b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h @@ -0,0 +1,55 @@ +/* + * Copyright 2011, Blender Foundation. + * + * 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. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_DistanceRGBMatteOperation_h +#define _COM_DistanceRGBMatteOperation_h +#include "COM_MixBaseOperation.h" + + +/** + * this program converts an input color to an output value. + * it assumes we are in sRGB color space. + */ +class DistanceRGBMatteOperation : public NodeOperation { +protected: + NodeChroma *m_settings; + SocketReader *m_inputImageProgram; + SocketReader *m_inputKeyProgram; + + virtual float calculateDistance(float key[4], float image[4]); + +public: + /** + * Default constructor + */ + DistanceRGBMatteOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float output[4], float x, float y, PixelSampler sampler); + + void initExecution(); + void deinitExecution(); + + void setSettings(NodeChroma *nodeChroma) { this->m_settings = nodeChroma; } +}; +#endif diff --git a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.cpp b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.cpp new file mode 100644 index 00000000000..32ed7486f5b --- /dev/null +++ b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.cpp @@ -0,0 +1,35 @@ +/* + * Copyright 2011, Blender Foundation. + * + * 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. + * + * Contributor: + * Dalai Felinto + */ + +#include "COM_DistanceYCCMatteOperation.h" +#include "BLI_math.h" + +DistanceYCCMatteOperation::DistanceYCCMatteOperation() : DistanceRGBMatteOperation() +{ + /* pass */ +} + +float DistanceYCCMatteOperation::calculateDistance(float key[4], float image[4]) +{ + return sqrt(pow((key[1] - image[1]), 2) + + pow((key[2] - image[2]), 2)); +} + diff --git a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h new file mode 100644 index 00000000000..f4866a327f1 --- /dev/null +++ b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h @@ -0,0 +1,43 @@ +/* + * Copyright 2011, Blender Foundation. + * + * 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. + * + * Contributor: + * Dalai Felinto + */ + +#ifndef _COM_DistanceYCCMatteOperation_h +#define _COM_DistanceYCCMatteOperation_h +#include "COM_MixBaseOperation.h" +#include "COM_DistanceRGBMatteOperation.h" + + +/** + * this program converts an input color to an output value. + * it assumes we are in sRGB color space. + */ +class DistanceYCCMatteOperation : public DistanceRGBMatteOperation { +protected: + virtual float calculateDistance(float key[4], float image[4]); + +public: + /** + * Default constructor + */ + DistanceYCCMatteOperation(); + +}; +#endif -- cgit v1.2.3