diff options
author | senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2010-12-07 21:07:56 +0000 |
---|---|---|
committer | senorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2010-12-07 21:07:56 +0000 |
commit | ec7a30cc8688923e0ccfff4c8f81c5e577c4c9ab (patch) | |
tree | e91c9784d26105c3dfd24f11df1b6871d41f36cd | |
parent | 038aff623d9fd47946cd31685f74cf473f7c84f0 (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.h | 10 | ||||
-rw-r--r-- | tests/MathTest.cpp | 14 |
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); { |