File indexing completed on 2024-12-22 04:04:15

0001 /* Copyright (C) 2001-2019 Peter Selinger.
0002    This file is part of Potrace. It is free software and it is covered
0003    by the GNU General Public License. See the file COPYING for details. */
0004 
0005 /* transform jaggy paths into smooth curves */
0006 
0007 #ifdef HAVE_CONFIG_H
0008 #include <config.h>
0009 #endif
0010 
0011 #include <stdio.h>
0012 #include <math.h>
0013 #include <stdlib.h>
0014 #include <string.h>
0015 
0016 #include "potracelib.h"
0017 #include "curve.h"
0018 #include "lists.h"
0019 #include "auxiliary.h"
0020 #include "trace.h"
0021 #include "progress.h"
0022 
0023 #define INFTY 10000000  /* it suffices that this is longer than any
0024                path; it need not be really infinite */
0025 #define COS179 -0.999847695156   /* the cosine of 179 degrees */
0026 
0027 /* ---------------------------------------------------------------------- */
0028 #define SAFE_CALLOC(var, n, typ) \
0029   if ((var = (typ *)calloc(n, sizeof(typ))) == NULL) goto calloc_error 
0030 
0031 /* ---------------------------------------------------------------------- */
0032 /* auxiliary functions */
0033 
0034 /* return a direction that is 90 degrees counterclockwise from p2-p0,
0035    but then restricted to one of the major wind directions (n, nw, w, etc) */
0036 static inline point_t dorth_infty(dpoint_t p0, dpoint_t p2) {
0037   point_t r;
0038   
0039   r.y = sign(p2.x-p0.x);
0040   r.x = -sign(p2.y-p0.y);
0041 
0042   return r;
0043 }
0044 
0045 /* return (p1-p0)x(p2-p0), the area of the parallelogram */
0046 static inline double dpara(dpoint_t p0, dpoint_t p1, dpoint_t p2) {
0047   double x1, y1, x2, y2;
0048 
0049   x1 = p1.x-p0.x;
0050   y1 = p1.y-p0.y;
0051   x2 = p2.x-p0.x;
0052   y2 = p2.y-p0.y;
0053 
0054   return x1*y2 - x2*y1;
0055 }
0056 
0057 /* ddenom/dpara have the property that the square of radius 1 centered
0058    at p1 intersects the line p0p2 iff |dpara(p0,p1,p2)| <= ddenom(p0,p2) */
0059 static inline double ddenom(dpoint_t p0, dpoint_t p2) {
0060   point_t r = dorth_infty(p0, p2);
0061 
0062   return r.y*(p2.x-p0.x) - r.x*(p2.y-p0.y);
0063 }
0064 
0065 /* return 1 if a <= b < c < a, in a cyclic sense (mod n) */
0066 static inline int cyclic(int a, int b, int c) {
0067   if (a<=c) {
0068     return (a<=b && b<c);
0069   } else {
0070     return (a<=b || b<c);
0071   }
0072 }
0073 
0074 /* determine the center and slope of the line i..j. Assume i<j. Needs
0075    "sum" components of p to be set. */
0076 static void pointslope(privpath_t *pp, int i, int j, dpoint_t *ctr, dpoint_t *dir) {
0077   /* assume i<j */
0078 
0079   int n = pp->len;
0080   sums_t *sums = pp->sums;
0081 
0082   double x, y, x2, xy, y2;
0083   double k;
0084   double a, b, c, lambda2, l;
0085   int r=0; /* rotations from i to j */
0086 
0087   while (j>=n) {
0088     j-=n;
0089     r+=1;
0090   }
0091   while (i>=n) {
0092     i-=n;
0093     r-=1;
0094   }
0095   while (j<0) {
0096     j+=n;
0097     r-=1;
0098   }
0099   while (i<0) {
0100     i+=n;
0101     r+=1;
0102   }
0103   
0104   x = sums[j+1].x-sums[i].x+r*sums[n].x;
0105   y = sums[j+1].y-sums[i].y+r*sums[n].y;
0106   x2 = sums[j+1].x2-sums[i].x2+r*sums[n].x2;
0107   xy = sums[j+1].xy-sums[i].xy+r*sums[n].xy;
0108   y2 = sums[j+1].y2-sums[i].y2+r*sums[n].y2;
0109   k = j+1-i+r*n;
0110   
0111   ctr->x = x/k;
0112   ctr->y = y/k;
0113 
0114   a = (x2-(double)x*x/k)/k;
0115   b = (xy-(double)x*y/k)/k;
0116   c = (y2-(double)y*y/k)/k;
0117   
0118   lambda2 = (a+c+sqrt((a-c)*(a-c)+4*b*b))/2; /* larger e.value */
0119 
0120   /* now find e.vector for lambda2 */
0121   a -= lambda2;
0122   c -= lambda2;
0123 
0124   if (fabs(a) >= fabs(c)) {
0125     l = sqrt(a*a+b*b);
0126     if (l!=0) {
0127       dir->x = -b/l;
0128       dir->y = a/l;
0129     }
0130   } else {
0131     l = sqrt(c*c+b*b);
0132     if (l!=0) {
0133       dir->x = -c/l;
0134       dir->y = b/l;
0135     }
0136   }
0137   if (l==0) {
0138     dir->x = dir->y = 0;   /* sometimes this can happen when k=4:
0139                   the two eigenvalues coincide */
0140   }
0141 }
0142 
0143 /* the type of (affine) quadratic forms, represented as symmetric 3x3
0144    matrices.  The value of the quadratic form at a vector (x,y) is v^t
0145    Q v, where v = (x,y,1)^t. */
0146 typedef double quadform_t[3][3];
0147 
0148 /* Apply quadratic form Q to vector w = (w.x,w.y) */
0149 static inline double quadform(quadform_t Q, dpoint_t w) {
0150   double v[3];
0151   int i, j;
0152   double sum;
0153 
0154   v[0] = w.x;
0155   v[1] = w.y;
0156   v[2] = 1;
0157   sum = 0.0;
0158 
0159   for (i=0; i<3; i++) {
0160     for (j=0; j<3; j++) {
0161       sum += v[i] * Q[i][j] * v[j];
0162     }
0163   }
0164   return sum;
0165 }
0166 
0167 /* calculate p1 x p2 */
0168 static inline int xprod(point_t p1, point_t p2) {
0169   return p1.x*p2.y - p1.y*p2.x;
0170 }
0171 
0172 /* calculate (p1-p0)x(p3-p2) */
0173 static inline double cprod(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
0174   double x1, y1, x2, y2;
0175 
0176   x1 = p1.x - p0.x;
0177   y1 = p1.y - p0.y;
0178   x2 = p3.x - p2.x;
0179   y2 = p3.y - p2.y;
0180 
0181   return x1*y2 - x2*y1;
0182 }
0183 
0184 /* calculate (p1-p0)*(p2-p0) */
0185 static inline double iprod(dpoint_t p0, dpoint_t p1, dpoint_t p2) {
0186   double x1, y1, x2, y2;
0187 
0188   x1 = p1.x - p0.x;
0189   y1 = p1.y - p0.y;
0190   x2 = p2.x - p0.x;
0191   y2 = p2.y - p0.y;
0192 
0193   return x1*x2 + y1*y2;
0194 }
0195 
0196 /* calculate (p1-p0)*(p3-p2) */
0197 static inline double iprod1(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
0198   double x1, y1, x2, y2;
0199 
0200   x1 = p1.x - p0.x;
0201   y1 = p1.y - p0.y;
0202   x2 = p3.x - p2.x;
0203   y2 = p3.y - p2.y;
0204 
0205   return x1*x2 + y1*y2;
0206 }
0207 
0208 /* calculate distance between two points */
0209 static inline double ddist(dpoint_t p, dpoint_t q) {
0210   return sqrt(sq(p.x-q.x)+sq(p.y-q.y));
0211 }
0212 
0213 /* calculate point of a bezier curve */
0214 static inline dpoint_t bezier(double t, dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
0215   double s = 1-t;
0216   dpoint_t res;
0217 
0218   /* Note: a good optimizing compiler (such as gcc-3) reduces the
0219      following to 16 multiplications, using common subexpression
0220      elimination. */
0221 
0222   res.x = s*s*s*p0.x + 3*(s*s*t)*p1.x + 3*(t*t*s)*p2.x + t*t*t*p3.x;
0223   res.y = s*s*s*p0.y + 3*(s*s*t)*p1.y + 3*(t*t*s)*p2.y + t*t*t*p3.y;
0224 
0225   return res;
0226 }
0227 
0228 /* calculate the point t in [0..1] on the (convex) bezier curve
0229    (p0,p1,p2,p3) which is tangent to q1-q0. Return -1.0 if there is no
0230    solution in [0..1]. */
0231 static double tangent(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3, dpoint_t q0, dpoint_t q1) {
0232   double A, B, C;   /* (1-t)^2 A + 2(1-t)t B + t^2 C = 0 */
0233   double a, b, c;   /* a t^2 + b t + c = 0 */
0234   double d, s, r1, r2;
0235 
0236   A = cprod(p0, p1, q0, q1);
0237   B = cprod(p1, p2, q0, q1);
0238   C = cprod(p2, p3, q0, q1);
0239 
0240   a = A - 2*B + C;
0241   b = -2*A + 2*B;
0242   c = A;
0243   
0244   d = b*b - 4*a*c;
0245 
0246   if (a==0 || d<0) {
0247     return -1.0;
0248   }
0249 
0250   s = sqrt(d);
0251 
0252   r1 = (-b + s) / (2 * a);
0253   r2 = (-b - s) / (2 * a);
0254 
0255   if (r1 >= 0 && r1 <= 1) {
0256     return r1;
0257   } else if (r2 >= 0 && r2 <= 1) {
0258     return r2;
0259   } else {
0260     return -1.0;
0261   }
0262 }
0263 
0264 /* ---------------------------------------------------------------------- */
0265 /* Preparation: fill in the sum* fields of a path (used for later
0266    rapid summing). Return 0 on success, 1 with errno set on
0267    failure. */
0268 static int calc_sums(privpath_t *pp) {
0269   int i, x, y;
0270   int n = pp->len;
0271 
0272   SAFE_CALLOC(pp->sums, pp->len+1, sums_t);
0273 
0274   /* origin */
0275   pp->x0 = pp->pt[0].x;
0276   pp->y0 = pp->pt[0].y;
0277 
0278   /* preparatory computation for later fast summing */
0279   pp->sums[0].x2 = pp->sums[0].xy = pp->sums[0].y2 = pp->sums[0].x = pp->sums[0].y = 0;
0280   for (i=0; i<n; i++) {
0281     x = pp->pt[i].x - pp->x0;
0282     y = pp->pt[i].y - pp->y0;
0283     pp->sums[i+1].x = pp->sums[i].x + x;
0284     pp->sums[i+1].y = pp->sums[i].y + y;
0285     pp->sums[i+1].x2 = pp->sums[i].x2 + (double)x*x;
0286     pp->sums[i+1].xy = pp->sums[i].xy + (double)x*y;
0287     pp->sums[i+1].y2 = pp->sums[i].y2 + (double)y*y;
0288   }
0289   return 0;  
0290 
0291  calloc_error:
0292   return 1;
0293 }
0294 
0295 /* ---------------------------------------------------------------------- */
0296 /* Stage 1: determine the straight subpaths (Sec. 2.2.1). Fill in the
0297    "lon" component of a path object (based on pt/len).  For each i,
0298    lon[i] is the furthest index such that a straight line can be drawn
0299    from i to lon[i]. Return 1 on error with errno set, else 0. */
0300 
0301 /* this algorithm depends on the fact that the existence of straight
0302    subpaths is a triplewise property. I.e., there exists a straight
0303    line through squares i0,...,in iff there exists a straight line
0304    through i,j,k, for all i0<=i<j<k<=in. (Proof?) */
0305 
0306 /* this implementation of calc_lon is O(n^2). It replaces an older
0307    O(n^3) version. A "constraint" means that future points must
0308    satisfy xprod(constraint[0], cur) >= 0 and xprod(constraint[1],
0309    cur) <= 0. */
0310 
0311 /* Remark for Potrace 1.1: the current implementation of calc_lon is
0312    more complex than the implementation found in Potrace 1.0, but it
0313    is considerably faster. The introduction of the "nc" data structure
0314    means that we only have to test the constraints for "corner"
0315    points. On a typical input file, this speeds up the calc_lon
0316    function by a factor of 31.2, thereby decreasing its time share
0317    within the overall Potrace algorithm from 72.6% to 7.82%, and
0318    speeding up the overall algorithm by a factor of 3.36. On another
0319    input file, calc_lon was sped up by a factor of 6.7, decreasing its
0320    time share from 51.4% to 13.61%, and speeding up the overall
0321    algorithm by a factor of 1.78. In any case, the savings are
0322    substantial. */
0323 
0324 /* returns 0 on success, 1 on error with errno set */
0325 static int calc_lon(privpath_t *pp) {
0326   point_t *pt = pp->pt;
0327   int n = pp->len;
0328   int i, j, k, k1;
0329   int ct[4], dir;
0330   point_t constraint[2];
0331   point_t cur;
0332   point_t off;
0333   int *pivk = NULL;  /* pivk[n] */
0334   int *nc = NULL;    /* nc[n]: next corner */
0335   point_t dk;  /* direction of k-k1 */
0336   int a, b, c, d;
0337 
0338   SAFE_CALLOC(pivk, n, int);
0339   SAFE_CALLOC(nc, n, int);
0340 
0341   /* initialize the nc data structure. Point from each point to the
0342      furthest future point to which it is connected by a vertical or
0343      horizontal segment. We take advantage of the fact that there is
0344      always a direction change at 0 (due to the path decomposition
0345      algorithm). But even if this were not so, there is no harm, as
0346      in practice, correctness does not depend on the word "furthest"
0347      above.  */
0348   k = 0;
0349   for (i=n-1; i>=0; i--) {
0350     if (pt[i].x != pt[k].x && pt[i].y != pt[k].y) {
0351       k = i+1;  /* necessarily i<n-1 in this case */
0352     }
0353     nc[i] = k;
0354   }
0355 
0356   SAFE_CALLOC(pp->lon, n, int);
0357 
0358   /* determine pivot points: for each i, let pivk[i] be the furthest k
0359      such that all j with i<j<k lie on a line connecting i,k. */
0360   
0361   for (i=n-1; i>=0; i--) {
0362     ct[0] = ct[1] = ct[2] = ct[3] = 0;
0363 
0364     /* keep track of "directions" that have occurred */
0365     dir = (3+3*(pt[mod(i+1,n)].x-pt[i].x)+(pt[mod(i+1,n)].y-pt[i].y))/2;
0366     ct[dir]++;
0367 
0368     constraint[0].x = 0;
0369     constraint[0].y = 0;
0370     constraint[1].x = 0;
0371     constraint[1].y = 0;
0372 
0373     /* find the next k such that no straight line from i to k */
0374     k = nc[i];
0375     k1 = i;
0376     while (1) {
0377       
0378       dir = (3+3*sign(pt[k].x-pt[k1].x)+sign(pt[k].y-pt[k1].y))/2;
0379       ct[dir]++;
0380 
0381       /* if all four "directions" have occurred, cut this path */
0382       if (ct[0] && ct[1] && ct[2] && ct[3]) {
0383     pivk[i] = k1;
0384     goto foundk;
0385       }
0386 
0387       cur.x = pt[k].x - pt[i].x;
0388       cur.y = pt[k].y - pt[i].y;
0389 
0390       /* see if current constraint is violated */
0391       if (xprod(constraint[0], cur) < 0 || xprod(constraint[1], cur) > 0) {
0392     goto constraint_viol;
0393       }
0394 
0395       /* else, update constraint */
0396       if (abs(cur.x) <= 1 && abs(cur.y) <= 1) {
0397     /* no constraint */
0398       } else {
0399     off.x = cur.x + ((cur.y>=0 && (cur.y>0 || cur.x<0)) ? 1 : -1);
0400     off.y = cur.y + ((cur.x<=0 && (cur.x<0 || cur.y<0)) ? 1 : -1);
0401     if (xprod(constraint[0], off) >= 0) {
0402       constraint[0] = off;
0403     }
0404     off.x = cur.x + ((cur.y<=0 && (cur.y<0 || cur.x<0)) ? 1 : -1);
0405     off.y = cur.y + ((cur.x>=0 && (cur.x>0 || cur.y<0)) ? 1 : -1);
0406     if (xprod(constraint[1], off) <= 0) {
0407       constraint[1] = off;
0408     }
0409       } 
0410       k1 = k;
0411       k = nc[k1];
0412       if (!cyclic(k,i,k1)) {
0413     break;
0414       }
0415     }
0416   constraint_viol:
0417     /* k1 was the last "corner" satisfying the current constraint, and
0418        k is the first one violating it. We now need to find the last
0419        point along k1..k which satisfied the constraint. */
0420     dk.x = sign(pt[k].x-pt[k1].x);
0421     dk.y = sign(pt[k].y-pt[k1].y);
0422     cur.x = pt[k1].x - pt[i].x;
0423     cur.y = pt[k1].y - pt[i].y;
0424     /* find largest integer j such that xprod(constraint[0], cur+j*dk)
0425        >= 0 and xprod(constraint[1], cur+j*dk) <= 0. Use bilinearity
0426        of xprod. */
0427     a = xprod(constraint[0], cur);
0428     b = xprod(constraint[0], dk);
0429     c = xprod(constraint[1], cur);
0430     d = xprod(constraint[1], dk);
0431     /* find largest integer j such that a+j*b>=0 and c+j*d<=0. This
0432        can be solved with integer arithmetic. */
0433     j = INFTY;
0434     if (b<0) {
0435       j = floordiv(a,-b);
0436     }
0437     if (d>0) {
0438       j = min(j, floordiv(-c,d));
0439     }
0440     pivk[i] = mod(k1+j,n);
0441   foundk:
0442     ;
0443   } /* for i */
0444 
0445   /* clean up: for each i, let lon[i] be the largest k such that for
0446      all i' with i<=i'<k, i'<k<=pivk[i']. */
0447 
0448   j=pivk[n-1];
0449   pp->lon[n-1]=j;
0450   for (i=n-2; i>=0; i--) {
0451     if (cyclic(i+1,pivk[i],j)) {
0452       j=pivk[i];
0453     }
0454     pp->lon[i]=j;
0455   }
0456 
0457   for (i=n-1; cyclic(mod(i+1,n),j,pp->lon[i]); i--) {
0458     pp->lon[i] = j;
0459   }
0460 
0461   free(pivk);
0462   free(nc);
0463   return 0;
0464 
0465  calloc_error:
0466   free(pivk);
0467   free(nc);
0468   return 1;
0469 }
0470 
0471 
0472 /* ---------------------------------------------------------------------- */
0473 /* Stage 2: calculate the optimal polygon (Sec. 2.2.2-2.2.4). */ 
0474 
0475 /* Auxiliary function: calculate the penalty of an edge from i to j in
0476    the given path. This needs the "lon" and "sum*" data. */
0477 
0478 static double penalty3(privpath_t *pp, int i, int j) {
0479   int n = pp->len;
0480   point_t *pt = pp->pt;
0481   sums_t *sums = pp->sums;
0482 
0483   /* assume 0<=i<j<=n  */
0484   double x, y, x2, xy, y2;
0485   double k;
0486   double a, b, c, s;
0487   double px, py, ex, ey;
0488 
0489   int r = 0; /* rotations from i to j */
0490 
0491   if (j>=n) {
0492     j -= n;
0493     r = 1;
0494   }
0495   
0496   /* critical inner loop: the "if" gives a 4.6 percent speedup */
0497   if (r == 0) {
0498     x = sums[j+1].x - sums[i].x;
0499     y = sums[j+1].y - sums[i].y;
0500     x2 = sums[j+1].x2 - sums[i].x2;
0501     xy = sums[j+1].xy - sums[i].xy;
0502     y2 = sums[j+1].y2 - sums[i].y2;
0503     k = j+1 - i;
0504   } else {
0505     x = sums[j+1].x - sums[i].x + sums[n].x;
0506     y = sums[j+1].y - sums[i].y + sums[n].y;
0507     x2 = sums[j+1].x2 - sums[i].x2 + sums[n].x2;
0508     xy = sums[j+1].xy - sums[i].xy + sums[n].xy;
0509     y2 = sums[j+1].y2 - sums[i].y2 + sums[n].y2;
0510     k = j+1 - i + n;
0511   } 
0512 
0513   px = (pt[i].x + pt[j].x) / 2.0 - pt[0].x;
0514   py = (pt[i].y + pt[j].y) / 2.0 - pt[0].y;
0515   ey = (pt[j].x - pt[i].x);
0516   ex = -(pt[j].y - pt[i].y);
0517 
0518   a = ((x2 - 2*x*px) / k + px*px);
0519   b = ((xy - x*py - y*px) / k + px*py);
0520   c = ((y2 - 2*y*py) / k + py*py);
0521   
0522   s = ex*ex*a + 2*ex*ey*b + ey*ey*c;
0523 
0524   return sqrt(s);
0525 }
0526 
0527 /* find the optimal polygon. Fill in the m and po components. Return 1
0528    on failure with errno set, else 0. Non-cyclic version: assumes i=0
0529    is in the polygon. Fixme: implement cyclic version. */
0530 static int bestpolygon(privpath_t *pp)
0531 {
0532   int i, j, m, k;     
0533   int n = pp->len;
0534   double *pen = NULL; /* pen[n+1]: penalty vector */
0535   int *prev = NULL;   /* prev[n+1]: best path pointer vector */
0536   int *clip0 = NULL;  /* clip0[n]: longest segment pointer, non-cyclic */
0537   int *clip1 = NULL;  /* clip1[n+1]: backwards segment pointer, non-cyclic */
0538   int *seg0 = NULL;    /* seg0[m+1]: forward segment bounds, m<=n */
0539   int *seg1 = NULL;   /* seg1[m+1]: backward segment bounds, m<=n */
0540   double thispen;
0541   double best;
0542   int c;
0543 
0544   SAFE_CALLOC(pen, n+1, double);
0545   SAFE_CALLOC(prev, n+1, int);
0546   SAFE_CALLOC(clip0, n, int);
0547   SAFE_CALLOC(clip1, n+1, int);
0548   SAFE_CALLOC(seg0, n+1, int);
0549   SAFE_CALLOC(seg1, n+1, int);
0550 
0551   /* calculate clipped paths */
0552   for (i=0; i<n; i++) {
0553     c = mod(pp->lon[mod(i-1,n)]-1,n);
0554     if (c == i) {
0555       c = mod(i+1,n);
0556     }
0557     if (c < i) {
0558       clip0[i] = n;
0559     } else {
0560       clip0[i] = c;
0561     }
0562   }
0563 
0564   /* calculate backwards path clipping, non-cyclic. j <= clip0[i] iff
0565      clip1[j] <= i, for i,j=0..n. */
0566   j = 1;
0567   for (i=0; i<n; i++) {
0568     while (j <= clip0[i]) {
0569       clip1[j] = i;
0570       j++;
0571     }
0572   }
0573 
0574   /* calculate seg0[j] = longest path from 0 with j segments */
0575   i = 0;
0576   for (j=0; i<n; j++) {
0577     seg0[j] = i;
0578     i = clip0[i];
0579   }
0580   seg0[j] = n;
0581   m = j;
0582 
0583   /* calculate seg1[j] = longest path to n with m-j segments */
0584   i = n;
0585   for (j=m; j>0; j--) {
0586     seg1[j] = i;
0587     i = clip1[i];
0588   }
0589   seg1[0] = 0;
0590 
0591   /* now find the shortest path with m segments, based on penalty3 */
0592   /* note: the outer 2 loops jointly have at most n iterations, thus
0593      the worst-case behavior here is quadratic. In practice, it is
0594      close to linear since the inner loop tends to be short. */
0595   pen[0]=0;
0596   for (j=1; j<=m; j++) {
0597     for (i=seg1[j]; i<=seg0[j]; i++) {
0598       best = -1;
0599       for (k=seg0[j-1]; k>=clip1[i]; k--) {
0600     thispen = penalty3(pp, k, i) + pen[k];
0601     if (best < 0 || thispen < best) {
0602       prev[i] = k;
0603       best = thispen;
0604     }
0605       }
0606       pen[i] = best;
0607     }
0608   }
0609 
0610   pp->m = m;
0611   SAFE_CALLOC(pp->po, m, int);
0612 
0613   /* read off shortest path */
0614   for (i=n, j=m-1; i>0; j--) {
0615     i = prev[i];
0616     pp->po[j] = i;
0617   }
0618 
0619   free(pen);
0620   free(prev);
0621   free(clip0);
0622   free(clip1);
0623   free(seg0);
0624   free(seg1);
0625   return 0;
0626   
0627  calloc_error:
0628   free(pen);
0629   free(prev);
0630   free(clip0);
0631   free(clip1);
0632   free(seg0);
0633   free(seg1);
0634   return 1;
0635 }
0636 
0637 /* ---------------------------------------------------------------------- */
0638 /* Stage 3: vertex adjustment (Sec. 2.3.1). */
0639 
0640 /* Adjust vertices of optimal polygon: calculate the intersection of
0641    the two "optimal" line segments, then move it into the unit square
0642    if it lies outside. Return 1 with errno set on error; 0 on
0643    success. */
0644 
0645 static int adjust_vertices(privpath_t *pp) {
0646   int m = pp->m;
0647   int *po = pp->po;
0648   int n = pp->len;
0649   point_t *pt = pp->pt;
0650   int x0 = pp->x0;
0651   int y0 = pp->y0;
0652 
0653   dpoint_t *ctr = NULL;      /* ctr[m] */
0654   dpoint_t *dir = NULL;      /* dir[m] */
0655   quadform_t *q = NULL;      /* q[m] */
0656   double v[3];
0657   double d;
0658   int i, j, k, l;
0659   dpoint_t s;
0660   int r;
0661 
0662   SAFE_CALLOC(ctr, m, dpoint_t);
0663   SAFE_CALLOC(dir, m, dpoint_t);
0664   SAFE_CALLOC(q, m, quadform_t);
0665 
0666   r = privcurve_init(&pp->curve, m);
0667   if (r) {
0668     goto calloc_error;
0669   }
0670   
0671   /* calculate "optimal" point-slope representation for each line
0672      segment */
0673   for (i=0; i<m; i++) {
0674     j = po[mod(i+1,m)];
0675     j = mod(j-po[i],n)+po[i];
0676     pointslope(pp, po[i], j, &ctr[i], &dir[i]);
0677   }
0678 
0679   /* represent each line segment as a singular quadratic form; the
0680      distance of a point (x,y) from the line segment will be
0681      (x,y,1)Q(x,y,1)^t, where Q=q[i]. */
0682   for (i=0; i<m; i++) {
0683     d = sq(dir[i].x) + sq(dir[i].y);
0684     if (d == 0.0) {
0685       for (j=0; j<3; j++) {
0686     for (k=0; k<3; k++) {
0687       q[i][j][k] = 0;
0688     }
0689       }
0690     } else {
0691       v[0] = dir[i].y;
0692       v[1] = -dir[i].x;
0693       v[2] = - v[1] * ctr[i].y - v[0] * ctr[i].x;
0694       for (l=0; l<3; l++) {
0695     for (k=0; k<3; k++) {
0696       q[i][l][k] = v[l] * v[k] / d;
0697     }
0698       }
0699     }
0700   }
0701 
0702   /* now calculate the "intersections" of consecutive segments.
0703      Instead of using the actual intersection, we find the point
0704      within a given unit square which minimizes the square distance to
0705      the two lines. */
0706   for (i=0; i<m; i++) {
0707     quadform_t Q;
0708     dpoint_t w;
0709     double dx, dy;
0710     double det;
0711     double min, cand; /* minimum and candidate for minimum of quad. form */
0712     double xmin, ymin;  /* coordinates of minimum */
0713     int z;
0714 
0715     /* let s be the vertex, in coordinates relative to x0/y0 */
0716     s.x = pt[po[i]].x-x0;
0717     s.y = pt[po[i]].y-y0;
0718 
0719     /* intersect segments i-1 and i */
0720 
0721     j = mod(i-1,m);
0722 
0723     /* add quadratic forms */
0724     for (l=0; l<3; l++) {
0725       for (k=0; k<3; k++) {
0726     Q[l][k] = q[j][l][k] + q[i][l][k];
0727       }
0728     }
0729     
0730     while(1) {
0731       /* minimize the quadratic form Q on the unit square */
0732       /* find intersection */
0733 
0734 #ifdef HAVE_GCC_LOOP_BUG
0735       /* work around gcc bug #12243 */
0736       free(NULL);
0737 #endif
0738       
0739       det = Q[0][0]*Q[1][1] - Q[0][1]*Q[1][0];
0740       if (det != 0.0) {
0741     w.x = (-Q[0][2]*Q[1][1] + Q[1][2]*Q[0][1]) / det;
0742     w.y = ( Q[0][2]*Q[1][0] - Q[1][2]*Q[0][0]) / det;
0743     break;
0744       }
0745 
0746       /* matrix is singular - lines are parallel. Add another,
0747      orthogonal axis, through the center of the unit square */
0748       if (Q[0][0]>Q[1][1]) {
0749     v[0] = -Q[0][1];
0750     v[1] = Q[0][0];
0751       } else if (Q[1][1]) {
0752     v[0] = -Q[1][1];
0753     v[1] = Q[1][0];
0754       } else {
0755     v[0] = 1;
0756     v[1] = 0;
0757       }
0758       d = sq(v[0]) + sq(v[1]);
0759       v[2] = - v[1] * s.y - v[0] * s.x;
0760       for (l=0; l<3; l++) {
0761     for (k=0; k<3; k++) {
0762       Q[l][k] += v[l] * v[k] / d;
0763     }
0764       }
0765     }
0766     dx = fabs(w.x-s.x);
0767     dy = fabs(w.y-s.y);
0768     if (dx <= .5 && dy <= .5) {
0769       pp->curve.vertex[i].x = w.x+x0;
0770       pp->curve.vertex[i].y = w.y+y0;
0771       continue;
0772     }
0773 
0774     /* the minimum was not in the unit square; now minimize quadratic
0775        on boundary of square */
0776     min = quadform(Q, s);
0777     xmin = s.x;
0778     ymin = s.y;
0779 
0780     if (Q[0][0] == 0.0) {
0781       goto fixx;
0782     }
0783     for (z=0; z<2; z++) {   /* value of the y-coordinate */
0784       w.y = s.y-0.5+z;
0785       w.x = - (Q[0][1] * w.y + Q[0][2]) / Q[0][0];
0786       dx = fabs(w.x-s.x);
0787       cand = quadform(Q, w);
0788       if (dx <= .5 && cand < min) {
0789     min = cand;
0790     xmin = w.x;
0791     ymin = w.y;
0792       }
0793     }
0794   fixx:
0795     if (Q[1][1] == 0.0) {
0796       goto corners;
0797     }
0798     for (z=0; z<2; z++) {   /* value of the x-coordinate */
0799       w.x = s.x-0.5+z;
0800       w.y = - (Q[1][0] * w.x + Q[1][2]) / Q[1][1];
0801       dy = fabs(w.y-s.y);
0802       cand = quadform(Q, w);
0803       if (dy <= .5 && cand < min) {
0804     min = cand;
0805     xmin = w.x;
0806     ymin = w.y;
0807       }
0808     }
0809   corners:
0810     /* check four corners */
0811     for (l=0; l<2; l++) {
0812       for (k=0; k<2; k++) {
0813     w.x = s.x-0.5+l;
0814     w.y = s.y-0.5+k;
0815     cand = quadform(Q, w);
0816     if (cand < min) {
0817       min = cand;
0818       xmin = w.x;
0819       ymin = w.y;
0820     }
0821       }
0822     }
0823 
0824     pp->curve.vertex[i].x = xmin + x0;
0825     pp->curve.vertex[i].y = ymin + y0;
0826     continue;
0827   }
0828 
0829   free(ctr);
0830   free(dir);
0831   free(q);
0832   return 0;
0833 
0834  calloc_error:
0835   free(ctr);
0836   free(dir);
0837   free(q);
0838   return 1;
0839 }
0840 
0841 /* ---------------------------------------------------------------------- */
0842 /* Stage 4: smoothing and corner analysis (Sec. 2.3.3) */
0843 
0844 /* reverse orientation of a path */
0845 static void reverse(privcurve_t *curve) {
0846   int m = curve->n;
0847   int i, j;
0848   dpoint_t tmp;
0849 
0850   for (i=0, j=m-1; i<j; i++, j--) {
0851     tmp = curve->vertex[i];
0852     curve->vertex[i] = curve->vertex[j];
0853     curve->vertex[j] = tmp;
0854   }
0855 }
0856 
0857 /* Always succeeds */
0858 static void smooth(privcurve_t *curve, double alphamax) {
0859   int m = curve->n;
0860 
0861   int i, j, k;
0862   double dd, denom, alpha;
0863   dpoint_t p2, p3, p4;
0864 
0865   /* examine each vertex and find its best fit */
0866   for (i=0; i<m; i++) {
0867     j = mod(i+1, m);
0868     k = mod(i+2, m);
0869     p4 = interval(1/2.0, curve->vertex[k], curve->vertex[j]);
0870 
0871     denom = ddenom(curve->vertex[i], curve->vertex[k]);
0872     if (denom != 0.0) {
0873       dd = dpara(curve->vertex[i], curve->vertex[j], curve->vertex[k]) / denom;
0874       dd = fabs(dd);
0875       alpha = dd>1 ? (1 - 1.0/dd) : 0;
0876       alpha = alpha / 0.75;
0877     } else {
0878       alpha = 4/3.0;
0879     }
0880     curve->alpha0[j] = alpha;    /* remember "original" value of alpha */
0881 
0882     if (alpha >= alphamax) {  /* pointed corner */
0883       curve->tag[j] = POTRACE_CORNER;
0884       curve->c[j][1] = curve->vertex[j];
0885       curve->c[j][2] = p4;
0886     } else {
0887       if (alpha < 0.55) {
0888     alpha = 0.55;
0889       } else if (alpha > 1) {
0890     alpha = 1;
0891       }
0892       p2 = interval(.5+.5*alpha, curve->vertex[i], curve->vertex[j]);
0893       p3 = interval(.5+.5*alpha, curve->vertex[k], curve->vertex[j]);
0894       curve->tag[j] = POTRACE_CURVETO;
0895       curve->c[j][0] = p2;
0896       curve->c[j][1] = p3;
0897       curve->c[j][2] = p4;
0898     }
0899     curve->alpha[j] = alpha;    /* store the "cropped" value of alpha */
0900     curve->beta[j] = 0.5;
0901   }
0902   curve->alphacurve = 1;
0903 
0904   return;
0905 }
0906 
0907 /* ---------------------------------------------------------------------- */
0908 /* Stage 5: Curve optimization (Sec. 2.4) */
0909 
0910 /* a private type for the result of opti_penalty */
0911 struct opti_s {
0912   double pen;      /* penalty */
0913   dpoint_t c[2];   /* curve parameters */
0914   double t, s;     /* curve parameters */
0915   double alpha;    /* curve parameter */
0916 };
0917 typedef struct opti_s opti_t;
0918 
0919 /* calculate best fit from i+.5 to j+.5.  Assume i<j (cyclically).
0920    Return 0 and set badness and parameters (alpha, beta), if
0921    possible. Return 1 if impossible. */
0922 static int opti_penalty(privpath_t *pp, int i, int j, opti_t *res, double opttolerance, int *convc, double *areac) {
0923   int m = pp->curve.n;
0924   int k, k1, k2, conv, i1;
0925   double area, alpha, d, d1, d2;
0926   dpoint_t p0, p1, p2, p3, pt;
0927   double A, R, A1, A2, A3, A4;
0928   double s, t;
0929 
0930   /* check convexity, corner-freeness, and maximum bend < 179 degrees */
0931 
0932   if (i==j) {  /* sanity - a full loop can never be an opticurve */
0933     return 1;
0934   }
0935 
0936   k = i;
0937   i1 = mod(i+1, m);
0938   k1 = mod(k+1, m);
0939   conv = convc[k1];
0940   if (conv == 0) {
0941     return 1;
0942   }
0943   d = ddist(pp->curve.vertex[i], pp->curve.vertex[i1]);
0944   for (k=k1; k!=j; k=k1) {
0945     k1 = mod(k+1, m);
0946     k2 = mod(k+2, m);
0947     if (convc[k1] != conv) {
0948       return 1;
0949     }
0950     if (sign(cprod(pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1], pp->curve.vertex[k2])) != conv) {
0951       return 1;
0952     }
0953     if (iprod1(pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1], pp->curve.vertex[k2]) < d * ddist(pp->curve.vertex[k1], pp->curve.vertex[k2]) * COS179) {
0954       return 1;
0955     }
0956   }
0957 
0958   /* the curve we're working in: */
0959   p0 = pp->curve.c[mod(i,m)][2];
0960   p1 = pp->curve.vertex[mod(i+1,m)];
0961   p2 = pp->curve.vertex[mod(j,m)];
0962   p3 = pp->curve.c[mod(j,m)][2];
0963 
0964   /* determine its area */
0965   area = areac[j] - areac[i];
0966   area -= dpara(pp->curve.vertex[0], pp->curve.c[i][2], pp->curve.c[j][2])/2;
0967   if (i>=j) {
0968     area += areac[m];
0969   }
0970 
0971   /* find intersection o of p0p1 and p2p3. Let t,s such that o =
0972      interval(t,p0,p1) = interval(s,p3,p2). Let A be the area of the
0973      triangle (p0,o,p3). */
0974 
0975   A1 = dpara(p0, p1, p2);
0976   A2 = dpara(p0, p1, p3);
0977   A3 = dpara(p0, p2, p3);
0978   /* A4 = dpara(p1, p2, p3); */
0979   A4 = A1+A3-A2;    
0980   
0981   if (A2 == A1) {  /* this should never happen */
0982     return 1;
0983   }
0984 
0985   t = A3/(A3-A4);
0986   s = A2/(A2-A1);
0987   A = A2 * t / 2.0;
0988   
0989   if (A == 0.0) {  /* this should never happen */
0990     return 1;
0991   }
0992 
0993   R = area / A;  /* relative area */
0994   alpha = 2 - sqrt(4 - R / 0.3);  /* overall alpha for p0-o-p3 curve */
0995 
0996   res->c[0] = interval(t * alpha, p0, p1);
0997   res->c[1] = interval(s * alpha, p3, p2);
0998   res->alpha = alpha;
0999   res->t = t;
1000   res->s = s;
1001 
1002   p1 = res->c[0];
1003   p2 = res->c[1];  /* the proposed curve is now (p0,p1,p2,p3) */
1004 
1005   res->pen = 0;
1006 
1007   /* calculate penalty */
1008   /* check tangency with edges */
1009   for (k=mod(i+1,m); k!=j; k=k1) {
1010     k1 = mod(k+1,m);
1011     t = tangent(p0, p1, p2, p3, pp->curve.vertex[k], pp->curve.vertex[k1]);
1012     if (t<-.5) {
1013       return 1;
1014     }
1015     pt = bezier(t, p0, p1, p2, p3);
1016     d = ddist(pp->curve.vertex[k], pp->curve.vertex[k1]);
1017     if (d == 0.0) {  /* this should never happen */
1018       return 1;
1019     }
1020     d1 = dpara(pp->curve.vertex[k], pp->curve.vertex[k1], pt) / d;
1021     if (fabs(d1) > opttolerance) {
1022       return 1;
1023     }
1024     if (iprod(pp->curve.vertex[k], pp->curve.vertex[k1], pt) < 0 || iprod(pp->curve.vertex[k1], pp->curve.vertex[k], pt) < 0) {
1025       return 1;
1026     }
1027     res->pen += sq(d1);
1028   }
1029 
1030   /* check corners */
1031   for (k=i; k!=j; k=k1) {
1032     k1 = mod(k+1,m);
1033     t = tangent(p0, p1, p2, p3, pp->curve.c[k][2], pp->curve.c[k1][2]);
1034     if (t<-.5) {
1035       return 1;
1036     }
1037     pt = bezier(t, p0, p1, p2, p3);
1038     d = ddist(pp->curve.c[k][2], pp->curve.c[k1][2]);
1039     if (d == 0.0) {  /* this should never happen */
1040       return 1;
1041     }
1042     d1 = dpara(pp->curve.c[k][2], pp->curve.c[k1][2], pt) / d;
1043     d2 = dpara(pp->curve.c[k][2], pp->curve.c[k1][2], pp->curve.vertex[k1]) / d;
1044     d2 *= 0.75 * pp->curve.alpha[k1];
1045     if (d2 < 0) {
1046       d1 = -d1;
1047       d2 = -d2;
1048     }
1049     if (d1 < d2 - opttolerance) {
1050       return 1;
1051     }
1052     if (d1 < d2) {
1053       res->pen += sq(d1 - d2);
1054     }
1055   }
1056 
1057   return 0;
1058 }
1059 
1060 /* optimize the path p, replacing sequences of Bezier segments by a
1061    single segment when possible. Return 0 on success, 1 with errno set
1062    on failure. */
1063 static int opticurve(privpath_t *pp, double opttolerance) {
1064   int m = pp->curve.n;
1065   int *pt = NULL;     /* pt[m+1] */
1066   double *pen = NULL; /* pen[m+1] */
1067   int *len = NULL;    /* len[m+1] */
1068   opti_t *opt = NULL; /* opt[m+1] */
1069   int om;
1070   int i,j,r;
1071   opti_t o;
1072   dpoint_t p0;
1073   int i1;
1074   double area;
1075   double alpha;
1076   double *s = NULL;
1077   double *t = NULL;
1078 
1079   int *convc = NULL; /* conv[m]: pre-computed convexities */
1080   double *areac = NULL; /* cumarea[m+1]: cache for fast area computation */
1081 
1082   SAFE_CALLOC(pt, m+1, int);
1083   SAFE_CALLOC(pen, m+1, double);
1084   SAFE_CALLOC(len, m+1, int);
1085   SAFE_CALLOC(opt, m+1, opti_t);
1086   SAFE_CALLOC(convc, m, int);
1087   SAFE_CALLOC(areac, m+1, double);
1088 
1089   /* pre-calculate convexity: +1 = right turn, -1 = left turn, 0 = corner */
1090   for (i=0; i<m; i++) {
1091     if (pp->curve.tag[i] == POTRACE_CURVETO) {
1092       convc[i] = sign(dpara(pp->curve.vertex[mod(i-1,m)], pp->curve.vertex[i], pp->curve.vertex[mod(i+1,m)]));
1093     } else {
1094       convc[i] = 0;
1095     }
1096   }
1097 
1098   /* pre-calculate areas */
1099   area = 0.0;
1100   areac[0] = 0.0;
1101   p0 = pp->curve.vertex[0];
1102   for (i=0; i<m; i++) {
1103     i1 = mod(i+1, m);
1104     if (pp->curve.tag[i1] == POTRACE_CURVETO) {
1105       alpha = pp->curve.alpha[i1];
1106       area += 0.3*alpha*(4-alpha)*dpara(pp->curve.c[i][2], pp->curve.vertex[i1], pp->curve.c[i1][2])/2;
1107       area += dpara(p0, pp->curve.c[i][2], pp->curve.c[i1][2])/2;
1108     }
1109     areac[i+1] = area;
1110   }
1111 
1112   pt[0] = -1;
1113   pen[0] = 0;
1114   len[0] = 0;
1115 
1116   /* Fixme: we always start from a fixed point -- should find the best
1117      curve cyclically */
1118 
1119   for (j=1; j<=m; j++) {
1120     /* calculate best path from 0 to j */
1121     pt[j] = j-1;
1122     pen[j] = pen[j-1];
1123     len[j] = len[j-1]+1;
1124 
1125     for (i=j-2; i>=0; i--) {
1126       r = opti_penalty(pp, i, mod(j,m), &o, opttolerance, convc, areac);
1127       if (r) {
1128     break;
1129       }
1130       if (len[j] > len[i]+1 || (len[j] == len[i]+1 && pen[j] > pen[i] + o.pen)) {
1131     pt[j] = i;
1132     pen[j] = pen[i] + o.pen;
1133     len[j] = len[i] + 1;
1134     opt[j] = o;
1135       }
1136     }
1137   }
1138   om = len[m];
1139   r = privcurve_init(&pp->ocurve, om);
1140   if (r) {
1141     goto calloc_error;
1142   }
1143   SAFE_CALLOC(s, om, double);
1144   SAFE_CALLOC(t, om, double);
1145 
1146   j = m;
1147   for (i=om-1; i>=0; i--) {
1148     if (pt[j]==j-1) {
1149       pp->ocurve.tag[i]     = pp->curve.tag[mod(j,m)];
1150       pp->ocurve.c[i][0]    = pp->curve.c[mod(j,m)][0];
1151       pp->ocurve.c[i][1]    = pp->curve.c[mod(j,m)][1];
1152       pp->ocurve.c[i][2]    = pp->curve.c[mod(j,m)][2];
1153       pp->ocurve.vertex[i]  = pp->curve.vertex[mod(j,m)];
1154       pp->ocurve.alpha[i]   = pp->curve.alpha[mod(j,m)];
1155       pp->ocurve.alpha0[i]  = pp->curve.alpha0[mod(j,m)];
1156       pp->ocurve.beta[i]    = pp->curve.beta[mod(j,m)];
1157       s[i] = t[i] = 1.0;
1158     } else {
1159       pp->ocurve.tag[i] = POTRACE_CURVETO;
1160       pp->ocurve.c[i][0] = opt[j].c[0];
1161       pp->ocurve.c[i][1] = opt[j].c[1];
1162       pp->ocurve.c[i][2] = pp->curve.c[mod(j,m)][2];
1163       pp->ocurve.vertex[i] = interval(opt[j].s, pp->curve.c[mod(j,m)][2], pp->curve.vertex[mod(j,m)]);
1164       pp->ocurve.alpha[i] = opt[j].alpha;
1165       pp->ocurve.alpha0[i] = opt[j].alpha;
1166       s[i] = opt[j].s;
1167       t[i] = opt[j].t;
1168     }
1169     j = pt[j];
1170   }
1171 
1172   /* calculate beta parameters */
1173   for (i=0; i<om; i++) {
1174     i1 = mod(i+1,om);
1175     pp->ocurve.beta[i] = s[i] / (s[i] + t[i1]);
1176   }
1177   pp->ocurve.alphacurve = 1;
1178 
1179   free(pt);
1180   free(pen);
1181   free(len);
1182   free(opt);
1183   free(s);
1184   free(t);
1185   free(convc);
1186   free(areac);
1187   return 0;
1188 
1189  calloc_error:
1190   free(pt);
1191   free(pen);
1192   free(len);
1193   free(opt);
1194   free(s);
1195   free(t);
1196   free(convc);
1197   free(areac);
1198   return 1;
1199 }
1200 
1201 /* ---------------------------------------------------------------------- */
1202 
1203 #define TRY(x) if (x) goto try_error
1204 
1205 /* return 0 on success, 1 on error with errno set. */
1206 int process_path(path_t *plist, const potrace_param_t *param, progress_t *progress) {
1207   path_t *p;
1208   double nn = 0, cn = 0;
1209 
1210   if (progress->callback) {
1211     /* precompute task size for progress estimates */
1212     nn = 0;
1213     list_forall (p, plist) {
1214       nn += p->priv->len;
1215     }
1216     cn = 0;
1217   }
1218   
1219   /* call downstream function with each path */
1220   list_forall (p, plist) {
1221     TRY(calc_sums(p->priv));
1222     TRY(calc_lon(p->priv));
1223     TRY(bestpolygon(p->priv));
1224     TRY(adjust_vertices(p->priv));
1225     if (p->sign == '-') {   /* reverse orientation of negative paths */
1226       reverse(&p->priv->curve);
1227     }
1228     smooth(&p->priv->curve, param->alphamax);
1229     if (param->opticurve) {
1230       TRY(opticurve(p->priv, param->opttolerance));
1231       p->priv->fcurve = &p->priv->ocurve;
1232     } else {
1233       p->priv->fcurve = &p->priv->curve;
1234     }
1235     privcurve_to_curve(p->priv->fcurve, &p->curve);
1236 
1237     if (progress->callback) {
1238       cn += p->priv->len;
1239       progress_update(cn/nn, progress);
1240     }
1241   }
1242 
1243   progress_update(1.0, progress);
1244 
1245   return 0;
1246 
1247  try_error:
1248   return 1;
1249 }