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.cc')
-rw-r--r--source/blender/compositor/operations/COM_ColorCorrectionOperation.cc81
1 files changed, 81 insertions, 0 deletions
diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc
index 168e9b57eb2..b50145b106d 100644
--- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc
+++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc
@@ -33,6 +33,7 @@ ColorCorrectionOperation::ColorCorrectionOperation()
this->m_redChannelEnabled = true;
this->m_greenChannelEnabled = true;
this->m_blueChannelEnabled = true;
+ flags.can_be_constant = true;
}
void ColorCorrectionOperation::initExecution()
{
@@ -157,6 +158,86 @@ void ColorCorrectionOperation::executePixelSampled(float output[4],
output[3] = inputImageColor[3];
}
+void ColorCorrectionOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ for (; p.out < p.row_end; p.next()) {
+ const float *in_color = p.ins[0];
+ const float *in_mask = p.ins[1];
+
+ const float level = (in_color[0] + in_color[1] + in_color[2]) / 3.0f;
+ float level_shadows = 0.0f;
+ float level_midtones = 0.0f;
+ float level_highlights = 0.0f;
+ constexpr float MARGIN = 0.10f;
+ constexpr float MARGIN_DIV = 0.5f / MARGIN;
+ if (level < this->m_data->startmidtones - MARGIN) {
+ level_shadows = 1.0f;
+ }
+ else if (level < this->m_data->startmidtones + MARGIN) {
+ level_midtones = ((level - this->m_data->startmidtones) * MARGIN_DIV) + 0.5f;
+ level_shadows = 1.0f - level_midtones;
+ }
+ else if (level < this->m_data->endmidtones - MARGIN) {
+ level_midtones = 1.0f;
+ }
+ else if (level < this->m_data->endmidtones + MARGIN) {
+ level_highlights = ((level - this->m_data->endmidtones) * MARGIN_DIV) + 0.5f;
+ level_midtones = 1.0f - level_highlights;
+ }
+ else {
+ level_highlights = 1.0f;
+ }
+ float contrast = this->m_data->master.contrast;
+ float saturation = this->m_data->master.saturation;
+ float gamma = this->m_data->master.gamma;
+ float gain = this->m_data->master.gain;
+ float lift = this->m_data->master.lift;
+ contrast *= level_shadows * this->m_data->shadows.contrast +
+ level_midtones * this->m_data->midtones.contrast +
+ level_highlights * this->m_data->highlights.contrast;
+ saturation *= level_shadows * this->m_data->shadows.saturation +
+ level_midtones * this->m_data->midtones.saturation +
+ level_highlights * this->m_data->highlights.saturation;
+ gamma *= level_shadows * this->m_data->shadows.gamma +
+ level_midtones * this->m_data->midtones.gamma +
+ level_highlights * this->m_data->highlights.gamma;
+ gain *= level_shadows * this->m_data->shadows.gain +
+ level_midtones * this->m_data->midtones.gain +
+ level_highlights * this->m_data->highlights.gain;
+ lift += level_shadows * this->m_data->shadows.lift +
+ level_midtones * this->m_data->midtones.lift +
+ level_highlights * this->m_data->highlights.lift;
+
+ const float inv_gamma = 1.0f / gamma;
+ const float luma = IMB_colormanagement_get_luminance(in_color);
+
+ float r = luma + saturation * (in_color[0] - luma);
+ float g = luma + saturation * (in_color[1] - luma);
+ float b = luma + saturation * (in_color[2] - luma);
+
+ r = 0.5f + (r - 0.5f) * contrast;
+ g = 0.5f + (g - 0.5f) * contrast;
+ b = 0.5f + (b - 0.5f) * contrast;
+
+ /* Check for negative values to avoid nan. */
+ r = color_correct_powf_safe(r * gain + lift, inv_gamma, r);
+ g = color_correct_powf_safe(g * gain + lift, inv_gamma, g);
+ b = color_correct_powf_safe(b * gain + lift, inv_gamma, b);
+
+ /* Mix with mask. */
+ const float value = MIN2(1.0f, in_mask[0]);
+ const float m_value = 1.0f - value;
+ r = m_value * in_color[0] + value * r;
+ g = m_value * in_color[1] + value * g;
+ b = m_value * in_color[2] + value * b;
+
+ p.out[0] = m_redChannelEnabled ? r : in_color[0];
+ p.out[1] = m_greenChannelEnabled ? g : in_color[1];
+ p.out[2] = m_blueChannelEnabled ? b : in_color[2];
+ p.out[3] = in_color[3];
+ }
+}
+
void ColorCorrectionOperation::deinitExecution()
{
this->m_inputImage = nullptr;