aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2010-12-07 21:07:56 +0000
committerGravatar senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2010-12-07 21:07:56 +0000
commitec7a30cc8688923e0ccfff4c8f81c5e577c4c9ab (patch)
treee91c9784d26105c3dfd24f11df1b6871d41f36cd
parent038aff623d9fd47946cd31685f74cf473f7c84f0 (diff)
Upstream mulDiv255Ceil() from WebKit to the skia repository.
(Patch by Noel Gordon (noel.gordon@gmail.com)) Review URL: http://codereview.appspot.com/3466042 git-svn-id: http://skia.googlecode.com/svn/trunk@632 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/core/SkMath.h10
-rw-r--r--tests/MathTest.cpp14
2 files changed, 24 insertions, 0 deletions
diff --git a/include/core/SkMath.h b/include/core/SkMath.h
index e0f23617ee..22ebd60748 100644
--- a/include/core/SkMath.h
+++ b/include/core/SkMath.h
@@ -213,6 +213,16 @@ static inline U8CPU SkMulDiv255Round(U8CPU a, U8CPU b) {
return (prod + (prod >> 8)) >> 8;
}
+/** Return (a*b)/255, taking the ceiling of any fractional bits. Only valid if
+ both a and b are 0..255. The expected result equals (a * b + 254) / 255.
+ */
+static inline U8CPU SkMulDiv255Ceiling(U8CPU a, U8CPU b) {
+ SkASSERT((uint8_t)a == a);
+ SkASSERT((uint8_t)b == b);
+ unsigned prod = SkMulS16(a, b) + 255;
+ return (prod + (prod >> 8)) >> 8;
+}
+
/** Return a*b/((1 << shift) - 1), rounding any fractional bits.
Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
*/
diff --git a/tests/MathTest.cpp b/tests/MathTest.cpp
index 4bfbd94283..2555d73866 100644
--- a/tests/MathTest.cpp
+++ b/tests/MathTest.cpp
@@ -171,6 +171,19 @@ static void test_muldiv255(skiatest::Reporter* reporter) {
#endif
}
+static void test_muldiv255ceiling(skiatest::Reporter* reporter) {
+ for (int c = 0; c <= 255; c++) {
+ for (int a = 0; a <= 255; a++) {
+ int product = (c * a + 255);
+ int expected_ceiling = (product + (product >> 8)) >> 8;
+ int webkit_ceiling = (c * a + 254) / 255;
+ REPORTER_ASSERT(reporter, expected_ceiling == webkit_ceiling);
+ int skia_ceiling = SkMulDiv255Ceiling(c, a);
+ REPORTER_ASSERT(reporter, skia_ceiling == webkit_ceiling);
+ }
+ }
+}
+
static void test_copysign(skiatest::Reporter* reporter) {
static const int32_t gTriples[] = {
// x, y, expected result
@@ -237,6 +250,7 @@ static void TestMath(skiatest::Reporter* reporter) {
#endif
test_muldiv255(reporter);
+ test_muldiv255ceiling(reporter);
test_copysign(reporter);
{