diff options
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 14 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/image_gen.c | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_validate.c | 1 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_color.h | 2 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_color_blend.h | 71 | ||||
-rw-r--r-- | source/blender/blenlib/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_base_inline.c | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_color_blend_inline.c | 413 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_image_2d.c | 9 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_image_proj.c | 24 | ||||
-rw-r--r-- | source/blender/imbuf/IMB_imbuf.h | 2 | ||||
-rw-r--r-- | source/blender/imbuf/intern/rectop.c | 114 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_lamp.c | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_mesh.c | 1 |
14 files changed, 570 insertions, 89 deletions
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index e3709143277..517180964a5 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -518,7 +518,9 @@ int BKE_brush_clone_image_delete(Brush *brush) } /* Generic texture sampler for 3D painting systems. point has to be either in - * region space mouse coordinates, or 3d world coordinates for 3D mapping */ + * region space mouse coordinates, or 3d world coordinates for 3D mapping. + * + * rgba outputs straight alpha. */ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br, const float point[3], float rgba[4], const int thread, @@ -755,7 +757,10 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br, return intensity; } -/* Brush Sampling for 2D brushes. when we unify the brush systems this will be necessarily a separate function */ +/* Brush Sampling for 2D brushes. when we unify the brush systems this will be + * necessarily a separate function. + * + * rgba outputs straight alpha. */ float BKE_brush_sample_tex_2D(const Scene *scene, Brush *brush, const float xy[2], float rgba[4]) { UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; @@ -873,6 +878,11 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf copy_v3_v3(dstf, brush_rgb); dstf[3] = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius); } + + /* output premultiplied alpha image */ + dstf[0] *= dstf[3]; + dstf[1] *= dstf[3]; + dstf[2] *= dstf[3]; } } } diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c index 415f0a87431..c31ec593e54 100644 --- a/source/blender/blenkernel/intern/image_gen.c +++ b/source/blender/blenkernel/intern/image_gen.c @@ -27,8 +27,9 @@ #include <math.h> #include <stdlib.h> -#include "BLI_math_color.h" #include "BLI_math_base.h" +#include "BLI_math_color.h" +#include "BLI_math_vector.h" #include "BKE_image.h" diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 6fb83b83c25..7a5bc33d323 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -40,6 +40,7 @@ #include "BLI_utildefines.h" #include "BLI_edgehash.h" #include "BLI_math_base.h" +#include "BLI_math_vector.h" #include "BKE_deform.h" #include "BKE_depsgraph.h" diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h index 145427ea529..6f432761a55 100644 --- a/source/blender/blenlib/BLI_math_color.h +++ b/source/blender/blenlib/BLI_math_color.h @@ -126,7 +126,7 @@ void xyz_to_lab(float x, float y, float z, float *l, float *a, float *b); MINLINE int compare_rgb_uchar(const unsigned char a[3], const unsigned char b[3], const int limit); -/***************** lift/gamma/gain / ASC-CDL conversion *****************/ +/********* lift/gamma/gain / ASC-CDL conversion ***********/ void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power); diff --git a/source/blender/blenlib/BLI_math_color_blend.h b/source/blender/blenlib/BLI_math_color_blend.h new file mode 100644 index 00000000000..a54bacf8714 --- /dev/null +++ b/source/blender/blenlib/BLI_math_color_blend.h @@ -0,0 +1,71 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: some of this file. + * + * ***** END GPL LICENSE BLOCK ***** + * */ + +#ifndef __BLI_MATH_COLOR_BLEND_H__ +#define __BLI_MATH_COLOR_BLEND_H__ + +/** \file BLI_math_color.h + * \ingroup bli + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "BLI_math_inline.h" + +/******************** Blending Modes ********************** + * - byte function assume straight alpha + * - float functions assume premultiplied alpha + */ + +MINLINE void blend_color_mix_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]); +MINLINE void blend_color_add_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]); +MINLINE void blend_color_sub_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]); +MINLINE void blend_color_mul_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]); +MINLINE void blend_color_lighten_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]); +MINLINE void blend_color_darken_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]); +MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]); +MINLINE void blend_color_add_alpha_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]); + +MINLINE void blend_color_mix_float(float dst[4], const float src1[4], const float src2[4]); +MINLINE void blend_color_add_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_mul_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_darken_float(float dst[4], const float src1[4], const float src2[4]); +MINLINE void blend_color_erase_alpha_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]); + +#if BLI_MATH_DO_INLINE +#include "intern/math_color_blend_inline.c" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __BLI_MATH_COLOR_BLEND_H__ */ + diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index e39ae395ffa..a9955f15016 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -70,6 +70,7 @@ set(SRC intern/math_base.c intern/math_base_inline.c intern/math_color.c + intern/math_color_blend_inline.c intern/math_color_inline.c intern/math_geom.c intern/math_geom_inline.c @@ -128,6 +129,7 @@ set(SRC BLI_math.h BLI_math_base.h BLI_math_color.h + BLI_math_color_blend.h BLI_math_geom.h BLI_math_inline.h BLI_math_interp.h diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index f916460dec4..3ffd96f62c7 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -35,7 +35,7 @@ #include <stdlib.h> #include <string.h> -#include "BLI_math.h" +#include "BLI_math_base.h" /* copied from BLI_utildefines.h */ #ifdef __GNUC__ diff --git a/source/blender/blenlib/intern/math_color_blend_inline.c b/source/blender/blenlib/intern/math_color_blend_inline.c new file mode 100644 index 00000000000..876ed6acf07 --- /dev/null +++ b/source/blender/blenlib/intern/math_color_blend_inline.c @@ -0,0 +1,413 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: some of this file. + * + * ***** END GPL LICENSE BLOCK ***** + * */ + +/** \file blender/blenlib/intern/math_color_inline.c + * \ingroup bli + */ + + +#include "BLI_math_base.h" +#include "BLI_math_color.h" +#include "BLI_utildefines.h" + +#ifndef __MATH_COLOR_BLEND_INLINE_C__ +#define __MATH_COLOR_BLEND_INLINE_C__ + +/***************************** Color Blending ******************************** + * + * - byte colors are assumed to be straight alpha + * - byte colors uses to do >>8 (same as /256) but actually should do /255, + * otherwise get quick darkening due to rounding + * - divide_round_i is also used to avoid darkening due to integers always + * rounding down + * - float colors are assumed to be premultiplied alpha + */ + +/* straight alpha byte blending modes */ + +MINLINE void blend_color_mix_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]) +{ + if (src2[3] != 0) { + /* straight over operation */ + const int t = src2[3]; + const int mt = 255 - t; + int tmp[4]; + + tmp[0] = (mt * src1[3] * src1[0]) + (t * 255 * src2[0]); + tmp[1] = (mt * src1[3] * src1[1]) + (t * 255 * src2[1]); + tmp[2] = (mt * src1[3] * src1[2]) + (t * 255 * src2[2]); + tmp[3] = (mt * src1[3]) + (t * 255); + + dst[0] = divide_round_i(tmp[0], tmp[3]); + dst[1] = divide_round_i(tmp[1], tmp[3]); + dst[2] = divide_round_i(tmp[2], tmp[3]); + dst[3] = divide_round_i(tmp[3], 255); + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_add_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]) +{ + if (src2[3] != 0) { + /* straight add operation */ + const int t = src2[3]; + int tmp[3]; + + tmp[0] = (src1[0] * 255) + (src2[0] * t); + tmp[1] = (src1[1] * 255) + (src2[1] * t); + tmp[2] = (src1[2] * 255) + (src2[2] * t); + + dst[0] = min_ii(divide_round_i(tmp[0], 255), 255); + dst[1] = min_ii(divide_round_i(tmp[1], 255), 255); + dst[2] = min_ii(divide_round_i(tmp[2], 255), 255); + dst[3] = src1[3]; + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_sub_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]) +{ + if (src2[3] != 0) { + /* straight sub operation */ + const int t = src2[3]; + int tmp[3]; + + tmp[0] = (src1[0] * 255) - (src2[0] * t); + tmp[1] = (src1[1] * 255) - (src2[1] * t); + tmp[2] = (src1[2] * 255) - (src2[2] * t); + + dst[0] = max_ii(divide_round_i(tmp[0], 255), 0); + dst[1] = max_ii(divide_round_i(tmp[1], 255), 0); + dst[2] = max_ii(divide_round_i(tmp[2], 255), 0); + dst[3] = src1[3]; + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_mul_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]) +{ + if (src2[3] != 0) { + /* straight multiply operation */ + const int t = src2[3]; + const int mt = 255 - t; + int tmp[3]; + + tmp[0] = (mt * src1[0] * 255) + (t * src1[0] * src2[0]); + tmp[1] = (mt * src1[1] * 255) + (t * src1[1] * src2[1]); + tmp[2] = (mt * src1[2] * 255) + (t * src1[2] * src2[2]); + + dst[0] = divide_round_i(tmp[0], 255 * 255); + dst[1] = divide_round_i(tmp[1], 255 * 255); + dst[2] = divide_round_i(tmp[2], 255 * 255); + dst[3] = src1[3]; + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_lighten_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]) +{ + if (src2[3] != 0) { + /* straight lighten operation */ + const int t = src2[3]; + const int mt = 255 - t; + int tmp[3]; + + tmp[0] = (mt * src1[0]) + (t * max_ii(src1[0], src2[0])); + tmp[1] = (mt * src1[1]) + (t * max_ii(src1[1], src2[1])); + tmp[2] = (mt * src1[2]) + (t * max_ii(src1[2], src2[2])); + + dst[0] = divide_round_i(tmp[0], 255); + dst[1] = divide_round_i(tmp[1], 255); + dst[2] = divide_round_i(tmp[2], 255); + dst[3] = src1[3]; + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_darken_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]) +{ + if (src2[3] != 0) { + /* straight darken operation */ + const int t = src2[3]; + const int mt = 255 - t; + int tmp[3]; + + tmp[0] = (mt * src1[0]) + (t * min_ii(src1[0], src2[0])); + tmp[1] = (mt * src1[1]) + (t * min_ii(src1[1], src2[1])); + tmp[2] = (mt * src1[2]) + (t * min_ii(src1[2], src2[2])); + + dst[0] = divide_round_i(tmp[0], 255); + dst[1] = divide_round_i(tmp[1], 255); + dst[2] = divide_round_i(tmp[2], 255); + dst[3] = src1[3]; + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]) +{ + if (src2[3] != 0) { + /* straight so just modify alpha channel */ + const int t = src2[3]; + + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = max_ii(src1[3] - divide_round_i(t * src2[3], 255), 0); + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_add_alpha_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]) +{ + if (src2[3] != 0) { + /* straight so just modify alpha channel */ + const int t = src2[3]; + + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = min_ii(src1[3] + divide_round_i(t * src2[3], 255), 255); + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +/* premultiplied alpha float blending modes */ + +MINLINE void blend_color_mix_float(float dst[4], const float src1[4], const float src2[4]) +{ + if (src2[3] != 0.0f) { + /* premul over operation */ + const float t = src2[3]; + const float mt = 1.0f - t; + + dst[0] = mt * src1[0] + src2[0]; + dst[1] = mt * src1[1] + src2[1]; + dst[2] = mt * src1[2] + src2[2]; + dst[3] = mt * src1[3] + t; + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_add_float(float dst[4], const float src1[4], const float src2[4]) +{ + if (src2[3] != 0.0f) { + /* unpremul > add > premul, simplified */ + dst[0] = src1[0] + src2[0] * src1[3]; + dst[1] = src1[1] + src2[1] * src1[3]; + dst[2] = src1[2] + src2[2] * src1[3]; + dst[3] = src1[3]; + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_sub_float(float dst[4], const float src1[4], const float src2[4]) +{ + if (src2[3] != 0.0f) { + /* unpremul > subtract > premul, simplified */ + dst[0] = max_ff(src1[0] - src2[0] * src1[3], 0.0f); + dst[1] = max_ff(src1[1] - src2[1] * src1[3], 0.0f); + dst[2] = max_ff(src1[2] - src2[2] * src1[3], 0.0f); + dst[3] = src1[3]; + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_mul_float(float dst[4], const float src1[4], const float src2[4]) +{ + if (src2[3] != 0.0f) { + /* unpremul > multiply > premul, simplified */ + const float t = src2[3]; + const float mt = 1.0f - t; + + dst[0] = mt * src1[0] + src1[0] * src2[0] * src1[3]; + dst[1] = mt * src1[1] + src1[1] * src2[1] * src1[3]; + dst[2] = mt * src1[2] + src1[2] * src2[2] * src1[3]; + dst[3] = src1[3]; + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_lighten_float(float dst[4], const float src1[4], const float src2[4]) +{ + if (src2[3] != 0.0f) { + /* remap src2 to have same alpha as src1 premultiplied, take maximum of + * src1 and src2, then blend it with src1 */ + const float t = src2[3]; + const float mt = 1.0f - t; + const float map_alpha = src1[3]/src2[3]; + + dst[0] = mt * src1[0] + t * max_ff(src1[0], src2[0] * map_alpha); + dst[1] = mt * src1[1] + t * max_ff(src1[1], src2[1] * map_alpha); + dst[2] = mt * src1[2] + t * max_ff(src1[2], src2[2] * map_alpha); + dst[3] = src1[3]; + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_darken_float(float dst[4], const float src1[4], const float src2[4]) +{ + if (src2[3] != 0.0f) { + /* remap src2 to have same alpha as src1 premultiplied, take minimum of + * src1 and src2, then blend it with src1 */ + const float t = src2[3]; + const float mt = 1.0f - t; + const float map_alpha = src1[3]/src2[3]; + + dst[0] = mt * src1[0] + t * min_ff(src1[0], src2[0] * map_alpha); + dst[1] = mt * src1[1] + t * min_ff(src1[1], src2[1] * map_alpha); + dst[2] = mt * src1[2] + t * min_ff(src1[2], src2[2] * map_alpha); + dst[3] = src1[3]; + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_erase_alpha_float(float dst[4], const float src1[4], const float src2[4]) +{ + if (src2[3] != 0.0f && src1[3] > 0.0f) { + /* subtract alpha and remap RGB channels to match */ + const float alpha = max_ff(src1[3] - src2[3], 0.0f); + const float map_alpha = alpha/src1[3]; + + dst[0] *= map_alpha; + dst[1] *= map_alpha; + dst[2] *= map_alpha; + dst[3] = alpha; + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +MINLINE void blend_color_add_alpha_float(float dst[4], const float src1[4], const float src2[4]) +{ + if (src2[3] != 0.0f && src1[3] < 1.0f) { + /* add alpha and remap RGB channels to match */ + const float alpha = min_ff(src1[3] + src2[3], 1.0f); + const float map_alpha = (src1[3] > 0.0f) ? alpha/src1[3] : 1.0f; + + dst[0] *= map_alpha; + dst[1] *= map_alpha; + dst[2] *= map_alpha; + dst[3] = alpha; + } + else { + /* no op */ + dst[0] = src1[0]; + dst[1] = src1[1]; + dst[2] = src1[2]; + dst[3] = src1[3]; + } +} + +#endif /* __MATH_COLOR_BLEND_INLINE_C__ */ diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c index 5452d9fb7e8..1c50b048fce 100644 --- a/source/blender/editors/sculpt_paint/paint_image_2d.c +++ b/source/blender/editors/sculpt_paint/paint_image_2d.c @@ -231,10 +231,11 @@ static void brush_painter_2d_do_partial(BrushPainter *painter, ImBuf *oldtexibuf BKE_brush_sample_tex_2D(scene, brush, xy, tf); } - bf[0] = tf[0] * mf[0]; - bf[1] = tf[1] * mf[1]; - bf[2] = tf[2] * mf[2]; - bf[3] = tf[3] * mf[3]; + /* output premultiplied float image, mf was already premultiplied */ + bf[0] = tf[0] * tf[3] * mf[0]; + bf[1] = tf[1] * tf[3] * mf[1]; + bf[2] = tf[2] * tf[3] * mf[2]; + bf[3] = tf[3] * tf[3] * mf[3]; } } } diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index de3c4db3b60..f6f85fd9fbd 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -3533,7 +3533,7 @@ typedef struct ProjectHandle { struct ImagePool *pool; } ProjectHandle; -static void blend_color_mix(unsigned char cp[4], const unsigned char cp1[4], const unsigned char cp2[4], const int fac) +static void interpolate_color(unsigned char cp[4], const unsigned char cp1[4], const unsigned char cp2[4], const int fac) { /* this and other blending modes previously used >>8 instead of /255. both * are not equivalent (>>8 is /256), and the former results in rounding @@ -3546,7 +3546,7 @@ static void blend_color_mix(unsigned char cp[4], const unsigned char cp1[4], con cp[3] = (mfac * cp1[3] + fac * cp2[3]) / 255; } -static void blend_color_mix_float(float cp[4], const float cp1[4], const float cp2[4], const float fac) +static void interpolate_color_float(float cp[4], const float cp1[4], const float cp2[4], const float fac) { const float mfac = 1.0f - fac; cp[0] = mfac * cp1[0] + fac * cp2[0]; @@ -3584,7 +3584,7 @@ static void do_projectpaint_clone(ProjPaintState *ps, ProjPixel *projPixel, floa { if (ps->do_masking && mask < 1.0f) { projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, ((ProjPixelClone *)projPixel)->clonepx.uint, (int)(alpha * 255), ps->blend); - blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255)); + interpolate_color(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255)); } else { *projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, ((ProjPixelClone *)projPixel)->clonepx.uint, (int)(alpha * mask * 255), ps->blend); @@ -3595,7 +3595,7 @@ static void do_projectpaint_clone_f(ProjPaintState *ps, ProjPixel *projPixel, fl { if (ps->do_masking && mask < 1.0f) { IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, ((ProjPixelClone *)projPixel)->clonepx.f, alpha, ps->blend); - blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask); + interpolate_color_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask); } else { IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.f, alpha * mask, ps->blend); @@ -3616,7 +3616,7 @@ static void do_projectpaint_smear(ProjPaintState *ps, ProjPixel *projPixel, floa if (project_paint_PickColor(ps, co, NULL, rgba_ub, 1) == 0) return; /* ((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */ - blend_color_mix(((ProjPixelClone *)projPixel)->clonepx.ch, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha * mask * 255)); + interpolate_color(((ProjPixelClone *)projPixel)->clonepx.ch, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha * mask * 255)); BLI_linklist_prepend_arena(smearPixels, (void *)projPixel, smearArena); } @@ -3629,7 +3629,7 @@ static void do_projectpaint_smear_f(ProjPaintState *ps, ProjPixel *projPixel, fl return; /* (ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*((unsigned int *)rgba_smear), *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */ - blend_color_mix_float(((ProjPixelClone *)projPixel)->clonepx.f, projPixel->pixel.f_pt, rgba, alpha * mask); + interpolate_color_float(((ProjPixelClone *)projPixel)->clonepx.f, projPixel->pixel.f_pt, rgba, alpha * mask); BLI_linklist_prepend_arena(smearPixels_f, (void *)projPixel, smearArena); } @@ -3669,8 +3669,8 @@ static void do_projectpaint_soften_f(ProjPaintState *ps, ProjPixel *projPixel, f if (LIKELY(accum_tot != 0)) { mul_v4_fl(rgba, 1.0f / (float)accum_tot); - blend_color_mix_float(rgba, projPixel->pixel.f_pt, rgba, alpha); - if (mask < 1.0f) blend_color_mix_float(rgba, projPixel->origColor.f, rgba, mask); + interpolate_color_float(rgba, projPixel->pixel.f_pt, rgba, alpha); + if (mask < 1.0f) interpolate_color_float(rgba, projPixel->origColor.f, rgba, mask); BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena); } } @@ -3706,8 +3706,8 @@ static void do_projectpaint_soften(ProjPaintState *ps, ProjPixel *projPixel, flo mul_v4_fl(rgba, 1.0f / (float)accum_tot); IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba_ub, rgba); - blend_color_mix(rgba_ub, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha * 255)); - if (mask != 1.0f) blend_color_mix(rgba_ub, projPixel->origColor.ch, rgba_ub, (int)(mask * 255)); + interpolate_color(rgba_ub, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha * 255)); + if (mask != 1.0f) interpolate_color(rgba_ub, projPixel->origColor.ch, rgba_ub, (int)(mask * 255)); BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena); } } @@ -3734,7 +3734,7 @@ static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, const if (ps->do_masking && mask < 1.0f) { projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, *((unsigned int *)rgba_ub), (int)(alpha * 255), ps->blend); - blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255)); + interpolate_color(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255)); } else { *projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha * mask * 255), ps->blend); @@ -3756,7 +3756,7 @@ static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, flo if (ps->do_masking && mask < 1.0f) { IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, rgba, alpha, ps->blend); - blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask); + interpolate_color_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask); } else { IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, rgba, alpha * mask, ps->blend); diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 59242e9020f..5eb7e663fd6 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -171,7 +171,7 @@ typedef enum IMB_BlendMode { unsigned int IMB_blend_color(unsigned int src1, unsigned int src2, int fac, IMB_BlendMode mode); -void IMB_blend_color_float(float *dst, float *src1, float *src2, float fac, +void IMB_blend_color_float(float dst[4], float src1[4], float src2[4], float fac, IMB_BlendMode mode); void IMB_rectclip(struct ImBuf *dbuf, struct ImBuf *sbuf, int *destx, diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c index 9e0c4f85273..54651b91e31 100644 --- a/source/blender/imbuf/intern/rectop.c +++ b/source/blender/imbuf/intern/rectop.c @@ -36,6 +36,7 @@ #include "BLI_utildefines.h" #include "BLI_math_base.h" #include "BLI_math_color.h" +#include "BLI_math_color_blend.h" #include "BLI_math_vector.h" #include "imbuf.h" @@ -48,7 +49,7 @@ /* blend modes */ -static void blend_color_mix(char cp[3], const char cp1[3], const char cp2[3], const int fac) +static void imb_blend_color_mix(char cp[3], const char cp1[3], const char cp2[3], const int fac) { /* this and other blending modes previously used >>8 instead of /255. both * are not equivalent (>>8 is /256), and the former results in rounding @@ -64,7 +65,7 @@ static void blend_color_mix(char cp[3], const char cp1[3], const char cp2[3], co cp[3] = (temp > 255) ? 255 : temp; } -static void blend_color_add(char cp[3], const char cp1[3], const char cp2[3], const int fac) +static void imb_blend_color_add(char cp[3], const char cp1[3], const char cp2[3], const int fac) { int temp; @@ -79,7 +80,7 @@ static void blend_color_add(char cp[3], const char cp1[3], const char cp2[3], co cp[3] = (temp > 255) ? 255 : temp; } -static void blend_color_sub(char cp[3], const char cp1[3], const char cp2[3], const int fac) +static void imb_blend_color_sub(char cp[3], const char cp1[3], const char cp2[3], const int fac) { int temp; @@ -94,7 +95,7 @@ static void blend_color_sub(char cp[3], const char cp1[3], const char cp2[3], co cp[3] = (temp > 255) ? 255 : temp; } -static void blend_color_mul(char cp[3], const char cp1[3], const char cp2[3], const int fac) +static void imb_blend_color_mul(char cp[3], const char cp1[3], const char cp2[3], const int fac) { int mfac = 255 - fac; int temp; @@ -108,7 +109,7 @@ static void blend_color_mul(char cp[3], const char cp1[3], const char cp2[3], co cp[3] = (temp > 255) ? 255 : temp; } -static void blend_color_lighten(char cp[3], const char cp1[3], const char cp2[3], const int fac) +static void imb_blend_color_lighten(char cp[3], const char cp1[3], const char cp2[3], const int fac) { /* See if are lighter, if so mix, else don't do anything. * if the paint col is darker then the original, then ignore */ @@ -123,11 +124,11 @@ static void blend_color_lighten(char cp[3], const char cp1[3], const char cp2[3] cp[3] = (temp > 255) ? 255 : temp; } else { - blend_color_mix(cp, cp1, cp2, fac); + imb_blend_color_mix(cp, cp1, cp2, fac); } } -static void blend_color_darken(char cp[3], const char cp1[3], const char cp2[3], const int fac) +static void imb_blend_color_darken(char cp[3], const char cp1[3], const char cp2[3], const int fac) { /* See if were darker, if so mix, else don't do anything. * if the paint col is brighter then the original, then ignore */ @@ -142,11 +143,11 @@ static void blend_color_darken(char cp[3], const char cp1[3], const char cp2[3], cp[3] = (temp > 255) ? 255 : temp; } else { - blend_color_mix(cp, cp1, cp2, fac); + imb_blend_color_mix(cp, cp1, cp2, fac); } } -static void blend_color_erase_alpha(char cp[4], const char cp1[4], const char cp2[4], const int fac) +static void imb_blend_color_erase_alpha(char cp[4], const char cp1[4], const char cp2[4], const int fac) { int temp = cp1[3] - divide_round_i(fac * cp2[3], 255); @@ -156,7 +157,7 @@ static void blend_color_erase_alpha(char cp[4], const char cp1[4], const char cp cp[3] = (temp < 0) ? 0 : temp; } -static void blend_color_add_alpha(char cp[4], const char cp1[4], const char cp2[4], const int fac) +static void imb_blend_color_add_alpha(char cp[4], const char cp1[4], const char cp2[4], const int fac) { int temp = cp1[3] + divide_round_i(fac * cp2[3], 255); @@ -181,21 +182,21 @@ unsigned int IMB_blend_color(unsigned int src1, unsigned int src2, int fac, IMB_ switch (mode) { case IMB_BLEND_MIX: - blend_color_mix(cp, cp1, cp2, fac); break; + imb_blend_color_mix(cp, cp1, cp2, fac); break; case IMB_BLEND_ADD: - blend_color_add(cp, cp1, cp2, fac); break; + imb_blend_color_add(cp, cp1, cp2, fac); break; case IMB_BLEND_SUB: - blend_color_sub(cp, cp1, cp2, fac); break; + imb_blend_color_sub(cp, cp1, cp2, fac); break; case IMB_BLEND_MUL: - blend_color_mul(cp, cp1, cp2, fac); break; + imb_blend_color_mul(cp, cp1, cp2, fac); break; case IMB_BLEND_LIGHTEN: - blend_color_lighten(cp, cp1, cp2, fac); break; + imb_blend_color_lighten(cp, cp1, cp2, fac); break; case IMB_BLEND_DARKEN: - blend_color_darken(cp, cp1, cp2, fac); break; + imb_blend_color_darken(cp, cp1, cp2, fac); break; case IMB_BLEND_ERASE_ALPHA: - blend_color_erase_alpha(cp, cp1, cp2, fac); break; + imb_blend_color_erase_alpha(cp, cp1, cp2, fac); break; case IMB_BLEND_ADD_ALPHA: - blend_color_add_alpha(cp, cp1, cp2, fac); break; + imb_blend_color_add_alpha(cp, cp1, cp2, fac); break; default: cp[0] = cp1[0]; cp[1] = cp1[1]; @@ -207,7 +208,7 @@ unsigned int IMB_blend_color(unsigned int src1, unsigned int src2, int fac, IMB_ return dst; } -static void blend_color_mix_float(float cp[3], const float cp1[3], const float cp2[3], const float fac) +static void imb_blend_color_mix_float(float cp[3], const float cp1[3], const float cp2[3], const float fac) { float mfac = 1.0f - fac; cp[0] = mfac * cp1[0] + fac * cp2[0]; @@ -215,7 +216,7 @@ static void blend_color_mix_float(float cp[3], const float cp1[3], const float c cp[2] = mfac * cp1[2] + fac * cp2[2]; } -static void blend_color_add_float(float cp[3], const float cp1[3], const float cp2[3], const float fac) +static void imb_blend_color_add_float(float cp[3], const float cp1[3], const float cp2[3], const float fac) { cp[0] = cp1[0] + fac * cp2[0]; cp[1] = cp1[1] + fac * cp2[1]; @@ -226,7 +227,7 @@ static void blend_color_add_float(float cp[3], const float cp1[3], const float c if (cp[2] > 1.0f) cp[2] = 1.0f; } -static void blend_color_sub_float(float cp[3], const float cp1[3], const float cp2[3], const float fac) +static void imb_blend_color_sub_float(float cp[3], const float cp1[3], const float cp2[3], const float fac) { cp[0] = cp1[0] - fac * cp2[0]; cp[1] = cp1[1] - fac * cp2[1]; @@ -237,7 +238,7 @@ static void blend_color_sub_float(float cp[3], const float cp1[3], const float c if (cp[2] < 0.0f) cp[2] = 0.0f; } -static void blend_color_mul_float(float cp[3], const float cp1[3], const float cp2[3], const float fac) +static void imb_blend_color_mul_float(float cp[3], const float cp1[3], const float cp2[3], const float fac) { float mfac = 1.0f - fac; @@ -246,7 +247,7 @@ static void blend_color_mul_float(float cp[3], const float cp1[3], const float c cp[2] = mfac * cp1[2] + fac * (cp1[2] * cp2[2]); } -static void blend_color_lighten_float(float cp[3], const float cp1[3], const float cp2[3], const float fac) +static void imb_blend_color_lighten_float(float cp[3], const float cp1[3], const float cp2[3], const float fac) { /* See if are lighter, if so mix, else don't do anything. * if the pafloat col is darker then the original, then ignore */ @@ -256,10 +257,10 @@ static void blend_color_lighten_float(float cp[3], const float cp1[3], const flo cp[2] = cp1[2]; } else - blend_color_mix_float(cp, cp1, cp2, fac); + imb_blend_color_mix_float(cp, cp1, cp2, fac); } -static void blend_color_darken_float(float cp[3], const float cp1[3], const float cp2[3], const float fac) +static void imb_blend_color_darken_float(float cp[3], const float cp1[3], const float cp2[3], const float fac) { /* See if were darker, if so mix, else don't do anything. * if the pafloat col is brighter then the original, then ignore */ @@ -269,31 +270,10 @@ static void blend_color_darken_float(float cp[3], const float cp1[3], const floa cp[2] = cp1[2]; } else - blend_color_mix_float(cp, cp1, cp2, fac); + imb_blend_color_mix_float(cp, cp1, cp2, fac); } -static void blend_color_erase_alpha_float(float cp[4], const float cp1[4], const float cp2[4], const float fac) -{ - cp[0] = cp1[0]; - cp[1] = cp1[1]; - cp[2] = cp1[2]; - - cp[3] = (cp1[3] - fac * cp2[3]); - if (cp[3] < 0.0f) cp[3] = 0.0f; -} - -static void blend_color_add_alpha_float(float cp[4], const float cp1[4], const float cp2[4], const float fac) -{ - cp[0] = cp1[0]; - cp[1] = cp1[1]; - cp[2] = cp1[2]; - - cp[3] = (cp1[3] + fac * cp2[3]); - if (cp[3] < 0.0f) cp[3] = 0.0f; - if (cp[3] > 1.0f) cp[3] = 1.0f; -} - -void IMB_blend_color_float(float *dst, float *src1, float *src2, float fac, IMB_BlendMode mode) +void IMB_blend_color_float(float dst[4], float src1[4], float src2[4], float fac, IMB_BlendMode mode) { if (fac == 0) { dst[0] = src1[0]; @@ -305,17 +285,17 @@ void IMB_blend_color_float(float *dst, float *src1, float *src2, float fac, IMB_ switch (mode) { case IMB_BLEND_MIX: - blend_color_mix_float(dst, src1, src2, fac); break; + imb_blend_color_mix_float(dst, src1, src2, fac); break; case IMB_BLEND_ADD: - blend_color_add_float(dst, src1, src2, fac); break; + imb_blend_color_add_float(dst, src1, src2, fac); break; case IMB_BLEND_SUB: - blend_color_sub_float(dst, src1, src2, fac); break; + imb_blend_color_sub_float(dst, src1, src2, fac); break; case IMB_BLEND_MUL: - blend_color_mul_float(dst, src1, src2, fac); break; + imb_blend_color_mul_float(dst, src1, src2, fac); break; case IMB_BLEND_LIGHTEN: - blend_color_lighten_float(dst, src1, src2, fac); break; + imb_blend_color_lighten_float(dst, src1, src2, fac); break; case IMB_BLEND_DARKEN: - blend_color_darken_float(dst, src1, src2, fac); break; + imb_blend_color_darken_float(dst, src1, src2, fac); break; default: dst[0] = src1[0]; dst[1] = src1[1]; @@ -389,8 +369,8 @@ void IMB_rectcpy(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx, IMB_BLEND_COPY); } -typedef void (*IMB_blend_func)(char *dst, const char *src1, const char *src2, const int fac); -typedef void (*IMB_blend_func_float)(float *dst, const float *src1, const float *src2, const float fac); +typedef void (*IMB_blend_func)(unsigned char *dst, const unsigned char *src1, const unsigned char *src2); +typedef void (*IMB_blend_func_float)(float *dst, const float *src1, const float *src2); void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx, @@ -498,35 +478,35 @@ void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx, else { switch (mode) { case IMB_BLEND_MIX: - func = blend_color_mix; + func = blend_color_mix_byte; func_float = blend_color_mix_float; break; case IMB_BLEND_ADD: - func = blend_color_add; + func = blend_color_add_byte; func_float = blend_color_add_float; break; case IMB_BLEND_SUB: - func = blend_color_sub; + func = blend_color_sub_byte; func_float = blend_color_sub_float; break; case IMB_BLEND_MUL: - func = blend_color_mul; + func = blend_color_mul_byte; func_float = blend_color_mul_float; break; case IMB_BLEND_LIGHTEN: - func = blend_color_lighten; + func = blend_color_lighten_byte; func_float = blend_color_lighten_float; break; case IMB_BLEND_DARKEN: - func = blend_color_darken; + func = blend_color_darken_byte; func_float = blend_color_darken_float; break; case IMB_BLEND_ERASE_ALPHA: - func = blend_color_erase_alpha; + func = blend_color_erase_alpha_byte; func_float = blend_color_erase_alpha_float; break; case IMB_BLEND_ADD_ALPHA: - func = blend_color_add_alpha; + func = blend_color_add_alpha_byte; func_float = blend_color_add_alpha_float; break; default: @@ -539,8 +519,8 @@ void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx, dr = drect; sr = srect; for (x = width; x > 0; x--, dr++, sr++) { - if (((char *)sr)[3]) - func((char *)dr, (char *)dr, (char *)sr, ((char *)sr)[3]); + if (((unsigned char *)sr)[3]) + func((unsigned char *)dr, (unsigned char *)dr, (unsigned char *)sr); } drect += destskip; @@ -552,7 +532,7 @@ void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx, srf = srectf; for (x = width; x > 0; x--, drf += 4, srf += 4) { if (srf[3] != 0) - func_float(drf, drf, srf, srf[3]); + func_float(drf, drf, srf); } drectf += destskip * 4; srectf += srcskip * 4; diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index 7fee67cd569..6be1933f12f 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -27,6 +27,7 @@ #include <stdlib.h> #include "BLI_math_base.h" +#include "BLI_math_rotation.h" #include "BLF_translation.h" diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index c5160cbd6e0..bcf89562f59 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -40,6 +40,7 @@ #include "BLI_array.h" #include "BLI_math_base.h" #include "BLI_math_rotation.h" +#include "BLI_utildefines.h" #include "RNA_access.h" #include "RNA_define.h" |