mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
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:
143
blitbuffer.c
143
blitbuffer.c
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user