diff options
Diffstat (limited to 'source/blender/blenlib/intern/math_color_blend_inline.c')
-rw-r--r-- | source/blender/blenlib/intern/math_color_blend_inline.c | 860 |
1 files changed, 789 insertions, 71 deletions
diff --git a/source/blender/blenlib/intern/math_color_blend_inline.c b/source/blender/blenlib/intern/math_color_blend_inline.c index 4810fe757fa..2522fe5f6c9 100644 --- a/source/blender/blenlib/intern/math_color_blend_inline.c +++ b/source/blender/blenlib/intern/math_color_blend_inline.c @@ -30,11 +30,16 @@ #include "BLI_math_base.h" #include "BLI_math_color.h" #include "BLI_math_color_blend.h" +#include "BLI_math_vector.h" #include "BLI_utildefines.h" #ifndef __MATH_COLOR_BLEND_INLINE_C__ #define __MATH_COLOR_BLEND_INLINE_C__ +/* don't add any saturation to a completly black and white image */ +#define EPS_SATURATION 0.0005f +#define EPS_ALPHA 0.0005f + /***************************** Color Blending ******************************** * * - byte colors are assumed to be straight alpha @@ -67,10 +72,7 @@ MINLINE void blend_color_mix_byte(unsigned char dst[4], const unsigned char src1 } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4_char((char *)dst, (char *)src1); } } @@ -92,10 +94,7 @@ MINLINE void blend_color_add_byte(unsigned char dst[4], const unsigned char src1 } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4_char((char *)dst, (char *)src1); } } @@ -117,10 +116,7 @@ MINLINE void blend_color_sub_byte(unsigned char dst[4], const unsigned char src1 } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4_char((char *)dst, (char *)src1); } } @@ -143,10 +139,7 @@ MINLINE void blend_color_mul_byte(unsigned char dst[4], const unsigned char src1 } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4_char((char *)dst, (char *)src1); } } @@ -169,10 +162,7 @@ MINLINE void blend_color_lighten_byte(unsigned char dst[4], const unsigned char } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4_char((char *)dst, (char *)src1); } } @@ -195,10 +185,7 @@ MINLINE void blend_color_darken_byte(unsigned char dst[4], const unsigned char s } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4_char((char *)dst, (char *)src1); } } @@ -215,10 +202,7 @@ MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4], const unsigned c } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4_char((char *)dst, (char *)src1); } } @@ -235,11 +219,391 @@ MINLINE void blend_color_add_alpha_byte(unsigned char dst[4], const unsigned cha } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + +MINLINE void blend_color_overlay_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = (int)src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + int i = 3; + + while (i--) { + int temp; + + if (src1[i] > 127) { + temp = 255 - ((255 - 2 * (src1[i] - 127)) * (255 - src2[i]) / 255); + } + else { + temp = (2 * src1[i] * src2[i]) >> 8; + } + dst[i] = (unsigned char)min_ii((temp * fac + src1[i] * mfac) / 255, 255); + } + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + + +MINLINE void blend_color_hardlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = (int)src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + int i = 3; + + while (i--) { + int temp; + + if (src2[i] > 127) { + temp = 255 - ((255 - 2 * (src2[i] - 127)) * (255 - src1[i]) / 255); + } + else { + temp = (2 * src2[i] * src1[i]) >> 8; + } + dst[i] = (unsigned char)min_ii((temp * fac + src1[i] * mfac) / 255, 255); + } + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + + +MINLINE void blend_color_burn_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + int i = 3; + + while (i--) { + const int temp = (src2[i] == 0) ? 0 : max_ii(255 - ((255 - src1[i]) * 255) / src2[i], 0); + dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + } + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + + +MINLINE void blend_color_linearburn_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + int i = 3; + + while (i--) { + const int temp = max_ii(src1[i] + src2[i] - 255, 0); + dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + } + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + + +MINLINE void blend_color_dodge_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + int i = 3; + + while (i--) { + const int temp = (src2[i] == 255) ? 255 : min_ii((src1[i] * 255) / (255 - src2[i]), 255); + dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + } + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + +MINLINE void blend_color_screen_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + int i = 3; + + while (i--) { + const int temp = max_ii(255 - (((255 - src1[i]) * (255 - src2[i])) / 255), 0); + dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + } + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + + +MINLINE void blend_color_softlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + int i = 3; + + while (i--) { + int temp; + + if (src1[i] < 127) { + temp = ((2 * ((src2[i] / 2) + 64)) * src1[i]) / 255; + } + else { + temp = 255 - (2 * (255 - ((src2[i] / 2) + 64)) * (255 - src1[i]) / 255); + } + dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + } + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + + +MINLINE void blend_color_pinlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + int i = 3; + + while (i--) { + int temp; + + if (src2[i] > 127) { + temp = max_ii(2 * (src2[i] - 127), src1[i]); + } + else { + temp = min_ii(2 * src2[i], src1[i]); + } + dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + } + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + + +MINLINE void blend_color_linearlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + int i = 3; + + while (i--) { + int temp; + + if (src2[i] > 127) { + temp = min_ii(src1[i] + 2 * (src2[i] - 127), 255); + } + else { + temp = max_ii(src1[i] + 2 * src2[i] - 255, 0); + } + dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + } + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + + +MINLINE void blend_color_vividlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + int i = 3; + + while (i--) { + int temp; + + if (src2[i] == 255) { + temp = 255; + } + else if (src2[i] == 0) { + temp = 0; + } + else if (src2[i] > 127) { + temp = min_ii(((src1[i]) * 255) / (2 * (255 - src2[i])), 255); + } + else { + temp = max_ii(255 - ((255 - src1[i]) * 255 / (2 * src2[i])), 0); + } + dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + } + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + + + +MINLINE void blend_color_difference_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + int i = 3; + + while (i--) { + const int temp = abs(src1[i] - src2[i]); + dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + } + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + + +MINLINE void blend_color_exclusion_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + int i = 3; + + while (i--) { + const int temp = 127 - ((2 * (src1[i] - 127) * (src2[i] - 127)) / 255); + dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + } + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + +MINLINE void blend_color_color_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1); + rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &v2); + + + h1 = h2; + s1 = s2; + + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); + dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); + dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + +MINLINE void blend_color_hue_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1); + rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &v2); + + + h1 = h2; + + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); + dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); + dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } + +} + +MINLINE void blend_color_saturation_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1); + rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &v2); + + if (s1 > EPS_SATURATION) { + s1 = s2; + } + + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); + dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); + dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); + } +} + +MINLINE void blend_color_luminosity_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]) +{ + const int fac = src2[3]; + if (fac != 0) { + const int mfac = 255 - fac; + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1); + rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &v2); + + v1 = v2; + + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); + dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); + dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); + + } + else { + /* no op */ + copy_v4_v4_char((char *)dst, (char *)src1); } + } MINLINE void blend_color_interpolate_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4], float ft) @@ -257,10 +621,7 @@ MINLINE void blend_color_interpolate_byte(unsigned char dst[4], const unsigned c dst[3] = (unsigned char)divide_round_i(tmp, 255); } else { - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4_char((char *)dst, (char *)src1); } } @@ -280,10 +641,7 @@ MINLINE void blend_color_mix_float(float dst[4], const float src1[4], const floa } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4(dst, src1); } } @@ -298,10 +656,7 @@ MINLINE void blend_color_add_float(float dst[4], const float src1[4], const floa } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4(dst, src1); } } @@ -316,10 +671,7 @@ MINLINE void blend_color_sub_float(float dst[4], const float src1[4], const floa } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4(dst, src1); } } @@ -337,10 +689,7 @@ MINLINE void blend_color_mul_float(float dst[4], const float src1[4], const floa } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4(dst, src1); } } @@ -360,10 +709,7 @@ MINLINE void blend_color_lighten_float(float dst[4], const float src1[4], const } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4(dst, src1); } } @@ -383,10 +729,7 @@ MINLINE void blend_color_darken_float(float dst[4], const float src1[4], const f } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4(dst, src1); } } @@ -397,8 +740,9 @@ MINLINE void blend_color_erase_alpha_float(float dst[4], const float src1[4], co float alpha = max_ff(src1[3] - src2[3], 0.0f); float map_alpha; - if (alpha <= 0.0005f) + if (alpha <= EPS_ALPHA) { alpha = 0.0f; + } map_alpha = alpha / src1[3]; @@ -409,10 +753,7 @@ MINLINE void blend_color_erase_alpha_float(float dst[4], const float src1[4], co } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4(dst, src1); } } @@ -423,8 +764,9 @@ MINLINE void blend_color_add_alpha_float(float dst[4], const float src1[4], cons float alpha = min_ff(src1[3] + src2[3], 1.0f); float map_alpha; - if (alpha >= 1.0f - 0.0005f) + if (alpha >= 1.0f - EPS_ALPHA) { alpha = 1.0f; + } map_alpha = (src1[3] > 0.0f) ? alpha / src1[3] : 1.0f; @@ -435,17 +777,390 @@ MINLINE void blend_color_add_alpha_float(float dst[4], const float src1[4], cons } else { /* no op */ - dst[0] = src1[0]; - dst[1] = src1[1]; - dst[2] = src1[2]; - dst[3] = src1[3]; + copy_v4_v4(dst, src1); + } +} + +MINLINE void blend_color_overlay_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + int i = 3; + + while (i--) { + float temp; + + if (src1[i] > 0.5f) { + temp = 1.0f - (1.0f - 2.0f * (src1[i] - 0.5f)) * (1.0f - src2[i]); + } + else { + temp = 2.0f * src1[i] * src2[i]; + } + dst[i] = min_ff(temp * fac + src1[i] * mfac, 1.0f); + } + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + + +MINLINE void blend_color_hardlight_float(float dst[4], const float src1[4], const float src2[2]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + int i = 3; + + while (i--) { + float temp; + + if (src2[i] > 0.5f) { + temp = 1.0f - ((1.0f - 2.0f * (src2[i] - 0.5f)) * (1.0f - src1[i])); + } + else { + temp = 2.0f * src2[i] * src1[i]; + } + dst[i] = min_ff((temp * fac + src1[i] * mfac) / 1.0f, 1.0f); + } + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + +MINLINE void blend_color_burn_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + int i = 3; + + while (i--) { + const float temp = (src2[i] == 0.0f) ? 0.0f : max_ff(1.0f - ((1.0f - src1[i]) / src2[i]), 0.0f); + dst[i] = (temp * fac + src1[i] * mfac); + } + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + +MINLINE void blend_color_linearburn_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + int i = 3; + + while (i--) { + const float temp = max_ff(src1[i] + src2[i] - 1.0f, 0.0f); + dst[i] = (temp * fac + src1[i] * mfac); + } + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + + +MINLINE void blend_color_dodge_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + int i = 3; + + while (i--) { + const float temp = (src2[i] >= 1.0f) ? 1.0f : min_ff(src1[i] / (1.0f - src2[i]), 1.0f); + dst[i] = (temp * fac + src1[i] * mfac); + } + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + +MINLINE void blend_color_screen_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + int i = 3; + + while (i--) { + const float temp = max_ff(1.0f - ((1.0f - src1[i]) * (1.0f - src2[i])), 0.0f); + dst[i] = (temp * fac + src1[i] * mfac); + } + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + +MINLINE void blend_color_softlight_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + int i = 3; + + while (i--) { + float temp; + + if (src1[i] < 0.5f) { + temp = (src2[i] + 0.5f) * src1[i]; + } + else { + temp = 1.0f - ((1.0f - (src2[i] + 0.5f)) * (1.0f - src1[i])); + } + dst[i] = (temp * fac + src1[i] * mfac); + } + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + +MINLINE void blend_color_pinlight_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + int i = 3; + + while (i--) { + float temp; + + if (src2[i] > 0.5f) { + temp = max_ff(2.0f * (src2[i] - 0.5f), src1[i]); + } + else { + temp = min_ff(2.0f * src2[i], src1[i]); + } + dst[i] = (temp * fac + src1[i] * mfac); + } + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + + +MINLINE void blend_color_linearlight_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + int i = 3; + + while (i--) { + float temp; + + if (src2[i] > 0.5f) { + temp = min_ff(src1[i] + 2.0f * (src2[i] - 0.5f), 1.0f); + } + else { + temp = max_ff(src1[i] + 2.0f * src2[i] - 1.0f, 0.0f); + } + dst[i] = (temp * fac + src1[i] * mfac); + } + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + + +MINLINE void blend_color_vividlight_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + int i = 3; + + while (i--) { + float temp; + + if (src2[i] == 1.0f) { + temp = 1.0f; + } + else if (src2[i] == 0.0f) { + temp = 0.0f; + } + else if (src2[i] > 0.5f) { + temp = min_ff(((src1[i]) * 1.0f) / (2.0f * (1.0f - src2[i])), 1.0f); + } + else { + temp = max_ff(1.0f - ((1.0f - src1[i]) * 1.0f / (2.0f * src2[i])), 0.0f); + } + dst[i] = (temp * fac + src1[i] * mfac); + } + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + +MINLINE void blend_color_difference_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + int i = 3; + + while (i--) { + dst[i] = (fabsf(src1[i] - src2[i]) * fac + src1[i] * mfac); + } + } + else { + /* no op */ + copy_v4_v4(dst, src1); } } + +MINLINE void blend_color_exclusion_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + int i = 3; + + while (i--) { + const float temp = 0.5f - ((2 * (src1[i] - 0.5f) * (src2[i] - 0.5f))); + dst[i] = (temp * fac + src1[i] * mfac); + } + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } + +} + +MINLINE void blend_color_color_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + + rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1); + rgb_to_hsv(src2[0], src2[1], src2[2], &h2, &s2, &v2); + + h1 = h2; + s1 = s2; + + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + dst[0] = (r * fac + src1[0] * mfac); + dst[1] = (g * fac + src1[1] * mfac); + dst[2] = (b * fac + src1[2] * mfac); + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + + +MINLINE void blend_color_hue_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + + rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1); + rgb_to_hsv(src2[0], src2[1], src2[2], &h2, &s2, &v2); + + h1 = h2; + + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + dst[0] = (r * fac + src1[0] * mfac); + dst[1] = (g * fac + src1[1] * mfac); + dst[2] = (b * fac + src1[2] * mfac); + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + +MINLINE void blend_color_saturation_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + + rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1); + rgb_to_hsv(src2[0], src2[1], src2[2], &h2, &s2, &v2); + + if (s1 > EPS_SATURATION) { + s1 = s2; + } + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + dst[0] = (r * fac + src1[0] * mfac); + dst[1] = (g * fac + src1[1] * mfac); + dst[2] = (b * fac + src1[2] * mfac); + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + +MINLINE void blend_color_luminosity_float(float dst[3], const float src1[3], const float src2[3]) +{ + const float fac = src2[3]; + if (fac != 0.0f && fac < 1.0f) { + const float mfac = 1.0f - fac; + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + + rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1); + rgb_to_hsv(src2[0], src2[1], src2[2], &h2, &s2, &v2); + + v1 = v2; + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + dst[0] = (r * fac + src1[0] * mfac); + dst[1] = (g * fac + src1[1] * mfac); + dst[2] = (b * fac + src1[2] * mfac); + } + else { + /* no op */ + copy_v4_v4(dst, src1); + } +} + + MINLINE void blend_color_interpolate_float(float dst[4], const float src1[4], const float src2[4], float t) { /* interpolation, colors are premultiplied so it goes fine */ - float mt = 1.0f - t; + const float mt = 1.0f - t; dst[0] = mt * src1[0] + t * src2[0]; dst[1] = mt * src1[1] + t * src2[1]; @@ -453,4 +1168,7 @@ MINLINE void blend_color_interpolate_float(float dst[4], const float src1[4], co dst[3] = mt * src1[3] + t * src2[3]; } +#undef EPS_SATURATION +#undef EPS_ALPHA + #endif /* __MATH_COLOR_BLEND_INLINE_C__ */ |