[Pixman] [PATCH 4/5] Make ColorDodge code follow the math closer

Søren Sandmann Pedersen sandmann at cs.au.dk
Sat Oct 5 17:30:47 PDT 2013


Change blend_color_dodge() to follow the math in the comment more
closely.

Note, the new code here is in some sense worse than the old code
because it can now underflow the unsigned variables when the source is
superluminescent and (as - s) is therefore negative. The old code was
careful to clamp to 0.

But for superluminescent variables we really need the ability for the
blend function to become negative, and so the solution the underflow
problem is to just use signed variables. The use of unsigned variables
is a general problem in all of the blend mode code that will have to
be solved later.

The CRC32 values in thread-test and blitters-test are updated to
account for the changes in output.
---
 pixman/pixman-combine32.c | 15 +++++++--------
 test/blitters-test.c      |  2 +-
 test/thread-test.c        |  2 +-
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/pixman/pixman-combine32.c b/pixman/pixman-combine32.c
index e0a6a98..af059eb 100644
--- a/pixman/pixman-combine32.c
+++ b/pixman/pixman-combine32.c
@@ -742,15 +742,14 @@ PDF_SEPARABLE_BLEND_MODE (lighten)
 static inline uint32_t
 blend_color_dodge (uint32_t d, uint32_t ad, uint32_t s, uint32_t as)
 {
-    if (s >= as)
-    {
-	return d == 0 ? 0 : DIV_ONE_UN8 (as * ad);
-    }
+    if (d == 0)
+        return 0;
+    else if (as * d >= ad * (as - s))
+	return DIV_ONE_UN8 (as * ad);
+    else if (as - s == 0)
+        return DIV_ONE_UN8 (as * ad);
     else
-    {
-	uint32_t r = d * as / (as - s);
-	return DIV_ONE_UN8 (as * MIN (r, ad));
-    }
+        return DIV_ONE_UN8 (as * ((d * as) / ((as - s))));
 }
 
 PDF_SEPARABLE_BLEND_MODE (color_dodge)
diff --git a/test/blitters-test.c b/test/blitters-test.c
index 920cbbb..396b5b5 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -394,6 +394,6 @@ main (int argc, const char *argv[])
     }
 
     return fuzzer_test_main("blitters", 2000000,
-			    0xAC8FDA98,
+			    0x6A783AD5,
 			    test_composite, argc, argv);
 }
diff --git a/test/thread-test.c b/test/thread-test.c
index f24c31d..a0c7819 100644
--- a/test/thread-test.c
+++ b/test/thread-test.c
@@ -181,7 +181,7 @@ main (void)
 
     crc32 = compute_crc32 (0, crc32s, sizeof crc32s);
 
-#define EXPECTED 0xFD497D8D
+#define EXPECTED 0x12F4B484
 
     if (crc32 != EXPECTED)
     {
-- 
1.7.11.7



More information about the Pixman mailing list