fix overflow in matrixproc, and add debugging code to test that



git-svn-id: http://skia.googlecode.com/svn/trunk@548 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index bd4fece..c3fd7d0 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -137,6 +137,15 @@
 
 #define BUF_MAX     128
 
+#define TEST_BUFFER_OVERRITEx
+
+#ifdef TEST_BUFFER_OVERRITE
+    #define TEST_BUFFER_EXTRA   32
+    #define TEST_PATTERN    0x88888888
+#else
+    #define TEST_BUFFER_EXTRA   0
+#endif
+
 void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
     const SkBitmapProcState& state = fState;
     if (state.fShaderProc32) {
@@ -144,10 +153,10 @@
         return;
     }
 
-    uint32_t buffer[BUF_MAX];
+    uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA];
     SkBitmapProcState::MatrixProc   mproc = state.fMatrixProc;
     SkBitmapProcState::SampleProc32 sproc = state.fSampleProc32;
-    int max = fState.maxCountForBufferSize(sizeof(buffer));
+    int max = fState.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX);
 
     SkASSERT(state.fBitmap->getPixels());
     SkASSERT(state.fBitmap->pixelRef() == NULL ||
@@ -158,12 +167,24 @@
         if (n > max) {
             n = max;
         }
+        SkASSERT(n > 0 && n < BUF_MAX*2);
+#ifdef TEST_BUFFER_OVERRITE
+        for (int i = 0; i < TEST_BUFFER_EXTRA; i++) {
+            buffer[BUF_MAX + i] = TEST_PATTERN;
+        }
+#endif
         mproc(state, buffer, n, x, y);
+#ifdef TEST_BUFFER_OVERRITE
+        for (int j = 0; j < TEST_BUFFER_EXTRA; j++) {
+            SkASSERT(buffer[BUF_MAX + j] == TEST_PATTERN);
+        }
+#endif
         sproc(state, buffer, n, dstC);
         
         if ((count -= n) == 0) {
             break;
         }
+        SkASSERT(count > 0);
         x += n;
         dstC += n;
     }
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp
index eabd966..e54818d 100644
--- a/src/core/SkBitmapProcState.cpp
+++ b/src/core/SkBitmapProcState.cpp
@@ -543,7 +543,6 @@
  */
 int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const {
     int32_t size = static_cast<int32_t>(bufferSize);
-    int perElemShift;
 
     size &= ~3; // only care about 4-byte aligned chunks
     if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
@@ -551,11 +550,15 @@
         if (size < 0) {
             size = 0;
         }
-        perElemShift = fDoFilter ? 2 : 1;
+        size >>= 1;
     } else {
-        perElemShift = fDoFilter ? 3 : 2;
+        size >>= 2;
     }
 
-    return size >> perElemShift;
+    if (fDoFilter) {
+        size >>= 1;
+    }
+
+    return size;
 }
 
diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h
index dd73c33..303696f 100644
--- a/src/core/SkBitmapProcState.h
+++ b/src/core/SkBitmapProcState.h
@@ -91,10 +91,11 @@
      */
     void platformProcs();
 
-    /** Given the size of a buffer, to be used for calling the matrix and
-        sample procs, this return the maximum count that can be stored in the
-        buffer, taking into account that filtering and scale-vs-affine affect
-        this value.
+    /** Given the byte size of the index buffer to be passed to the matrix proc,
+        return the maximum number of resulting pixels that can be computed
+        (i.e. the number of SkPMColor values to be written by the sample proc).
+        This routine takes into account that filtering and scale-vs-affine
+        affect the amount of buffer space needed.
      
         Only valid to call after chooseProcs (setContext) has been called. It is
         safe to call this inside the shader's shadeSpan() method.
diff --git a/src/core/SkBitmapProcState_matrixProcs.cpp b/src/core/SkBitmapProcState_matrixProcs.cpp
index 6654312..d0bc8d8 100644
--- a/src/core/SkBitmapProcState_matrixProcs.cpp
+++ b/src/core/SkBitmapProcState_matrixProcs.cpp
@@ -368,7 +368,7 @@
     }
 
     // fill the remaining with the max value
-    sk_memset16(xptr, width - 1, count * sizeof(uint16_t));
+    sk_memset16(xptr, width - 1, count);
 }
 
 static void repeatx_nofilter_trans(const SkBitmapProcState& s,