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:
authorAntony Riakiotakis <kalast@gmail.com>2014-07-21 14:02:05 +0400
committerAntony Riakiotakis <kalast@gmail.com>2014-07-21 14:02:05 +0400
commitf745564e4ee791e4faf804b09ce975b882f4f8d9 (patch)
tree90ebbe363ccd925cedc652c9bb018ce552b5a2ab /source/blender/blenlib/intern/math_color_blend_inline.c
parent8489b94e07f9e73bd3c9c3e4f6a91f1f0a259827 (diff)
GSOC 2013 paint
Yep, at last it's here! There are a few minor issues remaining but development can go on in master after discussion at blender institute. For full list of features see: http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.72/Painting Thanks to Sergey and Campbell for the extensive review and to the countless artists that have given their input and reported issues during development.
Diffstat (limited to 'source/blender/blenlib/intern/math_color_blend_inline.c')
-rw-r--r--source/blender/blenlib/intern/math_color_blend_inline.c1171
1 files changed, 1101 insertions, 70 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..1985e061172 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,547 @@ 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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ int temp;
+ int mfac = 255 - fac;
+ if (src1[0] > 127)
+ temp = 255 - ((255 - 2 * (src1[0] - 127)) * (255 - src2[0]) / 255);
+ else
+ temp = (2 * src1[0] * src2[0]) >> 8;
+ temp = (temp * fac + src1[0] * mfac) / 255;
+ if (temp < 255)
+ dst[0] = temp;
+ else
+ dst[0] = 255;
+ if (src1[1] > 127)
+ temp = 255 - ((255 - 2 * (src1[1] - 127)) * (255 - src2[1]) / 255);
+ else
+ temp = (2 * src1[1] * src2[1]) / 255;
+
+ temp = (temp * fac + src1[1] * mfac) / 255;
+ if (temp < 255)
+ dst[1] = temp;
+ else
+ dst[1] = 255;
+
+ if (src1[2] > 127)
+ temp = 255 - ((255 - 2 * (src1[2] - 127)) * (255 - src2[2]) / 255);
+ else
+ temp = (2 * src1[2] * src2[2]) / 255;
+
+ temp = (temp * fac + src1[2] * mfac) / 255;
+ if (temp < 255)
+ dst[2] = temp;
+ else
+ dst[2] = 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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ int temp;
+ int mfac = 255 - fac;
+ if (src2[0] > 127)
+ temp = 255 - ((255 - 2 * (src2[0] - 127)) * (255 - src1[0]) / 255);
+ else
+ temp = (2 * src2[0] * src1[0]) >> 8;
+ temp = (temp * fac + src1[0] * mfac) / 255;
+ if (temp < 255) dst[0] = temp; else dst[0] = 255;
+
+
+ if (src2[1] > 127)
+ temp = 255 - ((255 - 2 * (src2[1] - 127)) * (255 - src1[1]) / 255);
+ else
+ temp = (2 * src2[1] * src1[1]) / 255;
+ temp = (temp * fac + src1[1] * mfac) / 255;
+ if (temp < 255) dst[1] = temp; else dst[1] = 255;
+
+
+ if (src2[2] > 127)
+ temp = 255 - ((255 - 2 * (src2[2] - 127)) * (255 - src1[2]) / 255);
+ else
+ temp = (2 * src2[2] * src1[2]) / 255;
+
+ temp = (temp * fac + src1[2] * mfac) / 255;
+ if (temp < 255) dst[2] = temp; else dst[2] = 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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ int temp;
+ int mfac = 255 - fac;
+
+
+ if (src2[0] == 0)
+ temp = 0;
+ else
+ temp = 255 - ((255 - src1[0]) * 255) / src2[0];
+ if (temp < 0)
+ temp = 0;
+ dst[0] = (temp * fac + src1[0] * mfac) / 255;
+
+
+ if (src2[1] == 0)
+ temp = 0;
+ else
+ temp = 255 - ((255 - src1[1]) * 255) / src2[1];
+ if (temp < 0)
+ temp = 0;
+ dst[1] = (temp * fac + src1[1] * mfac) / 255;
+
+
+ if (src2[2] == 0)
+ temp = 0;
+ else
+ temp = 255 - ((255 - src1[2]) * 255) / src2[2];
+ if (temp < 0)
+ temp = 0;
+ dst[2] = (temp * fac + src1[2] * 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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ int temp;
+ int mfac = 255 - fac;
+
+ temp = src1[0] + src2[0] - 255;
+ if (temp < 0) temp = 0;
+ dst[0] = (temp * fac + src1[0] * mfac) / 255;
+
+ temp = src1[1] + src2[1] - 255;
+ if (temp < 0) temp = 0;
+ dst[1] = (temp * fac + src1[1] * mfac) / 255;
+
+ temp = src1[2] + src2[2] - 255;
+ if (temp < 0) temp = 0;
+ dst[2] = (temp * fac + src1[2] * 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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ int temp;
+ int mfac = 255 - fac;
+
+ if (src2[0] == 255) temp = 255;
+ else temp = (src1[0] * 255) / (255 - src2[0]);
+ if (temp > 255) temp = 255;
+ dst[0] = (temp * fac + src1[0] * mfac) / 255;
+
+ if (src2[1] == 255) temp = 255;
+ else temp = (src1[1] * 255) / (255 - src2[1]);
+ if (temp > 255) temp = 255;
+ dst[1] = (temp * fac + src1[1] * mfac) / 255;
+
+ if (src2[2] == 255) temp = 255;
+ else temp = (src1[2] * 255) / (255 - src2[2]);
+ if (temp > 255) temp = 255;
+ dst[2] = (temp * fac + src1[2] * 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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ int temp;
+ int mfac = 255 - fac;
+
+ temp = 255 - (((255 - src1[0]) * (255 - src2[0])) / 255);
+ if (temp < 0) temp = 0;
+ dst[0] = (temp * fac + src1[0] * mfac) / 255;
+
+ temp = 255 - (((255 - src1[1]) * (255 - src2[1])) / 255);
+ if (temp < 0) temp = 0;
+ dst[1] = (temp * fac + src1[1] * mfac) / 255;
+
+ temp = 255 - (((255 - src1[2]) * (255 - src2[2])) / 255);
+ if (temp < 0) temp = 0;
+ dst[2] = (temp * fac + src1[2] * 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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ int temp;
+ int mfac = 255 - fac;
+
+ temp = ((unsigned char)((src1[0] < 127) ? ((2 * ((src2[0] / 2) + 64)) * (src1[0])) / 255 : (255 - (2 * (255 - ((src2[0] / 2) + 64)) * (255 - src1[0]) / 255))));
+ dst[0] = (temp * fac + src1[0] * mfac) / 255;
+
+ temp = ((unsigned char)((src1[1] < 127) ? ((2 * ((src2[1] / 2) + 64)) * (src1[1])) / 255 : (255 - (2 * (255 - ((src2[1] / 2) + 64)) * (255 - src1[1]) / 255))));
+ dst[1] = (temp * fac + src1[1] * mfac) / 255;
+
+ temp = ((unsigned char)((src1[2] < 127) ? ((2 * ((src2[2] / 2) + 64)) * (src1[2])) / 255 : (255 - (2 * (255 - ((src2[2] / 2) + 64)) * (255 - src1[2]) / 255))));
+ dst[2] = (temp * fac + src1[2] * 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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ int temp;
+ int mfac = 255 - fac;
+
+ if (src2[0] > 127) {
+ temp = 2 * (src2[0] - 127);
+ if (src1[0] > temp)
+ temp = src1[0];
+ }
+ else {
+ temp = 2 * src2[0];
+ if (src1[0] < temp)
+ temp = src1[0];
+ }
+
+ dst[0] = (temp * fac + src1[0] * mfac) / 255;
+
+
+ if (src2[1] > 127) {
+ temp = 2 * (src2[1] - 127);
+ if (src1[1] > temp) temp = src1[1];
+ }
+ else {
+ temp = 2 * src2[1];
+ if (src1[1] < temp) temp = src1[1];
+ }
+
+ dst[1] = (temp * fac + src1[1] * mfac) / 255;
+
+
+ if (src2[2] > 127) {
+ temp = 2 * (src2[2] - 127);
+ if (src1[2] > temp) temp = src1[2];
+ }
+ else {
+ temp = 2 * src2[2];
+ if (src1[2] < temp) temp = src1[2];
+ }
+ dst[2] = (temp * fac + src1[2] * 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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ int temp;
+ int mfac = 255 - fac;
+
+ if (src2[0] > 127) {
+ temp = src1[0] + 2 * (src2[0] - 127);
+ if (temp > 255)
+ temp = 255;
+ }
+ else {
+ temp = src1[0] + 2 * src2[0] - 255;
+ if (temp < 0) temp = 0;
+ }
+ dst[0] = (temp * fac + src1[0] * mfac) / 255;
+
+ if (src2[1] > 127) {
+ temp = src1[1] + 2 * (src2[1] - 127);
+ if (temp > 255)
+ temp = 255;
+ }
+ else {
+ temp = src1[1] + 2 * src2[1] - 255;
+ if (temp < 0) temp = 0;
+ }
+ dst[1] = (temp * fac + src1[1] * mfac) / 255;
+
+ if (src2[2] > 127) {
+ temp = src1[2] + 2 * (src2[2] - 127);
+ if (temp > 255)
+ temp = 255;
+ }
+ else {
+ temp = src1[2] + 2 * src2[2] - 255;
+ if (temp < 0) temp = 0;
+ }
+ dst[2] = (temp * fac + src1[2] * 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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ int temp;
+ int mfac = 255 - fac;
+
+ if (src2[0] == 255)
+ temp = 255;
+ else if (src2[0] == 0)
+ temp = 0;
+ else if (src2[0] > 127) {
+ temp = ((src1[0]) * 255) / (2 * (255 - src2[0]));
+ if (temp > 255) temp = 255;
+ }
+ else {
+ temp = 255 - ((255 - src1[0]) * 255 / (2 * src2[0]));
+ if (temp < 0) temp = 0;
+ }
+
+ dst[0] = (temp * fac + src1[0] * mfac) / 255;
+
+ if (src2[1] == 255)
+ temp = 255;
+ else if (src2[1] == 0)
+ temp = 0;
+ else if (src2[1] > 127) {
+ temp = ((src1[1]) * 255) / (2 * (255 - src2[1]));
+ if (temp > 255) temp = 255;
+ }
+ else {
+ temp = 255 - ((255 - src1[1]) * 255 / (2 * src2[1]));
+ if (temp < 0) temp = 0;
+ }
+
+ dst[1] = (temp * fac + src1[1] * mfac) / 255;
+
+ if (src2[2] == 255)
+ temp = 255;
+ else if (src2[2] == 0)
+ temp = 0;
+ else if (src2[2] > 127) {
+ temp = ((src1[2]) * 255) / (2 * (255 - src2[2]));
+ if (temp > 255) temp = 255;
+ }
+ else {
+ temp = 255 - ((255 - src1[2]) * 255 / (2 * src2[2]));
+ if (temp < 0) temp = 0;
+ }
+
+ dst[2] = (temp * fac + src1[2] * 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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ int temp;
+ int mfac = 255 - fac;
+ temp = src1[0] - src2[0];
+ if (temp < 0) temp = -temp;
+ dst[0] = (temp * fac + src1[0] * mfac) / 255;
+
+ temp = src1[1] - src2[1];
+ if (temp < 0) temp = -temp;
+ dst[1] = (temp * fac + src1[1] * mfac) / 255;
+
+ temp = src1[2] - src2[2];
+ if (temp < 0) temp = -temp;
+ dst[2] = (temp * fac + src1[2] * 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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ int temp;
+ int mfac = 255 - fac;
+ temp = 127 - ((2 * (src1[0] - 127) * (src2[0] - 127)) / 255);
+ dst[0] = (temp * fac + src1[0] * mfac) / 255;
+
+ temp = 127 - ((2 * (src1[1] - 127) * (src2[1] - 127)) / 255);
+ dst[1] = (temp * fac + src1[1] * mfac) / 255;
+
+ temp = 127 - ((2 * (src1[2] - 127) * (src2[2] - 127)) / 255);
+ dst[2] = (temp * fac + src1[2] * 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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ 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] = ((int)(r * 255.0f) * fac + src1[0] * mfac) / 255;
+ dst[1] = ((int)(g * 255.0f) * fac + src1[1] * mfac) / 255;
+ dst[2] = ((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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ 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] = ((int)(r * 255.0f) * fac + src1[0] * mfac) / 255;
+ dst[1] = ((int)(g * 255.0f) * fac + src1[1] * mfac) / 255;
+ dst[2] = ((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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ 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] = ((int)(r * 255.0f) * fac + src1[0] * mfac) / 255;
+ dst[1] = ((int)(g * 255.0f) * fac + src1[1] * mfac) / 255;
+ dst[2] = ((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 unsigned char fac = src2[3];
+ if (fac != 0) {
+ 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] = ((int)(r * 255.0f) * fac + src1[0] * mfac) / 255;
+ dst[1] = ((int)(g * 255.0f) * fac + src1[1] * mfac) / 255;
+ dst[2] = ((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 +777,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 +797,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 +812,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 +827,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 +845,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 +865,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 +885,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 +896,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 +909,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 +920,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,13 +933,543 @@ 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])
+{
+ float fac = src2[3];
+ if (fac != 0.0f && fac < 1.0f) {
+
+ float temp;
+ float fac = src2[3];
+ float mfac = 1.0f - fac;
+
+ if (src1[0] > 0.5f)
+ temp = 1 - (1 - 2 * (src1[0] - 0.5f)) * (1 - src2[0]);
+ else
+ temp = 2 * src1[0] * src2[0];
+ temp = temp * fac + src1[0] * mfac;
+ if (temp < 1.0f)
+ dst[0] = temp;
+ else
+ dst[0] = 1.0f;
+
+
+ if (src1[1] > 0.5f)
+ temp = 1.0f - (1.0f - 2.0f * (src1[1] - 0.5f)) * (1.0f - src2[1]);
+ else
+ temp = 2.0f * src1[1] * src2[1];
+ temp = temp * fac + src1[1] * mfac;
+ if (temp < 1.0f)
+ dst[1] = temp;
+ else
+ dst[1] = 1.0f;
+
+ if (src1[2] > 0.5f)
+ temp = 1 - (1.0f - 2.0f * (src1[2] - 0.5f)) * (1.0f - src2[2]);
+ else
+ temp = 2.0f * src1[2] * src2[2];
+ temp = temp * fac + src1[2] * mfac;
+ if (temp < 1.0f)
+ dst[2] = temp;
+ else
+ dst[2] = 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) {
+ float temp;
+ float mfac = 1.0f - fac;
+ if (src2[0] > 0.5f)
+ temp = 1 - ((1.0f - 2.0f * (src2[0] - 0.5f)) * (1.0f - src1[0]));
+ else
+ temp = 2.0f * src2[0] * src1[0];
+ temp = (temp * fac + src1[0] * mfac) / 1.0f;
+ if (temp < 1.0f) dst[0] = temp; else dst[0] = 1.0f;
+
+ if (src2[1] > 0.5f)
+ temp = 1 - ((1.0f - 2.0f * (src2[1] - 0.5f)) * (1.0f - src1[1]));
+ else
+ temp = 2.0f * src2[1] * src1[1];
+ temp = (temp * fac + src1[1] * mfac) / 1.0f;
+ if (temp < 1.0f) dst[1] = temp; else dst[1] = 1.0f;
+
+ if (src2[2] > 0.5f)
+ temp = 1 - ((1.0f - 2.0f * (src2[2] - 0.5f)) * (1.0f - src1[2]));
+ else
+ temp = 2.0f * src2[2] * src1[2];
+ temp = (temp * fac + src1[2] * mfac) / 1.0f;
+
+ if (temp < 1.0f)
+ dst[2] = temp;
+ else
+ dst[2] = 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) {
+ float temp;
+ float mfac = 1.0f - fac;
+
+ if (src2[0] == 0.0f)
+ temp = 0.0f;
+ else
+ temp = 1.0f - ((1.0f - src1[0]) / src2[0]);
+ if (temp < 0.0f)
+ temp = 0.0f;
+ dst[0] = (temp * fac + src1[0] * mfac);
+
+ if (src2[1] == 0.0f)
+ temp = 0.0f;
+ else
+ temp = 1.0f - ((1.0f - src1[1]) / src2[1]);
+ if (temp < 0.0f)
+ temp = 0.0f;
+ dst[1] = (temp * fac + src1[1] * mfac);
+
+ if (src2[2] == 0.0f)
+ temp = 0.0f;
+ else
+ temp = 1.0f - ((1.0f - src1[2]) / src2[2]);
+ if (temp < 0.0f)
+ temp = 0.0f;
+ dst[2] = (temp * fac + src1[2] * 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) {
+ float temp;
+ float mfac = 1.0f - fac;
+
+ temp = src1[0] + src2[0] - 1.0f;
+ if (temp < 0) temp = 0;
+ dst[0] = (temp * fac + src1[0] * mfac);
+
+ temp = src1[1] + src2[1] - 1.0f;
+ if (temp < 0) temp = 0;
+ dst[1] = (temp * fac + src1[1] * mfac);
+
+ temp = src1[2] + src2[2] - 1.0f;
+ if (temp < 0) temp = 0;
+ dst[2] = (temp * fac + src1[2] * 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) {
+ float temp;
+ float mfac = 1.0f - fac;
+
+ if (src2[0] >= 1.0f) temp = 1.0f;
+ else temp = (src1[0]) / (1.0f - src2[0]);
+ if (temp > 1.0f) temp = 1.0f;
+ dst[0] = (temp * fac + src1[0] * mfac);
+
+ if (src2[1] >= 1.0f) temp = 1.0f;
+ else temp = (src1[1]) / (1.0f - src2[1]);
+ if (temp > 1.0f) temp = 1.0f;
+ dst[1] = (temp * fac + src1[1] * mfac);
+
+ if (src2[2] >= 1.0f) temp = 1.0f;
+ else temp = (src1[2]) / (1.0f - src2[2]);
+ if (temp > 1.0f) temp = 1.0f;
+ dst[2] = (temp * fac + src1[2] * 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) {
+ float temp;
+ float mfac = 1.0f - fac;
+
+ temp = 1.0f - ((1.0f - src1[0]) * (1.0f - src2[0]));
+ if (temp < 0) temp = 0;
+ dst[0] = (temp * fac + src1[0] * mfac);
+
+ temp = 1.0f - ((1.0f - src1[1]) * (1.0f - src2[1]));
+ if (temp < 0) temp = 0;
+ dst[1] = (temp * fac + src1[1] * mfac);
+
+ temp = 1.0f - ((1.0f - src1[2]) * (1.0f - src2[2]));
+ if (temp < 0) temp = 0;
+ dst[2] = (temp * fac + src1[2] * 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) {
+ float temp;
+ float mfac = 1.0f - fac;
+
+ temp = (((src1[0] < 0.5f) ? ((src2[0] + 0.5f) * (src1[0])) : (1.0f - ((1.0f - ((src2[0]) + 0.5f)) * (1.0f - src1[0])))));
+ dst[0] = (temp * fac + src1[0] * mfac);
+
+ temp = (((src1[1] < 0.5f) ? ((src2[1] + 0.5f) * (src1[1])) : (1.0f - ((1.0f - ((src2[1]) + 0.5f)) * (1.0f - src1[1])))));
+ dst[1] = (temp * fac + src1[1] * mfac);
+
+ temp = (((src1[2] < 0.5f) ? ((src2[2] + 0.5f) * (src1[2])) : (1.0f - ((1.0f - ((src2[2]) + 0.5f)) * (1.0f - src1[2])))));
+ dst[2] = (temp * fac + src1[2] * 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) {
+ float temp;
+ float mfac = 1.0f - fac;
+
+ if (src2[0] > 0.5f) {
+ temp = 2 * (src2[0] - 0.5f);
+ if (src1[0] > temp)
+ temp = src1[0];
+ }
+ else {
+ temp = 2 * src2[0];
+ if (src1[0] < temp)
+ temp = src1[0];
+ }
+
+ dst[0] = (temp * fac + src1[0] * mfac);
+
+
+ if (src2[1] > 0.5f) {
+ temp = 2 * (src2[1] - 0.5f);
+ if (src1[1] > temp) temp = src1[1];
+ }
+ else {
+ temp = 2 * src2[1];
+ if (src1[1] < temp) temp = src1[1];
+ }
+
+ dst[1] = (temp * fac + src1[1] * mfac);
+
+
+ if (src2[2] > 0.5f) {
+ temp = 2 * (src2[2] - 0.5f);
+ if (src1[2] > temp) temp = src1[2];
+ }
+ else {
+ temp = 2 * src2[2];
+ if (src1[2] < temp) temp = src1[2];
+ }
+ dst[2] = (temp * fac + src1[2] * 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) {
+ float temp;
+ float mfac = 1.0f - fac;
+
+ if (src2[0] > 0.5f) {
+ temp = src1[0] + 2 * (src2[0] - 0.5f);
+ if (temp > 1.0f)
+ temp = 1.0f;
+ }
+ else {
+ temp = src1[0] + 2 * src2[0] - 1.0f;
+ if (temp < 0) temp = 0;
+ }
+ dst[0] = (temp * fac + src1[0] * mfac);
+
+ if (src2[1] > 0.5f) {
+ temp = src1[1] + 2 * (src2[1] - 0.5f);
+ if (temp > 1.0f)
+ temp = 1.0f;
+ }
+ else {
+ temp = src1[1] + 2 * src2[1] - 1.0f;
+ if (temp < 0) temp = 0;
+ }
+ dst[1] = (temp * fac + src1[1] * mfac);
+
+ if (src2[2] > 0.5f) {
+ temp = src1[2] + 2 * (src2[2] - 0.5f);
+ if (temp > 1.0f)
+ temp = 1.0f;
+ }
+ else {
+ temp = src1[2] + 2 * src2[2] - 1.0f;
+ if (temp < 0) temp = 0;
+ }
+ dst[2] = (temp * fac + src1[2] * 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) {
+ float temp;
+ float mfac = 1.0f - fac;
+
+ if (src2[0] == 1.0f)
+ temp = 1.0f;
+ else if (src2[0] == 0)
+ temp = 0;
+ else if (src2[0] > 0.5f) {
+ temp = ((src1[0]) * 1.0f) / (2 * (1.0f - src2[0]));
+ if (temp > 1.0f) temp = 1.0f;
+ }
+ else {
+ temp = 1.0f - ((1.0f - src1[0]) * 1.0f / (2 * src2[0]));
+ if (temp < 0) temp = 0;
+ }
+
+ dst[0] = (temp * fac + src1[0] * mfac);
+
+ if (src2[1] == 1.0f)
+ temp = 1.0f;
+ else if (src2[1] == 0)
+ temp = 0;
+ else if (src2[1] > 0.5f) {
+ temp = ((src1[1]) * 1.0f) / (2 * (1.0f - src2[1]));
+ if (temp > 1.0f) temp = 1.0f;
+ }
+ else {
+ temp = 1.0f - ((1.0f - src1[1]) * 1.0f / (2 * src2[1]));
+ if (temp < 0) temp = 0;
+ }
+
+ dst[1] = (temp * fac + src1[1] * mfac);
+
+ if (src2[2] == 1.0f)
+ temp = 1.0f;
+ else if (src2[2] == 0)
+ temp = 0;
+ else if (src2[2] > 0.5f) {
+ temp = ((src1[2]) * 1.0f) / (2 * (1.0f - src2[2]));
+ if (temp > 1.0f) temp = 1.0f;
+ }
+ else {
+ temp = 1.0f - ((1.0f - src1[2]) * 1.0f / (2 * src2[2]));
+ if (temp < 0) temp = 0;
+ }
+
+ dst[2] = (temp * fac + src1[2] * 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) {
+ float temp;
+ float mfac = 1.0f - fac;
+ temp = src1[0] - src2[0];
+ if (temp < 0) temp = -temp;
+ dst[0] = (temp * fac + src1[0] * mfac);
+
+ temp = src1[1] - src2[1];
+ if (temp < 0) temp = -temp;
+ dst[1] = (temp * fac + src1[1] * mfac);
+
+ temp = src1[2] - src2[2];
+ if (temp < 0) temp = -temp;
+ dst[2] = (temp * fac + src1[2] * 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) {
+ float temp;
+ float mfac = 1.0f - fac;
+ temp = 0.5f - ((2 * (src1[0] - 0.5f) * (src2[0] - 0.5f)));
+ dst[0] = (temp * fac + src1[0] * mfac);
+
+ temp = 0.5f - ((2 * (src1[1] - 0.5f) * (src2[1] - 0.5f)));
+ dst[1] = (temp * fac + src1[1] * mfac);
+
+ temp = 0.5f - ((2 * (src1[2] - 0.5f) * (src2[2] - 0.5f)));
+ dst[2] = (temp * fac + src1[2] * 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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 */
@@ -453,4 +1481,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__ */