зеркало из https://github.com/mozilla/moz-skia.git
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:
Родитель
c846ede6a0
Коммит
258cb228c6
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче