~ubuntu-branches/ubuntu/wily/tupi/wily-proposed

« back to all changes in this revision

Viewing changes to 3rdparty/potrace/trace.c

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2013-05-13 09:53:35 UTC
  • mfrom: (8.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20130513095335-3iqdvt9ne07ia25v
Tags: 0.2+git01-1
* Upload to unstable.
* Removed unnecessary versioned Build-Depends.
* Removed obsolete "DM-Upload-Allowed".
* Added Vcs links to collab-maint.
* Standards updated to version 3.9.4.
* Corrected "libavutil51"-->"libavutil-dev" in Build-Depends.
* Updated debian/watch (corrected URL, removed comments).
* Updated get-orig-source (can work from any directory).
* Updated my email address; bumped copyright years.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2001-2005 Peter Selinger.
2
 
   This file is part of potrace. It is free software and it is covered
3
 
   by the GNU General Public License. See the file COPYING for details. */
4
 
 
5
 
/* $Id: trace.c,v 1.10 2005/02/27 01:54:08 selinger Exp $ */
6
 
/* transform jaggy paths into smooth curves */
7
 
 
8
 
#include <stdio.h>
9
 
#include <math.h>
10
 
#include <stdlib.h>
11
 
#include <string.h>
12
 
 
13
 
#include "potracelib.h"
14
 
#include "curve.h"
15
 
#include "lists.h"
16
 
#include "auxiliary.h"
17
 
#include "trace.h"
18
 
#include "progress.h"
19
 
 
20
 
#define INFTY 10000000  /* it suffices that this is longer than any
21
 
                           path; it need not be really infinite */
22
 
#define COS179 -0.999847695156   /* the cosine of 179 degrees */
23
 
 
24
 
/* ---------------------------------------------------------------------- */
25
 
/* some useful macros. Note: the "mod" macro works correctly for
26
 
   negative a. Also note that the test for a>=n, while redundant,
27
 
   speeds up the mod function by 70% in the average case (significant
28
 
   since the program spends about 16% of its time here - or 40%
29
 
   without the test). The "floordiv" macro returns the largest integer
30
 
   <= a/n, and again this works correctly for negative a, as long as
31
 
   a,n are integers and n>0. */
32
 
 
33
 
#define SAFE_MALLOC(var, n, typ) \
34
 
  if ((var = (typ *)malloc((n)*sizeof(typ))) == NULL) goto malloc_error 
35
 
 
36
 
/* ---------------------------------------------------------------------- */
37
 
/* auxiliary functions */
38
 
 
39
 
/* return a direction that is 90 degrees counterclockwise from p2-p0,
40
 
   but then restricted to one of the major wind directions (n, nw, w, etc) */
41
 
static inline point_t dorth_infty(dpoint_t p0, dpoint_t p2) {
42
 
  point_t r;
43
 
  
44
 
  r.y = sign(p2.x-p0.x);
45
 
  r.x = -sign(p2.y-p0.y);
46
 
 
47
 
  return r;
48
 
}
49
 
 
50
 
/* return (p1-p0)x(p2-p0), the area of the parallelogram */
51
 
static inline double dpara(dpoint_t p0, dpoint_t p1, dpoint_t p2) {
52
 
  double x1, y1, x2, y2;
53
 
 
54
 
  x1 = p1.x-p0.x;
55
 
  y1 = p1.y-p0.y;
56
 
  x2 = p2.x-p0.x;
57
 
  y2 = p2.y-p0.y;
58
 
 
59
 
  return x1*y2 - x2*y1;
60
 
}
61
 
 
62
 
/* ddenom/dpara have the property that the square of radius 1 centered
63
 
   at p1 intersects the line p0p2 iff |dpara(p0,p1,p2)| <= ddenom(p0,p2) */
64
 
static inline double ddenom(dpoint_t p0, dpoint_t p2) {
65
 
  point_t r = dorth_infty(p0, p2);
66
 
 
67
 
  return r.y*(p2.x-p0.x) - r.x*(p2.y-p0.y);
68
 
}
69
 
 
70
 
/* return 1 if a <= b < c < a, in a cyclic sense (mod n) */
71
 
static inline int cyclic(int a, int b, int c) {
72
 
  if (a<=c) {
73
 
    return (a<=b && b<c);
74
 
  } else {
75
 
    return (a<=b || b<c);
76
 
  }
77
 
}
78
 
 
79
 
/* determine the center and slope of the line i..j. Assume i<j. Needs
80
 
   "sum" components of p to be set. */
81
 
static void pointslope(privpath_t *pp, int i, int j, dpoint_t *ctr, dpoint_t *dir) {
82
 
  /* assume i<j */
83
 
 
84
 
  int n = pp->len;
85
 
  sums_t *sums = pp->sums;
86
 
 
87
 
  double x, y, x2, xy, y2;
88
 
  double k;
89
 
  double a, b, c, lambda2, l;
90
 
  int r=0; /* rotations from i to j */
91
 
 
92
 
  while (j>=n) {
93
 
    j-=n;
94
 
    r+=1;
95
 
  }
96
 
  while (i>=n) {
97
 
    i-=n;
98
 
    r-=1;
99
 
  }
100
 
  while (j<0) {
101
 
    j+=n;
102
 
    r-=1;
103
 
  }
104
 
  while (i<0) {
105
 
    i+=n;
106
 
    r+=1;
107
 
  }
108
 
  
109
 
  x = sums[j+1].x-sums[i].x+r*sums[n].x;
110
 
  y = sums[j+1].y-sums[i].y+r*sums[n].y;
111
 
  x2 = sums[j+1].x2-sums[i].x2+r*sums[n].x2;
112
 
  xy = sums[j+1].xy-sums[i].xy+r*sums[n].xy;
113
 
  y2 = sums[j+1].y2-sums[i].y2+r*sums[n].y2;
114
 
  k = j+1-i+r*n;
115
 
  
116
 
  ctr->x = x/k;
117
 
  ctr->y = y/k;
118
 
 
119
 
  a = (x2-(double)x*x/k)/k;
120
 
  b = (xy-(double)x*y/k)/k;
121
 
  c = (y2-(double)y*y/k)/k;
122
 
  
123
 
  lambda2 = (a+c+sqrt((a-c)*(a-c)+4*b*b))/2; /* larger e.value */
124
 
 
125
 
  /* now find e.vector for lambda2 */
126
 
  a -= lambda2;
127
 
  c -= lambda2;
128
 
 
129
 
  if (fabs(a) >= fabs(c)) {
130
 
    l = sqrt(a*a+b*b);
131
 
    if (l!=0) {
132
 
      dir->x = -b/l;
133
 
      dir->y = a/l;
134
 
    }
135
 
  } else {
136
 
    l = sqrt(c*c+b*b);
137
 
    if (l!=0) {
138
 
      dir->x = -c/l;
139
 
      dir->y = b/l;
140
 
    }
141
 
  }
142
 
  if (l==0) {
143
 
    dir->x = dir->y = 0;   /* sometimes this can happen when k=4:
144
 
                              the two eigenvalues coincide */
145
 
  }
146
 
}
147
 
 
148
 
/* the type of (affine) quadratic forms, represented as symmetric 3x3
149
 
   matrices.  The value of the quadratic form at a vector (x,y) is v^t
150
 
   Q v, where v = (x,y,1)^t. */
151
 
typedef double quadform_t[3][3];
152
 
 
153
 
/* Apply quadratic form Q to vector w = (w.x,w.y) */
154
 
static inline double quadform(quadform_t Q, dpoint_t w) {
155
 
  double v[3];
156
 
  int i, j;
157
 
  double sum;
158
 
 
159
 
  v[0] = w.x;
160
 
  v[1] = w.y;
161
 
  v[2] = 1;
162
 
  sum = 0.0;
163
 
 
164
 
  for (i=0; i<3; i++) {
165
 
    for (j=0; j<3; j++) {
166
 
      sum += v[i] * Q[i][j] * v[j];
167
 
    }
168
 
  }
169
 
  return sum;
170
 
}
171
 
 
172
 
/* calculate p1 x p2 */
173
 
static inline int xprod(point_t p1, point_t p2) {
174
 
  return p1.x*p2.y - p1.y*p2.x;
175
 
}
176
 
 
177
 
/* calculate (p1-p0)x(p3-p2) */
178
 
static inline double cprod(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
179
 
  double x1, y1, x2, y2;
180
 
 
181
 
  x1 = p1.x - p0.x;
182
 
  y1 = p1.y - p0.y;
183
 
  x2 = p3.x - p2.x;
184
 
  y2 = p3.y - p2.y;
185
 
 
186
 
  return x1*y2 - x2*y1;
187
 
}
188
 
 
189
 
/* calculate (p1-p0)*(p2-p0) */
190
 
static inline double iprod(dpoint_t p0, dpoint_t p1, dpoint_t p2) {
191
 
  double x1, y1, x2, y2;
192
 
 
193
 
  x1 = p1.x - p0.x;
194
 
  y1 = p1.y - p0.y;
195
 
  x2 = p2.x - p0.x;
196
 
  y2 = p2.y - p0.y;
197
 
 
198
 
  return x1*x2 + y1*y2;
199
 
}
200
 
 
201
 
/* calculate (p1-p0)*(p3-p2) */
202
 
static inline double iprod1(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
203
 
  double x1, y1, x2, y2;
204
 
 
205
 
  x1 = p1.x - p0.x;
206
 
  y1 = p1.y - p0.y;
207
 
  x2 = p3.x - p2.x;
208
 
  y2 = p3.y - p2.y;
209
 
 
210
 
  return x1*x2 + y1*y2;
211
 
}
212
 
 
213
 
/* calculate distance between two points */
214
 
static inline double ddist(dpoint_t p, dpoint_t q) {
215
 
  return sqrt(sq(p.x-q.x)+sq(p.y-q.y));
216
 
}
217
 
 
218
 
/* calculate point of a bezier curve */
219
 
static inline dpoint_t bezier(double t, dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
220
 
  double s = 1-t;
221
 
  dpoint_t res;
222
 
 
223
 
  /* Note: a good optimizing compiler (such as gcc-3) reduces the
224
 
     following to 16 multiplications, using common subexpression
225
 
     elimination. */
226
 
 
227
 
  res.x = s*s*s*p0.x + 3*(s*s*t)*p1.x + 3*(t*t*s)*p2.x + t*t*t*p3.x;
228
 
  res.y = s*s*s*p0.y + 3*(s*s*t)*p1.y + 3*(t*t*s)*p2.y + t*t*t*p3.y;
229
 
 
230
 
  return res;
231
 
}
232
 
 
233
 
/* calculate the point t in [0..1] on the (convex) bezier curve
234
 
   (p0,p1,p2,p3) which is tangent to q1-q0. Return -1.0 if there is no
235
 
   solution in [0..1]. */
236
 
static double tangent(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3, dpoint_t q0, dpoint_t q1) {
237
 
  double A, B, C;   /* (1-t)^2 A + 2(1-t)t B + t^2 C = 0 */
238
 
  double a, b, c;   /* a t^2 + b t + c = 0 */
239
 
  double d, s, r1, r2;
240
 
 
241
 
  A = cprod(p0, p1, q0, q1);
242
 
  B = cprod(p1, p2, q0, q1);
243
 
  C = cprod(p2, p3, q0, q1);
244
 
 
245
 
  a = A - 2*B + C;
246
 
  b = -2*A + 2*B;
247
 
  c = A;
248
 
  
249
 
  d = b*b - 4*a*c;
250
 
 
251
 
  if (a==0 || d<0) {
252
 
    return -1.0;
253
 
  }
254
 
 
255
 
  s = sqrt(d);
256
 
 
257
 
  r1 = (-b + s) / (2 * a);
258
 
  r2 = (-b - s) / (2 * a);
259
 
 
260
 
  if (r1 >= 0 && r1 <= 1) {
261
 
    return r1;
262
 
  } else if (r2 >= 0 && r2 <= 1) {
263
 
    return r2;
264
 
  } else {
265
 
    return -1.0;
266
 
  }
267
 
}
268
 
 
269
 
/* ---------------------------------------------------------------------- */
270
 
/* Preparation: fill in the sum* fields of a path (used for later
271
 
   rapid summing). Return 0 on success, 1 with errno set on
272
 
   failure. */
273
 
static int calc_sums(privpath_t *pp) {
274
 
  int i, x, y;
275
 
  int n = pp->len;
276
 
 
277
 
  SAFE_MALLOC(pp->sums, pp->len+1, sums_t);
278
 
 
279
 
  /* origin */
280
 
  pp->x0 = pp->pt[0].x;
281
 
  pp->y0 = pp->pt[0].y;
282
 
 
283
 
  /* preparatory computation for later fast summing */
284
 
  pp->sums[0].x2 = pp->sums[0].xy = pp->sums[0].y2 = pp->sums[0].x = pp->sums[0].y = 0;
285
 
  for (i=0; i<n; i++) {
286
 
    x = pp->pt[i].x - pp->x0;
287
 
    y = pp->pt[i].y - pp->y0;
288
 
    pp->sums[i+1].x = pp->sums[i].x + x;
289
 
    pp->sums[i+1].y = pp->sums[i].y + y;
290
 
    pp->sums[i+1].x2 = pp->sums[i].x2 + x*x;
291
 
    pp->sums[i+1].xy = pp->sums[i].xy + x*y;
292
 
    pp->sums[i+1].y2 = pp->sums[i].y2 + y*y;
293
 
  }
294
 
  return 0;  
295
 
 
296
 
 malloc_error:
297
 
  return 1;
298
 
}
299
 
 
300
 
/* ---------------------------------------------------------------------- */
301
 
/* Stage 1: determine the straight subpaths (Sec. 2.2.1). Fill in the
302
 
   "lon" component of a path object (based on pt/len).  For each i,
303
 
   lon[i] is the furthest index such that a straight line can be drawn
304
 
   from i to lon[i]. Return 1 on error with errno set, else 0. */
305
 
 
306
 
/* this algorithm depends on the fact that the existence of straight
307
 
   subpaths is a triplewise property. I.e., there exists a straight
308
 
   line through squares i0,...,in iff there exists a straight line
309
 
   through i,j,k, for all i0<=i<j<k<=in. (Proof?) */
310
 
 
311
 
/* this implementation of calc_lon is O(n^2). It replaces an older
312
 
   O(n^3) version. A "constraint" means that future points must
313
 
   satisfy xprod(constraint[0], cur) >= 0 and xprod(constraint[1],
314
 
   cur) <= 0. */
315
 
 
316
 
/* Remark for potrace 1.1: the current implementation of calc_lon is
317
 
   more complex than the implementation found in potrace 1.0, but it
318
 
   is considerably faster. The introduction of the "nc" data structure
319
 
   means that we only have to test the constraints for "corner"
320
 
   points. On a typical input file, this speeds up the calc_lon
321
 
   function by a factor of 31.2, thereby decreasing its time share
322
 
   within the overall potrace algorithm from 72.6% to 7.82%, and
323
 
   speeding up the overall algorithm by a factor of 3.36. On another
324
 
   input file, calc_lon was sped up by a factor of 6.7, decreasing its
325
 
   time share from 51.4% to 13.61%, and speeding up the overall
326
 
   algorithm by a factor of 1.78. In any case, the savings are
327
 
   substantial. */
328
 
 
329
 
/* returns 0 on success, 1 on error with errno set */
330
 
static int calc_lon(privpath_t *pp) {
331
 
  point_t *pt = pp->pt;
332
 
  int n = pp->len;
333
 
  int i, j, k, k1;
334
 
  int ct[4], dir;
335
 
  point_t constraint[2];
336
 
  point_t cur;
337
 
  point_t off;
338
 
  int *pivk = NULL;  /* pivk[n] */
339
 
  int *nc = NULL;    /* nc[n]: next corner */
340
 
  point_t dk;  /* direction of k-k1 */
341
 
  int a, b, c, d;
342
 
 
343
 
  SAFE_MALLOC(pivk, n, int);
344
 
  SAFE_MALLOC(nc, n, int);
345
 
 
346
 
  /* initialize the nc data structure. Point from each point to the
347
 
     furthest future point to which it is connected by a vertical or
348
 
     horizontal segment. We take advantage of the fact that there is
349
 
     always a direction change at 0 (due to the path decomposition
350
 
     algorithm). But even if this were not so, there is no harm, as
351
 
     in practice, correctness does not depend on the word "furthest"
352
 
     above.  */
353
 
  k = 0;
354
 
  for (i=n-1; i>=0; i--) {
355
 
    if (pt[i].x != pt[k].x && pt[i].y != pt[k].y) {
356
 
      k = i+1;  /* necessarily i<n-1 in this case */
357
 
    }
358
 
    nc[i] = k;
359
 
  }
360
 
 
361
 
  SAFE_MALLOC(pp->lon, n, int);
362
 
 
363
 
  /* determine pivot points: for each i, let pivk[i] be the furthest k
364
 
     such that all j with i<j<k lie on a line connecting i,k. */
365
 
  
366
 
  for (i=n-1; i>=0; i--) {
367
 
    ct[0] = ct[1] = ct[2] = ct[3] = 0;
368
 
 
369
 
    /* keep track of "directions" that have occurred */
370
 
    dir = (3+3*(pt[mod(i+1,n)].x-pt[i].x)+(pt[mod(i+1,n)].y-pt[i].y))/2;
371
 
    ct[dir]++;
372
 
 
373
 
    constraint[0].x = 0;
374
 
    constraint[0].y = 0;
375
 
    constraint[1].x = 0;
376
 
    constraint[1].y = 0;
377
 
 
378
 
    /* find the next k such that no straight line from i to k */
379
 
    k = nc[i];
380
 
    k1 = i;
381
 
    while (1) {
382
 
      
383
 
      dir = (3+3*sign(pt[k].x-pt[k1].x)+sign(pt[k].y-pt[k1].y))/2;
384
 
      ct[dir]++;
385
 
 
386
 
      /* if all four "directions" have occurred, cut this path */
387
 
      if (ct[0] && ct[1] && ct[2] && ct[3]) {
388
 
        pivk[i] = k1;
389
 
        goto foundk;
390
 
      }
391
 
 
392
 
      cur.x = pt[k].x - pt[i].x;
393
 
      cur.y = pt[k].y - pt[i].y;
394
 
 
395
 
      /* see if current constraint is violated */
396
 
      if (xprod(constraint[0], cur) < 0 || xprod(constraint[1], cur) > 0) {
397
 
        goto constraint_viol;
398
 
      }
399
 
 
400
 
      /* else, update constraint */
401
 
      if (abs(cur.x) <= 1 && abs(cur.y) <= 1) {
402
 
        /* no constraint */
403
 
      } else {
404
 
        off.x = cur.x + ((cur.y>=0 && (cur.y>0 || cur.x<0)) ? 1 : -1);
405
 
        off.y = cur.y + ((cur.x<=0 && (cur.x<0 || cur.y<0)) ? 1 : -1);
406
 
        if (xprod(constraint[0], off) >= 0) {
407
 
          constraint[0] = off;
408
 
        }
409
 
        off.x = cur.x + ((cur.y<=0 && (cur.y<0 || cur.x<0)) ? 1 : -1);
410
 
        off.y = cur.y + ((cur.x>=0 && (cur.x>0 || cur.y<0)) ? 1 : -1);
411
 
        if (xprod(constraint[1], off) <= 0) {
412
 
          constraint[1] = off;
413
 
        }
414
 
      } 
415
 
      k1 = k;
416
 
      k = nc[k1];
417
 
      if (!cyclic(k,i,k1)) {
418
 
        break;
419
 
      }
420
 
    }
421
 
  constraint_viol:
422
 
    /* k1 was the last "corner" satisfying the current constraint, and
423
 
       k is the first one violating it. We now need to find the last
424
 
       point along k1..k which satisfied the constraint. */
425
 
    dk.x = sign(pt[k].x-pt[k1].x);
426
 
    dk.y = sign(pt[k].y-pt[k1].y);
427
 
    cur.x = pt[k1].x - pt[i].x;
428
 
    cur.y = pt[k1].y - pt[i].y;
429
 
    /* find largest integer j such that xprod(constraint[0], cur+j*dk)
430
 
       >= 0 and xprod(constraint[1], cur+j*dk) <= 0. Use bilinearity
431
 
       of xprod. */
432
 
    a = xprod(constraint[0], cur);
433
 
    b = xprod(constraint[0], dk);
434
 
    c = xprod(constraint[1], cur);
435
 
    d = xprod(constraint[1], dk);
436
 
    /* find largest integer j such that a+j*b>=0 and c+j*d<=0. This
437
 
       can be solved with integer arithmetic. */
438
 
    j = INFTY;
439
 
    if (b<0) {
440
 
      j = floordiv(a,-b);
441
 
    }
442
 
    if (d>0) {
443
 
      j = min(j, floordiv(-c,d));
444
 
    }
445
 
    pivk[i] = mod(k1+j,n);
446
 
  foundk:
447
 
    ;
448
 
  } /* for i */
449
 
 
450
 
  /* clean up: for each i, let lon[i] be the largest k such that for
451
 
     all i' with i<=i'<k, i'<k<=pivk[i']. */
452
 
 
453
 
  j=pivk[n-1];
454
 
  pp->lon[n-1]=j;
455
 
  for (i=n-2; i>=0; i--) {
456
 
    if (cyclic(i+1,pivk[i],j)) {
457
 
      j=pivk[i];
458
 
    }
459
 
    pp->lon[i]=j;
460
 
  }
461
 
 
462
 
  for (i=n-1; cyclic(mod(i+1,n),j,pp->lon[i]); i--) {
463
 
    pp->lon[i] = j;
464
 
  }
465
 
 
466
 
  free(pivk);
467
 
  free(nc);
468
 
  return 0;
469
 
 
470
 
 malloc_error:
471
 
  free(pivk);
472
 
  free(nc);
473
 
  return 1;
474
 
}
475
 
 
476
 
 
477
 
/* ---------------------------------------------------------------------- */
478
 
/* Stage 2: calculate the optimal polygon (Sec. 2.2.2-2.2.4). */ 
479
 
 
480
 
/* Auxiliary function: calculate the penalty of an edge from i to j in
481
 
   the given path. This needs the "lon" and "sum*" data. */
482
 
 
483
 
static double penalty3(privpath_t *pp, int i, int j) {
484
 
  int n = pp->len;
485
 
  point_t *pt = pp->pt;
486
 
  sums_t *sums = pp->sums;
487
 
 
488
 
  /* assume 0<=i<j<=n  */
489
 
  double x, y, x2, xy, y2;
490
 
  double k;
491
 
  double a, b, c, s;
492
 
  double px, py, ex, ey;
493
 
 
494
 
  int r=0; /* rotations from i to j */
495
 
 
496
 
  if (j>=n) {
497
 
    j-=n;
498
 
    r+=1;
499
 
  }
500
 
  
501
 
  x = sums[j+1].x-sums[i].x+r*sums[n].x;
502
 
  y = sums[j+1].y-sums[i].y+r*sums[n].y;
503
 
  x2 = sums[j+1].x2-sums[i].x2+r*sums[n].x2;
504
 
  xy = sums[j+1].xy-sums[i].xy+r*sums[n].xy;
505
 
  y2 = sums[j+1].y2-sums[i].y2+r*sums[n].y2;
506
 
  k = j+1-i+r*n;
507
 
  
508
 
  px = (pt[i].x+pt[j].x)/2.0-pt[0].x;
509
 
  py = (pt[i].y+pt[j].y)/2.0-pt[0].y;
510
 
  ey = (pt[j].x-pt[i].x);
511
 
  ex = -(pt[j].y-pt[i].y);
512
 
 
513
 
  a = ((x2-2*x*px)/k+px*px);
514
 
  b = ((xy-x*py-y*px)/k+px*py);
515
 
  c = ((y2-2*y*py)/k+py*py);
516
 
  
517
 
  s = ex*ex*a + 2*ex*ey*b + ey*ey*c;
518
 
 
519
 
  return sqrt(s);
520
 
}
521
 
 
522
 
/* find the optimal polygon. Fill in the m and po components. Return 1
523
 
   on failure with errno set, else 0. Non-cyclic version: assumes i=0
524
 
   is in the polygon. Fixme: ### implement cyclic version. */
525
 
static int bestpolygon(privpath_t *pp)
526
 
{
527
 
  int i, j, m, k;     
528
 
  int n = pp->len;
529
 
  double *pen = NULL; /* pen[n+1]: penalty vector */
530
 
  int *prev = NULL;   /* prev[n+1]: best path pointer vector */
531
 
  int *clip0 = NULL;  /* clip0[n]: longest segment pointer, non-cyclic */
532
 
  int *clip1 = NULL;  /* clip1[n+1]: backwards segment pointer, non-cyclic */
533
 
  int *seg0 = NULL;    /* seg0[m+1]: forward segment bounds, m<=n */
534
 
  int *seg1 = NULL;   /* seg1[m+1]: backward segment bounds, m<=n */
535
 
  double thispen;
536
 
  double best;
537
 
  int c;
538
 
 
539
 
  SAFE_MALLOC(pen, n+1, double);
540
 
  SAFE_MALLOC(prev, n+1, int);
541
 
  SAFE_MALLOC(clip0, n, int);
542
 
  SAFE_MALLOC(clip1, n+1, int);
543
 
  SAFE_MALLOC(seg0, n+1, int);
544
 
  SAFE_MALLOC(seg1, n+1, int);
545
 
 
546
 
  /* calculate clipped paths */
547
 
  for (i=0; i<n; i++) {
548
 
    c = mod(pp->lon[mod(i-1,n)]-1,n);
549
 
    if (c == i) {
550
 
      c = mod(i+1,n);
551
 
    }
552
 
    if (c < i) {
553
 
      clip0[i] = n;
554
 
    } else {
555
 
      clip0[i] = c;
556
 
    }
557
 
  }
558
 
 
559
 
  /* calculate backwards path clipping, non-cyclic. j <= clip0[i] iff
560
 
     clip1[j] <= i, for i,j=0..n. */
561
 
  j = 1;
562
 
  for (i=0; i<n; i++) {
563
 
    while (j <= clip0[i]) {
564
 
      clip1[j] = i;
565
 
      j++;
566
 
    }
567
 
  }
568
 
 
569
 
  /* calculate seg0[j] = longest path from 0 with j segments */
570
 
  i = 0;
571
 
  for (j=0; i<n; j++) {
572
 
    seg0[j] = i;
573
 
    i = clip0[i];
574
 
  }
575
 
  seg0[j] = n;
576
 
  m = j;
577
 
 
578
 
  /* calculate seg1[j] = longest path to n with m-j segments */
579
 
  i = n;
580
 
  for (j=m; j>0; j--) {
581
 
    seg1[j] = i;
582
 
    i = clip1[i];
583
 
  }
584
 
  seg1[0] = 0;
585
 
 
586
 
  /* now find the shortest path with m segments, based on penalty3 */
587
 
  /* note: the outer 2 loops jointly have at most n interations, thus
588
 
     the worst-case behavior here is quadratic. In practice, it is
589
 
     close to linear since the inner loop tends to be short. */
590
 
  pen[0]=0;
591
 
  for (j=1; j<=m; j++) {
592
 
    for (i=seg1[j]; i<=seg0[j]; i++) {
593
 
      best = -1;
594
 
      for (k=seg0[j-1]; k>=clip1[i]; k--) {
595
 
        thispen = penalty3(pp, k, i) + pen[k];
596
 
        if (best < 0 || thispen < best) {
597
 
          prev[i] = k;
598
 
          best = thispen;
599
 
        }
600
 
      }
601
 
      pen[i] = best;
602
 
    }
603
 
  }
604
 
 
605
 
  pp->m = m;
606
 
  SAFE_MALLOC(pp->po, m, int);
607
 
 
608
 
  /* read off shortest path */
609
 
  for (i=n, j=m-1; i>0; j--) {
610
 
    i = prev[i];
611
 
    pp->po[j] = i;
612
 
  }
613
 
 
614
 
  free(pen);
615
 
  free(prev);
616
 
  free(clip0);
617
 
  free(clip1);
618
 
  free(seg0);
619
 
  free(seg1);
620
 
  return 0;
621
 
  
622
 
 malloc_error:
623
 
  free(pen);
624
 
  free(prev);
625
 
  free(clip0);
626
 
  free(clip1);
627
 
  free(seg0);
628
 
  free(seg1);
629
 
  return 1;
630
 
}
631
 
 
632
 
/* ---------------------------------------------------------------------- */
633
 
/* Stage 3: vertex adjustment (Sec. 2.3.1). */
634
 
 
635
 
/* Adjust vertices of optimal polygon: calculate the intersection of
636
 
   the two "optimal" line segments, then move it into the unit square
637
 
   if it lies outside. Return 1 with errno set on error; 0 on
638
 
   success. */
639
 
 
640
 
static int adjust_vertices(privpath_t *pp) {
641
 
  int m = pp->m;
642
 
  int *po = pp->po;
643
 
  int n = pp->len;
644
 
  point_t *pt = pp->pt;
645
 
  int x0 = pp->x0;
646
 
  int y0 = pp->y0;
647
 
 
648
 
  dpoint_t *ctr = NULL;      /* ctr[m] */
649
 
  dpoint_t *dir = NULL;      /* dir[m] */
650
 
  quadform_t *q = NULL;      /* q[m] */
651
 
  double v[3];
652
 
  double d;
653
 
  int i, j, k, l;
654
 
  dpoint_t s;
655
 
  int r;
656
 
 
657
 
  SAFE_MALLOC(ctr, m, dpoint_t);
658
 
  SAFE_MALLOC(dir, m, dpoint_t);
659
 
  SAFE_MALLOC(q, m, quadform_t);
660
 
 
661
 
  r = privcurve_init(&pp->curve, m);
662
 
  if (r) {
663
 
    goto malloc_error;
664
 
  }
665
 
  
666
 
  /* calculate "optimal" point-slope representation for each line
667
 
     segment */
668
 
  for (i=0; i<m; i++) {
669
 
    j = po[mod(i+1,m)];
670
 
    j = mod(j-po[i],n)+po[i];
671
 
    pointslope(pp, po[i], j, &ctr[i], &dir[i]);
672
 
  }
673
 
 
674
 
  /* represent each line segment as a singular quadratic form; the
675
 
     distance of a point (x,y) from the line segment will be
676
 
     (x,y,1)Q(x,y,1)^t, where Q=q[i]. */
677
 
  for (i=0; i<m; i++) {
678
 
    d = sq(dir[i].x) + sq(dir[i].y);
679
 
    if (d == 0.0) {
680
 
      for (j=0; j<3; j++) {
681
 
        for (k=0; k<3; k++) {
682
 
          q[i][j][k] = 0;
683
 
        }
684
 
      }
685
 
    } else {
686
 
      v[0] = dir[i].y;
687
 
      v[1] = -dir[i].x;
688
 
      v[2] = - v[1] * ctr[i].y - v[0] * ctr[i].x;
689
 
      for (l=0; l<3; l++) {
690
 
        for (k=0; k<3; k++) {
691
 
          q[i][l][k] = v[l] * v[k] / d;
692
 
        }
693
 
      }
694
 
    }
695
 
  }
696
 
 
697
 
  /* now calculate the "intersections" of consecutive segments.
698
 
     Instead of using the actual intersection, we find the point
699
 
     within a given unit square which minimizes the square distance to
700
 
     the two lines. */
701
 
  for (i=0; i<m; i++) {
702
 
    quadform_t Q;
703
 
    dpoint_t w;
704
 
    double dx, dy;
705
 
    double det;
706
 
    double min, cand; /* minimum and candidate for minimum of quad. form */
707
 
    double xmin, ymin;  /* coordinates of minimum */
708
 
    int z;
709
 
 
710
 
    /* let s be the vertex, in coordinates relative to x0/y0 */
711
 
    s.x = pt[po[i]].x-x0;
712
 
    s.y = pt[po[i]].y-y0;
713
 
 
714
 
    /* intersect segments i-1 and i */
715
 
 
716
 
    j = mod(i-1,m);
717
 
 
718
 
    /* add quadratic forms */
719
 
    for (l=0; l<3; l++) {
720
 
      for (k=0; k<3; k++) {
721
 
        Q[l][k] = q[j][l][k] + q[i][l][k];
722
 
      }
723
 
    }
724
 
    
725
 
    while(1) {
726
 
      /* minimize the quadratic form Q on the unit square */
727
 
      /* find intersection */
728
 
 
729
 
#ifdef HAVE_GCC_LOOP_BUG
730
 
      /* work around gcc bug #12243 */
731
 
      free(NULL);
732
 
#endif
733
 
      
734
 
      det = Q[0][0]*Q[1][1] - Q[0][1]*Q[1][0];
735
 
      if (det != 0.0) {
736
 
        w.x = (-Q[0][2]*Q[1][1] + Q[1][2]*Q[0][1]) / det;
737
 
        w.y = ( Q[0][2]*Q[1][0] - Q[1][2]*Q[0][0]) / det;
738
 
        break;
739
 
      }
740
 
 
741
 
      /* matrix is singular - lines are parallel. Add another,
742
 
         orthogonal axis, through the center of the unit square */
743
 
      if (Q[0][0]>Q[1][1]) {
744
 
        v[0] = -Q[0][1];
745
 
        v[1] = Q[0][0];
746
 
      } else if (Q[1][1]) {
747
 
        v[0] = -Q[1][1];
748
 
        v[1] = Q[1][0];
749
 
      } else {
750
 
        v[0] = 1;
751
 
        v[1] = 0;
752
 
      }
753
 
      d = sq(v[0]) + sq(v[1]);
754
 
      v[2] = - v[1] * s.y - v[0] * s.x;
755
 
      for (l=0; l<3; l++) {
756
 
        for (k=0; k<3; k++) {
757
 
          Q[l][k] += v[l] * v[k] / d;
758
 
        }
759
 
      }
760
 
    }
761
 
    dx = fabs(w.x-s.x);
762
 
    dy = fabs(w.y-s.y);
763
 
    if (dx <= .5 && dy <= .5) {
764
 
      pp->curve.vertex[i].x = w.x+x0;
765
 
      pp->curve.vertex[i].y = w.y+y0;
766
 
      continue;
767
 
    }
768
 
 
769
 
    /* the minimum was not in the unit square; now minimize quadratic
770
 
       on boundary of square */
771
 
    min = quadform(Q, s);
772
 
    xmin = s.x;
773
 
    ymin = s.y;
774
 
 
775
 
    if (Q[0][0] == 0.0) {
776
 
      goto fixx;
777
 
    }
778
 
    for (z=0; z<2; z++) {   /* value of the y-coordinate */
779
 
      w.y = s.y-0.5+z;
780
 
      w.x = - (Q[0][1] * w.y + Q[0][2]) / Q[0][0];
781
 
      dx = fabs(w.x-s.x);
782
 
      cand = quadform(Q, w);
783
 
      if (dx <= .5 && cand < min) {
784
 
        min = cand;
785
 
        xmin = w.x;
786
 
        ymin = w.y;
787
 
      }
788
 
    }
789
 
  fixx:
790
 
    if (Q[1][1] == 0.0) {
791
 
      goto corners;
792
 
    }
793
 
    for (z=0; z<2; z++) {   /* value of the x-coordinate */
794
 
      w.x = s.x-0.5+z;
795
 
      w.y = - (Q[1][0] * w.x + Q[1][2]) / Q[1][1];
796
 
      dy = fabs(w.y-s.y);
797
 
      cand = quadform(Q, w);
798
 
      if (dy <= .5 && cand < min) {
799
 
        min = cand;
800
 
        xmin = w.x;
801
 
        ymin = w.y;
802
 
      }
803
 
    }
804
 
  corners:
805
 
    /* check four corners */
806
 
    for (l=0; l<2; l++) {
807
 
      for (k=0; k<2; k++) {
808
 
        w.x = s.x-0.5+l;
809
 
        w.y = s.y-0.5+k;
810
 
        cand = quadform(Q, w);
811
 
        if (cand < min) {
812
 
          min = cand;
813
 
          xmin = w.x;
814
 
          ymin = w.y;
815
 
        }
816
 
      }
817
 
    }
818
 
 
819
 
    pp->curve.vertex[i].x = xmin + x0;
820
 
    pp->curve.vertex[i].y = ymin + y0;
821
 
    continue;
822
 
  }
823
 
 
824
 
  free(ctr);
825
 
  free(dir);
826
 
  free(q);
827
 
  return 0;
828
 
 
829
 
 malloc_error:
830
 
  free(ctr);
831
 
  free(dir);
832
 
  free(q);
833
 
  return 1;
834
 
}
835
 
 
836
 
/* ---------------------------------------------------------------------- */
837
 
/* Stage 4: smoothing and corner analysis (Sec. 2.3.3) */
838
 
 
839
 
/* Always succeeds and returns 0 */
840
 
static int smooth(privcurve_t *curve, int sign, double alphamax) {
841
 
  int m = curve->n;
842
 
 
843
 
  int i, j, k;
844
 
  double dd, denom, alpha;
845
 
  dpoint_t p2, p3, p4;
846
 
 
847
 
  if (sign == '-') {
848
 
    /* reverse orientation of negative paths */
849
 
    for (i=0, j=m-1; i<j; i++, j--) {
850
 
      dpoint_t tmp;
851
 
      tmp = curve->vertex[i];
852
 
      curve->vertex[i] = curve->vertex[j];
853
 
      curve->vertex[j] = tmp;
854
 
    }
855
 
  }
856
 
 
857
 
  /* examine each vertex and find its best fit */
858
 
  for (i=0; i<m; i++) {
859
 
    j = mod(i+1, m);
860
 
    k = mod(i+2, m);
861
 
    p4 = interval(1/2.0, curve->vertex[k], curve->vertex[j]);
862
 
 
863
 
    denom = ddenom(curve->vertex[i], curve->vertex[k]);
864
 
    if (denom != 0.0) {
865
 
      dd = dpara(curve->vertex[i], curve->vertex[j], curve->vertex[k]) / denom;
866
 
      dd = fabs(dd);
867
 
      alpha = dd>1 ? (1 - 1.0/dd) : 0;
868
 
      alpha = alpha / 0.75;
869
 
    } else {
870
 
      alpha = 4/3.0;
871
 
    }
872
 
    curve->alpha0[j] = alpha;    /* remember "original" value of alpha */
873
 
 
874
 
    if (alpha > alphamax) {  /* pointed corner */
875
 
      curve->tag[j] = POTRACE_CORNER;
876
 
      curve->c[j][1] = curve->vertex[j];
877
 
      curve->c[j][2] = p4;
878
 
    } else {
879
 
      if (alpha < 0.55) {
880
 
        alpha = 0.55;
881
 
      } else if (alpha > 1) {
882
 
        alpha = 1;
883
 
      }
884
 
      p2 = interval(.5+.5*alpha, curve->vertex[i], curve->vertex[j]);
885
 
      p3 = interval(.5+.5*alpha, curve->vertex[k], curve->vertex[j]);
886
 
      curve->tag[j] = POTRACE_CURVETO;
887
 
      curve->c[j][0] = p2;
888
 
      curve->c[j][1] = p3;
889
 
      curve->c[j][2] = p4;
890
 
    }
891
 
    curve->alpha[j] = alpha;    /* store the "cropped" value of alpha */
892
 
    curve->beta[j] = 0.5;
893
 
  }
894
 
 
895
 
  return 0;
896
 
}
897
 
 
898
 
/* ---------------------------------------------------------------------- */
899
 
/* Stage 5: Curve optimization (Sec. 2.4) */
900
 
 
901
 
/* a private type for the result of opti_penalty */
902
 
struct opti_s {
903
 
  double pen;      /* penalty */
904
 
  dpoint_t c[2];   /* curve parameters */
905
 
  double t, s;     /* curve parameters */
906
 
  double alpha;    /* curve parameter */
907
 
};
908
 
typedef struct opti_s opti_t;
909
 
 
910
 
/* calculate best fit from i+.5 to j+.5.  Assume i<j (cyclically).
911
 
   Return 0 and set badness and parameters (alpha, beta), if
912
 
   possible. Return 1 if impossible. */
913
 
static int opti_penalty(privpath_t *pp, int i, int j, opti_t *res, double opttolerance, int *convc, double *areac) {
914
 
  int m = pp->curve.n;
915
 
  int k, k1, k2, conv, i1;
916
 
  double area, alpha, d, d1, d2;
917
 
  dpoint_t p0, p1, p2, p3, pt;
918
 
  double A, R, A1, A2, A3, A4;
919
 
  double s, t;
920
 
 
921
 
  /* check convexity, corner-freeness, and maximum bend < 179 degrees */
922
 
 
923
 
  if (i==j) {  /* sanity - a full loop can never be an opticurve */
924
 
    return 1;
925
 
  }
926
 
 
927
 
  k = i;
928
 
  i1 = mod(i+1, m);
929
 
  k1 = mod(k+1, m);
930
 
  conv = convc[k1];
931
 
  if (conv == 0) {
932
 
    return 1;
933
 
  }
934
 
  d = ddist(pp->curve.vertex[i], pp->curve.vertex[i1]);
935
 
  for (k=k1; k!=j; k=k1) {
936
 
    k1 = mod(k+1, m);
937
 
    k2 = mod(k+2, m);
938
 
    if (convc[k1] != conv) {
939
 
      return 1;
940
 
    }
941
 
    if (sign(cprod(pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1], pp->curve.vertex[k2])) != conv) {
942
 
      return 1;
943
 
    }
944
 
    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) {
945
 
      return 1;
946
 
    }
947
 
  }
948
 
 
949
 
  /* the curve we're working in: */
950
 
  p0 = pp->curve.c[mod(i,m)][2];
951
 
  p1 = pp->curve.vertex[mod(i+1,m)];
952
 
  p2 = pp->curve.vertex[mod(j,m)];
953
 
  p3 = pp->curve.c[mod(j,m)][2];
954
 
 
955
 
  /* determine its area */
956
 
  area = areac[j] - areac[i];
957
 
  area -= dpara(pp->curve.vertex[0], pp->curve.c[i][2], pp->curve.c[j][2])/2;
958
 
  if (i>=j) {
959
 
    area += areac[m];
960
 
  }
961
 
 
962
 
  /* find intersection o of p0p1 and p2p3. Let t,s such that o =
963
 
     interval(t,p0,p1) = interval(s,p3,p2). Let A be the area of the
964
 
     triangle (p0,o,p3). */
965
 
 
966
 
  A1 = dpara(p0, p1, p2);
967
 
  A2 = dpara(p0, p1, p3);
968
 
  A3 = dpara(p0, p2, p3);
969
 
  /* A4 = dpara(p1, p2, p3); */
970
 
  A4 = A1+A3-A2;    
971
 
  
972
 
  if (A2 == A1) {  /* this should never happen */
973
 
    return 1;
974
 
  }
975
 
 
976
 
  t = A3/(A3-A4);
977
 
  s = A2/(A2-A1);
978
 
  A = A2 * t / 2.0;
979
 
  
980
 
  if (A == 0.0) {  /* this should never happen */
981
 
    return 1;
982
 
  }
983
 
 
984
 
  R = area / A;  /* relative area */
985
 
  alpha = 2 - sqrt(4 - R / 0.3);  /* overall alpha for p0-o-p3 curve */
986
 
 
987
 
  res->c[0] = interval(t * alpha, p0, p1);
988
 
  res->c[1] = interval(s * alpha, p3, p2);
989
 
  res->alpha = alpha;
990
 
  res->t = t;
991
 
  res->s = s;
992
 
 
993
 
  p1 = res->c[0];
994
 
  p2 = res->c[1];  /* the proposed curve is now (p0,p1,p2,p3) */
995
 
 
996
 
  res->pen = 0;
997
 
 
998
 
  /* calculate penalty */
999
 
  /* check tangency with edges */
1000
 
  for (k=mod(i+1,m); k!=j; k=k1) {
1001
 
    k1 = mod(k+1,m);
1002
 
    t = tangent(p0, p1, p2, p3, pp->curve.vertex[k], pp->curve.vertex[k1]);
1003
 
    if (t<-.5) {
1004
 
      return 1;
1005
 
    }
1006
 
    pt = bezier(t, p0, p1, p2, p3);
1007
 
    d = ddist(pp->curve.vertex[k], pp->curve.vertex[k1]);
1008
 
    if (d == 0.0) {  /* this should never happen */
1009
 
      return 1;
1010
 
    }
1011
 
    d1 = dpara(pp->curve.vertex[k], pp->curve.vertex[k1], pt) / d;
1012
 
    if (fabs(d1) > opttolerance) {
1013
 
      return 1;
1014
 
    }
1015
 
    if (iprod(pp->curve.vertex[k], pp->curve.vertex[k1], pt) < 0 || iprod(pp->curve.vertex[k1], pp->curve.vertex[k], pt) < 0) {
1016
 
      return 1;
1017
 
    }
1018
 
    res->pen += sq(d1);
1019
 
  }
1020
 
 
1021
 
  /* check corners */
1022
 
  for (k=i; k!=j; k=k1) {
1023
 
    k1 = mod(k+1,m);
1024
 
    t = tangent(p0, p1, p2, p3, pp->curve.c[k][2], pp->curve.c[k1][2]);
1025
 
    if (t<-.5) {
1026
 
      return 1;
1027
 
    }
1028
 
    pt = bezier(t, p0, p1, p2, p3);
1029
 
    d = ddist(pp->curve.c[k][2], pp->curve.c[k1][2]);
1030
 
    if (d == 0.0) {  /* this should never happen */
1031
 
      return 1;
1032
 
    }
1033
 
    d1 = dpara(pp->curve.c[k][2], pp->curve.c[k1][2], pt) / d;
1034
 
    d2 = dpara(pp->curve.c[k][2], pp->curve.c[k1][2], pp->curve.vertex[k1]) / d;
1035
 
    d2 *= 0.75 * pp->curve.alpha[k1];
1036
 
    if (d2 < 0) {
1037
 
      d1 = -d1;
1038
 
      d2 = -d2;
1039
 
    }
1040
 
    if (d1 < d2 - opttolerance) {
1041
 
      return 1;
1042
 
    }
1043
 
    if (d1 < d2) {
1044
 
      res->pen += sq(d1 - d2);
1045
 
    }
1046
 
  }
1047
 
 
1048
 
  return 0;
1049
 
}
1050
 
 
1051
 
/* optimize the path p, replacing sequences of Bezier segments by a
1052
 
   single segment when possible. Return 0 on success, 1 with errno set
1053
 
   on failure. */
1054
 
static int opticurve(privpath_t *pp, double opttolerance) {
1055
 
  int m = pp->curve.n;
1056
 
  int *pt = NULL;     /* pt[m+1] */
1057
 
  double *pen = NULL; /* pen[m+1] */
1058
 
  int *len = NULL;    /* len[m+1] */
1059
 
  opti_t *opt = NULL; /* opt[m+1] */
1060
 
  int om;
1061
 
  int i,j,r;
1062
 
  opti_t o;
1063
 
  dpoint_t p0;
1064
 
  int i1;
1065
 
  double area;
1066
 
  double alpha;
1067
 
  double *s = NULL;
1068
 
  double *t = NULL;
1069
 
 
1070
 
  int *convc = NULL; /* conv[m]: pre-computed convexities */
1071
 
  double *areac = NULL; /* cumarea[m+1]: cache for fast area computation */
1072
 
 
1073
 
  SAFE_MALLOC(pt, m+1, int);
1074
 
  SAFE_MALLOC(pen, m+1, double);
1075
 
  SAFE_MALLOC(len, m+1, int);
1076
 
  SAFE_MALLOC(opt, m+1, opti_t);
1077
 
  SAFE_MALLOC(convc, m, int);
1078
 
  SAFE_MALLOC(areac, m+1, double);
1079
 
 
1080
 
  /* pre-calculate convexity: +1 = right turn, -1 = left turn, 0 = corner */
1081
 
  for (i=0; i<m; i++) {
1082
 
    if (pp->curve.tag[i] == POTRACE_CURVETO) {
1083
 
      convc[i] = sign(dpara(pp->curve.vertex[mod(i-1,m)], pp->curve.vertex[i], pp->curve.vertex[mod(i+1,m)]));
1084
 
    } else {
1085
 
      convc[i] = 0;
1086
 
    }
1087
 
  }
1088
 
 
1089
 
  /* pre-calculate areas */
1090
 
  area = 0.0;
1091
 
  areac[0] = 0.0;
1092
 
  p0 = pp->curve.vertex[0];
1093
 
  for (i=0; i<m; i++) {
1094
 
    i1 = mod(i+1, m);
1095
 
    if (pp->curve.tag[i1] == POTRACE_CURVETO) {
1096
 
      alpha = pp->curve.alpha[i1];
1097
 
      area += 0.3*alpha*(4-alpha)*dpara(pp->curve.c[i][2], pp->curve.vertex[i1], pp->curve.c[i1][2])/2;
1098
 
      area += dpara(p0, pp->curve.c[i][2], pp->curve.c[i1][2])/2;
1099
 
    }
1100
 
    areac[i+1] = area;
1101
 
  }
1102
 
 
1103
 
  pt[0] = -1;
1104
 
  pen[0] = 0;
1105
 
  len[0] = 0;
1106
 
 
1107
 
  /* Fixme: we always start from a fixed point -- should find the best
1108
 
     curve cyclically ### */
1109
 
 
1110
 
  for (j=1; j<=m; j++) {
1111
 
    /* calculate best path from 0 to j */
1112
 
    pt[j] = j-1;
1113
 
    pen[j] = pen[j-1];
1114
 
    len[j] = len[j-1]+1;
1115
 
 
1116
 
    for (i=j-2; i>=0; i--) {
1117
 
      r = opti_penalty(pp, i, mod(j,m), &o, opttolerance, convc, areac);
1118
 
      if (r) {
1119
 
        break;
1120
 
      }
1121
 
      if (len[j] > len[i]+1 || (len[j] == len[i]+1 && pen[j] > pen[i] + o.pen)) {
1122
 
        pt[j] = i;
1123
 
        pen[j] = pen[i] + o.pen;
1124
 
        len[j] = len[i] + 1;
1125
 
        opt[j] = o;
1126
 
      }
1127
 
    }
1128
 
  }
1129
 
  om = len[m];
1130
 
  r = privcurve_init(&pp->ocurve, om);
1131
 
  if (r) {
1132
 
    goto malloc_error;
1133
 
  }
1134
 
  SAFE_MALLOC(s, om, double);
1135
 
  SAFE_MALLOC(t, om, double);
1136
 
 
1137
 
  j = m;
1138
 
  for (i=om-1; i>=0; i--) {
1139
 
    if (pt[j]==j-1) {
1140
 
      pp->ocurve.tag[i]    = pp->curve.tag[mod(j,m)];
1141
 
      pp->ocurve.c[i][0]   = pp->curve.c[mod(j,m)][0];
1142
 
      pp->ocurve.c[i][1]   = pp->curve.c[mod(j,m)][1];
1143
 
      pp->ocurve.c[i][2]   = pp->curve.c[mod(j,m)][2];
1144
 
      pp->ocurve.vertex[i] = pp->curve.vertex[mod(j,m)];
1145
 
      pp->ocurve.alpha[i]  = pp->curve.alpha[mod(j,m)];
1146
 
      pp->ocurve.alpha0[i] = pp->curve.alpha0[mod(j,m)];
1147
 
      pp->ocurve.beta[i]   = pp->curve.beta[mod(j,m)];
1148
 
      s[i] = t[i] = 1.0;
1149
 
    } else {
1150
 
      pp->ocurve.tag[i] = POTRACE_CURVETO;
1151
 
      pp->ocurve.c[i][0] = opt[j].c[0];
1152
 
      pp->ocurve.c[i][1] = opt[j].c[1];
1153
 
      pp->ocurve.c[i][2] = pp->curve.c[mod(j,m)][2];
1154
 
      pp->ocurve.vertex[i] = interval(opt[j].s, pp->curve.c[mod(j,m)][2], pp->curve.vertex[mod(j,m)]);
1155
 
      pp->ocurve.alpha[i] = opt[j].alpha;
1156
 
      pp->ocurve.alpha0[i] = opt[j].alpha;
1157
 
      s[i] = opt[j].s;
1158
 
      t[i] = opt[j].t;
1159
 
    }
1160
 
    j = pt[j];
1161
 
  }
1162
 
 
1163
 
  /* calculate beta parameters */
1164
 
  for (i=0; i<om; i++) {
1165
 
    i1 = mod(i+1,om);
1166
 
    pp->ocurve.beta[i] = s[i] / (s[i] + t[i1]);
1167
 
  }
1168
 
 
1169
 
  free(pt);
1170
 
  free(pen);
1171
 
  free(len);
1172
 
  free(opt);
1173
 
  free(s);
1174
 
  free(t);
1175
 
  free(convc);
1176
 
  free(areac);
1177
 
  return 0;
1178
 
 
1179
 
 malloc_error:
1180
 
  free(pt);
1181
 
  free(pen);
1182
 
  free(len);
1183
 
  free(opt);
1184
 
  free(s);
1185
 
  free(t);
1186
 
  free(convc);
1187
 
  free(areac);
1188
 
  return 1;
1189
 
}
1190
 
 
1191
 
/* ---------------------------------------------------------------------- */
1192
 
 
1193
 
#define TRY(x) if (x) goto try_error
1194
 
 
1195
 
/* return 0 on success, 1 on error with errno set. */
1196
 
int process_path(path_t *plist, const potrace_param_t *param, progress_t *progress) {
1197
 
  path_t *p;
1198
 
  double nn = 0, cn = 0;
1199
 
 
1200
 
  if (progress->callback) {
1201
 
    /* precompute task size for progress estimates */
1202
 
    nn = 0;
1203
 
    list_forall (p, plist) {
1204
 
      nn += p->priv->len;
1205
 
    }
1206
 
    cn = 0;
1207
 
  }
1208
 
  
1209
 
  /* call downstream function with each path */
1210
 
  list_forall (p, plist) {
1211
 
    TRY(calc_sums(p->priv));
1212
 
    TRY(calc_lon(p->priv));
1213
 
    TRY(bestpolygon(p->priv));
1214
 
    TRY(adjust_vertices(p->priv));
1215
 
    TRY(smooth(&p->priv->curve, p->sign, param->alphamax));
1216
 
    if (param->opticurve) {
1217
 
      TRY(opticurve(p->priv, param->opttolerance));
1218
 
      p->priv->fcurve = &p->priv->ocurve;
1219
 
    } else {
1220
 
      p->priv->fcurve = &p->priv->curve;
1221
 
    }
1222
 
    privcurve_to_curve(p->priv->fcurve, &p->curve);
1223
 
 
1224
 
    if (progress->callback) {
1225
 
      cn += p->priv->len;
1226
 
      progress_update(cn/nn, progress);
1227
 
    }
1228
 
  }
1229
 
 
1230
 
  progress_update(1.0, progress);
1231
 
 
1232
 
  return 0;
1233
 
 
1234
 
 try_error:
1235
 
  return 1;
1236
 
}