diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libpbm3.c | 4 | ||||
-rw-r--r-- | lib/libppmd.c | 86 |
2 files changed, 67 insertions, 23 deletions
diff --git a/lib/libpbm3.c b/lib/libpbm3.c index 7debedb9..084eeccc 100644 --- a/lib/libpbm3.c +++ b/lib/libpbm3.c @@ -116,7 +116,11 @@ packBitsWithMmxSse(FILE * const fileP, ) ]; */ +#if (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) + typedef char v8qi __attribute__ ((vector_size(8))); +#else typedef int v8qi __attribute__ ((mode(V8QI))); +#endif typedef int di __attribute__ ((mode(DI))); di const zero64 = 0; /* to clear with PXOR */ diff --git a/lib/libppmd.c b/lib/libppmd.c index e7be29b9..167d5c76 100644 --- a/lib/libppmd.c +++ b/lib/libppmd.c @@ -33,6 +33,17 @@ struct penpos { int y; }; +struct rectangle { + /* ((0,0),(0,0)) means empty. */ + /* 'lr' is guaranteed not to be left of or above 'ul' */ + struct penpos ul; + struct penpos lr; +}; + +static struct rectangle const emptyRectangle = { + {0, 0}, + {0, 0}, +}; @@ -76,7 +87,32 @@ ppmd_point_drawproc(pixel** const pixels, } -/* Simple fill routine. */ +static void +findRectangleIntersection(struct rectangle const rect1, + struct rectangle const rect2, + struct rectangle * const intersectionP) { +/*---------------------------------------------------------------------------- + Find the intersection between rectangles 'rect1' and 'rect2'. + Return it as *intersectionP. +-----------------------------------------------------------------------------*/ + struct penpos tentativeUl, tentativeLr; + + tentativeUl.x = MAX(rect1.ul.x, rect2.ul.x); + tentativeUl.y = MAX(rect1.ul.y, rect2.ul.y); + tentativeLr.x = MIN(rect1.lr.x, rect2.lr.x); + tentativeLr.y = MIN(rect1.lr.y, rect2.lr.y); + + if (tentativeLr.x <= tentativeUl.x || + tentativeLr.y <= tentativeUl.y) { + /* No intersection */ + *intersectionP = emptyRectangle; + } else { + intersectionP->ul = tentativeUl; + intersectionP->lr = tentativeLr; + } +} + + void ppmd_filledrectangle(pixel ** const pixels, @@ -87,35 +123,39 @@ ppmd_filledrectangle(pixel ** const pixels, int const y, int const width, int const height, - ppmd_drawproc drawProc, + ppmd_drawproc drawProc, const void * const clientdata) { - int cx, cy, cwidth, cheight, row; + struct rectangle image, request, intersection; + unsigned int row; - /* Clip. */ - cx = x; - cy = y; - cwidth = width; - cheight = height; + if (width < 0) + pm_error("negative width %d passed to ppmd_filledrectangle", width); + if (height < 0) + pm_error("negative height %d passed to ppmd_filledrectangle", height); + if (cols < 0) + pm_error("negative image width %d passed to ppmd_filledrectangle", + cols); + if (rows < 0) + pm_error("negative image height %d passed to ppmd_filledrectangle", + rows); - if (cx < 0) { - cx = 0; - cwidth += x; - } - if (cy < 0) { - cy = 0; - cheight += y; - } - if (cx + cwidth > cols) - cwidth = cols - cx; + request.ul.x = x; + request.ul.y = y; + request.lr.x = x + width; + request.lr.y = y + height; + + image.ul.x = 0; + image.ul.y = 0; + image.lr.x = cols; + image.lr.y = rows; - if (cy + cheight > rows) - cheight = rows - cy; + findRectangleIntersection(image, request, &intersection); /* Draw. */ - for (row = cy; row < cy + cheight; ++row) { - int col; - for (col = cx; col < cx + cwidth; ++col) + for (row = intersection.ul.y; row < intersection.lr.y; ++row) { + unsigned int col; + for (col = intersection.ul.x; col < intersection.lr.x; ++col) drawPoint(drawProc, clientdata, pixels, cols, rows, maxval, col, row); } |