11#if !BLI_MATH_DO_INLINE
18#ifndef __MATH_COLOR_BLEND_INLINE_C__
19# define __MATH_COLOR_BLEND_INLINE_C__
22# define EPS_SATURATION 0.0005f
23# define EPS_ALPHA 0.0005f
41 const int t = src2[3];
42 const int mt = 255 - t;
45 tmp[0] = (mt * src1[3] * src1[0]) + (t * 255 * src2[0]);
46 tmp[1] = (mt * src1[3] * src1[1]) + (t * 255 * src2[1]);
47 tmp[2] = (mt * src1[3] * src1[2]) + (t * 255 * src2[2]);
48 tmp[3] = (mt * src1[3]) + (t * 255);
65 const int t = src2[3];
68 tmp[0] = (src1[0] * 255) + (src2[0] * t);
69 tmp[1] = (src1[1] * 255) + (src2[1] * t);
70 tmp[2] = (src1[2] * 255) + (src2[2] * t);
87 const int t = src2[3];
90 tmp[0] = (src1[0] * 255) - (src2[0] * t);
91 tmp[1] = (src1[1] * 255) - (src2[1] * t);
92 tmp[2] = (src1[2] * 255) - (src2[2] * t);
109 const int t = src2[3];
110 const int mt = 255 - t;
113 tmp[0] = (mt * src1[0] * 255) + (t * src1[0] * src2[0]);
114 tmp[1] = (mt * src1[1] * 255) + (t * src1[1] * src2[1]);
115 tmp[2] = (mt * src1[2] * 255) + (t * src1[2] * src2[2]);
132 const int t = src2[3];
133 const int mt = 255 - t;
136 tmp[0] = (mt * src1[0]) + (t *
max_ii(src1[0], src2[0]));
137 tmp[1] = (mt * src1[1]) + (t *
max_ii(src1[1], src2[1]));
138 tmp[2] = (mt * src1[2]) + (t *
max_ii(src1[2], src2[2]));
155 const int t = src2[3];
156 const int mt = 255 - t;
159 tmp[0] = (mt * src1[0]) + (t *
min_ii(src1[0], src2[0]));
160 tmp[1] = (mt * src1[1]) + (t *
min_ii(src1[1], src2[1]));
161 tmp[2] = (mt * src1[2]) + (t *
min_ii(src1[2], src2[2]));
178 const int t = src2[3];
195 const int t = src2[3];
210 const int fac = (int)src2[3];
212 const int mfac = 255 - fac;
219 temp = 255 - ((255 - 2 * (src1[
i] - 127)) * (255 - src2[
i]) / 255);
222 temp = (2 * src1[
i] * src2[
i]) >> 8;
224 dst[
i] = (
uchar)
min_ii((temp * fac + src1[
i] * mfac) / 255, 255);
235 const int fac = (int)src2[3];
237 const int mfac = 255 - fac;
244 temp = 255 - ((255 - 2 * (src2[
i] - 127)) * (255 - src1[
i]) / 255);
247 temp = (2 * src2[
i] * src1[
i]) >> 8;
249 dst[
i] = (
uchar)
min_ii((temp * fac + src1[
i] * mfac) / 255, 255);
260 const int fac = src2[3];
262 const int mfac = 255 - fac;
266 const int temp = (src2[
i] == 0) ? 0 :
max_ii(255 - ((255 - src1[
i]) * 255) / src2[
i], 0);
267 dst[
i] = (
uchar)((temp * fac + src1[
i] * mfac) / 255);
278 const int fac = src2[3];
280 const int mfac = 255 - fac;
284 const int temp =
max_ii(src1[
i] + src2[
i] - 255, 0);
285 dst[
i] = (
uchar)((temp * fac + src1[
i] * mfac) / 255);
296 const int fac = src2[3];
298 const int mfac = 255 - fac;
302 const int temp = (src2[
i] == 255) ? 255 :
min_ii((src1[
i] * 255) / (255 - src2[
i]), 255);
303 dst[
i] = (
uchar)((temp * fac + src1[
i] * mfac) / 255);
314 const int fac = src2[3];
316 const int mfac = 255 - fac;
320 const int temp =
max_ii(255 - (((255 - src1[
i]) * (255 - src2[
i])) / 255), 0);
321 dst[
i] = (
uchar)((temp * fac + src1[
i] * mfac) / 255);
332 const float fac = (
float)(src2[3]) / 255.0f;
334 const float mfac = 1.0f - fac;
340 const float src1val = (
float)(src1[
i]) / 255.0f;
341 const float src2val = (
float)(src2[
i]) / 255.0f;
342 float screen = 1.0f - (1.0f - src1val) * (1.0f - src2val);
343 float soft_light = ((1.0f - src1val) * src2val + screen) * src1val;
355 const int fac = src2[3];
357 const int mfac = 255 - fac;
364 temp =
max_ii(2 * (src2[
i] - 127), src1[
i]);
367 temp =
min_ii(2 * src2[
i], src1[
i]);
369 dst[
i] = (
uchar)((
min_ii(temp, 255) * fac + src1[
i] * mfac) / 255);
380 const int fac = src2[3];
382 const int mfac = 255 - fac;
389 temp =
min_ii(src1[
i] + 2 * (src2[
i] - 127), 255);
392 temp =
max_ii(src1[
i] + 2 * src2[
i] - 255, 0);
394 dst[
i] = (
uchar)((temp * fac + src1[
i] * mfac) / 255);
405 const int fac = src2[3];
407 const int mfac = 255 - fac;
413 if (src2[
i] == 255) {
414 temp = (src1[
i] == 0) ? 127 : 255;
416 else if (src2[
i] == 0) {
417 temp = (src1[
i] == 255) ? 127 : 0;
419 else if (src2[
i] > 127) {
420 temp =
min_ii(((src1[
i]) * 255) / (2 * (255 - src2[
i])), 255);
423 temp =
max_ii(255 - ((255 - src1[
i]) * 255 / (2 * src2[
i])), 0);
425 dst[
i] = (
uchar)((temp * fac + src1[
i] * mfac) / 255);
436 const int fac = src2[3];
438 const int mfac = 255 - fac;
442 const int temp =
abs(src1[
i] - src2[
i]);
443 dst[
i] = (
uchar)((temp * fac + src1[
i] * mfac) / 255);
454 const int fac = src2[3];
456 const int mfac = 255 - fac;
460 const int temp = 127 -
min_ii(((2 * (src1[
i] - 127) * (src2[
i] - 127)) / 255), 127);
461 dst[
i] = (
uchar)((temp * fac + src1[
i] * mfac) / 255);
472 const int fac = src2[3];
474 const int mfac = 255 - fac;
478 rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1);
479 rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &
v2);
486 dst[0] = (
uchar)(((
int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
487 dst[1] = (
uchar)(((
int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
488 dst[2] = (
uchar)(((
int)(
b * 255.0f) * fac + src1[2] * mfac) / 255);
498 const int fac = src2[3];
500 const int mfac = 255 - fac;
504 rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1);
505 rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &
v2);
511 dst[0] = (
uchar)(((
int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
512 dst[1] = (
uchar)(((
int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
513 dst[2] = (
uchar)(((
int)(
b * 255.0f) * fac + src1[2] * mfac) / 255);
523 const int fac = src2[3];
525 const int mfac = 255 - fac;
529 rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1);
530 rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &
v2);
538 dst[0] = (
uchar)(((
int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
539 dst[1] = (
uchar)(((
int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
540 dst[2] = (
uchar)(((
int)(
b * 255.0f) * fac + src1[2] * mfac) / 255);
550 const int fac = src2[3];
552 const int mfac = 255 - fac;
556 rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1);
557 rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &
v2);
563 dst[0] = (
uchar)(((
int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
564 dst[1] = (
uchar)(((
int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
565 dst[2] = (
uchar)(((
int)(
b * 255.0f) * fac + src1[2] * mfac) / 255);
580 const int t = (int)(255 * ft);
581 const int mt = 255 - t;
582 int tmp = (mt * src1[3] + t * src2[3]);
600 if (src2[3] != 0.0f) {
602 const float t = src2[3];
603 const float mt = 1.0f - t;
605 dst[0] = mt * src1[0] + src2[0];
606 dst[1] = mt * src1[1] + src2[1];
607 dst[2] = mt * src1[2] + src2[2];
608 dst[3] = mt * src1[3] + t;
618 if (src2[3] != 0.0f) {
620 dst[0] = src1[0] + src2[0] * src1[3];
621 dst[1] = src1[1] + src2[1] * src1[3];
622 dst[2] = src1[2] + src2[2] * src1[3];
633 if (src2[3] != 0.0f) {
635 dst[0] =
max_ff(src1[0] - src2[0] * src1[3], 0.0f);
636 dst[1] =
max_ff(src1[1] - src2[1] * src1[3], 0.0f);
637 dst[2] =
max_ff(src1[2] - src2[2] * src1[3], 0.0f);
648 if (src2[3] != 0.0f) {
650 const float t = src2[3];
651 const float mt = 1.0f - t;
653 dst[0] = mt * src1[0] + src1[0] * src2[0] * src1[3];
654 dst[1] = mt * src1[1] + src1[1] * src2[1] * src1[3];
655 dst[2] = mt * src1[2] + src1[2] * src2[2] * src1[3];
666 if (src2[3] != 0.0f) {
669 const float t = src2[3];
670 const float mt = 1.0f - t;
671 const float map_alpha = src1[3] / src2[3];
673 dst[0] = mt * src1[0] + t *
max_ff(src1[0], src2[0] * map_alpha);
674 dst[1] = mt * src1[1] + t *
max_ff(src1[1], src2[1] * map_alpha);
675 dst[2] = mt * src1[2] + t *
max_ff(src1[2], src2[2] * map_alpha);
686 if (src2[3] != 0.0f) {
689 const float t = src2[3];
690 const float mt = 1.0f - t;
691 const float map_alpha = src1[3] / src2[3];
693 dst[0] = mt * src1[0] + t *
min_ff(src1[0], src2[0] * map_alpha);
694 dst[1] = mt * src1[1] + t *
min_ff(src1[1], src2[1] * map_alpha);
695 dst[2] = mt * src1[2] + t *
min_ff(src1[2], src2[2] * map_alpha);
706 if (src2[3] != 0.0f && src1[3] > 0.0f) {
708 float alpha =
max_ff(src1[3] - src2[3], 0.0f);
715 map_alpha = alpha / src1[3];
717 dst[0] = src1[0] * map_alpha;
718 dst[1] = src1[1] * map_alpha;
719 dst[2] = src1[2] * map_alpha;
730 if (src2[3] != 0.0f && src1[3] < 1.0f) {
732 float alpha =
min_ff(src1[3] + src2[3], 1.0f);
739 map_alpha = (src1[3] > 0.0f) ? alpha / src1[3] : 1.0f;
741 dst[0] = src1[0] * map_alpha;
742 dst[1] = src1[1] * map_alpha;
743 dst[2] = src1[2] * map_alpha;
754 const float fac = src2[3];
756 const float mfac = 1.0f - fac;
762 if (src1[
i] > 0.5f) {
763 temp = 1.0f - (1.0f - 2.0f * (src1[
i] - 0.5f)) * (1.0f - src2[
i]);
766 temp = 2.0f * src1[
i] * src2[
i];
768 dst[
i] =
min_ff(temp * fac + src1[
i] * mfac, 1.0f);
779 const float fac = src2[3];
781 const float mfac = 1.0f - fac;
787 if (src2[
i] > 0.5f) {
788 temp = 1.0f - ((1.0f - 2.0f * (src2[
i] - 0.5f)) * (1.0f - src1[
i]));
791 temp = 2.0f * src2[
i] * src1[
i];
793 dst[
i] =
min_ff((temp * fac + src1[
i] * mfac) / 1.0f, 1.0f);
804 const float fac = src2[3];
806 const float mfac = 1.0f - fac;
810 const float temp = (src2[
i] == 0.0f) ? 0.0f :
811 max_ff(1.0f - ((1.0f - src1[
i]) / src2[
i]), 0.0f);
812 dst[
i] = (temp * fac + src1[
i] * mfac);
823 const float fac = src2[3];
825 const float mfac = 1.0f - fac;
829 const float temp =
max_ff(src1[
i] + src2[
i] - 1.0f, 0.0f);
830 dst[
i] = (temp * fac + src1[
i] * mfac);
841 const float fac = src2[3];
843 const float mfac = 1.0f - fac;
847 const float temp = (src2[
i] >= 1.0f) ? 1.0f :
min_ff(src1[
i] / (1.0f - src2[
i]), 1.0f);
848 dst[
i] = (temp * fac + src1[
i] * mfac);
859 const float fac = src2[3];
861 const float mfac = 1.0f - fac;
865 const float temp =
max_ff(1.0f - ((1.0f - src1[
i]) * (1.0f - src2[
i])), 0.0f);
866 dst[
i] = (temp * fac + src1[
i] * mfac);
877 const float fac = src2[3];
879 const float mfac = 1.0f - fac;
883 float screen = 1.0f - (1.0f - src1[
i]) * (1.0f - src2[
i]);
884 float soft_light = ((1.0f - src1[
i]) * src2[
i] + screen) * src1[
i];
885 dst[
i] = src1[
i] * mfac + soft_light * fac;
896 const float fac = src2[3];
898 const float mfac = 1.0f - fac;
904 if (src2[
i] > 0.5f) {
905 temp =
max_ff(2.0f * (src2[
i] - 0.5f), src1[
i]);
908 temp =
min_ff(2.0f * src2[
i], src1[
i]);
910 dst[
i] = (temp * fac + src1[
i] * mfac);
921 const float fac = src2[3];
923 const float mfac = 1.0f - fac;
929 if (src2[
i] > 0.5f) {
930 temp =
min_ff(src1[
i] + 2.0f * (src2[
i] - 0.5f), 1.0f);
933 temp =
max_ff(src1[
i] + 2.0f * src2[
i] - 1.0f, 0.0f);
935 dst[
i] = (temp * fac + src1[
i] * mfac);
946 const float fac = src2[3];
948 const float mfac = 1.0f - fac;
954 if (src2[
i] == 1.0f) {
955 temp = (src1[
i] == 0.0f) ? 0.5f : 1.0f;
957 else if (src2[
i] == 0.0f) {
958 temp = (src1[
i] == 1.0f) ? 0.5f : 0.0f;
960 else if (src2[
i] > 0.5f) {
961 temp =
min_ff(((src1[
i]) * 1.0f) / (2.0f * (1.0f - src2[
i])), 1.0f);
964 temp =
max_ff(1.0f - ((1.0f - src1[
i]) * 1.0f / (2.0f * src2[
i])), 0.0f);
966 dst[
i] = (temp * fac + src1[
i] * mfac);
977 const float fac = src2[3];
979 const float mfac = 1.0f - fac;
983 dst[
i] = (
fabsf(src1[
i] - src2[
i]) * fac + src1[
i] * mfac);
994 const float fac = src2[3];
996 const float mfac = 1.0f - fac;
1000 const float temp = 0.5f - ((2 * (src1[
i] - 0.5f) * (src2[
i] - 0.5f)));
1001 dst[
i] = (temp * fac + src1[
i] * mfac);
1012 const float fac = src2[3];
1014 const float mfac = 1.0f - fac;
1019 rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1);
1027 dst[0] = (r * fac + src1[0] * mfac);
1028 dst[1] = (g * fac + src1[1] * mfac);
1029 dst[2] = (
b * fac + src1[2] * mfac);
1039 const float fac = src2[3];
1041 const float mfac = 1.0f - fac;
1046 rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1);
1053 dst[0] = (r * fac + src1[0] * mfac);
1054 dst[1] = (g * fac + src1[1] * mfac);
1055 dst[2] = (
b * fac + src1[2] * mfac);
1065 const float fac = src2[3];
1067 const float mfac = 1.0f - fac;
1072 rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1);
1080 dst[0] = (r * fac + src1[0] * mfac);
1081 dst[1] = (g * fac + src1[1] * mfac);
1082 dst[2] = (
b * fac + src1[2] * mfac);
1092 const float fac = src2[3];
1094 const float mfac = 1.0f - fac;
1099 rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1);
1105 dst[0] = (r * fac + src1[0] * mfac);
1106 dst[1] = (g * fac + src1[1] * mfac);
1107 dst[2] = (
b * fac + src1[2] * mfac);
1116 const float src1[4],
1117 const float src2[4],
1121 const float mt = 1.0f - t;
1123 dst[0] = mt * src1[0] + t * src2[0];
1124 dst[1] = mt * src1[1] + t * src2[1];
1125 dst[2] = mt * src1[2] + t * src2[2];
1126 dst[3] = mt * src1[3] + t * src2[3];
1129# undef EPS_SATURATION
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
MINLINE unsigned char round_fl_to_uchar_clamp(float a)
MINLINE int divide_round_i(int a, int b)
void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v)
void hsv_to_rgb(float h, float s, float v, float *r_r, float *r_g, float *r_b)
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v4_v4_uchar(unsigned char r[4], const unsigned char a[4])
ATTR_WARN_UNUSED_RESULT const BMVert * v2
MINLINE void blend_color_add_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_mul_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_exclusion_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_overlay_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_burn_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_sub_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_color_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_linearlight_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_saturation_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_darken_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_hue_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_dodge_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_difference_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_dodge_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_pinlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_pinlight_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_mul_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_overlay_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_erase_alpha_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_screen_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_add_alpha_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_exclusion_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_hardlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_color_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_hue_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_erase_alpha_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_saturation_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_linearburn_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_vividlight_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_mix_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_mix_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_luminosity_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_sub_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_burn_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_darken_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_interpolate_byte(uchar dst[4], const uchar src1[4], const uchar src2[4], float ft)
MINLINE void blend_color_vividlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_add_alpha_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_add_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_hardlight_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_lighten_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_linearburn_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_softlight_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_luminosity_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_difference_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_linearlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_lighten_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_screen_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_softlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4])
MINLINE void blend_color_interpolate_float(float dst[4], const float src1[4], const float src2[4], float t)