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:
Diffstat (limited to 'source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp')
-rw-r--r--source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp
new file mode 100644
index 00000000000..fef045481f7
--- /dev/null
+++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp
@@ -0,0 +1,134 @@
+/*
+ * 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:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ */
+
+#include "COM_ColorCorrectionOperation.h"
+#include "BLI_math.h"
+
+ColorCorrectionOperation::ColorCorrectionOperation(): NodeOperation() {
+ this->addInputSocket(COM_DT_COLOR);
+ this->addInputSocket(COM_DT_VALUE);
+ this->addOutputSocket(COM_DT_COLOR);
+ this->inputImage = NULL;
+ this->inputMask = NULL;
+ this->redChannelEnabled = true;
+ this->greenChannelEnabled = true;
+ this->blueChannelEnabled = true;
+}
+void ColorCorrectionOperation::initExecution() {
+ this->inputImage = this->getInputSocketReader(0);
+ this->inputMask = this->getInputSocketReader(1);
+}
+
+void ColorCorrectionOperation::executePixel(float* output, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) {
+ float inputImageColor[4];
+ float inputMask[4];
+ this->inputImage->read(inputImageColor, x, y, sampler, inputBuffers);
+ this->inputMask->read(inputMask, x, y, sampler, inputBuffers);
+
+ float level = (inputImageColor[0] + inputImageColor[1] + inputImageColor[2])/3.0f;
+ float contrast= this->data->master.contrast;
+ float saturation = this->data->master.saturation;
+ float gamma = this->data->master.gamma;
+ float gain = this->data->master.gain;
+ float lift = this->data->master.lift;
+ float r, g, b;
+
+ float value = inputMask[0];
+ value = min(1.0f, value);
+ const float mvalue= 1.0f - value;
+
+ float levelShadows = 0.0;
+ float levelMidtones = 0.0;
+ float levelHighlights = 0.0;
+#define MARGIN 0.10
+#define MARGIN_DIV (0.5/MARGIN)
+ if ( level < this->data->startmidtones-MARGIN) {
+ levelShadows = 1.0f;
+ } else if (level < this->data->startmidtones+MARGIN) {
+ levelMidtones = ((level-this->data->startmidtones)*MARGIN_DIV)+0.5;
+ levelShadows = 1.0- levelMidtones;
+ } else if (level < this->data->endmidtones-MARGIN) {
+ levelMidtones = 1.0f;
+ } else if (level < this->data->endmidtones+MARGIN) {
+ levelHighlights = ((level-this->data->endmidtones)*MARGIN_DIV)+0.5;
+ levelMidtones = 1.0- levelHighlights;
+ } else {
+ levelHighlights = 1.0f;
+ }
+#undef MARGIN
+#undef MARGIN_DIV
+ contrast *= (levelShadows*this->data->shadows.contrast)+(levelMidtones*this->data->midtones.contrast)+(levelHighlights*this->data->highlights.contrast);
+ saturation *= (levelShadows*this->data->shadows.saturation)+(levelMidtones*this->data->midtones.saturation)+(levelHighlights*this->data->highlights.saturation);
+ gamma *= (levelShadows*this->data->shadows.gamma)+(levelMidtones*this->data->midtones.gamma)+(levelHighlights*this->data->highlights.gamma);
+ gain *= (levelShadows*this->data->shadows.gain)+(levelMidtones*this->data->midtones.gain)+(levelHighlights*this->data->highlights.gain);
+ lift += (levelShadows*this->data->shadows.lift)+(levelMidtones*this->data->midtones.lift)+(levelHighlights*this->data->highlights.lift);
+
+ r = inputImageColor[0];
+ g = inputImageColor[1];
+ b = inputImageColor[2];
+
+ float invgamma = 1.0f/gamma;
+ float luma = 0.2126 * r + 0.7152 * g + 0.0722 * b;
+ r = ( luma + saturation * (r - luma));
+ g = ( luma + saturation * (g - luma));
+ b = ( luma + saturation * (b - luma));
+ CLAMP (r, 0.0f, 1.0f);
+ CLAMP (g, 0.0f, 1.0f);
+ CLAMP (b, 0.0f, 1.0f);
+
+ r = 0.5+((r-0.5)*contrast);
+ g = 0.5+((g-0.5)*contrast);
+ b = 0.5+((b-0.5)*contrast);
+
+ r = powf(r*gain+lift, invgamma);
+ g = powf(g*gain+lift, invgamma);
+ b = powf(b*gain+lift, invgamma);
+
+
+ // mix with mask
+ r = mvalue*inputImageColor[0] + value * r;
+ g = mvalue*inputImageColor[1] + value * g;
+ b = mvalue*inputImageColor[2] + value * b;
+
+ if (this->redChannelEnabled) {
+ output[0] = r;
+ } else {
+ output[0] = inputImageColor[0];
+ }
+ if (this->greenChannelEnabled) {
+ output[1] = g;
+ } else {
+ output[1] = inputImageColor[1];
+ }
+ if (this->blueChannelEnabled) {
+ output[2] = b;
+ } else {
+ output[2] = inputImageColor[2];
+ }
+ output[3] = inputImageColor[3];
+}
+
+void ColorCorrectionOperation::deinitExecution() {
+ this->inputImage = NULL;
+ this->inputMask = NULL;
+}
+