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_MixOperation.cc')
-rw-r--r--source/blender/compositor/operations/COM_MixOperation.cc555
1 files changed, 555 insertions, 0 deletions
diff --git a/source/blender/compositor/operations/COM_MixOperation.cc b/source/blender/compositor/operations/COM_MixOperation.cc
index 58fa09fa2a8..77ecbf60356 100644
--- a/source/blender/compositor/operations/COM_MixOperation.cc
+++ b/source/blender/compositor/operations/COM_MixOperation.cc
@@ -35,6 +35,7 @@ MixBaseOperation::MixBaseOperation()
this->m_inputColor2Operation = nullptr;
this->setUseValueAlphaMultiply(false);
this->setUseClamp(false);
+ flags.can_be_constant = true;
}
void MixBaseOperation::initExecution()
@@ -97,6 +98,45 @@ void MixBaseOperation::deinitExecution()
this->m_inputColor2Operation = nullptr;
}
+void MixBaseOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ const MemoryBuffer *input_value = inputs[0];
+ const MemoryBuffer *input_color1 = inputs[1];
+ const MemoryBuffer *input_color2 = inputs[2];
+ const int width = BLI_rcti_size_x(&area);
+ PixelCursor p;
+ p.out_stride = output->elem_stride;
+ p.value_stride = input_value->elem_stride;
+ p.color1_stride = input_color1->elem_stride;
+ p.color2_stride = input_color2->elem_stride;
+ for (const int y : YRange(area)) {
+ p.out = output->get_elem(area.xmin, y);
+ p.row_end = p.out + width * output->elem_stride;
+ p.value = input_value->get_elem(area.xmin, y);
+ p.color1 = input_color1->get_elem(area.xmin, y);
+ p.color2 = input_color2->get_elem(area.xmin, y);
+ update_memory_buffer_row(p);
+ }
+}
+
+void MixBaseOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ const float value_m = 1.0f - value;
+ p.out[0] = value_m * p.color1[0] + value * p.color2[0];
+ p.out[1] = value_m * p.color1[1] + value * p.color2[1];
+ p.out[2] = value_m * p.color1[2] + value * p.color2[2];
+ p.out[3] = p.color1[3];
+ p.next();
+ }
+}
+
/* ******** Mix Add Operation ******** */
void MixAddOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
@@ -121,6 +161,23 @@ void MixAddOperation::executePixelSampled(float output[4], float x, float y, Pix
clampIfNeeded(output);
}
+void MixAddOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ p.out[0] = p.color1[0] + value * p.color2[0];
+ p.out[1] = p.color1[1] + value * p.color2[1];
+ p.out[2] = p.color1[2] + value * p.color2[2];
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Blend Operation ******** */
void MixBlendOperation::executePixelSampled(float output[4],
@@ -150,6 +207,24 @@ void MixBlendOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixBlendOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ float value_m = 1.0f - value;
+ p.out[0] = value_m * p.color1[0] + value * p.color2[0];
+ p.out[1] = value_m * p.color1[1] + value * p.color2[1];
+ p.out[2] = value_m * p.color1[2] + value * p.color2[2];
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Burn Operation ******** */
void MixColorBurnOperation::executePixelSampled(float output[4],
@@ -228,6 +303,48 @@ void MixColorBurnOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixColorBurnOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ const float value_m = 1.0f - value;
+
+ float tmp = value_m + value * p.color2[0];
+ if (tmp <= 0.0f) {
+ p.out[0] = 0.0f;
+ }
+ else {
+ tmp = 1.0f - (1.0f - p.color1[0]) / tmp;
+ p.out[0] = CLAMPIS(tmp, 0.0f, 1.0f);
+ }
+
+ tmp = value_m + value * p.color2[1];
+ if (tmp <= 0.0f) {
+ p.out[1] = 0.0f;
+ }
+ else {
+ tmp = 1.0f - (1.0f - p.color1[1]) / tmp;
+ p.out[1] = CLAMPIS(tmp, 0.0f, 1.0f);
+ }
+
+ tmp = value_m + value * p.color2[2];
+ if (tmp <= 0.0f) {
+ p.out[2] = 0.0f;
+ }
+ else {
+ tmp = 1.0f - (1.0f - p.color1[2]) / tmp;
+ p.out[2] = CLAMPIS(tmp, 0.0f, 1.0f);
+ }
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Color Operation ******** */
void MixColorOperation::executePixelSampled(float output[4],
@@ -268,6 +385,36 @@ void MixColorOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixColorOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ const float value_m = 1.0f - value;
+
+ float colH, colS, colV;
+ rgb_to_hsv(p.color2[0], p.color2[1], p.color2[2], &colH, &colS, &colV);
+ if (colS != 0.0f) {
+ float rH, rS, rV;
+ float tmpr, tmpg, tmpb;
+ rgb_to_hsv(p.color1[0], p.color1[1], p.color1[2], &rH, &rS, &rV);
+ hsv_to_rgb(colH, colS, rV, &tmpr, &tmpg, &tmpb);
+ p.out[0] = (value_m * p.color1[0]) + (value * tmpr);
+ p.out[1] = (value_m * p.color1[1]) + (value * tmpg);
+ p.out[2] = (value_m * p.color1[2]) + (value * tmpb);
+ }
+ else {
+ copy_v3_v3(p.out, p.color1);
+ }
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Darken Operation ******** */
void MixDarkenOperation::executePixelSampled(float output[4],
@@ -296,6 +443,24 @@ void MixDarkenOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixDarkenOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ float value_m = 1.0f - value;
+ p.out[0] = min_ff(p.color1[0], p.color2[0]) * value + p.color1[0] * value_m;
+ p.out[1] = min_ff(p.color1[1], p.color2[1]) * value + p.color1[1] * value_m;
+ p.out[2] = min_ff(p.color1[2], p.color2[2]) * value + p.color1[2] * value_m;
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Difference Operation ******** */
void MixDifferenceOperation::executePixelSampled(float output[4],
@@ -324,6 +489,24 @@ void MixDifferenceOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixDifferenceOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ const float value_m = 1.0f - value;
+ p.out[0] = value_m * p.color1[0] + value * fabsf(p.color1[0] - p.color2[0]);
+ p.out[1] = value_m * p.color1[1] + value * fabsf(p.color1[1] - p.color2[1]);
+ p.out[2] = value_m * p.color1[2] + value * fabsf(p.color1[2] - p.color2[2]);
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Difference Operation ******** */
void MixDivideOperation::executePixelSampled(float output[4],
@@ -369,6 +552,41 @@ void MixDivideOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixDivideOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ const float value_m = 1.0f - value;
+
+ if (p.color2[0] != 0.0f) {
+ p.out[0] = value_m * (p.color1[0]) + value * (p.color1[0]) / p.color2[0];
+ }
+ else {
+ p.out[0] = 0.0f;
+ }
+ if (p.color2[1] != 0.0f) {
+ p.out[1] = value_m * (p.color1[1]) + value * (p.color1[1]) / p.color2[1];
+ }
+ else {
+ p.out[1] = 0.0f;
+ }
+ if (p.color2[2] != 0.0f) {
+ p.out[2] = value_m * (p.color1[2]) + value * (p.color1[2]) / p.color2[2];
+ }
+ else {
+ p.out[2] = 0.0f;
+ }
+
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Dodge Operation ******** */
void MixDodgeOperation::executePixelSampled(float output[4],
@@ -452,6 +670,64 @@ void MixDodgeOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixDodgeOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+
+ float tmp;
+ if (p.color1[0] != 0.0f) {
+ tmp = 1.0f - value * p.color2[0];
+ if (tmp <= 0.0f) {
+ p.out[0] = 1.0f;
+ }
+ else {
+ p.out[0] = p.color1[0] / tmp;
+ CLAMP_MAX(p.out[0], 1.0f);
+ }
+ }
+ else {
+ p.out[0] = 0.0f;
+ }
+
+ if (p.color1[1] != 0.0f) {
+ tmp = 1.0f - value * p.color2[1];
+ if (tmp <= 0.0f) {
+ p.out[1] = 1.0f;
+ }
+ else {
+ p.out[1] = p.color1[1] / tmp;
+ CLAMP_MAX(p.out[1], 1.0f);
+ }
+ }
+ else {
+ p.out[1] = 0.0f;
+ }
+
+ if (p.color1[2] != 0.0f) {
+ tmp = 1.0f - value * p.color2[2];
+ if (tmp <= 0.0f) {
+ p.out[2] = 1.0f;
+ }
+ else {
+ p.out[2] = p.color1[2] / tmp;
+ CLAMP_MAX(p.out[2], 1.0f);
+ }
+ }
+ else {
+ p.out[2] = 0.0f;
+ }
+
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Glare Operation ******** */
void MixGlareOperation::executePixelSampled(float output[4],
@@ -487,6 +763,33 @@ void MixGlareOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixGlareOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ const float value = p.value[0];
+ /* Linear interpolation between 3 cases:
+ * value=-1:output=input value=0:output=input+glare value=1:output=glare
+ */
+ float input_weight;
+ float glare_weight;
+ if (value < 0.0f) {
+ input_weight = 1.0f;
+ glare_weight = 1.0f + value;
+ }
+ else {
+ input_weight = 1.0f - value;
+ glare_weight = 1.0f;
+ }
+ p.out[0] = input_weight * MAX2(p.color1[0], 0.0f) + glare_weight * p.color2[0];
+ p.out[1] = input_weight * MAX2(p.color1[1], 0.0f) + glare_weight * p.color2[1];
+ p.out[2] = input_weight * MAX2(p.color1[2], 0.0f) + glare_weight * p.color2[2];
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Hue Operation ******** */
void MixHueOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
@@ -524,6 +827,36 @@ void MixHueOperation::executePixelSampled(float output[4], float x, float y, Pix
clampIfNeeded(output);
}
+void MixHueOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ const float value_m = 1.0f - value;
+
+ float colH, colS, colV;
+ rgb_to_hsv(p.color2[0], p.color2[1], p.color2[2], &colH, &colS, &colV);
+ if (colS != 0.0f) {
+ float rH, rS, rV;
+ float tmpr, tmpg, tmpb;
+ rgb_to_hsv(p.color1[0], p.color1[1], p.color1[2], &rH, &rS, &rV);
+ hsv_to_rgb(colH, rS, rV, &tmpr, &tmpg, &tmpb);
+ p.out[0] = value_m * p.color1[0] + value * tmpr;
+ p.out[1] = value_m * p.color1[1] + value * tmpg;
+ p.out[2] = value_m * p.color1[2] + value * tmpb;
+ }
+ else {
+ copy_v3_v3(p.out, p.color1);
+ }
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Lighten Operation ******** */
void MixLightenOperation::executePixelSampled(float output[4],
@@ -570,6 +903,30 @@ void MixLightenOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixLightenOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+
+ float tmp = value * p.color2[0];
+ p.out[0] = MAX2(tmp, p.color1[0]);
+
+ tmp = value * p.color2[1];
+ p.out[1] = MAX2(tmp, p.color1[1]);
+
+ tmp = value * p.color2[2];
+ p.out[2] = MAX2(tmp, p.color1[2]);
+
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Linear Light Operation ******** */
void MixLinearLightOperation::executePixelSampled(float output[4],
@@ -613,6 +970,39 @@ void MixLinearLightOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixLinearLightOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ if (p.color2[0] > 0.5f) {
+ p.out[0] = p.color1[0] + value * (2.0f * (p.color2[0] - 0.5f));
+ }
+ else {
+ p.out[0] = p.color1[0] + value * (2.0f * (p.color2[0]) - 1.0f);
+ }
+ if (p.color2[1] > 0.5f) {
+ p.out[1] = p.color1[1] + value * (2.0f * (p.color2[1] - 0.5f));
+ }
+ else {
+ p.out[1] = p.color1[1] + value * (2.0f * (p.color2[1]) - 1.0f);
+ }
+ if (p.color2[2] > 0.5f) {
+ p.out[2] = p.color1[2] + value * (2.0f * (p.color2[2] - 0.5f));
+ }
+ else {
+ p.out[2] = p.color1[2] + value * (2.0f * (p.color2[2]) - 1.0f);
+ }
+
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Multiply Operation ******** */
void MixMultiplyOperation::executePixelSampled(float output[4],
@@ -641,6 +1031,25 @@ void MixMultiplyOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixMultiplyOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ const float value_m = 1.0f - value;
+ p.out[0] = p.color1[0] * (value_m + value * p.color2[0]);
+ p.out[1] = p.color1[1] * (value_m + value * p.color2[1]);
+ p.out[2] = p.color1[2] * (value_m + value * p.color2[2]);
+
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Overlay Operation ******** */
void MixOverlayOperation::executePixelSampled(float output[4],
@@ -686,6 +1095,40 @@ void MixOverlayOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixOverlayOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ const float value_m = 1.0f - value;
+ if (p.color1[0] < 0.5f) {
+ p.out[0] = p.color1[0] * (value_m + 2.0f * value * p.color2[0]);
+ }
+ else {
+ p.out[0] = 1.0f - (value_m + 2.0f * value * (1.0f - p.color2[0])) * (1.0f - p.color1[0]);
+ }
+ if (p.color1[1] < 0.5f) {
+ p.out[1] = p.color1[1] * (value_m + 2.0f * value * p.color2[1]);
+ }
+ else {
+ p.out[1] = 1.0f - (value_m + 2.0f * value * (1.0f - p.color2[1])) * (1.0f - p.color1[1]);
+ }
+ if (p.color1[2] < 0.5f) {
+ p.out[2] = p.color1[2] * (value_m + 2.0f * value * p.color2[2]);
+ }
+ else {
+ p.out[2] = 1.0f - (value_m + 2.0f * value * (1.0f - p.color2[2])) * (1.0f - p.color1[2]);
+ }
+
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Saturation Operation ******** */
void MixSaturationOperation::executePixelSampled(float output[4],
@@ -723,6 +1166,33 @@ void MixSaturationOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixSaturationOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ const float value_m = 1.0f - value;
+
+ float rH, rS, rV;
+ rgb_to_hsv(p.color1[0], p.color1[1], p.color1[2], &rH, &rS, &rV);
+ if (rS != 0.0f) {
+ float colH, colS, colV;
+ rgb_to_hsv(p.color2[0], p.color2[1], p.color2[2], &colH, &colS, &colV);
+ hsv_to_rgb(rH, (value_m * rS + value * colS), rV, &p.out[0], &p.out[1], &p.out[2]);
+ }
+ else {
+ copy_v3_v3(p.out, p.color1);
+ }
+
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Screen Operation ******** */
void MixScreenOperation::executePixelSampled(float output[4],
@@ -752,6 +1222,25 @@ void MixScreenOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixScreenOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ const float value_m = 1.0f - value;
+
+ p.out[0] = 1.0f - (value_m + value * (1.0f - p.color2[0])) * (1.0f - p.color1[0]);
+ p.out[1] = 1.0f - (value_m + value * (1.0f - p.color2[1])) * (1.0f - p.color1[1]);
+ p.out[2] = 1.0f - (value_m + value * (1.0f - p.color2[2])) * (1.0f - p.color1[2]);
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Soft Light Operation ******** */
void MixSoftLightOperation::executePixelSampled(float output[4],
@@ -793,6 +1282,34 @@ void MixSoftLightOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixSoftLightOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ const float value_m = 1.0f - value;
+ float scr, scg, scb;
+
+ /* First calculate non-fac based Screen mix. */
+ scr = 1.0f - (1.0f - p.color2[0]) * (1.0f - p.color1[0]);
+ scg = 1.0f - (1.0f - p.color2[1]) * (1.0f - p.color1[1]);
+ scb = 1.0f - (1.0f - p.color2[2]) * (1.0f - p.color1[2]);
+
+ p.out[0] = value_m * p.color1[0] +
+ value * ((1.0f - p.color1[0]) * p.color2[0] * p.color1[0] + p.color1[0] * scr);
+ p.out[1] = value_m * p.color1[1] +
+ value * ((1.0f - p.color1[1]) * p.color2[1] * p.color1[1] + p.color1[1] * scg);
+ p.out[2] = value_m * p.color1[2] +
+ value * ((1.0f - p.color1[2]) * p.color2[2] * p.color1[2] + p.color1[2] * scb);
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Subtract Operation ******** */
void MixSubtractOperation::executePixelSampled(float output[4],
@@ -820,6 +1337,23 @@ void MixSubtractOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixSubtractOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ p.out[0] = p.color1[0] - value * p.color2[0];
+ p.out[1] = p.color1[1] - value * p.color2[1];
+ p.out[2] = p.color1[2] - value * p.color2[2];
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
/* ******** Mix Value Operation ******** */
void MixValueOperation::executePixelSampled(float output[4],
@@ -851,4 +1385,25 @@ void MixValueOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
+void MixValueOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ while (p.out < p.row_end) {
+ float value = p.value[0];
+ if (this->useValueAlphaMultiply()) {
+ value *= p.color2[3];
+ }
+ float value_m = 1.0f - value;
+
+ float rH, rS, rV;
+ float colH, colS, colV;
+ rgb_to_hsv(p.color1[0], p.color1[1], p.color1[2], &rH, &rS, &rV);
+ rgb_to_hsv(p.color2[0], p.color2[1], p.color2[2], &colH, &colS, &colV);
+ hsv_to_rgb(rH, rS, (value_m * rV + value * colV), &p.out[0], &p.out[1], &p.out[2]);
+ p.out[3] = p.color1[3];
+
+ clampIfNeeded(p.out);
+ p.next();
+ }
+}
+
} // namespace blender::compositor