Bug 633627 - Fixedpoint division in blur code. r=jmuizelaar
authorAlon Zakai <azakai@mozilla.com>
Mon, 19 Sep 2011 09:32:59 -0700
changeset 77134 2e63e7fcecd69f25a0195700b7343c66f99ce880
parent 77133 19518187d2e8051bddb81c2fc7a5f99ae4053e16
child 77135 f1586578808bb623b198ac31ef19e9a2dee61325
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjmuizelaar
bugs633627
milestone9.0a1
Bug 633627 - Fixedpoint division in blur code. r=jmuizelaar
gfx/thebes/gfxBlur.cpp
--- a/gfx/thebes/gfxBlur.cpp
+++ b/gfx/thebes/gfxBlur.cpp
@@ -141,29 +141,34 @@ BoxBlurHorizontal(unsigned char* aInput,
                   PRInt32 aRows,
                   const nsIntRect& aSkipRect)
 {
     NS_ASSERTION(aWidth > 0, "Can't handle zero width here");
 
     PRInt32 boxSize = aLeftLobe + aRightLobe + 1;
     PRBool skipRectCoversWholeRow = 0 >= aSkipRect.x &&
                                     aWidth <= aSkipRect.XMost();
+    if (boxSize == 1) {
+        memcpy(aOutput, aInput, aWidth*aRows);
+        return;
+    }
+    PRUint32 reciprocal = (PRUint64(1) << 32)/boxSize;
 
     for (PRInt32 y = 0; y < aRows; y++) {
         // Check whether the skip rect intersects this row. If the skip
         // rect covers the whole surface in this row, we can avoid
         // this row entirely (and any others along the skip rect).
         PRBool inSkipRectY = y >= aSkipRect.y &&
                              y < aSkipRect.YMost();
         if (inSkipRectY && skipRectCoversWholeRow) {
             y = aSkipRect.YMost() - 1;
             continue;
         }
 
-        PRInt32 alphaSum = 0;
+        PRUint32 alphaSum = 0;
         for (PRInt32 i = 0; i < boxSize; i++) {
             PRInt32 pos = i - aLeftLobe;
             // See assertion above; if aWidth is zero, then we would have no
             // valid position to clamp to.
             pos = NS_MAX(pos, 0);
             pos = NS_MIN(pos, aWidth - 1);
             alphaSum += aInput[aWidth * y + pos];
         }
@@ -187,17 +192,17 @@ BoxBlurHorizontal(unsigned char* aInput,
                     pos = NS_MIN(pos, aWidth - 1);
                     alphaSum += aInput[aWidth * y + pos];
                 }
             }
             PRInt32 tmp = x - aLeftLobe;
             PRInt32 last = NS_MAX(tmp, 0);
             PRInt32 next = NS_MIN(tmp + boxSize, aWidth - 1);
 
-            aOutput[aWidth * y + x] = alphaSum/boxSize;
+            aOutput[aWidth * y + x] = (PRUint64(alphaSum)*reciprocal) >> 32;
 
             alphaSum += aInput[aWidth * y + next] -
                         aInput[aWidth * y + last];
         }
     }
 }
 
 /**
@@ -214,26 +219,31 @@ BoxBlurVertical(unsigned char* aInput,
                 PRInt32 aRows,
                 const nsIntRect& aSkipRect)
 {
     NS_ASSERTION(aRows > 0, "Can't handle zero rows here");
 
     PRInt32 boxSize = aTopLobe + aBottomLobe + 1;
     PRBool skipRectCoversWholeColumn = 0 >= aSkipRect.y &&
                                        aRows <= aSkipRect.YMost();
+    if (boxSize == 1) {
+        memcpy(aOutput, aInput, aWidth*aRows);
+        return;
+    }
+    PRUint32 reciprocal = (PRUint64(1) << 32)/boxSize;
 
     for (PRInt32 x = 0; x < aWidth; x++) {
         PRBool inSkipRectX = x >= aSkipRect.x &&
                              x < aSkipRect.XMost();
         if (inSkipRectX && skipRectCoversWholeColumn) {
             x = aSkipRect.XMost() - 1;
             continue;
         }
 
-        PRInt32 alphaSum = 0;
+        PRUint32 alphaSum = 0;
         for (PRInt32 i = 0; i < boxSize; i++) {
             PRInt32 pos = i - aTopLobe;
             // See assertion above; if aRows is zero, then we would have no
             // valid position to clamp to.
             pos = NS_MAX(pos, 0);
             pos = NS_MIN(pos, aRows - 1);
             alphaSum += aInput[aWidth * pos + x];
         }
@@ -253,17 +263,17 @@ BoxBlurVertical(unsigned char* aInput,
                     pos = NS_MIN(pos, aRows - 1);
                     alphaSum += aInput[aWidth * pos + x];
                 }
             }
             PRInt32 tmp = y - aTopLobe;
             PRInt32 last = NS_MAX(tmp, 0);
             PRInt32 next = NS_MIN(tmp + boxSize, aRows - 1);
 
-            aOutput[aWidth * y + x] = alphaSum/boxSize;
+            aOutput[aWidth * y + x] = (PRUint64(alphaSum)*reciprocal) >> 32;
 
             alphaSum += aInput[aWidth * next + x] -
                         aInput[aWidth * last + x];
         }
     }
 }
 
 static void ComputeLobes(PRInt32 aRadius, PRInt32 aLobes[3][2])