[Pixman] [PATCH 09/13] Soft Light: Consistent approach to division by zero

Søren Sandmann sandmann at cs.au.dk
Wed Dec 11 07:41:58 PST 2013


The Soft Light operator has several branches. One them is decided
based on whether 2 * s is less than or equal to 2 * sa. In floating
point implementations, when those two values are very close to each
other, it may not be completely predictable which branch we hit.

This is a problem because in one branch, when destination alpha is
zero, we get the result

      r = d * as

and in the other we get

      r = 0

So when d and as are not 0, this causes two different results to be
returned from essentially identical input values. In other words,
there is a discontinuity in the current implementation.

This patch randomly changes the second branch such that it now returns
d * sa instead. There is no deep meaning behind this, because
essentially this is an attempt to assign meaning to division by zero,
and all that is requires is that that meaning doesn't depend on minute
differences in input values.

This makes the number of failed pixels in pixel-test go down to 347.
---
 pixman/pixman-combine-float.c | 2 +-
 pixman/pixman-combine32.c     | 2 +-
 test/utils.c                  | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/pixman/pixman-combine-float.c b/pixman/pixman-combine-float.c
index e9aab48..ff02105 100644
--- a/pixman/pixman-combine-float.c
+++ b/pixman/pixman-combine-float.c
@@ -449,7 +449,7 @@ blend_soft_light (float sa, float s, float da, float d)
     {
 	if (FLOAT_IS_ZERO (da))
 	{
-	    return 0.0f;
+	    return d * sa;
 	}
 	else
 	{
diff --git a/pixman/pixman-combine32.c b/pixman/pixman-combine32.c
index 01c2523..d4425ac 100644
--- a/pixman/pixman-combine32.c
+++ b/pixman/pixman-combine32.c
@@ -893,7 +893,7 @@ blend_soft_light (int32_t d_org,
     }
     else if (ad == 0)
     {
-	r = 0;
+	r = d * as;
     }
     else if (4 * d <= ad)
     {
diff --git a/test/utils.c b/test/utils.c
index c57ca64..d182710 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -1198,7 +1198,7 @@ blend_soft_light (double sa, double s, double da, double d)
     {
         if (IS_ZERO (da))
         {
-            return 0.0f;
+	    return d * sa;
         }
         else
         {
-- 
1.8.3.1



More information about the Pixman mailing list