summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <ssp@redhat.com>2013-11-18 13:26:33 -0500
committerSøren Sandmann <ssp@redhat.com>2014-01-04 16:13:27 -0500
commit8f3824316300e257a3698daa13db802e32489236 (patch)
tree9f6acd46d9ae955b6af4f2bc35ffd6e595dc1c7a
parent89662adf77c69c3f71ded9cd8818ac5626b68451 (diff)
Soft Light: Consistent approach to division by zero
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.
-rw-r--r--pixman/pixman-combine-float.c2
-rw-r--r--pixman/pixman-combine32.c2
-rw-r--r--test/utils.c2
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
{