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
This commit is contained in:
reed@android.com 2010-04-14 13:36:33 +00:00
parent c846ede6a0
commit 258cb228c6
4 changed files with 36 additions and 11 deletions

View File

@ -137,6 +137,15 @@ bool SkBitmapProcShader::setContext(const SkBitmap& device,
#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 @@ void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
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 @@ void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
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;
}

View File

@ -543,7 +543,6 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
*/
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 @@ int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const {
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;
}

View File

@ -91,10 +91,11 @@ struct SkBitmapProcState {
*/
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.

View File

@ -368,7 +368,7 @@ static void clampx_nofilter_trans(const SkBitmapProcState& s,
}
// 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,