about summary refs log tree commit diff
path: root/editor/pamrubber.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2011-04-07 03:14:11 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2011-04-07 03:14:11 +0000
commit61f4bbba826090298e1dff2c960db35286f6a0c4 (patch)
tree9c89624db9c28b07d9bc6ad60c2cb8b211a1c5b6 /editor/pamrubber.c
parent53967ba521969a1decb5259f2523f061c7d2d3db (diff)
downloadnetpbm-mirror-61f4bbba826090298e1dff2c960db35286f6a0c4.tar.gz
netpbm-mirror-61f4bbba826090298e1dff2c960db35286f6a0c4.tar.xz
netpbm-mirror-61f4bbba826090298e1dff2c960db35286f6a0c4.zip
Fix crash
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1471 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'editor/pamrubber.c')
-rw-r--r--editor/pamrubber.c323
1 files changed, 175 insertions, 148 deletions
diff --git a/editor/pamrubber.c b/editor/pamrubber.c
index 81a3070a..b1c5dca9 100644
--- a/editor/pamrubber.c
+++ b/editor/pamrubber.c
@@ -171,10 +171,10 @@ makepoint(double const x,
 
 
 static double
-distance(point * const p1P,
-         point * const p2P) {
+distance(point const p1,
+         point const p2) {
 
-    return sqrt(SQR(p1P->x - p2P->x) + SQR(p1P->y - p2P->y));
+    return sqrt(SQR(p1.x - p2.x) + SQR(p1.y - p2.y));
 }
 
 
@@ -274,30 +274,30 @@ maketriangle(point const p1,
 
 static int
 insidetri(triangle * const triP,
-          point *    const pP) {
+          point      const p) {
 
     int cnt;
 
     cnt = 0;  /* initial value */
 
-    if ((((triP->p1.y <= pP->y) && (pP->y < triP->p3.y))
-         || ((triP->p3.y <= pP->y) && (pP->y < triP->p1.y)))
+    if ((((triP->p1.y <= p.y) && (p.y < triP->p3.y))
+         || ((triP->p3.y <= p.y) && (p.y < triP->p1.y)))
         &&
-        (pP->x < (triP->p3.x - triP->p1.x) * (pP->y - triP->p1.y)
+        (p.x < (triP->p3.x - triP->p1.x) * (p.y - triP->p1.y)
          / (triP->p3.y - triP->p1.y) + triP->p1.x))
         cnt = !cnt;
 
-    if ((((triP->p2.y <= pP->y) && (pP->y < triP->p1.y))
-         || ((triP->p1.y <= pP->y) && (pP->y < triP->p2.y)))
+    if ((((triP->p2.y <= p.y) && (p.y < triP->p1.y))
+         || ((triP->p1.y <= p.y) && (p.y < triP->p2.y)))
         &&
-        (pP->x < (triP->p1.x - triP->p2.x) * (pP->y - triP->p2.y)
+        (p.x < (triP->p1.x - triP->p2.x) * (p.y - triP->p2.y)
          / (triP->p1.y - triP->p2.y) + triP->p2.x))
         cnt = !cnt;
 
-    if ((((triP->p3.y <= pP->y) && (pP->y < triP->p2.y))
-         || ((triP->p2.y <= pP->y) && (pP->y < triP->p3.y)))
+    if ((((triP->p3.y <= p.y) && (p.y < triP->p2.y))
+         || ((triP->p2.y <= p.y) && (p.y < triP->p3.y)))
         &&
-        (pP->x < (triP->p2.x - triP->p3.x) * (pP->y - triP->p3.y)
+        (p.x < (triP->p2.x - triP->p3.x) * (p.y - triP->p3.y)
          / (triP->p2.y - triP->p3.y) + triP->p3.x))
         cnt = !cnt;
 
@@ -350,7 +350,10 @@ tiny(void) {
 static void
 angle(point * const p1P,
       point * const p2P) {
-
+/*----------------------------------------------------------------------------
+   Move *p2P slightly if necessary to make sure the line (*p1P, *p2P)
+   is not horizontal or vertical.
+-----------------------------------------------------------------------------*/
     if (p1P->x == p2P->x) { /* vertical line */
         p2P->x += tiny();
     }
@@ -803,14 +806,16 @@ prepTrig(int const wd,
         c2p2 = newCP[1];
         c2p3 = newCP[2];
 
-        /* check for hor/ver edges */
-        angle (&c1p1, &c1p2);
-        angle (&c1p2, &c1p3);
-        angle (&c1p3, &c1p1);
+        /* Move vertices slightly if necessary to make sure no edge is
+           horizontal or vertical.
+        */
+        angle(&c1p1, &c1p2);
+        angle(&c1p2, &c1p3);
+        angle(&c1p3, &c1p1);
 
-        angle (&c2p1, &c2p2);
-        angle (&c2p2, &c2p3);
-        angle (&c2p3, &c2p1);
+        angle(&c2p1, &c2p2);
+        angle(&c2p2, &c2p3);
+        angle(&c2p3, &c2p1);
 
         if (windtriangle(&tri1s[0], c1p1, c1p2, c1p3)) {
             tri2s[0] = maketriangle(c2p1, c2p2, c2p3);
@@ -1028,9 +1033,9 @@ prepQuad(void) {
                furthest apart
             */
             
-            d01 = distance (&newCP[0], &newCP[1]);
-            d12 = distance (&newCP[1], &newCP[2]);
-            d20 = distance (&newCP[2], &newCP[0]);
+            d01 = distance(newCP[0], newCP[1]);
+            d12 = distance(newCP[1], newCP[2]);
+            d20 = distance(newCP[2], newCP[0]);
 
             if ((d01 > d12) && (d01 > d20)) {
                 oldCP[3].x = oldCP[0].x + oldCP[1].x - oldCP[2].x;
@@ -1113,7 +1118,7 @@ prepQuad(void) {
 
 
 static void
-warpTrig(point * const p2P,
+warpTrig(point   const p2,
          point * const p1P) {
 
 /* map target to source by triangulation */
@@ -1127,7 +1132,7 @@ warpTrig(point * const p2P,
 
     /* find in which triangle p2 lies */
     for (i = 0; i < nTri; i++) {
-        if (insidetri (&tri2s[i], p2P))
+        if (insidetri (&tri2s[i], p2))
             break;
     }
 
@@ -1135,22 +1140,22 @@ warpTrig(point * const p2P,
         *p1P = makepoint(0.0, 0.0);
     else {
         /* where in triangle is point */
-        d1 = fabs (p2P->x - tri2s[i].p1.x) + fabs (p2P->y - tri2s[i].p1.y);
-        d2 = fabs (p2P->x - tri2s[i].p2.x) + fabs (p2P->y - tri2s[i].p2.y);
-        d3 = fabs (p2P->x - tri2s[i].p3.x) + fabs (p2P->y - tri2s[i].p3.y);
+        d1 = fabs (p2.x - tri2s[i].p1.x) + fabs (p2.y - tri2s[i].p1.y);
+        d2 = fabs (p2.x - tri2s[i].p2.x) + fabs (p2.y - tri2s[i].p2.y);
+        d3 = fabs (p2.x - tri2s[i].p3.x) + fabs (p2.y - tri2s[i].p3.y);
 
         /* line through p1 and p intersecting with edge p2-p3 */
-        lp = makeline(tri2s[i].p1, *p2P);
+        lp = makeline(tri2s[i].p1, p2);
         le = makeline(tri2s[i].p2, tri2s[i].p3);
         intersect (&lp, &le, &e2p1);
 
         /* line through p2 and p intersecting with edge p3-p1 */
-        lp = makeline(tri2s[i].p2, *p2P);
+        lp = makeline(tri2s[i].p2, p2);
         le = makeline(tri2s[i].p3, tri2s[i].p1);
         intersect (&lp, &le, &e2p2);
 
         /* line through p3 and p intersecting with edge p1-p2 */
-        lp = makeline(tri2s[i].p3, *p2P);
+        lp = makeline(tri2s[i].p3, p2);
         le = makeline(tri2s[i].p1, tri2s[i].p2);
         intersect (&lp, &le, &e2p3);
 
@@ -1191,76 +1196,80 @@ warpTrig(point * const p2P,
 
 
 static void
-warpQuad(point * const p2P,
+warpQuad(point   const p2,
          point * const p1P) {
 
 /* map target to source for quad control points */
 
-  point h2, v2;
-  point c1tl, c1tr, c1bl, c1br;
-  point c2tl, c2tr, c2bl, c2br;
-  point e1t, e1b, e1l, e1r;
-  point e2t, e2b, e2l, e2r;
-  line l2t, l2b, l2l, l2r;
-  line lh, lv;
-
-  c1tl = quad1.tl;
-  c1tr = quad1.tr;
-  c1bl = quad1.bl;
-  c1br = quad1.br;
+    point h2, v2;
+    point c1tl, c1tr, c1bl, c1br;
+    point c2tl, c2tr, c2bl, c2br;
+    point e1t, e1b, e1l, e1r;
+    point e2t, e2b, e2l, e2r;
+    line l2t, l2b, l2l, l2r;
+    line lh, lv;
+
+    c1tl = quad1.tl;
+    c1tr = quad1.tr;
+    c1bl = quad1.bl;
+    c1br = quad1.br;
        
-  c2tl = quad2.tl;
-  c2tr = quad2.tr;
-  c2bl = quad2.bl;
-  c2br = quad2.br;
-
-  l2t = makeline(c2tl, c2tr);
-  l2b = makeline(c2bl, c2br);
-  l2l = makeline(c2tl, c2bl);
-  l2r = makeline(c2tr, c2br);
-
-  /* find intersections of lines through control points */
-  intersect (&l2t, &l2b, &h2);
-  intersect (&l2l, &l2r, &v2);
-
-  /* find intersections of axes through P with control point box */
-  lv = makeline(*p2P, v2);
-  intersect (&l2t, &lv, &e2t);
-  intersect (&l2b, &lv, &e2b);
-
-  lh = makeline(*p2P, h2);
-  intersect (&l2l, &lh, &e2l);
-  intersect (&l2r, &lh, &e2r);
-
-  /* map target control points to source control points */
-  e1t.x = c1tl.x + (e2t.x - c2tl.x)/(c2tr.x - c2tl.x) * (c1tr.x - c1tl.x);
-  if (c1tl.y == c1tr.y)
-    e1t.y = c1tl.y;
-  else
-    e1t.y = c1tl.y + (e2t.x - c2tl.x)/(c2tr.x - c2tl.x) * (c1tr.y - c1tl.y);
-
-  e1b.x = c1bl.x + (e2b.x - c2bl.x)/(c2br.x - c2bl.x) * (c1br.x - c1bl.x);
-  if (c1bl.y == c1br.y)
-    e1b.y = c1bl.y;
-  else
-    e1b.y = c1bl.y + (e2b.x - c2bl.x)/(c2br.x - c2bl.x) * (c1br.y - c1bl.y);
-
-  if (c1tl.x == c1bl.x)
-    e1l.x = c1tl.x;
-  else
-    e1l.x = c1tl.x + (e2l.y - c2tl.y)/(c2bl.y - c2tl.y) * (c1bl.x - c1tl.x);
-  e1l.y = c1tl.y + (e2l.y - c2tl.y)/(c2bl.y - c2tl.y) * (c1bl.y - c1tl.y);
-
-  if (c1tr.x == c1br.x)
-    e1r.x = c1tr.x;
-  else
-    e1r.x = c1tr.x + (e2r.y - c2tr.y)/(c2br.y - c2tr.y) * (c1br.x - c1tr.x);
-  e1r.y = c1tr.y + (e2r.y - c2tr.y)/(c2br.y - c2tr.y) * (c1br.y - c1tr.y);
-
-  /* intersect grid lines in source */
-  lv = makeline(e1t, e1b);
-  lh = makeline(e1l, e1r);
-  intersect (&lh, &lv, p1P);
+    c2tl = quad2.tl;
+    c2tr = quad2.tr;
+    c2bl = quad2.bl;
+    c2br = quad2.br;
+
+    l2t = makeline(c2tl, c2tr);
+    l2b = makeline(c2bl, c2br);
+    l2l = makeline(c2tl, c2bl);
+    l2r = makeline(c2tr, c2br);
+
+    /* find intersections of lines through control points */
+    intersect (&l2t, &l2b, &h2);
+    intersect (&l2l, &l2r, &v2);
+
+    /* find intersections of axes through P with control point box */
+    lv = makeline(p2, v2);
+    intersect (&l2t, &lv, &e2t);
+    intersect (&l2b, &lv, &e2b);
+
+    lh = makeline(p2, h2);
+    intersect (&l2l, &lh, &e2l);
+    intersect (&l2r, &lh, &e2r);
+
+    /* map target control points to source control points */
+    e1t.x = c1tl.x + (e2t.x - c2tl.x)/(c2tr.x - c2tl.x) * (c1tr.x - c1tl.x);
+    if (c1tl.y == c1tr.y)
+        e1t.y = c1tl.y;
+    else
+        e1t.y =
+            c1tl.y + (e2t.x - c2tl.x)/(c2tr.x - c2tl.x) * (c1tr.y - c1tl.y);
+
+    e1b.x = c1bl.x + (e2b.x - c2bl.x)/(c2br.x - c2bl.x) * (c1br.x - c1bl.x);
+    if (c1bl.y == c1br.y)
+        e1b.y = c1bl.y;
+    else
+        e1b.y =
+            c1bl.y + (e2b.x - c2bl.x)/(c2br.x - c2bl.x) * (c1br.y - c1bl.y);
+
+    if (c1tl.x == c1bl.x)
+        e1l.x = c1tl.x;
+    else
+        e1l.x =
+            c1tl.x + (e2l.y - c2tl.y)/(c2bl.y - c2tl.y) * (c1bl.x - c1tl.x);
+    e1l.y = c1tl.y + (e2l.y - c2tl.y)/(c2bl.y - c2tl.y) * (c1bl.y - c1tl.y);
+
+    if (c1tr.x == c1br.x)
+        e1r.x = c1tr.x;
+    else
+        e1r.x
+            = c1tr.x + (e2r.y - c2tr.y)/(c2br.y - c2tr.y) * (c1br.x - c1tr.x);
+    e1r.y = c1tr.y + (e2r.y - c2tr.y)/(c2br.y - c2tr.y) * (c1br.y - c1tr.y);
+
+    /* intersect grid lines in source */
+    lv = makeline(e1t, e1b);
+    lh = makeline(e1l, e1r);
+    intersect (&lh, &lv, p1P);
 }
 
 
@@ -1300,44 +1309,6 @@ createWhiteTuple(const struct pam * const pamP,
 
 
 
-static sample
-pix(tuple **     const tuples,
-    point        const p,
-    unsigned int const plane,
-    bool         const linear) {
-                    
-    double pix;
-
-    if (!linear) {
-        pix = tuples
-            [(int) floor(p.y + 0.5)]
-            [(int) floor(p.x + 0.5)][plane];
-    } else {
-        double const rx = p.x - floor(p.x);
-        double const ry = p.y - floor(p.y);
-        pix = 0.0;
-        pix += (1.0 - rx) * (1.0 - ry)
-            * tuples
-            [(int) floor(p.y)]
-            [(int) floor(p.x)][plane];
-        pix += rx * (1.0 - ry)
-            * tuples
-            [(int) floor(p.y)]
-            [(int) floor(p.x) + 1][plane];
-        pix += (1.0 - rx) * ry 
-            * tuples
-            [(int) floor(p.y) + 1]
-            [(int) floor(p.x)][plane];
-        pix += rx * ry
-            * tuples
-            [(int) floor(p.y) + 1]
-            [(int) floor(p.x) + 1][plane];
-    }
-    return (int) floor(pix);
-}
-
-
-
 static void
 makeAllWhite(struct pam * const pamP,
              tuple **     const tuples) {
@@ -1358,6 +1329,64 @@ makeAllWhite(struct pam * const pamP,
 
 
 
+static sample
+pix(tuple **     const tuples,
+    unsigned int const width,
+    unsigned int const height,
+    point        const p1,
+    unsigned int const plane,
+    bool         const linear) {
+
+    point p;
+    double pix;
+
+    p.x = p1.x + 1E-3;
+    p.y = p1.y + 1E-3;
+
+    if (p.x < 0.0)
+        p.x = 0.0;
+    if (p.x > (double) width - 1.0)
+        p.x = (double) width - 1.0;
+    if (p.y < 0.0)
+        p.y = 0.0;
+    if (p.y > (double) height - 1.0)
+        p.y = (double) height - 1.0;
+
+    if (!linear) {
+        pix = tuples
+            [(int) floor(p.y + 0.5)]
+            [(int) floor(p.x + 0.5)][plane];
+    } else {
+        double const rx = p.x - floor(p.x);
+        double const ry = p.y - floor(p.y);
+        pix = 0.0;
+        if (((int) floor(p.x) >= 0) && ((int) floor(p.x) < width) &&
+            ((int) floor(p.y) >= 0) && ((int) floor(p.y) < height)) {
+            pix += (1.0 - rx) * (1.0 - ry) 
+                * tuples[(int) floor(p.y)][(int) floor(p.x)][plane];
+        }
+        if (((int) floor(p.x) + 1 >= 0) && ((int) floor(p.x) + 1 < width) &&
+            ((int) floor(p.y) >= 0) && ((int) floor(p.y) < height)) {
+            pix += rx * (1.0 - ry) 
+                * tuples[(int) floor(p.y)][(int) floor(p.x) + 1][plane];
+        }
+        if (((int) floor(p.x) >= 0) && ((int) floor(p.x) < width) &&
+            ((int) floor(p.y) + 1 >= 0) && ((int) floor(p.y) + 1 < height)) {
+            pix += (1.0 - rx) * ry 
+                * tuples[(int) floor(p.y) + 1][(int) floor(p.x)][plane];
+        }
+        if (((int) floor(p.x) + 1 >= 0) && ((int) floor(p.x) + 1 < width) &&
+            ((int) floor(p.y) + 1 >= 0) && ((int) floor(p.y) + 1 < height)) {
+            pix += rx * ry 
+                * tuples[(int) floor(p.y) + 1][(int) floor(p.x) + 1][plane];
+        }
+    }
+
+    return (int) floor(pix);
+}
+
+
+
 int
 main(int argc, const char ** const argv) {
 
@@ -1366,7 +1395,6 @@ main(int argc, const char ** const argv) {
     struct pam inpam, outpam;
     tuple ** inTuples;
     tuple ** outTuples;
-
     unsigned int p2y;
   
     pm_proginit(&argc, argv);
@@ -1399,22 +1427,18 @@ main(int argc, const char ** const argv) {
         unsigned int p2x;
         for (p2x = 0; p2x < inpam.width; ++p2x) {
             point p1, p2;
+            unsigned int plane;
+
             p2 = makepoint(p2x, p2y);
             if (cmdline.quad)
-                warpQuad (&p2, &p1);
+                warpQuad(p2, &p1);
             if (cmdline.tri)
-                warpTrig (&p2, &p1);
-
-            p1.x += 1E-3;
-            p1.y += 1E-3;
-            if ((p1.x >= 0.0) && (p1.x < (double) inpam.width - 0.5) &&
-                (p1.y >= 0.0) && (p1.y < (double) inpam.height - 0.5)) {
-                unsigned int plane;
-                for (plane = 0; plane < inpam.depth; ++plane) {
-                    outTuples[p2y][p2x][plane] =
-                        pix(inTuples, p1, plane, cmdline.linear);
+                warpTrig(p2, &p1);
 
-                }
+            for (plane = 0; plane < inpam.depth; ++plane) {
+                outTuples[p2y][p2x][plane] =
+                    pix(inTuples, inpam.width, inpam.height, p1, plane,
+                        cmdline.linear);
             }
         }
     }
@@ -1444,3 +1468,6 @@ main(int argc, const char ** const argv) {
 
     return 0;
 }
+
+
+