Fix SkFixed overflows in SkFixedSquare, SkGradientShader.
Return SK_FixedMax when overflow occurs.
git-svn-id: http://skia.googlecode.com/svn/trunk@1117 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkFixed.h b/include/core/SkFixed.h
index 2a2456e..1deb72c 100644
--- a/include/core/SkFixed.h
+++ b/include/core/SkFixed.h
@@ -118,7 +118,11 @@
uint32_t a = SkAbs32(value);
uint32_t ah = a >> 16;
uint32_t al = a & 0xFFFF;
- return ah * a + al * ah + (al * al >> 16);
+ SkFixed result = ah * a + al * ah + (al * al >> 16);
+ if (result >= 0)
+ return result;
+ else // Overflow.
+ return SK_FixedMax;
}
#define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16)
diff --git a/src/effects/SkGradientShader.cpp b/src/effects/SkGradientShader.cpp
index dca87b0..f43cf4b 100644
--- a/src/effects/SkGradientShader.cpp
+++ b/src/effects/SkGradientShader.cpp
@@ -1096,7 +1096,10 @@
else if (proc == mirror_tileproc)
{
do {
- SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
+ SkFixed magnitudeSquared = SkFixedSquare(fx) + SkFixedSquare(fy);
+ if (magnitudeSquared < 0) // Overflow.
+ magnitudeSquared = SK_FixedMax;
+ SkFixed dist = SkFixedSqrt(magnitudeSquared);
unsigned fi = mirror_tileproc(dist);
SkASSERT(fi <= 0xFFFF);
*dstC++ = cache[fi >> (16 - kCache32Bits)];
@@ -1108,7 +1111,10 @@
{
SkASSERT(proc == repeat_tileproc);
do {
- SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
+ SkFixed magnitudeSquared = SkFixedSquare(fx) + SkFixedSquare(fy);
+ if (magnitudeSquared < 0) // Overflow.
+ magnitudeSquared = SK_FixedMax;
+ SkFixed dist = SkFixedSqrt(magnitudeSquared);
unsigned fi = repeat_tileproc(dist);
SkASSERT(fi <= 0xFFFF);
*dstC++ = cache[fi >> (16 - kCache32Bits)];