diff options
| author | Andrew Higginson <at.higginson@gmail.com> | 2011-12-27 21:04:47 +0000 |
|---|---|---|
| committer | Andrew <at.higginson@gmail.com> | 2011-12-27 21:04:47 +0000 |
| commit | 80960b623a99aae1402ab651b2974ef544ed3b03 (patch) | |
| tree | ba49d42c2789e9e11f805e2d5263e10f9fedeef8 /src/trace | |
| parent | try to fix bug (diff) | |
| parent | GDL: Cherry-pick upstream patch 73852 (2011-03-23) - Add missing return value. (diff) | |
| download | inkscape-80960b623a99aae1402ab651b2974ef544ed3b03.tar.gz inkscape-80960b623a99aae1402ab651b2974ef544ed3b03.zip | |
merged with trunk so I can build again...
(bzr r10092.1.36)
Diffstat (limited to 'src/trace')
26 files changed, 472 insertions, 450 deletions
diff --git a/src/trace/CMakeLists.txt b/src/trace/CMakeLists.txt index 3cb378995..958907df6 100644 --- a/src/trace/CMakeLists.txt +++ b/src/trace/CMakeLists.txt @@ -1,13 +1,43 @@ -ADD_SUBDIRECTORY(potrace) -SET(trace_SRC -filterset.cpp -imagemap.cpp -imagemap-gdk.cpp -quantize.cpp -siox.cpp -trace.cpp -${trace_potrace_SRC} + +set(trace_SRC + filterset.cpp + imagemap.cpp + imagemap-gdk.cpp + quantize.cpp + siox.cpp + trace.cpp + + potrace/curve.cpp + potrace/decompose.cpp + potrace/greymap.cpp + potrace/inkscape-potrace.cpp + potrace/potracelib.cpp + potrace/render.cpp + potrace/trace.cpp + + + # ------- + # Headers + filterset.h + imagemap-gdk.h + imagemap.h + pool.h + quantize.h + siox.h + trace.h + + potrace/auxiliary.h + potrace/bitmap.h + potrace/curve.h + potrace/decompose.h + potrace/greymap.h + potrace/inkscape-potrace.h + potrace/lists.h + potrace/potracelib.h + potrace/progress.h + potrace/render.h + potrace/trace.h ) -ADD_LIBRARY(trace STATIC ${trace_SRC}) -TARGET_LINK_LIBRARIES(trace -2geom ${INKSCAPE_LIBS})
\ No newline at end of file + +# add_inkscape_lib(trace_LIB "${trace_SRC}") +add_inkscape_source("${trace_SRC}") diff --git a/src/trace/imagemap-gdk.cpp b/src/trace/imagemap-gdk.cpp index e217dd619..e5ff23ad0 100644 --- a/src/trace/imagemap-gdk.cpp +++ b/src/trace/imagemap-gdk.cpp @@ -190,9 +190,9 @@ RgbMap *gdkPixbufToRgbMap(GdkPixbuf *buf) { int alpha = (int)p[3]; int white = 255 - alpha; - int r = (int)p[0]; r = r * alpha / 256 + white; + int r = (int)p[2]; r = r * alpha / 256 + white; int g = (int)p[1]; g = g * alpha / 256 + white; - int b = (int)p[2]; b = b * alpha / 256 + white; + int b = (int)p[0]; b = b * alpha / 256 + white; rgbMap->setPixel(rgbMap, x, y, r, g, b); p += n_channels; diff --git a/src/trace/imagemap.cpp b/src/trace/imagemap.cpp index a9ad9b9c8..c5a6bc2b5 100644 --- a/src/trace/imagemap.cpp +++ b/src/trace/imagemap.cpp @@ -78,10 +78,16 @@ GrayMap *GrayMapCreate(int width, int height) me->height = height; me->pixels = (unsigned long *) malloc(sizeof(unsigned long) * width * height); + if (!me->pixels) + { + free(me); + return NULL; + } me->rows = (unsigned long **) malloc(sizeof(unsigned long *) * height); - if (!me->pixels || !me->rows) + if (!me->rows) { + free(me->pixels); free(me); return NULL; } diff --git a/src/trace/potrace/CMakeLists.txt b/src/trace/potrace/CMakeLists.txt deleted file mode 100644 index f61e8bcd1..000000000 --- a/src/trace/potrace/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -SET(trace_potrace_SRC -curve.cpp -decompose.cpp -greymap.cpp -inkscape-potrace.cpp -potracelib.cpp -render.cpp -trace.cpp -) diff --git a/src/trace/potrace/auxiliary.h b/src/trace/potrace/auxiliary.h index 7baab851c..b7480bbb8 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-2011 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..2df04b46f 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-2011 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..d2e32aa7b 100644 --- a/src/trace/potrace/curve.cpp +++ b/src/trace/potrace/curve.cpp @@ -1,8 +1,7 @@ -/* Copyright (C) 2001-2007 Peter Selinger. +/* Copyright (C) 2001-2011 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$ */ /* 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..6ceae0c3a 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-2011 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..708c17106 100644 --- a/src/trace/potrace/decompose.cpp +++ b/src/trace/potrace/decompose.cpp @@ -1,8 +1,7 @@ -/* Copyright (C) 2001-2007 Peter Selinger. +/* Copyright (C) 2001-2011 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> @@ -12,11 +11,11 @@ #include "potracelib.h" #include "curve.h" #include "lists.h" -#include "auxiliary.h" #include "bitmap.h" #include "decompose.h" #include "progress.h" + /* ---------------------------------------------------------------------- */ /* auxiliary bitmap manipulations */ @@ -55,32 +54,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 +277,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 +365,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 +397,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 +413,7 @@ static int findnext(potrace_bitmap_t *bm, int *xp, int *yp) { return 0; } } + x0 = 0; } /* not found */ return 1; @@ -451,7 +429,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 +443,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 +462,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..89b01e504 100644 --- a/src/trace/potrace/decompose.h +++ b/src/trace/potrace/decompose.h @@ -1,14 +1,14 @@ -/* Copyright (C) 2001-2007 Peter Selinger. +/* Copyright (C) 2001-2011 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$ */ #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..2495575e8 100644 --- a/src/trace/potrace/greymap.cpp +++ b/src/trace/potrace/greymap.cpp @@ -1,14 +1,12 @@ -/* Copyright (C) 2001-2007 Peter Selinger. +/* Copyright (C) 2001-2011 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$ */ /* 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 +26,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 +35,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 +55,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 +64,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 +156,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 +408,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 +477,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 +511,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 +525,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 +540,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 +600,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 +627,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 +647,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 +671,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 +700,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 +727,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 +754,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..1fb5426c1 100644 --- a/src/trace/potrace/greymap.h +++ b/src/trace/potrace/greymap.h @@ -1,11 +1,10 @@ -/* Copyright (C) 2001-2007 Peter Selinger. +/* Copyright (C) 2001-2011 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$ */ -#ifndef PGM_H -#define PGM_H +#ifndef GREYMAP_H +#define GREYMAP_H #include <stdio.h> @@ -55,4 +54,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/inkscape-potrace.cpp b/src/trace/potrace/inkscape-potrace.cpp index 2f4dc7a6f..0907573e9 100644 --- a/src/trace/potrace/inkscape-potrace.cpp +++ b/src/trace/potrace/inkscape-potrace.cpp @@ -18,6 +18,7 @@ #include <glibmm/i18n.h> #include <gtkmm.h> +#include <iomanip> #include "trace/filterset.h" #include "trace/quantize.h" @@ -31,7 +32,7 @@ #include "curve.h" #include "bitmap.h" - +using Glib::ustring; static void updateGui() { @@ -57,6 +58,12 @@ static void potraceStatusCallback(double /*progress*/, void *userData) /* callba } +namespace { +ustring twohex( int value ) +{ + return ustring::format(std::hex, std::setfill(L'0'), std::setw(2), value); +} +} // namespace //required by potrace @@ -70,20 +77,23 @@ namespace Potrace { /** * */ -PotraceTracingEngine::PotraceTracingEngine() +PotraceTracingEngine::PotraceTracingEngine() : + keepGoing(1), + traceType(TRACE_BRIGHTNESS), + invert(false), + quantizationNrColors(8), + brightnessThreshold(0.45), + brightnessFloor(0), + cannyHighThreshold(0.65), + multiScanNrColors(8), + multiScanStack(true), + multiScanSmooth(false), + multiScanRemoveBackground(false) { /* get default parameters */ potraceParams = potrace_param_default(); potraceParams->progress.callback = potraceStatusCallback; potraceParams->progress.data = (void *)this; - - //##### Our defaults - invert = false; - traceType = TRACE_BRIGHTNESS; - quantizationNrColors = 8; - brightnessThreshold = 0.45; - cannyHighThreshold = 0.65; - } PotraceTracingEngine::~PotraceTracingEngine() @@ -471,67 +481,56 @@ PotraceTracingEngine::traceGrayMap(GrayMap *grayMap) /** * Called for multiple-scanning algorithms */ -std::vector<TracingEngineResult> -PotraceTracingEngine::traceBrightnessMulti(GdkPixbuf * thePixbuf) +std::vector<TracingEngineResult> PotraceTracingEngine::traceBrightnessMulti(GdkPixbuf * thePixbuf) { - std::vector<TracingEngineResult> results; - if (!thePixbuf) - return results; + if ( thePixbuf ) { + double low = 0.2; //bottom of range + double high = 0.9; //top of range + double delta = (high - low ) / ((double)multiScanNrColors); - double low = 0.2; //bottom of range - double high = 0.9; //top of range - double delta = (high - low ) / ((double)multiScanNrColors); + brightnessFloor = 0.0; //Set bottom to black - brightnessFloor = 0.0; //Set bottom to black + int traceCount = 0; - int traceCount = 0; + for ( brightnessThreshold = low ; + brightnessThreshold <= high ; + brightnessThreshold += delta) { + GrayMap *grayMap = filter(*this, thePixbuf); + if ( grayMap ) { + long nodeCount; + std::string d = grayMapToPath(grayMap, &nodeCount); - for ( brightnessThreshold = low ; - brightnessThreshold <= high ; - brightnessThreshold += delta) - - { + grayMap->destroy(grayMap); - GrayMap *grayMap = filter(*this, thePixbuf); - if (!grayMap) - return results; + if ( !d.empty() ) { + //### get style info + int grayVal = (int)(256.0 * brightnessThreshold); + ustring style = ustring::compose("fill-opacity:1.0;fill:%1%2%3", twohex(grayVal), twohex(grayVal), twohex(grayVal) ); - long nodeCount; - std::string d = grayMapToPath(grayMap, &nodeCount); + //g_message("### GOT '%s' \n", style.c_str()); + TracingEngineResult result(style, d, nodeCount); + results.push_back(result); - grayMap->destroy(grayMap); + if (!multiScanStack) { + brightnessFloor = brightnessThreshold; + } - if (d.size() == 0) - return results; - - int grayVal = (int)(256.0 * brightnessThreshold); - char style[31]; - sprintf(style, "fill-opacity:1.0;fill:#%02x%02x%02x", - grayVal, grayVal, grayVal); - - //g_message("### GOT '%s' \n", d); - TracingEngineResult result(style, d, nodeCount); - results.push_back(result); - - if (!multiScanStack) - brightnessFloor = brightnessThreshold; - - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) - { - gchar *msg = g_strdup_printf(_("Trace: %d. %ld nodes"), traceCount++, nodeCount); - sp_desktop_message_stack(desktop)->flash(Inkscape::NORMAL_MESSAGE, msg); - g_free(msg); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + ustring msg = ustring::compose(_("Trace: %1. %2 nodes"), traceCount++, nodeCount); + sp_desktop_message_stack(desktop)->flash(Inkscape::NORMAL_MESSAGE, msg); + } + } } } - //# Remove the bottom-most scan, if requested - if (results.size() > 1 && multiScanRemoveBackground) - { - results.erase(results.end() - 1); + //# Remove the bottom-most scan, if requested + if (results.size() > 1 && multiScanRemoveBackground) { + results.erase(results.end() - 1); } + } return results; } @@ -540,77 +539,64 @@ PotraceTracingEngine::traceBrightnessMulti(GdkPixbuf * thePixbuf) /** * Quantization */ -std::vector<TracingEngineResult> -PotraceTracingEngine::traceQuant(GdkPixbuf * thePixbuf) +std::vector<TracingEngineResult> PotraceTracingEngine::traceQuant(GdkPixbuf * thePixbuf) { - std::vector<TracingEngineResult> results; - if (!thePixbuf) - return results; - - IndexedMap *iMap = filterIndexed(*this, thePixbuf); - if (!iMap) - return results; - - //Create and clear a gray map - GrayMap *gm = GrayMapCreate(iMap->width, iMap->height); - for (int row=0 ; row<gm->height ; row++) - for (int col=0 ; col<gm->width ; col++) - gm->setPixel(gm, col, row, GRAYMAP_WHITE); - - - for (int colorIndex=0 ; colorIndex<iMap->nrColors ; colorIndex++) - { - - /*Make a gray map for each color index */ - for (int row=0 ; row<iMap->height ; row++) - { - for (int col=0 ; col<iMap->width ; col++) - { - int indx = (int) iMap->getPixel(iMap, col, row); - if (indx == colorIndex) - gm->setPixel(gm, col, row, GRAYMAP_BLACK); //black - else if (!multiScanStack) - gm->setPixel(gm, col, row, GRAYMAP_WHITE); //white + if (thePixbuf) { + IndexedMap *iMap = filterIndexed(*this, thePixbuf); + if ( iMap ) { + //Create and clear a gray map + GrayMap *gm = GrayMapCreate(iMap->width, iMap->height); + for (int row=0 ; row<gm->height ; row++) { + for (int col=0 ; col<gm->width ; col++) { + gm->setPixel(gm, col, row, GRAYMAP_WHITE); } } - //## Now we have a traceable graymap - long nodeCount; - std::string d = grayMapToPath(gm, &nodeCount); - - if (d.size() == 0) - return results; - - //### get style info - char style[13]; - RGB rgb = iMap->clut[colorIndex]; - sprintf(style, "fill:#%02x%02x%02x", rgb.r, rgb.g, rgb.b); + for (int colorIndex=0 ; colorIndex<iMap->nrColors ; colorIndex++) { + // Make a gray map for each color index + for (int row=0 ; row<iMap->height ; row++) { + for (int col=0 ; col<iMap->width ; col++) { + int indx = (int) iMap->getPixel(iMap, col, row); + if (indx == colorIndex) { + gm->setPixel(gm, col, row, GRAYMAP_BLACK); //black + } else if (!multiScanStack) { + gm->setPixel(gm, col, row, GRAYMAP_WHITE); //white + } + } + } - //g_message("### GOT '%s' \n", d); - TracingEngineResult result(style, d, nodeCount); - results.push_back(result); + //## Now we have a traceable graymap + long nodeCount; + std::string d = grayMapToPath(gm, &nodeCount); - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) - { - gchar *msg = g_strdup_printf(_("Trace: %d. %ld nodes"), colorIndex, nodeCount); - sp_desktop_message_stack(desktop)->flash(Inkscape::NORMAL_MESSAGE, msg); - g_free(msg); - } + if ( !d.empty() ) { + //### get style info + RGB rgb = iMap->clut[colorIndex]; + ustring style = ustring::compose("fill:#%1%2%3", twohex(rgb.r), twohex(rgb.g), twohex(rgb.b) ); + //g_message("### GOT '%s' \n", style.c_str()); + TracingEngineResult result(style, d, nodeCount); + results.push_back(result); - }// for colorIndex + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + ustring msg = ustring::compose(_("Trace: %1. %2 nodes"), colorIndex, nodeCount); + sp_desktop_message_stack(desktop)->flash(Inkscape::NORMAL_MESSAGE, msg); + } + } + }// for colorIndex - gm->destroy(gm); - iMap->destroy(iMap); + gm->destroy(gm); + iMap->destroy(iMap); + } - //# Remove the bottom-most scan, if requested - if (results.size() > 1 && multiScanRemoveBackground) - { - results.erase(results.end() - 1); + //# Remove the bottom-most scan, if requested + if (results.size() > 1 && multiScanRemoveBackground) { + results.erase(results.end() - 1); } + } return results; } @@ -667,3 +653,13 @@ PotraceTracingEngine::abort() } // namespace Trace } // namespace Inkscape +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/trace/potrace/inkscape-potrace.h b/src/trace/potrace/inkscape-potrace.h index b32ab6461..f2fc9a71f 100644 --- a/src/trace/potrace/inkscape-potrace.h +++ b/src/trace/potrace/inkscape-potrace.h @@ -245,7 +245,7 @@ class PotraceTracingEngine : public TracingEngine potrace_param_t *potraceParams; TraceType traceType; - //## do i invert at the end? + //## do I invert at the end? bool invert; //## Color-->b&w quantization @@ -286,3 +286,13 @@ class PotraceTracingEngine : public TracingEngine #endif //__INKSCAPE_POTRACE_H__ +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/trace/potrace/lists.h b/src/trace/potrace/lists.h index fc853398a..078129afc 100644 --- a/src/trace/potrace/lists.h +++ b/src/trace/potrace/lists.h @@ -1,8 +1,7 @@ -/* Copyright (C) 2001-2007 Peter Selinger. +/* Copyright (C) 2001-2011 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$ */ #ifndef _PS_LISTS_H #define _PS_LISTS_H diff --git a/src/trace/potrace/potracelib.cpp b/src/trace/potrace/potracelib.cpp index 17e04cabb..0fb835593 100644 --- a/src/trace/potrace/potracelib.cpp +++ b/src/trace/potrace/potracelib.cpp @@ -1,10 +1,10 @@ -/* Copyright (C) 2001-2007 Peter Selinger. +/* Copyright (C) 2001-2011 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. */ #include <stdlib.h> #include <string.h> -#include <glib/gstrfuncs.h> +#include <glib.h> #include "potracelib.h" #include "inkscape-version.h" @@ -35,79 +35,80 @@ static const potrace_param_t param_default = { /* Return a fresh copy of the set of default parameters, or NULL on failure with errno set. */ potrace_param_t *potrace_param_default(void) { - potrace_param_t *p; - - p = (potrace_param_t *) malloc(sizeof(potrace_param_t)); - if (!p) { - return NULL; - } - memcpy(p, ¶m_default, sizeof(potrace_param_t)); - return p; + potrace_param_t *p; + + p = (potrace_param_t *) malloc(sizeof(potrace_param_t)); + if (!p) { + return NULL; + } + memcpy(p, ¶m_default, sizeof(potrace_param_t)); + return p; } /* 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; - prog.min = param->progress.min; - prog.max = param->progress.max; - prog.epsilon = param->progress.epsilon; - prog.d_prev = param->progress.min; - - /* allocate state object */ - st = (potrace_state_t *)malloc(sizeof(potrace_state_t)); - if (!st) { - return NULL; - } - - progress_subrange_start(0.0, 0.1, &prog, &subprog); - - /* process the image */ - r = bm_to_pathlist(bm, &plist, param, &subprog); - if (r) { - free(st); - return NULL; - } - - st->status = POTRACE_STATUS_OK; - st->plist = plist; - st->priv = NULL; /* private state currently unused */ - - progress_subrange_end(&prog, &subprog); - - progress_subrange_start(0.1, 1.0, &prog, &subprog); - - /* partial success. */ - r = process_path(plist, param, &subprog); - if (r) { - st->status = POTRACE_STATUS_INCOMPLETE; - } - - progress_subrange_end(&prog, &subprog); - - return st; + 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; + prog.min = param->progress.min; + prog.max = param->progress.max; + prog.epsilon = param->progress.epsilon; + prog.d_prev = param->progress.min; + + /* allocate state object */ + st = (potrace_state_t *)malloc(sizeof(potrace_state_t)); + if (!st) { + return NULL; + } + + progress_subrange_start(0.0, 0.1, &prog, &subprog); + + /* process the image */ + r = bm_to_pathlist(bm, &plist, param, &subprog); + if (r) { + free(st); + return NULL; + } + + st->status = POTRACE_STATUS_OK; + st->plist = plist; + st->priv = NULL; /* private state currently unused */ + + progress_subrange_end(&prog, &subprog); + + progress_subrange_start(0.1, 1.0, &prog, &subprog); + + /* partial success. */ + r = process_path(plist, param, &subprog); + if (r) { + st->status = POTRACE_STATUS_INCOMPLETE; + } + + progress_subrange_end(&prog, &subprog); + + return st; } /* free a Potrace state, without disturbing errno. */ void potrace_state_free(potrace_state_t *st) { - pathlist_free(st->plist); - free(st); + pathlist_free(st->plist); + free(st); } /* free a parameter list, without disturbing errno. */ void potrace_param_free(potrace_param_t *p) { - free(p); + free(p); } char *potrace_version(void) { diff --git a/src/trace/potrace/potracelib.h b/src/trace/potrace/potracelib.h index 0b93d65de..cd142a6e1 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-2011 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..93a1fa3f0 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-2011 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..3c8f79c05 100644 --- a/src/trace/potrace/render.cpp +++ b/src/trace/potrace/render.cpp @@ -1,8 +1,7 @@ -/* Copyright (C) 2001-2007 Peter Selinger. +/* Copyright (C) 2001-2011 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> diff --git a/src/trace/potrace/render.h b/src/trace/potrace/render.h index 9c9d921d2..ad600156a 100644 --- a/src/trace/potrace/render.h +++ b/src/trace/potrace/render.h @@ -1,8 +1,7 @@ -/* Copyright (C) 2001-2007 Peter Selinger. +/* Copyright (C) 2001-2011 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$ */ #ifndef RENDER_H #define RENDER_H diff --git a/src/trace/potrace/trace.cpp b/src/trace/potrace/trace.cpp index 909ffb712..f1e88a908 100644 --- a/src/trace/potrace/trace.cpp +++ b/src/trace/potrace/trace.cpp @@ -1,8 +1,7 @@ -/* Copyright (C) 2001-2007 Peter Selinger. +/* Copyright (C) 2001-2011 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$ */ /* transform jaggy paths into smooth curves */ #include <stdio.h> @@ -483,28 +482,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 +522,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 +585,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 +837,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 +897,7 @@ static int smooth(privcurve_t *curve, int sign, double alphamax) { } curve->alphacurve = 1; - return 0; + return; } /* ---------------------------------------------------------------------- */ @@ -1098,7 +1110,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 +1218,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..dc2b9247a 100644 --- a/src/trace/potrace/trace.h +++ b/src/trace/potrace/trace.h @@ -1,14 +1,14 @@ -/* Copyright (C) 2001-2007 Peter Selinger. +/* Copyright (C) 2001-2011 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$ */ #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); diff --git a/src/trace/siox.cpp b/src/trace/siox.cpp index b3404fc00..4c6cf1eac 100644 --- a/src/trace/siox.cpp +++ b/src/trace/siox.cpp @@ -584,7 +584,7 @@ void SioxImage::assign(const SioxImage &other) /** * Write the image to a PPM file */ -bool SioxImage::writePPM(const std::string fileName) +bool SioxImage::writePPM(const std::string &fileName) { FILE *f = fopen(fileName.c_str(), "wb"); @@ -736,19 +736,33 @@ const float Siox::CERTAIN_BACKGROUND_CONFIDENCE=0.0f; /** * Construct a Siox engine */ -Siox::Siox() +Siox::Siox() : + sioxObserver(0), + keepGoing(true), + width(0), + height(0), + pixelCount(0), + image(0), + cm(0), + labelField(0) { - sioxObserver = NULL; init(); } /** * Construct a Siox engine */ -Siox::Siox(SioxObserver *observer) +Siox::Siox(SioxObserver *observer) : + sioxObserver(observer), + keepGoing(true), + width(0), + height(0), + pixelCount(0), + image(0), + cm(0), + labelField(0) { init(); - sioxObserver = observer; } @@ -1011,7 +1025,7 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage, } tupel.minFgDist = minFg; tupel.indexMinFg = minIndex; - if (fgSignature.size() == 0) + if (fgSignature.empty()) { isBackground = (minBg <= clusterSize); // remove next line to force behaviour of old algorithm @@ -1414,7 +1428,7 @@ int Siox::depthFirstSearch(int startPos, } - while (pixelsToVisit.size() > 0) + while (!pixelsToVisit.empty()) { int pos = pixelsToVisit[pixelsToVisit.size() - 1]; pixelsToVisit.erase(pixelsToVisit.end() - 1); @@ -1486,7 +1500,7 @@ void Siox::fillColorRegions() // int componentSize = 1; pixelsToVisit.push_back(i); // depth first search to fill region - while (pixelsToVisit.size() > 0) + while (!pixelsToVisit.empty()) { int pos = pixelsToVisit[pixelsToVisit.size() - 1]; pixelsToVisit.erase(pixelsToVisit.end() - 1); diff --git a/src/trace/siox.h b/src/trace/siox.h index 6b7256fe0..9a44ce1cf 100644 --- a/src/trace/siox.h +++ b/src/trace/siox.h @@ -1,6 +1,6 @@ -#ifndef __SIOX_H__ -#define __SIOX_H__ -/** +#ifndef SEEN_SIOX_H +#define SEEN_SIOX_H +/* * Copyright 2005, 2006 by Gerald Friedland, Kristian Jantz and Lars Knipping * * Conversion to C++ for Inkscape by Bob Jamison @@ -18,7 +18,7 @@ * limitations under the License. */ -/** +/* * Note by Bob Jamison: * After translating the siox.org Java API to C++ and receiving an * education into this wonderful code, I began again, @@ -316,7 +316,7 @@ public: /** * Saves this image as a simple color PPM */ - bool writePPM(const std::string fileName); + bool writePPM(const std::string &fileName); @@ -508,11 +508,6 @@ private: bool keepGoing; /** - * Our signature limits - */ - float limits[3]; - - /** * Image width */ unsigned int width; @@ -544,6 +539,11 @@ private: /** + * Our signature limits + */ + float limits[3]; + + /** * Maximum distance of two lab values. */ float clusterSize; @@ -649,9 +649,6 @@ private: */ float sqrEuclidianDist(float *p, int pSize, float *q); - - - }; @@ -660,10 +657,7 @@ private: } // namespace siox } // namespace org -#endif /* __SIOX_H__ */ +#endif // SEEN_SIOX_H //######################################################################## //# E N D O F F I L E //######################################################################## - - - diff --git a/src/trace/trace.cpp b/src/trace/trace.cpp index 1ee32e6bf..8f04d7a2d 100644 --- a/src/trace/trace.cpp +++ b/src/trace/trace.cpp @@ -1,4 +1,4 @@ -/** +/* * A generic interface for plugging different * autotracers into Inkscape. * @@ -12,50 +12,33 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ - - #include "trace/potrace/inkscape-potrace.h" -#include <inkscape.h> -#include <desktop.h> -#include <desktop-handles.h> -#include <document.h> -#include <message-stack.h> +#include "inkscape.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "document.h" +#include "message-stack.h" #include <gtkmm.h> #include <glibmm/i18n.h> -#include <selection.h> -#include <xml/repr.h> -#include <xml/attribute-record.h> -#include <sp-item.h> -#include <sp-shape.h> -#include <sp-image.h> -#include <libnr/nr-matrix-ops.h> +#include "selection.h" +#include "xml/repr.h" +#include "xml/attribute-record.h" +#include "sp-item.h" +#include "sp-shape.h" +#include "sp-image.h" #include <2geom/transforms.h> -#include <display/nr-arena.h> -#include <display/nr-arena-shape.h> +#include "display/drawing.h" +#include "display/drawing-shape.h" #include "siox.h" #include "imagemap-gdk.h" +namespace Inkscape { +namespace Trace { - -namespace Inkscape -{ - -namespace Trace -{ - - - - - -/** - * Get the selected image. Also check for any SPItems over it, in - * case the user wants SIOX pre-processing. - */ -SPImage * -Tracer::getSelectedSPImage() +SPImage *Tracer::getSelectedSPImage() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; @@ -98,7 +81,7 @@ Tracer::getSelectedSPImage() items.insert(items.begin(), item); } std::vector<SPItem *>::iterator iter; - for (iter = items.begin() ; iter!= items.end() ; iter++) + for (iter = items.begin() ; iter!= items.end() ; ++iter) { SPItem *item = *iter; if (SP_IS_IMAGE(item)) @@ -210,13 +193,7 @@ public: -/** - * Process a GdkPixbuf, according to which areas have been - * obscured in the GUI. - */ -Glib::RefPtr<Gdk::Pixbuf> -Tracer::sioxProcessImage(SPImage *img, - Glib::RefPtr<Gdk::Pixbuf>origPixbuf) +Glib::RefPtr<Gdk::Pixbuf> Tracer::sioxProcessImage(SPImage *img, Glib::RefPtr<Gdk::Pixbuf>origPixbuf) { if (!sioxEnabled) return origPixbuf; @@ -248,25 +225,25 @@ Tracer::sioxProcessImage(SPImage *img, return Glib::RefPtr<Gdk::Pixbuf>(NULL); } - NRArenaItem *aImg = img->get_arenaitem(desktop->dkey); + Inkscape::DrawingItem *aImg = img->get_arenaitem(desktop->dkey); //g_message("img: %d %d %d %d\n", aImg->bbox.x0, aImg->bbox.y0, // aImg->bbox.x1, aImg->bbox.y1); - double width = (double)(aImg->bbox.x1 - aImg->bbox.x0); - double height = (double)(aImg->bbox.y1 - aImg->bbox.y0); + double width = aImg->geometricBounds()->width(); + double height = aImg->geometricBounds()->height(); - double iwidth = (double)simage.getWidth(); - double iheight = (double)simage.getHeight(); + double iwidth = simage.getWidth(); + double iheight = simage.getHeight(); double iwscale = width / iwidth; double ihscale = height / iheight; - std::vector<NRArenaItem *> arenaItems; + std::vector<Inkscape::DrawingItem *> arenaItems; std::vector<SPShape *>::iterator iter; - for (iter = sioxShapes.begin() ; iter!=sioxShapes.end() ; iter++) + for (iter = sioxShapes.begin() ; iter!=sioxShapes.end() ; ++iter) { SPItem *item = *iter; - NRArenaItem *aItem = item->get_arenaitem(desktop->dkey); + Inkscape::DrawingItem *aItem = item->get_arenaitem(desktop->dkey); arenaItems.push_back(aItem); } @@ -279,25 +256,22 @@ Tracer::sioxProcessImage(SPImage *img, for (int row=0 ; row<iheight ; row++) { - double ypos = ((double)aImg->bbox.y0) + ihscale * (double) row; + double ypos = aImg->geometricBounds()->top() + ihscale * (double) row; for (int col=0 ; col<simage.getWidth() ; col++) { //Get absolute X,Y position - double xpos = ((double)aImg->bbox.x0) + iwscale * (double)col; + double xpos = aImg->geometricBounds()->left() + iwscale * (double)col; Geom::Point point(xpos, ypos); - if (aImg->transform) - point *= *aImg->transform; + point *= aImg->transform(); //point *= imgMat; //point = desktop->doc2dt(point); //g_message("x:%f y:%f\n", point[0], point[1]); bool weHaveAHit = false; - std::vector<NRArenaItem *>::iterator aIter; - for (aIter = arenaItems.begin() ; aIter!=arenaItems.end() ; aIter++) + std::vector<Inkscape::DrawingItem *>::iterator aIter; + for (aIter = arenaItems.begin() ; aIter!=arenaItems.end() ; ++aIter) { - NRArenaItem *arenaItem = *aIter; - NRArenaItemClass *arenaClass = - (NRArenaItemClass *) NR_OBJECT_GET_CLASS (arenaItem); - if (arenaClass->pick(arenaItem, point, 1.0f, 1)) + Inkscape::DrawingItem *arenaItem = *aIter; + if (arenaItem->pick(point, 1.0f, 1)) { weHaveAHit = true; break; @@ -339,17 +313,6 @@ Tracer::sioxProcessImage(SPImage *img, //result.writePPM("siox2.ppm"); - /* Free Arena and ArenaItem */ - /* - std::vector<NRArenaItem *>::iterator aIter; - for (aIter = arenaItems.begin() ; aIter!=arenaItems.end() ; aIter++) - { - NRArenaItem *arenaItem = *aIter; - nr_arena_item_unref(arenaItem); - } - nr_object_unref((NRObject *) arena); - */ - Glib::RefPtr<Gdk::Pixbuf> newPixbuf = Glib::wrap(result.getGdkPixbuf()); //g_message("siox: done"); @@ -360,11 +323,7 @@ Tracer::sioxProcessImage(SPImage *img, } -/** - * - */ -Glib::RefPtr<Gdk::Pixbuf> -Tracer::getSelectedImage() +Glib::RefPtr<Gdk::Pixbuf> Tracer::getSelectedImage() { @@ -404,18 +363,12 @@ Tracer::getSelectedImage() //# T R A C E //######################################################################### -/** - * Whether we want to enable SIOX subimage selection - */ void Tracer::enableSiox(bool enable) { sioxEnabled = enable; } -/** - * Threaded method that does single bitmap--->path conversion - */ void Tracer::traceThread() { //## Remember. NEVER leave this method without setting @@ -585,9 +538,6 @@ void Tracer::traceThread() -/** - * Main tracing method - */ void Tracer::trace(TracingEngine *theEngine) { //Check if we are already running @@ -614,9 +564,6 @@ void Tracer::trace(TracingEngine *theEngine) -/** - * Abort the thread that is executing trace() - */ void Tracer::abort() { diff --git a/src/trace/trace.h b/src/trace/trace.h index 2c9922e10..a7fbe0cc8 100644 --- a/src/trace/trace.h +++ b/src/trace/trace.h @@ -1,7 +1,4 @@ -/** - * A generic interface for plugging different - * autotracers into Inkscape. - * +/* * Authors: * Bob Jamison <rjamison@titan.com> * @@ -9,8 +6,8 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifndef __TRACE_H__ -#define __TRACE_H__ +#ifndef SEEN_TRACE_H +#define SEEN_TRACE_H #ifdef HAVE_CONFIG_H # include "config.h" @@ -30,7 +27,7 @@ #include <sp-shape.h> struct SPImage; -struct SPItem; +class SPItem; namespace Inkscape { @@ -110,7 +107,8 @@ private: /** - * + * A generic interface for plugging different + * autotracers into Inkscape. */ class TracingEngine { @@ -209,7 +207,7 @@ public: void abort(); /** - * Whether we want to enable SIOX subimage selection + * Whether we want to enable SIOX subimage selection. */ void enableSiox(bool enable); @@ -218,6 +216,7 @@ private: /** * This is the single path code that is called by its counterpart above. + * Threaded method that does single bitmap--->path conversion. */ void traceThread(); @@ -233,14 +232,21 @@ private: */ TracingEngine *engine; + /** + * Get the selected image. Also check for any SPItems over it, in + * case the user wants SIOX pre-processing. + */ SPImage *getSelectedSPImage(); std::vector<SPShape *> sioxShapes; bool sioxEnabled; - Glib::RefPtr<Gdk::Pixbuf> sioxProcessImage( - SPImage *img, Glib::RefPtr<Gdk::Pixbuf> origPixbuf); + /** + * Process a GdkPixbuf, according to which areas have been + * obscured in the GUI. + */ + Glib::RefPtr<Gdk::Pixbuf> sioxProcessImage(SPImage *img, Glib::RefPtr<Gdk::Pixbuf> origPixbuf); Glib::RefPtr<Gdk::Pixbuf> lastSioxPixbuf; Glib::RefPtr<Gdk::Pixbuf> lastOrigPixbuf; @@ -256,7 +262,7 @@ private: -#endif //__TRACE_H__ +#endif // SEEN_TRACE_H //######################################################################### //# E N D O F F I L E |
