зеркало из 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 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) {
|
void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
|
||||||
const SkBitmapProcState& state = fState;
|
const SkBitmapProcState& state = fState;
|
||||||
if (state.fShaderProc32) {
|
if (state.fShaderProc32) {
|
||||||
|
@ -144,10 +153,10 @@ void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t buffer[BUF_MAX];
|
uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA];
|
||||||
SkBitmapProcState::MatrixProc mproc = state.fMatrixProc;
|
SkBitmapProcState::MatrixProc mproc = state.fMatrixProc;
|
||||||
SkBitmapProcState::SampleProc32 sproc = state.fSampleProc32;
|
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->getPixels());
|
||||||
SkASSERT(state.fBitmap->pixelRef() == NULL ||
|
SkASSERT(state.fBitmap->pixelRef() == NULL ||
|
||||||
|
@ -158,12 +167,24 @@ void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
|
||||||
if (n > max) {
|
if (n > max) {
|
||||||
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);
|
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);
|
sproc(state, buffer, n, dstC);
|
||||||
|
|
||||||
if ((count -= n) == 0) {
|
if ((count -= n) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
SkASSERT(count > 0);
|
||||||
x += n;
|
x += n;
|
||||||
dstC += n;
|
dstC += n;
|
||||||
}
|
}
|
||||||
|
|
|
@ -543,7 +543,6 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
|
||||||
*/
|
*/
|
||||||
int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const {
|
int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const {
|
||||||
int32_t size = static_cast<int32_t>(bufferSize);
|
int32_t size = static_cast<int32_t>(bufferSize);
|
||||||
int perElemShift;
|
|
||||||
|
|
||||||
size &= ~3; // only care about 4-byte aligned chunks
|
size &= ~3; // only care about 4-byte aligned chunks
|
||||||
if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
|
if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
|
||||||
|
@ -551,11 +550,15 @@ int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const {
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
perElemShift = fDoFilter ? 2 : 1;
|
size >>= 1;
|
||||||
} else {
|
} else {
|
||||||
perElemShift = fDoFilter ? 3 : 2;
|
size >>= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return size >> perElemShift;
|
if (fDoFilter) {
|
||||||
|
size >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,10 +91,11 @@ struct SkBitmapProcState {
|
||||||
*/
|
*/
|
||||||
void platformProcs();
|
void platformProcs();
|
||||||
|
|
||||||
/** Given the size of a buffer, to be used for calling the matrix and
|
/** Given the byte size of the index buffer to be passed to the matrix proc,
|
||||||
sample procs, this return the maximum count that can be stored in the
|
return the maximum number of resulting pixels that can be computed
|
||||||
buffer, taking into account that filtering and scale-vs-affine affect
|
(i.e. the number of SkPMColor values to be written by the sample proc).
|
||||||
this value.
|
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
|
Only valid to call after chooseProcs (setContext) has been called. It is
|
||||||
safe to call this inside the shader's shadeSpan() method.
|
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
|
// 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,
|
static void repeatx_nofilter_trans(const SkBitmapProcState& s,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче