diff options
-rw-r--r-- | source/blender/blenkernel/BKE_colortools.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/colortools.c | 55 | ||||
-rw-r--r-- | source/blender/compositor/operations/COM_ColorCurveOperation.cpp | 19 |
3 files changed, 59 insertions, 18 deletions
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h index dcb40c960b1..90358ba9609 100644 --- a/source/blender/blenkernel/BKE_colortools.h +++ b/source/blender/blenkernel/BKE_colortools.h @@ -53,6 +53,7 @@ void curvemapping_free_data(struct CurveMapping *cumap); void curvemapping_free(struct CurveMapping *cumap); void curvemapping_copy_data(struct CurveMapping *target, struct CurveMapping *cumap); struct CurveMapping *curvemapping_copy(struct CurveMapping *cumap); +void curvemapping_set_black_white_ex(const float black[3], const float white[3], float r_bwmul[3]); void curvemapping_set_black_white(struct CurveMapping *cumap, const float black[3], const float white[3]); #define CURVEMAP_SLOPE_NEGATIVE 0 @@ -73,6 +74,8 @@ float curvemapping_evaluateF(struct CurveMapping *cumap, int cur, void curvemapping_evaluate3F(struct CurveMapping *cumap, float vecout[3], const float vecin[3]); void curvemapping_evaluateRGBF(struct CurveMapping *cumap, float vecout[3], const float vecin[3]); void curvemapping_evaluate_premulRGB(struct CurveMapping *cumap, unsigned char vecout_byte[3], const unsigned char vecin_byte[3]); +void curvemapping_evaluate_premulRGBF_ex(struct CurveMapping *cumap, float vecout[3], const float vecin[3], + const float black[3], const float bwmul[3]); void curvemapping_evaluate_premulRGBF(struct CurveMapping *cumap, float vecout[3], const float vecin[3]); void curvemapping_do_ibuf(struct CurveMapping *cumap, struct ImBuf *ibuf); void curvemapping_premultiply(struct CurveMapping *cumap, int restore); diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 118169e8f7d..606fd83b1a5 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -145,21 +145,31 @@ CurveMapping *curvemapping_copy(CurveMapping *cumap) return NULL; } -void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], const float white[3]) +void curvemapping_set_black_white_ex(const float black[3], const float white[3], float r_bwmul[3]) { int a; - - if (white) + + for (a = 0; a < 3; a++) { + const float delta = white[a] - black[a]; + if (delta != 0.0f) { + r_bwmul[a] = 1.0f / delta; + } + else { + r_bwmul[a] = 0.0f; + } + } +} + +void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], const float white[3]) +{ + if (white) { copy_v3_v3(cumap->white, white); - if (black) + } + if (black) { copy_v3_v3(cumap->black, black); - - for (a = 0; a < 3; a++) { - if (cumap->white[a] == cumap->black[a]) - cumap->bwmul[a] = 0.0f; - else - cumap->bwmul[a] = 1.0f / (cumap->white[a] - cumap->black[a]); - } + } + + curvemapping_set_black_white_ex(cumap->black, cumap->white, cumap->bwmul); } /* ***************** operations on single curve ************* */ @@ -785,6 +795,29 @@ void curvemapping_evaluateRGBF(CurveMapping *cumap, float vecout[3], const float vecout[2] = curvemapping_evaluateF(cumap, 2, curvemapping_evaluateF(cumap, 3, vecin[2])); } +/** same as #curvemapping_evaluate_premulRGBF + * but black/bwmul are passed as args for the compositor + * where they can change per pixel. + * + * Use in conjunction with #curvemapping_set_black_white_ex + * + * \param black Use instead of cumap->black + * \param bwmul Use instead of cumap->bwmul + */ +void curvemapping_evaluate_premulRGBF_ex(CurveMapping *cumap, float vecout[3], const float vecin[3], + const float black[3], const float bwmul[3]) +{ + float fac; + + fac = (vecin[0] - black[0]) * bwmul[0]; + vecout[0] = curvemap_evaluateF(cumap->cm, fac); + + fac = (vecin[1] - black[1]) * bwmul[1]; + vecout[1] = curvemap_evaluateF(cumap->cm + 1, fac); + + fac = (vecin[2] - black[2]) * bwmul[2]; + vecout[2] = curvemap_evaluateF(cumap->cm + 2, fac); +} /* RGB with black/white points and premult. tables are checked */ void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float vecout[3], const float vecin[3]) diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.cpp b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp index ff2cf96d0ad..81205514040 100644 --- a/source/blender/compositor/operations/COM_ColorCurveOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp @@ -61,34 +61,39 @@ void ColorCurveOperation::initExecution() void ColorCurveOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) { CurveMapping *cumap = this->m_curveMapping; - CurveMapping *workingCopy = (CurveMapping *)MEM_dupallocN(cumap); - float black[4]; - float white[4]; float fac[4]; float image[4]; + /* local versions of cumap->black, cumap->white, cumap->bwmul */ + float black[4]; + float white[4]; + float bwmul[3]; + this->m_inputBlackProgram->read(black, x, y, sampler); this->m_inputWhiteProgram->read(white, x, y, sampler); - curvemapping_set_black_white(workingCopy, black, white); + /* get our own local bwmul value, + * since we can't be threadsafe and use cumap->bwmul & friends */ + curvemapping_set_black_white_ex(black, white, bwmul); this->m_inputFacProgram->read(fac, x, y, sampler); this->m_inputImageProgram->read(image, x, y, sampler); if (*fac >= 1.0f) { - curvemapping_evaluate_premulRGBF(workingCopy, output, image); + curvemapping_evaluate_premulRGBF_ex(cumap, output, image, + black, bwmul); } else if (*fac <= 0.0f) { copy_v3_v3(output, image); } else { float col[4]; - curvemapping_evaluate_premulRGBF(workingCopy, col, image); + curvemapping_evaluate_premulRGBF_ex(cumap, col, image, + black, bwmul); interp_v3_v3v3(output, image, col, *fac); } output[3] = image[3]; - MEM_freeN(workingCopy); } void ColorCurveOperation::deinitExecution() |