Statistics
| Revision:

gvsig-raster / libjni-potrace / trunk / libjni-potrace / src / main / native / jpotrace / trace.c @ 1780

History | View | Annotate | Download (31.2 KB)

1
/* Copyright (C) 2001-2007 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 147 2007-04-09 00:44:09Z selinger $ */
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
#define SAFE_MALLOC(var, n, typ) \
26
  if ((var = (typ *)malloc((n)*sizeof(typ))) == NULL) goto malloc_error 
27

    
28
/* ---------------------------------------------------------------------- */
29
/* auxiliary functions */
30

    
31
/* return a direction that is 90 degrees counterclockwise from p2-p0,
32
   but then restricted to one of the major wind directions (n, nw, w, etc) */
33
static inline point_t dorth_infty(dpoint_t p0, dpoint_t p2) {
34
  point_t r;
35
  
36
  r.y = sign(p2.x-p0.x);
37
  r.x = -sign(p2.y-p0.y);
38

    
39
  return r;
40
}
41

    
42
/* return (p1-p0)x(p2-p0), the area of the parallelogram */
43
static inline double dpara(dpoint_t p0, dpoint_t p1, dpoint_t p2) {
44
  double x1, y1, x2, y2;
45

    
46
  x1 = p1.x-p0.x;
47
  y1 = p1.y-p0.y;
48
  x2 = p2.x-p0.x;
49
  y2 = p2.y-p0.y;
50

    
51
  return x1*y2 - x2*y1;
52
}
53

    
54
/* ddenom/dpara have the property that the square of radius 1 centered
55
   at p1 intersects the line p0p2 iff |dpara(p0,p1,p2)| <= ddenom(p0,p2) */
56
static inline double ddenom(dpoint_t p0, dpoint_t p2) {
57
  point_t r = dorth_infty(p0, p2);
58

    
59
  return r.y*(p2.x-p0.x) - r.x*(p2.y-p0.y);
60
}
61

    
62
/* return 1 if a <= b < c < a, in a cyclic sense (mod n) */
63
static inline int cyclic(int a, int b, int c) {
64
  if (a<=c) {
65
    return (a<=b && b<c);
66
  } else {
67
    return (a<=b || b<c);
68
  }
69
}
70

    
71
/* determine the center and slope of the line i..j. Assume i<j. Needs
72
   "sum" components of p to be set. */
73
static void pointslope(privpath_t *pp, int i, int j, dpoint_t *ctr, dpoint_t *dir) {
74
  /* assume i<j */
75

    
76
  int n = pp->len;
77
  sums_t *sums = pp->sums;
78

    
79
  double x, y, x2, xy, y2;
80
  double k;
81
  double a, b, c, lambda2, l;
82
  int r=0; /* rotations from i to j */
83

    
84
  while (j>=n) {
85
    j-=n;
86
    r+=1;
87
  }
88
  while (i>=n) {
89
    i-=n;
90
    r-=1;
91
  }
92
  while (j<0) {
93
    j+=n;
94
    r-=1;
95
  }
96
  while (i<0) {
97
    i+=n;
98
    r+=1;
99
  }
100
  
101
  x = sums[j+1].x-sums[i].x+r*sums[n].x;
102
  y = sums[j+1].y-sums[i].y+r*sums[n].y;
103
  x2 = sums[j+1].x2-sums[i].x2+r*sums[n].x2;
104
  xy = sums[j+1].xy-sums[i].xy+r*sums[n].xy;
105
  y2 = sums[j+1].y2-sums[i].y2+r*sums[n].y2;
106
  k = j+1-i+r*n;
107
  
108
  ctr->x = x/k;
109
  ctr->y = y/k;
110

    
111
  a = (x2-(double)x*x/k)/k;
112
  b = (xy-(double)x*y/k)/k;
113
  c = (y2-(double)y*y/k)/k;
114
  
115
  lambda2 = (a+c+sqrt((a-c)*(a-c)+4*b*b))/2; /* larger e.value */
116

    
117
  /* now find e.vector for lambda2 */
118
  a -= lambda2;
119
  c -= lambda2;
120

    
121
  if (fabs(a) >= fabs(c)) {
122
    l = sqrt(a*a+b*b);
123
    if (l!=0) {
124
      dir->x = -b/l;
125
      dir->y = a/l;
126
    }
127
  } else {
128
    l = sqrt(c*c+b*b);
129
    if (l!=0) {
130
      dir->x = -c/l;
131
      dir->y = b/l;
132
    }
133
  }
134
  if (l==0) {
135
    dir->x = dir->y = 0;   /* sometimes this can happen when k=4:
136
                              the two eigenvalues coincide */
137
  }
138
}
139

    
140
/* the type of (affine) quadratic forms, represented as symmetric 3x3
141
   matrices.  The value of the quadratic form at a vector (x,y) is v^t
142
   Q v, where v = (x,y,1)^t. */
143
typedef double quadform_t[3][3];
144

    
145
/* Apply quadratic form Q to vector w = (w.x,w.y) */
146
static inline double quadform(quadform_t Q, dpoint_t w) {
147
  double v[3];
148
  int i, j;
149
  double sum;
150

    
151
  v[0] = w.x;
152
  v[1] = w.y;
153
  v[2] = 1;
154
  sum = 0.0;
155

    
156
  for (i=0; i<3; i++) {
157
    for (j=0; j<3; j++) {
158
      sum += v[i] * Q[i][j] * v[j];
159
    }
160
  }
161
  return sum;
162
}
163

    
164
/* calculate p1 x p2 */
165
static inline int xprod(point_t p1, point_t p2) {
166
  return p1.x*p2.y - p1.y*p2.x;
167
}
168

    
169
/* calculate (p1-p0)x(p3-p2) */
170
static inline double cprod(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
171
  double x1, y1, x2, y2;
172

    
173
  x1 = p1.x - p0.x;
174
  y1 = p1.y - p0.y;
175
  x2 = p3.x - p2.x;
176
  y2 = p3.y - p2.y;
177

    
178
  return x1*y2 - x2*y1;
179
}
180

    
181
/* calculate (p1-p0)*(p2-p0) */
182
static inline double iprod(dpoint_t p0, dpoint_t p1, dpoint_t p2) {
183
  double x1, y1, x2, y2;
184

    
185
  x1 = p1.x - p0.x;
186
  y1 = p1.y - p0.y;
187
  x2 = p2.x - p0.x;
188
  y2 = p2.y - p0.y;
189

    
190
  return x1*x2 + y1*y2;
191
}
192

    
193
/* calculate (p1-p0)*(p3-p2) */
194
static inline double iprod1(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
195
  double x1, y1, x2, y2;
196

    
197
  x1 = p1.x - p0.x;
198
  y1 = p1.y - p0.y;
199
  x2 = p3.x - p2.x;
200
  y2 = p3.y - p2.y;
201

    
202
  return x1*x2 + y1*y2;
203
}
204

    
205
/* calculate distance between two points */
206
static inline double ddist(dpoint_t p, dpoint_t q) {
207
  return sqrt(sq(p.x-q.x)+sq(p.y-q.y));
208
}
209

    
210
/* calculate point of a bezier curve */
211
static inline dpoint_t bezier(double t, dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
212
  double s = 1-t;
213
  dpoint_t res;
214

    
215
  /* Note: a good optimizing compiler (such as gcc-3) reduces the
216
     following to 16 multiplications, using common subexpression
217
     elimination. */
218

    
219
  res.x = s*s*s*p0.x + 3*(s*s*t)*p1.x + 3*(t*t*s)*p2.x + t*t*t*p3.x;
220
  res.y = s*s*s*p0.y + 3*(s*s*t)*p1.y + 3*(t*t*s)*p2.y + t*t*t*p3.y;
221

    
222
  return res;
223
}
224

    
225
/* calculate the point t in [0..1] on the (convex) bezier curve
226
   (p0,p1,p2,p3) which is tangent to q1-q0. Return -1.0 if there is no
227
   solution in [0..1]. */
228
static double tangent(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3, dpoint_t q0, dpoint_t q1) {
229
  double A, B, C;   /* (1-t)^2 A + 2(1-t)t B + t^2 C = 0 */
230
  double a, b, c;   /* a t^2 + b t + c = 0 */
231
  double d, s, r1, r2;
232

    
233
  A = cprod(p0, p1, q0, q1);
234
  B = cprod(p1, p2, q0, q1);
235
  C = cprod(p2, p3, q0, q1);
236

    
237
  a = A - 2*B + C;
238
  b = -2*A + 2*B;
239
  c = A;
240
  
241
  d = b*b - 4*a*c;
242

    
243
  if (a==0 || d<0) {
244
    return -1.0;
245
  }
246

    
247
  s = sqrt(d);
248

    
249
  r1 = (-b + s) / (2 * a);
250
  r2 = (-b - s) / (2 * a);
251

    
252
  if (r1 >= 0 && r1 <= 1) {
253
    return r1;
254
  } else if (r2 >= 0 && r2 <= 1) {
255
    return r2;
256
  } else {
257
    return -1.0;
258
  }
259
}
260

    
261
/* ---------------------------------------------------------------------- */
262
/* Preparation: fill in the sum* fields of a path (used for later
263
   rapid summing). Return 0 on success, 1 with errno set on
264
   failure. */
265
static int calc_sums(privpath_t *pp) {
266
  int i, x, y;
267
  int n = pp->len;
268

    
269
  SAFE_MALLOC(pp->sums, pp->len+1, sums_t);
270

    
271
  /* origin */
272
  pp->x0 = pp->pt[0].x;
273
  pp->y0 = pp->pt[0].y;
274

    
275
  /* preparatory computation for later fast summing */
276
  pp->sums[0].x2 = pp->sums[0].xy = pp->sums[0].y2 = pp->sums[0].x = pp->sums[0].y = 0;
277
  for (i=0; i<n; i++) {
278
    x = pp->pt[i].x - pp->x0;
279
    y = pp->pt[i].y - pp->y0;
280
    pp->sums[i+1].x = pp->sums[i].x + x;
281
    pp->sums[i+1].y = pp->sums[i].y + y;
282
    pp->sums[i+1].x2 = pp->sums[i].x2 + x*x;
283
    pp->sums[i+1].xy = pp->sums[i].xy + x*y;
284
    pp->sums[i+1].y2 = pp->sums[i].y2 + y*y;
285
  }
286
  return 0;  
287

    
288
 malloc_error:
289
  return 1;
290
}
291

    
292
/* ---------------------------------------------------------------------- */
293
/* Stage 1: determine the straight subpaths (Sec. 2.2.1). Fill in the
294
   "lon" component of a path object (based on pt/len).        For each i,
295
   lon[i] is the furthest index such that a straight line can be drawn
296
   from i to lon[i]. Return 1 on error with errno set, else 0. */
297

    
298
/* this algorithm depends on the fact that the existence of straight
299
   subpaths is a triplewise property. I.e., there exists a straight
300
   line through squares i0,...,in iff there exists a straight line
301
   through i,j,k, for all i0<=i<j<k<=in. (Proof?) */
302

    
303
/* this implementation of calc_lon is O(n^2). It replaces an older
304
   O(n^3) version. A "constraint" means that future points must
305
   satisfy xprod(constraint[0], cur) >= 0 and xprod(constraint[1],
306
   cur) <= 0. */
307

    
308
/* Remark for Potrace 1.1: the current implementation of calc_lon is
309
   more complex than the implementation found in Potrace 1.0, but it
310
   is considerably faster. The introduction of the "nc" data structure
311
   means that we only have to test the constraints for "corner"
312
   points. On a typical input file, this speeds up the calc_lon
313
   function by a factor of 31.2, thereby decreasing its time share
314
   within the overall Potrace algorithm from 72.6% to 7.82%, and
315
   speeding up the overall algorithm by a factor of 3.36. On another
316
   input file, calc_lon was sped up by a factor of 6.7, decreasing its
317
   time share from 51.4% to 13.61%, and speeding up the overall
318
   algorithm by a factor of 1.78. In any case, the savings are
319
   substantial. */
320

    
321
/* returns 0 on success, 1 on error with errno set */
322
static int calc_lon(privpath_t *pp) {
323
  point_t *pt = pp->pt;
324
  int n = pp->len;
325
  int i, j, k, k1;
326
  int ct[4], dir;
327
  point_t constraint[2];
328
  point_t cur;
329
  point_t off;
330
  int *pivk = NULL;  /* pivk[n] */
331
  int *nc = NULL;    /* nc[n]: next corner */
332
  point_t dk;  /* direction of k-k1 */
333
  int a, b, c, d;
334

    
335
  SAFE_MALLOC(pivk, n, int);
336
  SAFE_MALLOC(nc, n, int);
337

    
338
  /* initialize the nc data structure. Point from each point to the
339
     furthest future point to which it is connected by a vertical or
340
     horizontal segment. We take advantage of the fact that there is
341
     always a direction change at 0 (due to the path decomposition
342
     algorithm). But even if this were not so, there is no harm, as
343
     in practice, correctness does not depend on the word "furthest"
344
     above.  */
345
  k = 0;
346
  for (i=n-1; i>=0; i--) {
347
    if (pt[i].x != pt[k].x && pt[i].y != pt[k].y) {
348
      k = i+1;  /* necessarily i<n-1 in this case */
349
    }
350
    nc[i] = k;
351
  }
352

    
353
  SAFE_MALLOC(pp->lon, n, int);
354

    
355
  /* determine pivot points: for each i, let pivk[i] be the furthest k
356
     such that all j with i<j<k lie on a line connecting i,k. */
357
  
358
  for (i=n-1; i>=0; i--) {
359
    ct[0] = ct[1] = ct[2] = ct[3] = 0;
360

    
361
    /* keep track of "directions" that have occurred */
362
    dir = (3+3*(pt[mod(i+1,n)].x-pt[i].x)+(pt[mod(i+1,n)].y-pt[i].y))/2;
363
    ct[dir]++;
364

    
365
    constraint[0].x = 0;
366
    constraint[0].y = 0;
367
    constraint[1].x = 0;
368
    constraint[1].y = 0;
369

    
370
    /* find the next k such that no straight line from i to k */
371
    k = nc[i];
372
    k1 = i;
373
    while (1) {
374
      
375
      dir = (3+3*sign(pt[k].x-pt[k1].x)+sign(pt[k].y-pt[k1].y))/2;
376
      ct[dir]++;
377

    
378
      /* if all four "directions" have occurred, cut this path */
379
      if (ct[0] && ct[1] && ct[2] && ct[3]) {
380
        pivk[i] = k1;
381
        goto foundk;
382
      }
383

    
384
      cur.x = pt[k].x - pt[i].x;
385
      cur.y = pt[k].y - pt[i].y;
386

    
387
      /* see if current constraint is violated */
388
      if (xprod(constraint[0], cur) < 0 || xprod(constraint[1], cur) > 0) {
389
        goto constraint_viol;
390
      }
391

    
392
      /* else, update constraint */
393
      if (abs(cur.x) <= 1 && abs(cur.y) <= 1) {
394
        /* no constraint */
395
      } else {
396
        off.x = cur.x + ((cur.y>=0 && (cur.y>0 || cur.x<0)) ? 1 : -1);
397
        off.y = cur.y + ((cur.x<=0 && (cur.x<0 || cur.y<0)) ? 1 : -1);
398
        if (xprod(constraint[0], off) >= 0) {
399
          constraint[0] = off;
400
        }
401
        off.x = cur.x + ((cur.y<=0 && (cur.y<0 || cur.x<0)) ? 1 : -1);
402
        off.y = cur.y + ((cur.x>=0 && (cur.x>0 || cur.y<0)) ? 1 : -1);
403
        if (xprod(constraint[1], off) <= 0) {
404
          constraint[1] = off;
405
        }
406
      }        
407
      k1 = k;
408
      k = nc[k1];
409
      if (!cyclic(k,i,k1)) {
410
        break;
411
      }
412
    }
413
  constraint_viol:
414
    /* k1 was the last "corner" satisfying the current constraint, and
415
       k is the first one violating it. We now need to find the last
416
       point along k1..k which satisfied the constraint. */
417
    dk.x = sign(pt[k].x-pt[k1].x);
418
    dk.y = sign(pt[k].y-pt[k1].y);
419
    cur.x = pt[k1].x - pt[i].x;
420
    cur.y = pt[k1].y - pt[i].y;
421
    /* find largest integer j such that xprod(constraint[0], cur+j*dk)
422
       >= 0 and xprod(constraint[1], cur+j*dk) <= 0. Use bilinearity
423
       of xprod. */
424
    a = xprod(constraint[0], cur);
425
    b = xprod(constraint[0], dk);
426
    c = xprod(constraint[1], cur);
427
    d = xprod(constraint[1], dk);
428
    /* find largest integer j such that a+j*b>=0 and c+j*d<=0. This
429
       can be solved with integer arithmetic. */
430
    j = INFTY;
431
    if (b<0) {
432
      j = floordiv(a,-b);
433
    }
434
    if (d>0) {
435
      j = min(j, floordiv(-c,d));
436
    }
437
    pivk[i] = mod(k1+j,n);
438
  foundk:
439
    ;
440
  } /* for i */
441

    
442
  /* clean up: for each i, let lon[i] be the largest k such that for
443
     all i' with i<=i'<k, i'<k<=pivk[i']. */
444

    
445
  j=pivk[n-1];
446
  pp->lon[n-1]=j;
447
  for (i=n-2; i>=0; i--) {
448
    if (cyclic(i+1,pivk[i],j)) {
449
      j=pivk[i];
450
    }
451
    pp->lon[i]=j;
452
  }
453

    
454
  for (i=n-1; cyclic(mod(i+1,n),j,pp->lon[i]); i--) {
455
    pp->lon[i] = j;
456
  }
457

    
458
  free(pivk);
459
  free(nc);
460
  return 0;
461

    
462
 malloc_error:
463
  free(pivk);
464
  free(nc);
465
  return 1;
466
}
467

    
468

    
469
/* ---------------------------------------------------------------------- */
470
/* Stage 2: calculate the optimal polygon (Sec. 2.2.2-2.2.4). */ 
471

    
472
/* Auxiliary function: calculate the penalty of an edge from i to j in
473
   the given path. This needs the "lon" and "sum*" data. */
474

    
475
static double penalty3(privpath_t *pp, int i, int j) {
476
  int n = pp->len;
477
  point_t *pt = pp->pt;
478
  sums_t *sums = pp->sums;
479

    
480
  /* assume 0<=i<j<=n  */
481
  double x, y, x2, xy, y2;
482
  double k;
483
  double a, b, c, s;
484
  double px, py, ex, ey;
485

    
486
  int r=0; /* rotations from i to j */
487

    
488
  if (j>=n) {
489
    j-=n;
490
    r+=1;
491
  }
492
  
493
  x = sums[j+1].x-sums[i].x+r*sums[n].x;
494
  y = sums[j+1].y-sums[i].y+r*sums[n].y;
495
  x2 = sums[j+1].x2-sums[i].x2+r*sums[n].x2;
496
  xy = sums[j+1].xy-sums[i].xy+r*sums[n].xy;
497
  y2 = sums[j+1].y2-sums[i].y2+r*sums[n].y2;
498
  k = j+1-i+r*n;
499
  
500
  px = (pt[i].x+pt[j].x)/2.0-pt[0].x;
501
  py = (pt[i].y+pt[j].y)/2.0-pt[0].y;
502
  ey = (pt[j].x-pt[i].x);
503
  ex = -(pt[j].y-pt[i].y);
504

    
505
  a = ((x2-2*x*px)/k+px*px);
506
  b = ((xy-x*py-y*px)/k+px*py);
507
  c = ((y2-2*y*py)/k+py*py);
508
  
509
  s = ex*ex*a + 2*ex*ey*b + ey*ey*c;
510

    
511
  return sqrt(s);
512
}
513

    
514
/* find the optimal polygon. Fill in the m and po components. Return 1
515
   on failure with errno set, else 0. Non-cyclic version: assumes i=0
516
   is in the polygon. Fixme: ### implement cyclic version. */
517
static int bestpolygon(privpath_t *pp)
518
{
519
  int i, j, m, k;     
520
  int n = pp->len;
521
  double *pen = NULL; /* pen[n+1]: penalty vector */
522
  int *prev = NULL;   /* prev[n+1]: best path pointer vector */
523
  int *clip0 = NULL;  /* clip0[n]: longest segment pointer, non-cyclic */
524
  int *clip1 = NULL;  /* clip1[n+1]: backwards segment pointer, non-cyclic */
525
  int *seg0 = NULL;    /* seg0[m+1]: forward segment bounds, m<=n */
526
  int *seg1 = NULL;   /* seg1[m+1]: backward segment bounds, m<=n */
527
  double thispen;
528
  double best;
529
  int c;
530

    
531
  SAFE_MALLOC(pen, n+1, double);
532
  SAFE_MALLOC(prev, n+1, int);
533
  SAFE_MALLOC(clip0, n, int);
534
  SAFE_MALLOC(clip1, n+1, int);
535
  SAFE_MALLOC(seg0, n+1, int);
536
  SAFE_MALLOC(seg1, n+1, int);
537

    
538
  /* calculate clipped paths */
539
  for (i=0; i<n; i++) {
540
    c = mod(pp->lon[mod(i-1,n)]-1,n);
541
    if (c == i) {
542
      c = mod(i+1,n);
543
    }
544
    if (c < i) {
545
      clip0[i] = n;
546
    } else {
547
      clip0[i] = c;
548
    }
549
  }
550

    
551
  /* calculate backwards path clipping, non-cyclic. j <= clip0[i] iff
552
     clip1[j] <= i, for i,j=0..n. */
553
  j = 1;
554
  for (i=0; i<n; i++) {
555
    while (j <= clip0[i]) {
556
      clip1[j] = i;
557
      j++;
558
    }
559
  }
560

    
561
  /* calculate seg0[j] = longest path from 0 with j segments */
562
  i = 0;
563
  for (j=0; i<n; j++) {
564
    seg0[j] = i;
565
    i = clip0[i];
566
  }
567
  seg0[j] = n;
568
  m = j;
569

    
570
  /* calculate seg1[j] = longest path to n with m-j segments */
571
  i = n;
572
  for (j=m; j>0; j--) {
573
    seg1[j] = i;
574
    i = clip1[i];
575
  }
576
  seg1[0] = 0;
577

    
578
  /* now find the shortest path with m segments, based on penalty3 */
579
  /* note: the outer 2 loops jointly have at most n interations, thus
580
     the worst-case behavior here is quadratic. In practice, it is
581
     close to linear since the inner loop tends to be short. */
582
  pen[0]=0;
583
  for (j=1; j<=m; j++) {
584
    for (i=seg1[j]; i<=seg0[j]; i++) {
585
      best = -1;
586
      for (k=seg0[j-1]; k>=clip1[i]; k--) {
587
        thispen = penalty3(pp, k, i) + pen[k];
588
        if (best < 0 || thispen < best) {
589
          prev[i] = k;
590
          best = thispen;
591
        }
592
      }
593
      pen[i] = best;
594
    }
595
  }
596

    
597
  pp->m = m;
598
  SAFE_MALLOC(pp->po, m, int);
599

    
600
  /* read off shortest path */
601
  for (i=n, j=m-1; i>0; j--) {
602
    i = prev[i];
603
    pp->po[j] = i;
604
  }
605

    
606
  free(pen);
607
  free(prev);
608
  free(clip0);
609
  free(clip1);
610
  free(seg0);
611
  free(seg1);
612
  return 0;
613
  
614
 malloc_error:
615
  free(pen);
616
  free(prev);
617
  free(clip0);
618
  free(clip1);
619
  free(seg0);
620
  free(seg1);
621
  return 1;
622
}
623

    
624
/* ---------------------------------------------------------------------- */
625
/* Stage 3: vertex adjustment (Sec. 2.3.1). */
626

    
627
/* Adjust vertices of optimal polygon: calculate the intersection of
628
   the two "optimal" line segments, then move it into the unit square
629
   if it lies outside. Return 1 with errno set on error; 0 on
630
   success. */
631

    
632
static int adjust_vertices(privpath_t *pp) {
633
  int m = pp->m;
634
  int *po = pp->po;
635
  int n = pp->len;
636
  point_t *pt = pp->pt;
637
  int x0 = pp->x0;
638
  int y0 = pp->y0;
639

    
640
  dpoint_t *ctr = NULL;      /* ctr[m] */
641
  dpoint_t *dir = NULL;      /* dir[m] */
642
  quadform_t *q = NULL;      /* q[m] */
643
  double v[3];
644
  double d;
645
  int i, j, k, l;
646
  dpoint_t s;
647
  int r;
648

    
649
  SAFE_MALLOC(ctr, m, dpoint_t);
650
  SAFE_MALLOC(dir, m, dpoint_t);
651
  SAFE_MALLOC(q, m, quadform_t);
652

    
653
  r = privcurve_init(&pp->curve, m);
654
  if (r) {
655
    goto malloc_error;
656
  }
657
  
658
  /* calculate "optimal" point-slope representation for each line
659
     segment */
660
  for (i=0; i<m; i++) {
661
    j = po[mod(i+1,m)];
662
    j = mod(j-po[i],n)+po[i];
663
    pointslope(pp, po[i], j, &ctr[i], &dir[i]);
664
  }
665

    
666
  /* represent each line segment as a singular quadratic form; the
667
     distance of a point (x,y) from the line segment will be
668
     (x,y,1)Q(x,y,1)^t, where Q=q[i]. */
669
  for (i=0; i<m; i++) {
670
    d = sq(dir[i].x) + sq(dir[i].y);
671
    if (d == 0.0) {
672
      for (j=0; j<3; j++) {
673
        for (k=0; k<3; k++) {
674
          q[i][j][k] = 0;
675
        }
676
      }
677
    } else {
678
      v[0] = dir[i].y;
679
      v[1] = -dir[i].x;
680
      v[2] = - v[1] * ctr[i].y - v[0] * ctr[i].x;
681
      for (l=0; l<3; l++) {
682
        for (k=0; k<3; k++) {
683
          q[i][l][k] = v[l] * v[k] / d;
684
        }
685
      }
686
    }
687
  }
688

    
689
  /* now calculate the "intersections" of consecutive segments.
690
     Instead of using the actual intersection, we find the point
691
     within a given unit square which minimizes the square distance to
692
     the two lines. */
693
  for (i=0; i<m; i++) {
694
    quadform_t Q;
695
    dpoint_t w;
696
    double dx, dy;
697
    double det;
698
    double min, cand; /* minimum and candidate for minimum of quad. form */
699
    double xmin, ymin;        /* coordinates of minimum */
700
    int z;
701

    
702
    /* let s be the vertex, in coordinates relative to x0/y0 */
703
    s.x = pt[po[i]].x-x0;
704
    s.y = pt[po[i]].y-y0;
705

    
706
    /* intersect segments i-1 and i */
707

    
708
    j = mod(i-1,m);
709

    
710
    /* add quadratic forms */
711
    for (l=0; l<3; l++) {
712
      for (k=0; k<3; k++) {
713
        Q[l][k] = q[j][l][k] + q[i][l][k];
714
      }
715
    }
716
    
717
    while(1) {
718
      /* minimize the quadratic form Q on the unit square */
719
      /* find intersection */
720

    
721
#ifdef HAVE_GCC_LOOP_BUG
722
      /* work around gcc bug #12243 */
723
      free(NULL);
724
#endif
725
      
726
      det = Q[0][0]*Q[1][1] - Q[0][1]*Q[1][0];
727
      if (det != 0.0) {
728
        w.x = (-Q[0][2]*Q[1][1] + Q[1][2]*Q[0][1]) / det;
729
        w.y = ( Q[0][2]*Q[1][0] - Q[1][2]*Q[0][0]) / det;
730
        break;
731
      }
732

    
733
      /* matrix is singular - lines are parallel. Add another,
734
         orthogonal axis, through the center of the unit square */
735
      if (Q[0][0]>Q[1][1]) {
736
        v[0] = -Q[0][1];
737
        v[1] = Q[0][0];
738
      } else if (Q[1][1]) {
739
        v[0] = -Q[1][1];
740
        v[1] = Q[1][0];
741
      } else {
742
        v[0] = 1;
743
        v[1] = 0;
744
      }
745
      d = sq(v[0]) + sq(v[1]);
746
      v[2] = - v[1] * s.y - v[0] * s.x;
747
      for (l=0; l<3; l++) {
748
        for (k=0; k<3; k++) {
749
          Q[l][k] += v[l] * v[k] / d;
750
        }
751
      }
752
    }
753
    dx = fabs(w.x-s.x);
754
    dy = fabs(w.y-s.y);
755
    if (dx <= .5 && dy <= .5) {
756
      pp->curve.vertex[i].x = w.x+x0;
757
      pp->curve.vertex[i].y = w.y+y0;
758
      continue;
759
    }
760

    
761
    /* the minimum was not in the unit square; now minimize quadratic
762
       on boundary of square */
763
    min = quadform(Q, s);
764
    xmin = s.x;
765
    ymin = s.y;
766

    
767
    if (Q[0][0] == 0.0) {
768
      goto fixx;
769
    }
770
    for (z=0; z<2; z++) {   /* value of the y-coordinate */
771
      w.y = s.y-0.5+z;
772
      w.x = - (Q[0][1] * w.y + Q[0][2]) / Q[0][0];
773
      dx = fabs(w.x-s.x);
774
      cand = quadform(Q, w);
775
      if (dx <= .5 && cand < min) {
776
        min = cand;
777
        xmin = w.x;
778
        ymin = w.y;
779
      }
780
    }
781
  fixx:
782
    if (Q[1][1] == 0.0) {
783
      goto corners;
784
    }
785
    for (z=0; z<2; z++) {   /* value of the x-coordinate */
786
      w.x = s.x-0.5+z;
787
      w.y = - (Q[1][0] * w.x + Q[1][2]) / Q[1][1];
788
      dy = fabs(w.y-s.y);
789
      cand = quadform(Q, w);
790
      if (dy <= .5 && cand < min) {
791
        min = cand;
792
        xmin = w.x;
793
        ymin = w.y;
794
      }
795
    }
796
  corners:
797
    /* check four corners */
798
    for (l=0; l<2; l++) {
799
      for (k=0; k<2; k++) {
800
        w.x = s.x-0.5+l;
801
        w.y = s.y-0.5+k;
802
        cand = quadform(Q, w);
803
        if (cand < min) {
804
          min = cand;
805
          xmin = w.x;
806
          ymin = w.y;
807
        }
808
      }
809
    }
810

    
811
    pp->curve.vertex[i].x = xmin + x0;
812
    pp->curve.vertex[i].y = ymin + y0;
813
    continue;
814
  }
815

    
816
  free(ctr);
817
  free(dir);
818
  free(q);
819
  return 0;
820

    
821
 malloc_error:
822
  free(ctr);
823
  free(dir);
824
  free(q);
825
  return 1;
826
}
827

    
828
/* ---------------------------------------------------------------------- */
829
/* Stage 4: smoothing and corner analysis (Sec. 2.3.3) */
830

    
831
/* Always succeeds and returns 0 */
832
static int smooth(privcurve_t *curve, int sign, double alphamax) {
833
  int m = curve->n;
834

    
835
  int i, j, k;
836
  double dd, denom, alpha;
837
  dpoint_t p2, p3, p4;
838

    
839
  if (sign == '-') {
840
    /* reverse orientation of negative paths */
841
    for (i=0, j=m-1; i<j; i++, j--) {
842
      dpoint_t tmp;
843
      tmp = curve->vertex[i];
844
      curve->vertex[i] = curve->vertex[j];
845
      curve->vertex[j] = tmp;
846
    }
847
  }
848

    
849
  /* examine each vertex and find its best fit */
850
  for (i=0; i<m; i++) {
851
    j = mod(i+1, m);
852
    k = mod(i+2, m);
853
    p4 = interval(1/2.0, curve->vertex[k], curve->vertex[j]);
854

    
855
    denom = ddenom(curve->vertex[i], curve->vertex[k]);
856
    if (denom != 0.0) {
857
      dd = dpara(curve->vertex[i], curve->vertex[j], curve->vertex[k]) / denom;
858
      dd = fabs(dd);
859
      alpha = dd>1 ? (1 - 1.0/dd) : 0;
860
      alpha = alpha / 0.75;
861
    } else {
862
      alpha = 4/3.0;
863
    }
864
    curve->alpha0[j] = alpha;         /* remember "original" value of alpha */
865

    
866
    if (alpha > alphamax) {  /* pointed corner */
867
      curve->tag[j] = POTRACE_CORNER;
868
      curve->c[j][1] = curve->vertex[j];
869
      curve->c[j][2] = p4;
870
    } else {
871
      if (alpha < 0.55) {
872
        alpha = 0.55;
873
      } else if (alpha > 1) {
874
        alpha = 1;
875
      }
876
      p2 = interval(.5+.5*alpha, curve->vertex[i], curve->vertex[j]);
877
      p3 = interval(.5+.5*alpha, curve->vertex[k], curve->vertex[j]);
878
      curve->tag[j] = POTRACE_CURVETO;
879
      curve->c[j][0] = p2;
880
      curve->c[j][1] = p3;
881
      curve->c[j][2] = p4;
882
    }
883
    curve->alpha[j] = alpha;        /* store the "cropped" value of alpha */
884
    curve->beta[j] = 0.5;
885
  }
886
  curve->alphacurve = 1;
887

    
888
  return 0;
889
}
890

    
891
/* ---------------------------------------------------------------------- */
892
/* Stage 5: Curve optimization (Sec. 2.4) */
893

    
894
/* a private type for the result of opti_penalty */
895
struct opti_s {
896
  double pen;           /* penalty */
897
  dpoint_t c[2];   /* curve parameters */
898
  double t, s;           /* curve parameters */
899
  double alpha;           /* curve parameter */
900
};
901
typedef struct opti_s opti_t;
902

    
903
/* calculate best fit from i+.5 to j+.5.  Assume i<j (cyclically).
904
   Return 0 and set badness and parameters (alpha, beta), if
905
   possible. Return 1 if impossible. */
906
static int opti_penalty(privpath_t *pp, int i, int j, opti_t *res, double opttolerance, int *convc, double *areac) {
907
  int m = pp->curve.n;
908
  int k, k1, k2, conv, i1;
909
  double area, alpha, d, d1, d2;
910
  dpoint_t p0, p1, p2, p3, pt;
911
  double A, R, A1, A2, A3, A4;
912
  double s, t;
913

    
914
  /* check convexity, corner-freeness, and maximum bend < 179 degrees */
915

    
916
  if (i==j) {  /* sanity - a full loop can never be an opticurve */
917
    return 1;
918
  }
919

    
920
  k = i;
921
  i1 = mod(i+1, m);
922
  k1 = mod(k+1, m);
923
  conv = convc[k1];
924
  if (conv == 0) {
925
    return 1;
926
  }
927
  d = ddist(pp->curve.vertex[i], pp->curve.vertex[i1]);
928
  for (k=k1; k!=j; k=k1) {
929
    k1 = mod(k+1, m);
930
    k2 = mod(k+2, m);
931
    if (convc[k1] != conv) {
932
      return 1;
933
    }
934
    if (sign(cprod(pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1], pp->curve.vertex[k2])) != conv) {
935
      return 1;
936
    }
937
    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) {
938
      return 1;
939
    }
940
  }
941

    
942
  /* the curve we're working in: */
943
  p0 = pp->curve.c[mod(i,m)][2];
944
  p1 = pp->curve.vertex[mod(i+1,m)];
945
  p2 = pp->curve.vertex[mod(j,m)];
946
  p3 = pp->curve.c[mod(j,m)][2];
947

    
948
  /* determine its area */
949
  area = areac[j] - areac[i];
950
  area -= dpara(pp->curve.vertex[0], pp->curve.c[i][2], pp->curve.c[j][2])/2;
951
  if (i>=j) {
952
    area += areac[m];
953
  }
954

    
955
  /* find intersection o of p0p1 and p2p3. Let t,s such that o =
956
     interval(t,p0,p1) = interval(s,p3,p2). Let A be the area of the
957
     triangle (p0,o,p3). */
958

    
959
  A1 = dpara(p0, p1, p2);
960
  A2 = dpara(p0, p1, p3);
961
  A3 = dpara(p0, p2, p3);
962
  /* A4 = dpara(p1, p2, p3); */
963
  A4 = A1+A3-A2;    
964
  
965
  if (A2 == A1) {  /* this should never happen */
966
    return 1;
967
  }
968

    
969
  t = A3/(A3-A4);
970
  s = A2/(A2-A1);
971
  A = A2 * t / 2.0;
972
  
973
  if (A == 0.0) {  /* this should never happen */
974
    return 1;
975
  }
976

    
977
  R = area / A;         /* relative area */
978
  alpha = 2 - sqrt(4 - R / 0.3);  /* overall alpha for p0-o-p3 curve */
979

    
980
  res->c[0] = interval(t * alpha, p0, p1);
981
  res->c[1] = interval(s * alpha, p3, p2);
982
  res->alpha = alpha;
983
  res->t = t;
984
  res->s = s;
985

    
986
  p1 = res->c[0];
987
  p2 = res->c[1];  /* the proposed curve is now (p0,p1,p2,p3) */
988

    
989
  res->pen = 0;
990

    
991
  /* calculate penalty */
992
  /* check tangency with edges */
993
  for (k=mod(i+1,m); k!=j; k=k1) {
994
    k1 = mod(k+1,m);
995
    t = tangent(p0, p1, p2, p3, pp->curve.vertex[k], pp->curve.vertex[k1]);
996
    if (t<-.5) {
997
      return 1;
998
    }
999
    pt = bezier(t, p0, p1, p2, p3);
1000
    d = ddist(pp->curve.vertex[k], pp->curve.vertex[k1]);
1001
    if (d == 0.0) {  /* this should never happen */
1002
      return 1;
1003
    }
1004
    d1 = dpara(pp->curve.vertex[k], pp->curve.vertex[k1], pt) / d;
1005
    if (fabs(d1) > opttolerance) {
1006
      return 1;
1007
    }
1008
    if (iprod(pp->curve.vertex[k], pp->curve.vertex[k1], pt) < 0 || iprod(pp->curve.vertex[k1], pp->curve.vertex[k], pt) < 0) {
1009
      return 1;
1010
    }
1011
    res->pen += sq(d1);
1012
  }
1013

    
1014
  /* check corners */
1015
  for (k=i; k!=j; k=k1) {
1016
    k1 = mod(k+1,m);
1017
    t = tangent(p0, p1, p2, p3, pp->curve.c[k][2], pp->curve.c[k1][2]);
1018
    if (t<-.5) {
1019
      return 1;
1020
    }
1021
    pt = bezier(t, p0, p1, p2, p3);
1022
    d = ddist(pp->curve.c[k][2], pp->curve.c[k1][2]);
1023
    if (d == 0.0) {  /* this should never happen */
1024
      return 1;
1025
    }
1026
    d1 = dpara(pp->curve.c[k][2], pp->curve.c[k1][2], pt) / d;
1027
    d2 = dpara(pp->curve.c[k][2], pp->curve.c[k1][2], pp->curve.vertex[k1]) / d;
1028
    d2 *= 0.75 * pp->curve.alpha[k1];
1029
    if (d2 < 0) {
1030
      d1 = -d1;
1031
      d2 = -d2;
1032
    }
1033
    if (d1 < d2 - opttolerance) {
1034
      return 1;
1035
    }
1036
    if (d1 < d2) {
1037
      res->pen += sq(d1 - d2);
1038
    }
1039
  }
1040

    
1041
  return 0;
1042
}
1043

    
1044
/* optimize the path p, replacing sequences of Bezier segments by a
1045
   single segment when possible. Return 0 on success, 1 with errno set
1046
   on failure. */
1047
static int opticurve(privpath_t *pp, double opttolerance) {
1048
  int m = pp->curve.n;
1049
  int *pt = NULL;     /* pt[m+1] */
1050
  double *pen = NULL; /* pen[m+1] */
1051
  int *len = NULL;    /* len[m+1] */
1052
  opti_t *opt = NULL; /* opt[m+1] */
1053
  int om;
1054
  int i,j,r;
1055
  opti_t o;
1056
  dpoint_t p0;
1057
  int i1;
1058
  double area;
1059
  double alpha;
1060
  double *s = NULL;
1061
  double *t = NULL;
1062

    
1063
  int *convc = NULL; /* conv[m]: pre-computed convexities */
1064
  double *areac = NULL; /* cumarea[m+1]: cache for fast area computation */
1065

    
1066
  SAFE_MALLOC(pt, m+1, int);
1067
  SAFE_MALLOC(pen, m+1, double);
1068
  SAFE_MALLOC(len, m+1, int);
1069
  SAFE_MALLOC(opt, m+1, opti_t);
1070
  SAFE_MALLOC(convc, m, int);
1071
  SAFE_MALLOC(areac, m+1, double);
1072

    
1073
  /* pre-calculate convexity: +1 = right turn, -1 = left turn, 0 = corner */
1074
  for (i=0; i<m; i++) {
1075
    if (pp->curve.tag[i] == POTRACE_CURVETO) {
1076
      convc[i] = sign(dpara(pp->curve.vertex[mod(i-1,m)], pp->curve.vertex[i], pp->curve.vertex[mod(i+1,m)]));
1077
    } else {
1078
      convc[i] = 0;
1079
    }
1080
  }
1081

    
1082
  /* pre-calculate areas */
1083
  area = 0.0;
1084
  areac[0] = 0.0;
1085
  p0 = pp->curve.vertex[0];
1086
  for (i=0; i<m; i++) {
1087
    i1 = mod(i+1, m);
1088
    if (pp->curve.tag[i1] == POTRACE_CURVETO) {
1089
      alpha = pp->curve.alpha[i1];
1090
      area += 0.3*alpha*(4-alpha)*dpara(pp->curve.c[i][2], pp->curve.vertex[i1], pp->curve.c[i1][2])/2;
1091
      area += dpara(p0, pp->curve.c[i][2], pp->curve.c[i1][2])/2;
1092
    }
1093
    areac[i+1] = area;
1094
  }
1095

    
1096
  pt[0] = -1;
1097
  pen[0] = 0;
1098
  len[0] = 0;
1099

    
1100
  /* Fixme: we always start from a fixed point -- should find the best
1101
     curve cyclically ### */
1102

    
1103
  for (j=1; j<=m; j++) {
1104
    /* calculate best path from 0 to j */
1105
    pt[j] = j-1;
1106
    pen[j] = pen[j-1];
1107
    len[j] = len[j-1]+1;
1108

    
1109
    for (i=j-2; i>=0; i--) {
1110
      r = opti_penalty(pp, i, mod(j,m), &o, opttolerance, convc, areac);
1111
      if (r) {
1112
        break;
1113
      }
1114
      if (len[j] > len[i]+1 || (len[j] == len[i]+1 && pen[j] > pen[i] + o.pen)) {
1115
        pt[j] = i;
1116
        pen[j] = pen[i] + o.pen;
1117
        len[j] = len[i] + 1;
1118
        opt[j] = o;
1119
      }
1120
    }
1121
  }
1122
  om = len[m];
1123
  r = privcurve_init(&pp->ocurve, om);
1124
  if (r) {
1125
    goto malloc_error;
1126
  }
1127
  SAFE_MALLOC(s, om, double);
1128
  SAFE_MALLOC(t, om, double);
1129

    
1130
  j = m;
1131
  for (i=om-1; i>=0; i--) {
1132
    if (pt[j]==j-1) {
1133
      pp->ocurve.tag[i]     = pp->curve.tag[mod(j,m)];
1134
      pp->ocurve.c[i][0]    = pp->curve.c[mod(j,m)][0];
1135
      pp->ocurve.c[i][1]    = pp->curve.c[mod(j,m)][1];
1136
      pp->ocurve.c[i][2]    = pp->curve.c[mod(j,m)][2];
1137
      pp->ocurve.vertex[i]  = pp->curve.vertex[mod(j,m)];
1138
      pp->ocurve.alpha[i]   = pp->curve.alpha[mod(j,m)];
1139
      pp->ocurve.alpha0[i]  = pp->curve.alpha0[mod(j,m)];
1140
      pp->ocurve.beta[i]    = pp->curve.beta[mod(j,m)];
1141
      s[i] = t[i] = 1.0;
1142
    } else {
1143
      pp->ocurve.tag[i] = POTRACE_CURVETO;
1144
      pp->ocurve.c[i][0] = opt[j].c[0];
1145
      pp->ocurve.c[i][1] = opt[j].c[1];
1146
      pp->ocurve.c[i][2] = pp->curve.c[mod(j,m)][2];
1147
      pp->ocurve.vertex[i] = interval(opt[j].s, pp->curve.c[mod(j,m)][2], pp->curve.vertex[mod(j,m)]);
1148
      pp->ocurve.alpha[i] = opt[j].alpha;
1149
      pp->ocurve.alpha0[i] = opt[j].alpha;
1150
      s[i] = opt[j].s;
1151
      t[i] = opt[j].t;
1152
    }
1153
    j = pt[j];
1154
  }
1155

    
1156
  /* calculate beta parameters */
1157
  for (i=0; i<om; i++) {
1158
    i1 = mod(i+1,om);
1159
    pp->ocurve.beta[i] = s[i] / (s[i] + t[i1]);
1160
  }
1161
  pp->ocurve.alphacurve = 1;
1162

    
1163
  free(pt);
1164
  free(pen);
1165
  free(len);
1166
  free(opt);
1167
  free(s);
1168
  free(t);
1169
  free(convc);
1170
  free(areac);
1171
  return 0;
1172

    
1173
 malloc_error:
1174
  free(pt);
1175
  free(pen);
1176
  free(len);
1177
  free(opt);
1178
  free(s);
1179
  free(t);
1180
  free(convc);
1181
  free(areac);
1182
  return 1;
1183
}
1184

    
1185
/* ---------------------------------------------------------------------- */
1186

    
1187
#define TRY(x) if (x) goto try_error
1188

    
1189
/* return 0 on success, 1 on error with errno set. */
1190
int process_path(path_t *plist, const potrace_param_t *param, progress_t *progress) {
1191
  path_t *p;
1192
  double nn = 0, cn = 0;
1193

    
1194
  if (progress->callback) {
1195
    /* precompute task size for progress estimates */
1196
    nn = 0;
1197
    list_forall (p, plist) {
1198
      nn += p->priv->len;
1199
    }
1200
    cn = 0;
1201
  }
1202
  
1203
  /* call downstream function with each path */
1204
  list_forall (p, plist) {
1205
    TRY(calc_sums(p->priv));
1206
    TRY(calc_lon(p->priv));
1207
    TRY(bestpolygon(p->priv));
1208
    TRY(adjust_vertices(p->priv));
1209
    TRY(smooth(&p->priv->curve, p->sign, param->alphamax));
1210
    if (param->opticurve) {
1211
      TRY(opticurve(p->priv, param->opttolerance));
1212
      p->priv->fcurve = &p->priv->ocurve;
1213
    } else {
1214
      p->priv->fcurve = &p->priv->curve;
1215
    }
1216
    privcurve_to_curve(p->priv->fcurve, &p->curve);
1217

    
1218
    if (progress->callback) {
1219
      cn += p->priv->len;
1220
      progress_update(cn/nn, progress);
1221
    }
1222
  }
1223

    
1224
  progress_update(1.0, progress);
1225

    
1226
  return 0;
1227

    
1228
 try_error:
1229
  return 1;
1230
}