about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2008-05-14 03:49:24 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2008-05-14 03:49:24 +0000
commitbd0e223d1bfa19c1ed4997d37e27e22db94ed538 (patch)
treec812d2b481ae7623ad2c456ee4519a9b791e60c8
parent7e51994ff76dd2f4efcf0eb599c7e35a132c9855 (diff)
downloadnetpbm-mirror-bd0e223d1bfa19c1ed4997d37e27e22db94ed538.tar.gz
netpbm-mirror-bd0e223d1bfa19c1ed4997d37e27e22db94ed538.tar.xz
netpbm-mirror-bd0e223d1bfa19c1ed4997d37e27e22db94ed538.zip
cleanup, add error checking to ppmd_filled_rectangle, add backward compatibility ppmd_fill_init()
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@626 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--doc/HISTORY9
-rw-r--r--lib/libppmd.c100
-rw-r--r--lib/ppmdraw.h4
3 files changed, 91 insertions, 22 deletions
diff --git a/doc/HISTORY b/doc/HISTORY
index 781a02a9..395c2c26 100644
--- a/doc/HISTORY
+++ b/doc/HISTORY
@@ -6,6 +6,9 @@ CHANGE HISTORY
 
 not yet  BJH  Release 10.43.00
 
+              pamthreshold: copy transparency information from input to
+              output.
+
               pnmnorm: adjust bvalue, wvalue when -bpercent and/or -wpercent
               would cause an overlap, instead of failing.
 
@@ -19,6 +22,12 @@ not yet  BJH  Release 10.43.00
 
               pnmnorm: fix resolution of conflicting -wpercent and -wvalue.
 
+              ppmd_filledrectangle: fail properly on negative image
+              height, width.
+
+              Add back ppmd_fill_init() for backward compatibility;
+              removed in 10.29.
+
               Build: make it work with Gcc 4.3 and -sse.
 
 08.03.26 BJH  Release 10.42.00
diff --git a/lib/libppmd.c b/lib/libppmd.c
index a6ff0059..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;
 
-    if (cy + cheight > rows)
-        cheight = rows - cy;
+    image.ul.x = 0;
+    image.ul.y = 0;
+    image.lr.x = cols;
+    image.lr.y = rows;
+
+    findRectangleIntersection(image, request, &intersection);
 
     /* Draw. */
-    for (row = cy; row < cy + cheight; ++row) {
+    for (row = intersection.ul.y; row < intersection.lr.y; ++row) {
         unsigned int col;
-        for (col = cx; col < cx + cwidth; ++col)
+        for (col = intersection.ul.x; col < intersection.lr.x; ++col)
             drawPoint(drawProc, clientdata,
                       pixels, cols, rows, maxval, col, row);
     }
@@ -676,6 +716,22 @@ ppmd_fill_create(void) {
 
 
 
+char *
+ppmd_fill_init(void) {
+/*----------------------------------------------------------------------------
+   Backward compatibility interface.  This is what was used before
+   ppmd_fill_create() existed.
+
+   Note that old programs treat a fill handle as a pointer to char
+   rather than a pointer to fillObj, and backward compatibility
+   depends upon the fact that these are implemented as identical types
+   (an address).
+-----------------------------------------------------------------------------*/
+    return (char *)ppmd_fill_create();
+}
+
+
+
 void
 ppmd_fill_destroy(struct fillobj * fillObjP) {
 
diff --git a/lib/ppmdraw.h b/lib/ppmdraw.h
index a3c4f831..298668ed 100644
--- a/lib/ppmdraw.h
+++ b/lib/ppmdraw.h
@@ -237,6 +237,10 @@ ppmd_fill_create(void);
 void
 ppmd_fill_destroy(struct fillobj * fillObjP);
 
+/* For backward compatibility only: */
+char *
+ppmd_fill_init(void);
+
 void
 ppmd_fill_drawproc(pixel ** const pixels, 
                    int      const cols,