diff options
| author | Bob Jamison <ishmalius@gmail.com> | 2007-10-26 21:01:30 +0000 |
|---|---|---|
| committer | ishmal <ishmal@users.sourceforge.net> | 2007-10-26 21:01:30 +0000 |
| commit | 7427b461ed13f3e84f61a02f55ca04ff8f2d49ad (patch) | |
| tree | c1e4331a2a92b26e157904fd6ecca93c8cff3552 /src/trace/potrace/decompose.cpp | |
| parent | add ca@valencian language to win32 installer selection (diff) | |
| download | inkscape-7427b461ed13f3e84f61a02f55ca04ff8f2d49ad.tar.gz inkscape-7427b461ed13f3e84f61a02f55ca04ff8f2d49ad.zip | |
Update Potrace to 1.8
(bzr r3965)
Diffstat (limited to 'src/trace/potrace/decompose.cpp')
| -rw-r--r-- | src/trace/potrace/decompose.cpp | 71 |
1 files changed, 48 insertions, 23 deletions
diff --git a/src/trace/potrace/decompose.cpp b/src/trace/potrace/decompose.cpp index 512d9f4fe..15c39825e 100644 --- a/src/trace/potrace/decompose.cpp +++ b/src/trace/potrace/decompose.cpp @@ -1,15 +1,21 @@ -/* Copyright (C) 2001-2005 Peter Selinger. - This file is part of potrace. It is free software and it is covered +/* Copyright (C) 2001-2007 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$ */ +#include <stdio.h> #include <stdlib.h> +#include <string.h> #include <limits.h> +#include "potracelib.h" +#include "curve.h" #include "lists.h" +#include "auxiliary.h" #include "bitmap.h" #include "decompose.h" +#include "progress.h" /* ---------------------------------------------------------------------- */ /* auxiliary bitmap manipulations */ @@ -49,10 +55,30 @@ static void clear_bm_with_bbox(potrace_bitmap_t *bm, bbox_t *bbox) { /* ---------------------------------------------------------------------- */ /* auxiliary functions */ -/* return a "random" value which deterministically depends on x,y */ +/* deterministically and efficiently hash (x,y) into a pseudo-random bit */ static inline int detrand(int x, int y) { - srand(x+123456789*y); - return rand(); + 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 @@ -86,7 +112,7 @@ static void xor_to_ref(potrace_bitmap_t *bm, int x, int y, int xa) { int xhi = x & -BM_WORDBITS; int xlo = x & (BM_WORDBITS-1); /* = x % BM_WORDBITS */ int i; - + if (xhi<xa) { for (i = xhi; i < xa; i+=BM_WORDBITS) { *bm_index(bm, i, y) ^= BM_ALLBITS; @@ -183,13 +209,12 @@ static path_t *findpath(potrace_bitmap_t *bm, int x0, int y0, int sign, int turn len = size = 0; pt = NULL; area = 0; - + while (1) { /* add point to path */ if (len>=size) { - size+=100; - //size*=1.3; - size = size * 13 / 10; + size += 100; + size = (int)(1.3 * size); pt1 = (point_t *)realloc(pt, size * sizeof(point_t)); if (!pt1) { goto error; @@ -199,26 +224,26 @@ static path_t *findpath(potrace_bitmap_t *bm, int x0, int y0, int sign, int turn pt[len].x = x; pt[len].y = y; len++; - + /* move to next point */ x += dirx; y += diry; area += x*diry; - + /* path complete? */ if (x==x0 && y==y0) { break; } - + /* determine next direction */ c = BM_GET(bm, x + (dirx+diry-1)/2, y + (diry-dirx-1)/2); d = BM_GET(bm, x + (dirx-diry-1)/2, y + (diry+dirx-1)/2); - + if (c && !d) { /* ambiguous turn */ if (turnpolicy == POTRACE_TURNPOLICY_RIGHT || (turnpolicy == POTRACE_TURNPOLICY_BLACK && sign == '+') || (turnpolicy == POTRACE_TURNPOLICY_WHITE && sign == '-') - || (turnpolicy == POTRACE_TURNPOLICY_RANDOM && (detrand(x,y) & 1)) + || (turnpolicy == POTRACE_TURNPOLICY_RANDOM && detrand(x,y)) || (turnpolicy == POTRACE_TURNPOLICY_MAJORITY && majority(bm, x, y)) || (turnpolicy == POTRACE_TURNPOLICY_MINORITY && !majority(bm, x, y))) { tmp = dirx; /* right turn */ @@ -252,10 +277,10 @@ static path_t *findpath(potrace_bitmap_t *bm, int x0, int y0, int sign, int turn p->sign = sign; return p; - + error: free(pt); - return NULL; + return NULL; } /* Give a tree structure to the given path list, based on "insideness" @@ -281,7 +306,7 @@ static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) { path_t *head; path_t **hook, **hook_in, **hook_out; /* for fast appending to linked list */ bbox_t bbox; - + bm_clear(bm, 0); /* save original "next" pointers */ @@ -289,7 +314,7 @@ static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) { p->sibling = p->next; p->childlist = NULL; } - + heap = plist; /* the heap holds a list of lists of paths. Use "childlist" field @@ -304,7 +329,7 @@ static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) { cur = heap; heap = heap->childlist; cur->childlist = NULL; - + /* unlink first path */ head = cur; cur = cur->next; @@ -347,7 +372,7 @@ static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) { heap = head->childlist; } } - + /* copy sibling structure from "next" to "sibling" component */ p = plist; while (p) { @@ -373,7 +398,7 @@ static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) { /* p is a positive path */ /* append to linked list */ list_insert_beforehook(p, hook); - + /* go through its children */ for (p1=p->childlist; p1; p1=p1->sibling) { /* append to linked list */ @@ -441,7 +466,7 @@ int bm_to_pathlist(const potrace_bitmap_t *bm, path_t **plistp, const potrace_pa /* iterate through components */ y = bm1->h - 1; - while (findnext(bm1, &x, &y) == 0) { + while (findnext(bm1, &x, &y) == 0) { /* calculate the sign by looking at the original */ sign = BM_GET(bm, x, y) ? '+' : '-'; |
