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.
8f38243 Soft Light: Consistent approach to division by zero
pixman/pixman-combine-float.c | 2 +-
pixman/pixman-combine32.c | 2 +-
test/utils.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)