added framework to check the involved pointers in blitbuffer operations

blitbuffer operations in 4bpp can be a nasty experience, easy to
get the pointers wrong. so a macro can check them now.

Conflicts:

	blitbuffer.c
This commit is contained in:
HW
2012-10-10 16:59:07 +02:00
committed by Qingping Hou
parent b56f4bf958
commit cf38d02e80

View File

@@ -20,14 +20,19 @@
#include <string.h>
#include "blitbuffer.h"
inline int setPixel(lua_State *L, BlitBuffer *bb, int x, int y, int c) {
uint8_t *dstptr = (uint8_t*)(bb->data) + (y * bb->pitch) + (x / 2);
#ifndef NO_CHECK_BOUNDS
if(x < 0 || x >= bb->w || y < 0 || y >= bb->h) {
return luaL_error(L, "out of bounds in blitbuffer.setPixel()");
/* debugging statements, switch as needed */
#ifdef DEBUG
#define ASSERT_BLITBUFFER_BOUNDARIES(bb,bb_ptr) \
if((bb_ptr < bb->data) || (bb_ptr >= (bb->data + bb->pitch * bb->h))) { \
fprintf(stderr, "violated blitbuffer constraints in file %s, line %d!\r\n", __FILE__, __LINE__); exit(1); \
}
#endif
#else // DEBUG
#define ASSERT_BLITBUFFER_BOUNDARIES(bb,bb_ptr) {}
#endif // DEBUG
inline int setPixel(BlitBuffer *bb, int x, int y, int c) {
uint8_t *dstptr = (uint8_t*)(bb->data) + (y * bb->pitch) + (x / 2);
ASSERT_BLITBUFFER_BOUNDARIES(bb, dstptr);
if(x % 2 == 0) {
*dstptr &= 0x0F;
@@ -173,6 +178,8 @@ static int blitToBuffer(lua_State *L) {
xoffs / 2 );
if(xoffs & 1) {
for(y = 0; y < h; y++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
*dstptr &= 0xF0;
*dstptr |= *srcptr & 0x0F;
dstptr += dst->pitch;
@@ -180,6 +187,8 @@ static int blitToBuffer(lua_State *L) {
}
} else {
for(y = 0; y < h; y++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
*dstptr &= 0xF0;
*dstptr |= *srcptr >> 4;
dstptr += dst->pitch;
@@ -200,6 +209,8 @@ static int blitToBuffer(lua_State *L) {
if(xoffs & 1) {
for(y = 0; y < h; y++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
for(x = 0; x < (w / 2); x++) {
dstptr[x] = (srcptr[x] << 4) | (srcptr[x+1] >> 4);
}
@@ -212,6 +223,8 @@ static int blitToBuffer(lua_State *L) {
}
} else {
for(y = 0; y < h; y++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
memcpy(dstptr, srcptr, w / 2);
if(w & 1) {
dstptr[w/2] &= 0x0F;
@@ -270,6 +283,8 @@ static int addblitToBuffer(lua_State *L) {
xoffs / 2 );
if(xoffs & 1) {
for(y = 0; y < h; y++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
uint8_t v = (*dstptr & 0x0F) + (*srcptr & 0x0F);
*dstptr = (*dstptr & 0xF0) | (v < 0x0F ? v : 0x0F);
dstptr += dst->pitch;
@@ -277,6 +292,8 @@ static int addblitToBuffer(lua_State *L) {
}
} else {
for(y = 0; y < h; y++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
uint8_t v = (*dstptr & 0x0F) + (*srcptr >> 4);
*dstptr = (*dstptr & 0xF0) | (v < 0x0F ? v : 0x0F);
dstptr += dst->pitch;
@@ -298,11 +315,15 @@ static int addblitToBuffer(lua_State *L) {
if(xoffs & 1) {
for(y = 0; y < h; y++) {
for(x = 0; x < (w / 2); x++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
uint16_t v1 = (dstptr[x] & 0xF0) + ((srcptr[x] & 0x0F) << 4);
uint8_t v2 = (dstptr[x] & 0x0F) + (srcptr[x+1] >> 4);
dstptr[x] = (v1 < 0xF0 ? v1 : 0xF0) | (v2 < 0x0F ? v2 : 0x0F);
}
if(w & 1) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
uint16_t v1 = (dstptr[x] & 0xF0) + ((srcptr[x] & 0x0F) << 4);
dstptr[x] = (dstptr[x] & 0x0F) | (v1 < 0xF0 ? v1 : 0xF0);
}
@@ -312,11 +333,15 @@ static int addblitToBuffer(lua_State *L) {
} else {
for(y = 0; y < h; y++) {
for(x = 0; x < (w / 2); x++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
uint16_t v1 = (dstptr[x] & 0xF0) + (srcptr[x] & 0xF0);
uint8_t v2 = (dstptr[x] & 0x0F) + (srcptr[x] & 0x0F);
dstptr[x] = (v1 < 0xF0 ? v1 : 0xF0) | (v2 < 0x0F ? v2 : 0x0F);
}
if(w & 1) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
uint16_t v1 = (dstptr[x] & 0xF0) + (srcptr[x] & 0xF0);
dstptr[x] = (dstptr[x] & 0x0F) | (v1 < 0xF0 ? v1 : 0xF0);
}
@@ -337,9 +362,25 @@ static int paintRect(lua_State *L) {
uint8_t *dstptr;
int cy;
if(w <= 0 || h <= 0 || x >= dst->w || y >= dst->h) {
return 0;
if(x < 0) {
if (x+w > 0) {
w += x;
x = 0;
} else {
return 0;
}
}
if(y < 0) {
if (y+h > 0) {
h += y;
y = 0;
} else {
return 0;
}
}
if(x + w > dst->w) {
w = dst->w - x;
}
@@ -347,6 +388,10 @@ static int paintRect(lua_State *L) {
h = dst->h - y;
}
if(w <= 0 || h <= 0 || x >= dst->w || y >= dst->h) {
return 0;
}
if(x & 1) {
/* This will render the leftmost column
* in the case when x is odd. After this,
@@ -355,6 +400,7 @@ static int paintRect(lua_State *L) {
y * dst->pitch +
x / 2);
for(cy = 0; cy < h; cy++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
*dstptr &= 0xF0;
*dstptr |= c;
dstptr += dst->pitch;
@@ -366,6 +412,7 @@ static int paintRect(lua_State *L) {
y * dst->pitch +
x / 2);
for(cy = 0; cy < h; cy++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
memset(dstptr, c | (c << 4), w / 2);
dstptr += dst->pitch;
}
@@ -377,6 +424,7 @@ static int paintRect(lua_State *L) {
y * dst->pitch +
(x + w) / 2);
for(cy = 0; cy < h; cy++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
*dstptr &= 0x0F;
*dstptr |= (c << 4);
dstptr += dst->pitch;
@@ -435,6 +483,7 @@ static int invertRect(lua_State *L) {
y * dst->pitch +
x / 2);
for(cy = 0; cy < h; cy++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
*dstptr ^= 0x0F;
dstptr += dst->pitch;
}
@@ -446,6 +495,7 @@ static int invertRect(lua_State *L) {
x / 2);
for(cy = 0; cy < h; cy++) {
for(cx = 0; cx < w/2; cx++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, (dstptr+cx));
*(dstptr+cx) ^= 0xFF;
}
dstptr += dst->pitch;
@@ -458,6 +508,7 @@ static int invertRect(lua_State *L) {
y * dst->pitch +
(x + w) / 2);
for(cy = 0; cy < h; cy++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
*dstptr ^= 0xF0;
dstptr += dst->pitch;
}
@@ -474,6 +525,27 @@ static int dimRect(lua_State *L) {
uint8_t *dstptr;
int cy, cx;
if (x < 0) {
if ( x + w > 0 ) {
w = w + x;
x = 0;
} else {
//printf("## invertRect x out of bound\n");
return 0;
}
}
if (y < 0) {
if ( y + h > 0 ) {
h = h + y;
y = 0;
} else {
//printf("## invertRect y out of bound\n");
return 0;
}
}
if(w <= 0 || h <= 0 || x >= dst->w || y >= dst->h) {
return 0;
}
@@ -492,6 +564,7 @@ static int dimRect(lua_State *L) {
y * dst->pitch +
x / 2);
for(cy = 0; cy < h; cy++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
int px = *dstptr & 0x0F;
*dstptr &= 0xF0 | px >> 1;
dstptr += dst->pitch;
@@ -504,6 +577,7 @@ static int dimRect(lua_State *L) {
x / 2);
for(cy = 0; cy < h; cy++) {
for(cx = 0; cx < w/2; cx++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, (dstptr+cx));
*(dstptr+cx) =
( *(dstptr+cx) >> 1 ) & 0xF0 |
( *(dstptr+cx) & 0x0F ) >> 1;
@@ -518,6 +592,7 @@ static int dimRect(lua_State *L) {
y * dst->pitch +
(x + w) / 2);
for(cy = 0; cy < h; cy++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
int px = *dstptr & 0xF0;
*dstptr &= 0x0F | ( px >> 1 & 0xF0 );
dstptr += dst->pitch;
@@ -560,10 +635,10 @@ static int paintCircle(lua_State *L) {
/* draw two axles */
for(tmp_y = r; tmp_y > r2; tmp_y--) {
setPixel(L, dst, center_x+0, center_y+tmp_y, c);
setPixel(L, dst, center_x-0, center_y-tmp_y, c);
setPixel(L, dst, center_x+tmp_y, center_y+0, c);
setPixel(L, dst, center_x-tmp_y, center_y-0, c);
setPixel(dst, center_x+0, center_y+tmp_y, c);
setPixel(dst, center_x-0, center_y-tmp_y, c);
setPixel(dst, center_x+tmp_y, center_y+0, c);
setPixel(dst, center_x-tmp_y, center_y-0, c);
}
while(x < y) {
@@ -591,21 +666,21 @@ static int paintCircle(lua_State *L) {
}
for(tmp_y = y; tmp_y > y2; tmp_y--) {
setPixel(L, dst, center_x+x, center_y+tmp_y, c);
setPixel(L, dst, center_x+tmp_y, center_y+x, c);
setPixel(dst, center_x+x, center_y+tmp_y, c);
setPixel(dst, center_x+tmp_y, center_y+x, c);
setPixel(L, dst, center_x+tmp_y, center_y-x, c);
setPixel(L, dst, center_x+x, center_y-tmp_y, c);
setPixel(dst, center_x+tmp_y, center_y-x, c);
setPixel(dst, center_x+x, center_y-tmp_y, c);
setPixel(L, dst, center_x-x, center_y-tmp_y, c);
setPixel(L, dst, center_x-tmp_y, center_y-x, c);
setPixel(dst, center_x-x, center_y-tmp_y, c);
setPixel(dst, center_x-tmp_y, center_y-x, c);
setPixel(L, dst, center_x-tmp_y, center_y+x, c);
setPixel(L, dst, center_x-x, center_y+tmp_y, c);
setPixel(dst, center_x-tmp_y, center_y+x, c);
setPixel(dst, center_x-x, center_y+tmp_y, c);
}
}
if(r == w) {
setPixel(L, dst, center_x, center_y, c);
setPixel(dst, center_x, center_y, c);
}
return 0;
}
@@ -645,10 +720,10 @@ static int paintRoundedCorner(lua_State *L) {
/* draw two axles */
/*for(tmp_y = r; tmp_y > r2; tmp_y--) {*/
/*setPixel(L, dst, (w-r)+off_x+0, (h-r)+off_y+tmp_y-1, c);*/
/*setPixel(L, dst, (w-r)+off_x-0, (r)+off_y-tmp_y, c);*/
/*setPixel(L, dst, (w-r)+off_x+tmp_y, (h-r)+off_y+0, c);*/
/*setPixel(L, dst, (r)+off_x-tmp_y, (h-r)+off_y-0-1, c);*/
/*setPixel(dst, (w-r)+off_x+0, (h-r)+off_y+tmp_y-1, c);*/
/*setPixel(dst, (w-r)+off_x-0, (r)+off_y-tmp_y, c);*/
/*setPixel(dst, (w-r)+off_x+tmp_y, (h-r)+off_y+0, c);*/
/*setPixel(dst, (r)+off_x-tmp_y, (h-r)+off_y-0-1, c);*/
/*}*/
while(x < y) {
@@ -676,17 +751,17 @@ static int paintRoundedCorner(lua_State *L) {
}
for(tmp_y = y; tmp_y > y2; tmp_y--) {
setPixel(L, dst, (w-r)+off_x+x-1, (h-r)+off_y+tmp_y-1, c);
setPixel(L, dst, (w-r)+off_x+tmp_y-1, (h-r)+off_y+x-1, c);
setPixel(dst, (w-r)+off_x+x-1, (h-r)+off_y+tmp_y-1, c);
setPixel(dst, (w-r)+off_x+tmp_y-1, (h-r)+off_y+x-1, c);
setPixel(L, dst, (w-r)+off_x+tmp_y-1, (r)+off_y-x, c);
setPixel(L, dst, (w-r)+off_x+x-1, (r)+off_y-tmp_y, c);
setPixel(dst, (w-r)+off_x+tmp_y-1, (r)+off_y-x, c);
setPixel(dst, (w-r)+off_x+x-1, (r)+off_y-tmp_y, c);
setPixel(L, dst, (r)+off_x-x, (r)+off_y-tmp_y, c);
setPixel(L, dst, (r)+off_x-tmp_y, (r)+off_y-x, c);
setPixel(dst, (r)+off_x-x, (r)+off_y-tmp_y, c);
setPixel(dst, (r)+off_x-tmp_y, (r)+off_y-x, c);
setPixel(L, dst, (r)+off_x-tmp_y, (h-r)+off_y+x-1, c);
setPixel(L, dst, (r)+off_x-x, (h-r)+off_y+tmp_y-1, c);
setPixel(dst, (r)+off_x-tmp_y, (h-r)+off_y+x-1, c);
setPixel(dst, (r)+off_x-x, (h-r)+off_y+tmp_y-1, c);
}
}
return 0;