summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNicolas Dufour <nicoduf@yahoo.fr>2011-04-14 06:29:21 +0000
committerJazzyNico <nicoduf@yahoo.fr>2011-04-14 06:29:21 +0000
commitde76d854317e700b1f0297c83f6a1cacc2ffa533 (patch)
tree097e2cafc1ee46bc4aa1b9694626273fc1a3fdae /src
parentadd expression evaluator for spinbox input boxes. also knows a little about u... (diff)
downloadinkscape-de76d854317e700b1f0297c83f6a1cacc2ffa533.tar.gz
inkscape-de76d854317e700b1f0297c83f6a1cacc2ffa533.zip
Tracing. Potrace 1.9 update (see http://potrace.sourceforge.net/ChangeLog).
(bzr r10163)
Diffstat (limited to 'src')
-rw-r--r--src/trace/potrace/auxiliary.h29
-rw-r--r--src/trace/potrace/bitmap.h6
-rw-r--r--src/trace/potrace/curve.cpp4
-rw-r--r--src/trace/potrace/curve.h2
-rw-r--r--src/trace/potrace/decompose.cpp50
-rw-r--r--src/trace/potrace/decompose.h5
-rw-r--r--src/trace/potrace/greymap.cpp52
-rw-r--r--src/trace/potrace/greymap.h10
-rw-r--r--src/trace/potrace/lists.h4
-rw-r--r--src/trace/potrace/potracelib.cpp9
-rw-r--r--src/trace/potrace/potracelib.h12
-rw-r--r--src/trace/potrace/progress.h8
-rw-r--r--src/trace/potrace/render.cpp4
-rw-r--r--src/trace/potrace/render.h4
-rw-r--r--src/trace/potrace/trace.cpp90
-rw-r--r--src/trace/potrace/trace.h5
16 files changed, 166 insertions, 128 deletions
diff --git a/src/trace/potrace/auxiliary.h b/src/trace/potrace/auxiliary.h
index 7baab851c..1c2765816 100644
--- a/src/trace/potrace/auxiliary.h
+++ b/src/trace/potrace/auxiliary.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
@@ -75,4 +75,31 @@ static inline int floordiv(int a, int n) {
#define sq(a) ((a)*(a))
#define cu(a) ((a)*(a)*(a))
+/* ---------------------------------------------------------------------- */
+/* deterministically and efficiently hash (x,y) into a pseudo-random bit */
+static inline int detrand(int x, int y) {
+ unsigned int z;
+ static const unsigned char t[256] = {
+ /* non-linear sequence: constant term of inverse in GF(8),
+ mod x^8+x^4+x^3+x+1 */
+ 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0,
+ 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1,
+ 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0,
+ 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
+ 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0,
+ 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1,
+ 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ };
+
+ /* 0x04b3e375 and 0x05a8ef93 are chosen to contain every possible
+ 5-bit sequence */
+ z = ((0x04b3e375 * x) ^ y) * 0x05a8ef93;
+ z = t[z & 0xff] ^ t[(z>>8) & 0xff] ^ t[(z>>16) & 0xff] ^ t[(z>>24) & 0xff];
+ return z;
+}
+
#endif /* AUXILIARY_H */
diff --git a/src/trace/potrace/bitmap.h b/src/trace/potrace/bitmap.h
index 2a172b1ad..671382dc2 100644
--- a/src/trace/potrace/bitmap.h
+++ b/src/trace/potrace/bitmap.h
@@ -1,14 +1,10 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
#ifndef BITMAP_H
#define BITMAP_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <string.h>
#include <stdlib.h>
diff --git a/src/trace/potrace/curve.cpp b/src/trace/potrace/curve.cpp
index c9a6fbe04..00d7bd2db 100644
--- a/src/trace/potrace/curve.cpp
+++ b/src/trace/potrace/curve.cpp
@@ -1,8 +1,8 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
-/* $Id$ */
+/* $Id: curve.c 227 2010-12-16 05:47:19Z selinger $ */
/* private part of the path and curve data structures */
#include <stdio.h>
diff --git a/src/trace/potrace/curve.h b/src/trace/potrace/curve.h
index 45c0790be..bfde0af1a 100644
--- a/src/trace/potrace/curve.h
+++ b/src/trace/potrace/curve.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
diff --git a/src/trace/potrace/decompose.cpp b/src/trace/potrace/decompose.cpp
index 15c39825e..8219234c4 100644
--- a/src/trace/potrace/decompose.cpp
+++ b/src/trace/potrace/decompose.cpp
@@ -1,8 +1,8 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
-/* $Id$ */
+/* $Id: decompose.c 227 2010-12-16 05:47:19Z selinger $ */
#include <stdio.h>
#include <stdlib.h>
@@ -55,32 +55,6 @@ static void clear_bm_with_bbox(potrace_bitmap_t *bm, bbox_t *bbox) {
/* ---------------------------------------------------------------------- */
/* auxiliary functions */
-/* deterministically and efficiently hash (x,y) into a pseudo-random bit */
-static inline int detrand(int x, int y) {
- unsigned int z;
- static const unsigned char t[256] = {
- /* non-linear sequence: constant term of inverse in GF(8),
- mod x^8+x^4+x^3+x+1 */
- 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1,
- 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1,
- 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0,
- 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
- 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0,
- 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1,
- 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- };
-
- /* 0x04b3e375 and 0x05a8ef93 are chosen to contain every possible
- 5-bit sequence */
- z = ((0x04b3e375 * x) ^ y) * 0x05a8ef93;
- z = t[z & 0xff] ^ t[(z>>8) & 0xff] ^ t[(z>>16) & 0xff] ^ t[(z>>24) & 0xff];
- return z & 1;
-}
-
/* return the "majority" value of bitmap bm at intersection (x,y). We
assume that the bitmap is balanced at "radius" 1. */
static int majority(potrace_bitmap_t *bm, int x, int y) {
@@ -304,7 +278,8 @@ static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) {
path_t *heap, *heap1;
path_t *cur;
path_t *head;
- path_t **hook, **hook_in, **hook_out; /* for fast appending to linked list */
+ path_t **plist_hook; /* for fast appending to linked list */
+ path_t **hook_in, **hook_out; /* for fast appending to linked list */
bbox_t bbox;
bm_clear(bm, 0);
@@ -391,18 +366,18 @@ static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) {
heap->next = NULL; /* heap is a linked list of childlists */
}
plist = NULL;
- hook = &plist;
+ plist_hook = &plist;
while (heap) {
heap1 = heap->next;
for (p=heap; p; p=p->sibling) {
/* p is a positive path */
/* append to linked list */
- list_insert_beforehook(p, hook);
+ list_insert_beforehook(p, plist_hook);
/* go through its children */
for (p1=p->childlist; p1; p1=p1->sibling) {
/* append to linked list */
- list_insert_beforehook(p1, hook);
+ list_insert_beforehook(p1, plist_hook);
/* append its childlist to heap, if non-empty */
if (p1->childlist) {
list_append(path_t, heap1, p1->childlist);
@@ -423,9 +398,12 @@ static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) {
static int findnext(potrace_bitmap_t *bm, int *xp, int *yp) {
int x;
int y;
+ int x0;
+
+ x0 = (*xp) & ~(BM_WORDBITS-1);
for (y=*yp; y>=0; y--) {
- for (x=0; x<bm->w; x+=BM_WORDBITS) {
+ for (x=x0; x<bm->w; x+=BM_WORDBITS) {
if (*bm_index(bm, x, y)) {
while (!BM_GET(bm, x, y)) {
x++;
@@ -436,6 +414,7 @@ static int findnext(potrace_bitmap_t *bm, int *xp, int *yp) {
return 0;
}
}
+ x0 = 0;
}
/* not found */
return 1;
@@ -451,7 +430,7 @@ int bm_to_pathlist(const potrace_bitmap_t *bm, path_t **plistp, const potrace_pa
int y;
path_t *p;
path_t *plist = NULL; /* linked list of path objects */
- path_t **hook = &plist; /* used to speed up appending to linked list */
+ path_t **plist_hook = &plist; /* used to speed up appending to linked list */
potrace_bitmap_t *bm1 = NULL;
int sign;
@@ -465,6 +444,7 @@ int bm_to_pathlist(const potrace_bitmap_t *bm, path_t **plistp, const potrace_pa
bm_clearexcess(bm1);
/* iterate through components */
+ x = 0;
y = bm1->h - 1;
while (findnext(bm1, &x, &y) == 0) {
/* calculate the sign by looking at the original */
@@ -483,7 +463,7 @@ int bm_to_pathlist(const potrace_bitmap_t *bm, path_t **plistp, const potrace_pa
if (p->area <= param->turdsize) {
path_free(p);
} else {
- list_insert_beforehook(p, hook);
+ list_insert_beforehook(p, plist_hook);
}
if (bm1->h > 0) { /* to be sure */
diff --git a/src/trace/potrace/decompose.h b/src/trace/potrace/decompose.h
index 5552fa0a1..409439c62 100644
--- a/src/trace/potrace/decompose.h
+++ b/src/trace/potrace/decompose.h
@@ -1,14 +1,15 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
-/* $Id$ */
+/* $Id: decompose.h 227 2010-12-16 05:47:19Z selinger $ */
#ifndef DECOMPOSE_H
#define DECOMPOSE_H
#include "potracelib.h"
#include "progress.h"
+#include "curve.h"
int bm_to_pathlist(const potrace_bitmap_t *bm, path_t **plistp, const potrace_param_t *param, progress_t *progress);
diff --git a/src/trace/potrace/greymap.cpp b/src/trace/potrace/greymap.cpp
index 646ecc3a5..770dd72e6 100644
--- a/src/trace/potrace/greymap.cpp
+++ b/src/trace/potrace/greymap.cpp
@@ -1,14 +1,13 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
-/* $Id$ */
+/* $Id: greymap.c 227 2010-12-16 05:47:19Z selinger $ */
/* Routines for manipulating greymaps, including reading pgm files. We
only deal with greymaps of depth 8 bits. */
#include <stdlib.h>
-#include <errno.h>
#include <string.h>
#include <math.h>
@@ -28,7 +27,6 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp);
greymap_t *gm_new(int w, int h) {
greymap_t *gm;
- int errno_save;
gm = (greymap_t *) malloc(sizeof(greymap_t));
if (!gm) {
@@ -38,9 +36,7 @@ greymap_t *gm_new(int w, int h) {
gm->h = h;
gm->map = (signed short int *) malloc(w*h*sizeof(signed short int));
if (!gm->map) {
- errno_save = errno;
free(gm);
- errno = errno_save;
return NULL;
}
return gm;
@@ -60,7 +56,7 @@ greymap_t *gm_dup(greymap_t *gm) {
if (!gm1) {
return NULL;
}
- memcpy(gm1->map, gm->map, gm->w*gm->h*2);
+ memcpy(gm1->map, gm->map, gm->w*gm->h*sizeof(signed short int));
return gm1;
}
@@ -69,7 +65,7 @@ void gm_clear(greymap_t *gm, int b) {
int i;
if (b==0) {
- memset(gm->map, 0, gm->w*gm->h*2);
+ memset(gm->map, 0, gm->w*gm->h*sizeof(signed short int));
} else {
for (i=0; i<gm->w*gm->h; i++) {
gm->map[i] = b;
@@ -161,16 +157,16 @@ static int readbit(FILE *f) {
/* ---------------------------------------------------------------------- */
-char const *gm_read_error = NULL;
-
-/** Read a PNM stream: P1-P6 format (see pnm(5)), or a BMP stream, and
+/* read a PNM stream: P1-P6 format (see pnm(5)), or a BMP stream, and
convert the output to a greymap. Return greymap in *gmp. Return 0
on success, -1 on error with errno set, -2 on bad file format (with
error message in gm_read_error), and 1 on premature end of file, -3
on empty file (including files with only whitespace and comments),
-4 if wrong magic number. If the return value is >=0, *gmp is
- valid.
- */
+ valid. */
+
+char const *gm_read_error = NULL;
+
int gm_read(FILE *f, greymap_t **gmp) {
int magic[2];
@@ -413,6 +409,7 @@ struct bmp_info_s {
unsigned int ncolors; /* number of colors in palette */
unsigned int ColorsImportant;
unsigned int ctbits; /* sample size for color table */
+ int topdown; /* top-down mode? */
};
typedef struct bmp_info_s bmp_info_t;
@@ -481,6 +478,9 @@ static int bmp_forward(FILE *f, int pos) {
#define TRY(x) if (x) goto try_error
#define TRY_EOF(x) if (x) goto eof
+/* correct y-coordinate for top-down format */
+#define ycorr(y) (bmpinfo.topdown ? bmpinfo.h-1-y : y)
+
/* read BMP stream after magic number. Return values as for gm_read.
We choose to be as permissive as possible, since there are many
programs out there which produce BMP. For instance, ppmtobmp can
@@ -512,7 +512,8 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
/* info header */
TRY(bmp_readint(f, 4, &bmpinfo.InfoSize));
- if (bmpinfo.InfoSize == 40 || bmpinfo.InfoSize == 64) {
+ if (bmpinfo.InfoSize == 40 || bmpinfo.InfoSize == 64
+ || bmpinfo.InfoSize == 108 || bmpinfo.InfoSize == 124) {
/* Windows or new OS/2 format */
bmpinfo.ctbits = 32; /* sample size in color table */
TRY(bmp_readint(f, 4, &bmpinfo.w));
@@ -525,6 +526,12 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
TRY(bmp_readint(f, 4, &bmpinfo.YpixelsPerM));
TRY(bmp_readint(f, 4, &bmpinfo.ncolors));
TRY(bmp_readint(f, 4, &bmpinfo.ColorsImportant));
+ if ((signed int)bmpinfo.h < 0) {
+ bmpinfo.h = -bmpinfo.h;
+ bmpinfo.topdown = 1;
+ } else {
+ bmpinfo.topdown = 0;
+ }
} else if (bmpinfo.InfoSize == 12) {
/* old OS/2 format */
bmpinfo.ctbits = 24; /* sample size in color table */
@@ -534,11 +541,12 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
TRY(bmp_readint(f, 2, &bmpinfo.bits));
bmpinfo.comp = 0;
bmpinfo.ncolors = 0;
+ bmpinfo.topdown = 0;
} else {
goto format_error;
}
- /* forward to color table (i.e., if bmpinfo.InfoSize == 64) */
+ /* forward to color table (e.g., if bmpinfo.InfoSize == 64) */
TRY(bmp_forward(f, 14+bmpinfo.InfoSize));
if (bmpinfo.Planes != 1) {
@@ -593,7 +601,7 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
for (i=0; 8*i<bmpinfo.w; i++) {
TRY_EOF(bmp_readint(f, 1, &b));
for (j=0; j<8; j++) {
- GM_PUT(gm, i*8+j, y, b & (0x80 >> j) ? coltable[1] : coltable[0]);
+ GM_PUT(gm, i*8+j, ycorr(y), b & (0x80 >> j) ? coltable[1] : coltable[0]);
}
}
TRY(bmp_pad(f));
@@ -620,7 +628,7 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
b = bitbuf >> (INTBITS - bmpinfo.bits);
bitbuf <<= bmpinfo.bits;
n -= bmpinfo.bits;
- GM_UPUT(gm, x, y, coltable[b]);
+ GM_UPUT(gm, x, ycorr(y), coltable[b]);
}
TRY(bmp_pad(f));
}
@@ -640,7 +648,7 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
for (x=0; x<bmpinfo.w; x++) {
TRY_EOF(bmp_readint(f, bmpinfo.bits/8, &c));
c = ((c>>16) & 0xff) + ((c>>8) & 0xff) + (c & 0xff);
- GM_UPUT(gm, x, y, c/3);
+ GM_UPUT(gm, x, ycorr(y), c/3);
}
TRY(bmp_pad(f));
}
@@ -664,7 +672,7 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
if (y>=bmpinfo.h) {
break;
}
- GM_UPUT(gm, x, y, col[i&1]);
+ GM_UPUT(gm, x, ycorr(y), col[i&1]);
x++;
}
} else if (c == 0) {
@@ -693,7 +701,7 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
if (y>=bmpinfo.h) {
break;
}
- GM_PUT(gm, x, y, coltable[(b>>(4-4*(i&1))) & 0xf]);
+ GM_PUT(gm, x, ycorr(y), coltable[(b>>(4-4*(i&1))) & 0xf]);
x++;
}
if ((c+1) & 2) {
@@ -720,7 +728,7 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
if (y>=bmpinfo.h) {
break;
}
- GM_UPUT(gm, x, y, coltable[c]);
+ GM_UPUT(gm, x, ycorr(y), coltable[c]);
x++;
}
} else if (c == 0) {
@@ -747,7 +755,7 @@ static int gm_readbody_bmp(FILE *f, greymap_t **gmp) {
if (y>=bmpinfo.h) {
break;
}
- GM_PUT(gm, x, y, coltable[b]);
+ GM_PUT(gm, x, ycorr(y), coltable[b]);
x++;
}
if (c & 1) {
diff --git a/src/trace/potrace/greymap.h b/src/trace/potrace/greymap.h
index 059fec4e4..0736232a7 100644
--- a/src/trace/potrace/greymap.h
+++ b/src/trace/potrace/greymap.h
@@ -1,11 +1,11 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
-/* $Id$ */
+/* $Id: greymap.h 227 2010-12-16 05:47:19Z selinger $ */
-#ifndef PGM_H
-#define PGM_H
+#ifndef GREYMAP_H
+#define GREYMAP_H
#include <stdio.h>
@@ -55,4 +55,4 @@ int gm_read(FILE *f, greymap_t **gmp);
int gm_writepgm(FILE *f, greymap_t *gm, char *comment, int raw, int mode, double gamma);
int gm_print(FILE *f, greymap_t *gm);
-#endif /* PGM_H */
+#endif /* GREYMAP_H */
diff --git a/src/trace/potrace/lists.h b/src/trace/potrace/lists.h
index fc853398a..4f78bf20f 100644
--- a/src/trace/potrace/lists.h
+++ b/src/trace/potrace/lists.h
@@ -1,8 +1,8 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
-/* $Id$ */
+/* $Id: lists.h 227 2010-12-16 05:47:19Z selinger $ */
#ifndef _PS_LISTS_H
#define _PS_LISTS_H
diff --git a/src/trace/potrace/potracelib.cpp b/src/trace/potrace/potracelib.cpp
index 17e04cabb..3dbf3230b 100644
--- a/src/trace/potrace/potracelib.cpp
+++ b/src/trace/potrace/potracelib.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
@@ -48,15 +48,16 @@ potrace_param_t *potrace_param_default(void) {
/* On success, returns a Potrace state st with st->status ==
POTRACE_STATUS_OK. On failure, returns NULL if no Potrace state
could be created (with errno set), or returns an incomplete Potrace
- state (with st->status == POTRACE_STATUS_INCOMPLETE). Complete or
- incomplete Potrace state can be freed with potrace_state_free(). */
+ state (with st->status == POTRACE_STATUS_INCOMPLETE, and with errno
+ set). Complete or incomplete Potrace state can be freed with
+ potrace_state_free(). */
potrace_state_t *potrace_trace(const potrace_param_t *param, const potrace_bitmap_t *bm) {
int r;
path_t *plist = NULL;
potrace_state_t *st;
progress_t prog;
progress_t subprog;
-
+
/* prepare private progress bar state */
prog.callback = param->progress.callback;
prog.data = param->progress.data;
diff --git a/src/trace/potrace/potracelib.h b/src/trace/potrace/potracelib.h
index 0b93d65de..d15b05e5c 100644
--- a/src/trace/potrace/potracelib.h
+++ b/src/trace/potrace/potracelib.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
@@ -6,7 +6,11 @@
#define POTRACELIB_H
/* this file defines the API for the core Potrace library. For a more
- detailed description of the API, see doc/potracelib.txt */
+ detailed description of the API, see potracelib.pdf */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
/* ---------------------------------------------------------------------- */
/* tracing parameters */
@@ -128,4 +132,8 @@ void potrace_state_free(potrace_state_t *st);
of potracelib */
char *potrace_version(void);
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
#endif /* POTRACELIB_H */
diff --git a/src/trace/potrace/progress.h b/src/trace/potrace/progress.h
index 0e077430d..220639c6e 100644
--- a/src/trace/potrace/progress.h
+++ b/src/trace/potrace/progress.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
@@ -28,7 +28,7 @@ typedef struct progress_s progress_t;
static inline void progress_update(double d, progress_t *prog) {
double d_scaled;
- if (prog->callback != NULL) {
+ if (prog != NULL && prog->callback != NULL) {
d_scaled = prog->min * (1-d) + prog->max * d;
if (d == 1.0 || d_scaled >= prog->d_prev + prog->epsilon) {
prog->callback(prog->min * (1-d) + prog->max * d, prog->data);
@@ -43,7 +43,7 @@ static inline void progress_update(double d, progress_t *prog) {
static inline void progress_subrange_start(double a, double b, const progress_t *prog, progress_t *sub) {
double min, max;
- if (prog->callback == NULL) {
+ if (prog == NULL || prog->callback == NULL) {
sub->callback = NULL;
return;
}
@@ -66,7 +66,7 @@ static inline void progress_subrange_start(double a, double b, const progress_t
}
static inline void progress_subrange_end(progress_t *prog, progress_t *sub) {
- if (prog->callback != NULL) {
+ if (prog != NULL && prog->callback != NULL) {
if (sub->callback == NULL) {
progress_update(sub->b, prog);
} else {
diff --git a/src/trace/potrace/render.cpp b/src/trace/potrace/render.cpp
index f9183b931..39bec0684 100644
--- a/src/trace/potrace/render.cpp
+++ b/src/trace/potrace/render.cpp
@@ -1,8 +1,8 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
-/* $Id$ */
+/* $Id: render.c 227 2010-12-16 05:47:19Z selinger $ */
#include <stdio.h>
#include <stdlib.h>
diff --git a/src/trace/potrace/render.h b/src/trace/potrace/render.h
index 9c9d921d2..6cfbe0964 100644
--- a/src/trace/potrace/render.h
+++ b/src/trace/potrace/render.h
@@ -1,8 +1,8 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
-/* $Id$ */
+/* $Id: render.h 227 2010-12-16 05:47:19Z selinger $ */
#ifndef RENDER_H
#define RENDER_H
diff --git a/src/trace/potrace/trace.cpp b/src/trace/potrace/trace.cpp
index 909ffb712..8fe1a1bc4 100644
--- a/src/trace/potrace/trace.cpp
+++ b/src/trace/potrace/trace.cpp
@@ -1,8 +1,8 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
-/* $Id$ */
+/* $Id: trace.c 227 2010-12-16 05:47:19Z selinger $ */
/* transform jaggy paths into smooth curves */
#include <stdio.h>
@@ -483,28 +483,38 @@ static double penalty3(privpath_t *pp, int i, int j) {
double a, b, c, s;
double px, py, ex, ey;
- int r=0; /* rotations from i to j */
+ int r = 0; /* rotations from i to j */
if (j>=n) {
- j-=n;
- r+=1;
+ j -= n;
+ r = 1;
}
- x = sums[j+1].x-sums[i].x+r*sums[n].x;
- y = sums[j+1].y-sums[i].y+r*sums[n].y;
- x2 = sums[j+1].x2-sums[i].x2+r*sums[n].x2;
- xy = sums[j+1].xy-sums[i].xy+r*sums[n].xy;
- y2 = sums[j+1].y2-sums[i].y2+r*sums[n].y2;
- k = j+1-i+r*n;
-
- px = (pt[i].x+pt[j].x)/2.0-pt[0].x;
- py = (pt[i].y+pt[j].y)/2.0-pt[0].y;
- ey = (pt[j].x-pt[i].x);
- ex = -(pt[j].y-pt[i].y);
-
- a = ((x2-2*x*px)/k+px*px);
- b = ((xy-x*py-y*px)/k+px*py);
- c = ((y2-2*y*py)/k+py*py);
+ /* critical inner loop: the "if" gives a 4.6 percent speedup */
+ if (r == 0) {
+ x = sums[j+1].x - sums[i].x;
+ y = sums[j+1].y - sums[i].y;
+ x2 = sums[j+1].x2 - sums[i].x2;
+ xy = sums[j+1].xy - sums[i].xy;
+ y2 = sums[j+1].y2 - sums[i].y2;
+ k = j+1 - i;
+ } else {
+ x = sums[j+1].x - sums[i].x + sums[n].x;
+ y = sums[j+1].y - sums[i].y + sums[n].y;
+ x2 = sums[j+1].x2 - sums[i].x2 + sums[n].x2;
+ xy = sums[j+1].xy - sums[i].xy + sums[n].xy;
+ y2 = sums[j+1].y2 - sums[i].y2 + sums[n].y2;
+ k = j+1 - i + n;
+ }
+
+ px = (pt[i].x + pt[j].x) / 2.0 - pt[0].x;
+ py = (pt[i].y + pt[j].y) / 2.0 - pt[0].y;
+ ey = (pt[j].x - pt[i].x);
+ ex = -(pt[j].y - pt[i].y);
+
+ a = ((x2 - 2*x*px) / k + px*px);
+ b = ((xy - x*py - y*px) / k + px*py);
+ c = ((y2 - 2*y*py) / k + py*py);
s = ex*ex*a + 2*ex*ey*b + ey*ey*c;
@@ -513,7 +523,7 @@ static double penalty3(privpath_t *pp, int i, int j) {
/* find the optimal polygon. Fill in the m and po components. Return 1
on failure with errno set, else 0. Non-cyclic version: assumes i=0
- is in the polygon. Fixme: ### implement cyclic version. */
+ is in the polygon. Fixme: implement cyclic version. */
static int bestpolygon(privpath_t *pp)
{
int i, j, m, k;
@@ -576,7 +586,7 @@ static int bestpolygon(privpath_t *pp)
seg1[0] = 0;
/* now find the shortest path with m segments, based on penalty3 */
- /* note: the outer 2 loops jointly have at most n interations, thus
+ /* note: the outer 2 loops jointly have at most n iterations, thus
the worst-case behavior here is quadratic. In practice, it is
close to linear since the inner loop tends to be short. */
pen[0]=0;
@@ -828,24 +838,27 @@ static int adjust_vertices(privpath_t *pp) {
/* ---------------------------------------------------------------------- */
/* Stage 4: smoothing and corner analysis (Sec. 2.3.3) */
-/* Always succeeds and returns 0 */
-static int smooth(privcurve_t *curve, int sign, double alphamax) {
+/* reverse orientation of a path */
+static void reverse(privcurve_t *curve) {
+ int m = curve->n;
+ int i, j;
+ dpoint_t tmp;
+
+ for (i=0, j=m-1; i<j; i++, j--) {
+ tmp = curve->vertex[i];
+ curve->vertex[i] = curve->vertex[j];
+ curve->vertex[j] = tmp;
+ }
+}
+
+/* Always succeeds */
+static void smooth(privcurve_t *curve, double alphamax) {
int m = curve->n;
int i, j, k;
double dd, denom, alpha;
dpoint_t p2, p3, p4;
- if (sign == '-') {
- /* reverse orientation of negative paths */
- for (i=0, j=m-1; i<j; i++, j--) {
- dpoint_t tmp;
- tmp = curve->vertex[i];
- curve->vertex[i] = curve->vertex[j];
- curve->vertex[j] = tmp;
- }
- }
-
/* examine each vertex and find its best fit */
for (i=0; i<m; i++) {
j = mod(i+1, m);
@@ -885,7 +898,7 @@ static int smooth(privcurve_t *curve, int sign, double alphamax) {
}
curve->alphacurve = 1;
- return 0;
+ return;
}
/* ---------------------------------------------------------------------- */
@@ -1098,7 +1111,7 @@ static int opticurve(privpath_t *pp, double opttolerance) {
len[0] = 0;
/* Fixme: we always start from a fixed point -- should find the best
- curve cyclically ### */
+ curve cyclically */
for (j=1; j<=m; j++) {
/* calculate best path from 0 to j */
@@ -1206,7 +1219,10 @@ int process_path(path_t *plist, const potrace_param_t *param, progress_t *progre
TRY(calc_lon(p->priv));
TRY(bestpolygon(p->priv));
TRY(adjust_vertices(p->priv));
- TRY(smooth(&p->priv->curve, p->sign, param->alphamax));
+ if (p->sign == '-') { /* reverse orientation of negative paths */
+ reverse(&p->priv->curve);
+ }
+ smooth(&p->priv->curve, param->alphamax);
if (param->opticurve) {
TRY(opticurve(p->priv, param->opttolerance));
p->priv->fcurve = &p->priv->ocurve;
diff --git a/src/trace/potrace/trace.h b/src/trace/potrace/trace.h
index b33f8ba4d..72d1a3696 100644
--- a/src/trace/potrace/trace.h
+++ b/src/trace/potrace/trace.h
@@ -1,14 +1,15 @@
-/* Copyright (C) 2001-2007 Peter Selinger.
+/* Copyright (C) 2001-2010 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
-/* $Id$ */
+/* $Id: trace.h 227 2010-12-16 05:47:19Z selinger $ */
#ifndef TRACE_H
#define TRACE_H
#include "potracelib.h"
#include "progress.h"
+#include "curve.h"
int process_path(path_t *plist, const potrace_param_t *param, progress_t *progress);