[gimp] Bug 790566 - Modify the divide blend mode to not max out at 5.0
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 790566 - Modify the divide blend mode to not max out at 5.0
- Date: Sat, 6 Jan 2018 17:36:44 +0000 (UTC)
commit 0f9da165e078e146cbe960a6aa5f909677d27eb5
Author: Ell <ell_se yahoo com>
Date: Sat Jan 6 11:48:58 2018 -0500
Bug 790566 - Modify the divide blend mode to not max out at 5.0
Add a safe_div() function to gimpoperationlayermode-blend.c, and
use it in the relevant blend funcs, instead of plain division.
This function clamps the quotient to some reasonable range, to
avoid infinities, and maps epsilon/... to 0, to avoid NaN. The
latter part results in similar qualitative results to the
corresponding legacy modes, when calculating 0/0.
.../layer-modes/gimpoperationlayermode-blend.c | 78 ++++++++++---------
1 files changed, 41 insertions(+), 37 deletions(-)
---
diff --git a/app/operations/layer-modes/gimpoperationlayermode-blend.c
b/app/operations/layer-modes/gimpoperationlayermode-blend.c
index 3bf0ebd..973dc66 100644
--- a/app/operations/layer-modes/gimpoperationlayermode-blend.c
+++ b/app/operations/layer-modes/gimpoperationlayermode-blend.c
@@ -35,7 +35,41 @@
#include "gimpoperationlayermode-blend.h"
-#define EPSILON 1e-6f
+#define EPSILON 1e-6f
+
+#define SAFE_DIV_MIN EPSILON
+#define SAFE_DIV_MAX (1.0f / SAFE_DIV_MIN)
+
+
+/* local function prototypes */
+
+static inline gfloat safe_div (gfloat a,
+ gfloat b);
+
+
+/* private functions */
+
+
+/* returns a / b, clamped to [-SAFE_DIV_MAX, SAFE_DIV_MAX].
+ * if -SAFE_DIV_MIN <= a <= SAFE_DIV_MIN, returns 0.
+ */
+static inline gfloat
+safe_div (gfloat a,
+ gfloat b)
+{
+ gfloat result = 0.0f;
+
+ if (fabsf (a) > SAFE_DIV_MIN)
+ {
+ result = a / b;
+ result = CLAMP (result, -SAFE_DIV_MAX, SAFE_DIV_MAX);
+ }
+
+ return result;
+}
+
+
+/* public functions */
/* non-subtractive blending functions. these functions must set comp[ALPHA]
@@ -82,14 +116,7 @@ gimp_operation_layer_mode_blend_burn (const gfloat *in,
gint c;
for (c = 0; c < 3; c++)
- {
- gfloat val = 1.0f - (1.0f - in[c]) / layer[c];
-
- /* The CLAMP macro is deliberately inlined and written
- * to map comp == NAN (0 / 0) -> 1
- */
- comp[c] = val < 0 ? 0.0f : val < 1.0f ? val : 1.0f;
- }
+ comp[c] = 1.0f - safe_div (1.0f - in[c], layer[c]);
}
comp[ALPHA] = layer[ALPHA];
@@ -166,19 +193,7 @@ gimp_operation_layer_mode_blend_divide (const gfloat *in,
gint c;
for (c = 0; c < 3; c++)
- {
- gfloat val = in[c] / layer[c];
-
- /* make infinities(or NaN) correspond to a high number,
- * to get more predictable math, ideally higher than 5.0
- * but it seems like some babl conversions might be
- * acting up then
- */
- if (!(val > -42949672.0f && val < 5.0f))
- val = 5.0f;
-
- comp[c] = val;
- }
+ comp[c] = safe_div (in[c], layer[c]);
}
comp[ALPHA] = layer[ALPHA];
@@ -202,13 +217,7 @@ gimp_operation_layer_mode_blend_dodge (const gfloat *in,
gint c;
for (c = 0; c < 3; c++)
- {
- gfloat val = in[c] / (1.0f - layer[c]);
-
- val = MIN (val, 1.0f);
-
- comp[c] = val;
- }
+ comp[c] = safe_div (in[c], 1.0f - layer[c]);
}
comp[ALPHA] = layer[ALPHA];
@@ -872,7 +881,7 @@ gimp_operation_layer_mode_blend_luminance (const gfloat *in,
{
if (layer[ALPHA] != 0.0f && in[ALPHA] != 0.0f)
{
- gfloat ratio = layer_Y_p[0] / MAX(in_Y_p[0], 0.0000000000000000001);
+ gfloat ratio = safe_div (layer_Y_p[0], in_Y_p[0]);
gint c;
for (c = 0; c < 3; c ++)
comp[c] = in[c] * ratio;
@@ -1082,14 +1091,9 @@ gimp_operation_layer_mode_blend_vivid_light (const gfloat *in,
gfloat val;
if (layer[c] <= 0.5f)
- {
- val = 1.0f - (1.0f - in[c]) / (2.0f * (layer[c]));
- }
+ val = 1.0f - safe_div (1.0f - in[c], 2.0f * layer[c]);
else
- {
- val = in[c] / (2.0f * (1.0f - layer[c]));
- }
- val = MIN (val, 1.0f);
+ val = safe_div (in[c], 2.0f * (1.0f - layer[c]));
comp[c] = val;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]