diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2023-10-08 17:45:23 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2023-10-08 17:45:23 +0000 |
commit | bb4ba2586d4cfe9302278a427ee4cf7a89aef53b (patch) | |
tree | e48d17b2acafd26e2367c33d96d56cf58eb1f858 /converter/other/pamtosvg | |
parent | 4b091760fddc73ffc877563b445599db21557e78 (diff) | |
download | netpbm-mirror-bb4ba2586d4cfe9302278a427ee4cf7a89aef53b.tar.gz netpbm-mirror-bb4ba2586d4cfe9302278a427ee4cf7a89aef53b.tar.xz netpbm-mirror-bb4ba2586d4cfe9302278a427ee4cf7a89aef53b.zip |
cleanup
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@4736 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other/pamtosvg')
23 files changed, 671 insertions, 587 deletions
diff --git a/converter/other/pamtosvg/autotrace.c b/converter/other/pamtosvg/autotrace.c index fa5b7e15..37f5d5ec 100644 --- a/converter/other/pamtosvg/autotrace.c +++ b/converter/other/pamtosvg/autotrace.c @@ -42,6 +42,8 @@ at_fitting_opts_new(void) return opts; } + + at_fitting_opts_type * at_fitting_opts_copy (at_fitting_opts_type * original) { @@ -56,12 +58,16 @@ at_fitting_opts_copy (at_fitting_opts_type * original) return new_opts; } + + void at_fitting_opts_free(at_fitting_opts_type * opts) { free(opts); } + + at_output_opts_type * at_output_opts_new(void) { @@ -71,6 +77,8 @@ at_output_opts_new(void) return opts; } + + at_output_opts_type * at_output_opts_copy(at_output_opts_type * original) { @@ -79,12 +87,16 @@ at_output_opts_copy(at_output_opts_type * original) return opts; } + + void at_output_opts_free(at_output_opts_type * opts) { free(opts); } + + /* at_splines_new_full modifies its 'bitmap' argument when it does the thin_image thing. */ diff --git a/converter/other/pamtosvg/bitmap.c b/converter/other/pamtosvg/bitmap.c index 84a8a8ae..8b8ce092 100644 --- a/converter/other/pamtosvg/bitmap.c +++ b/converter/other/pamtosvg/bitmap.c @@ -13,7 +13,7 @@ at_bitmap_new(unsigned short width, at_bitmap_type * bitmap; - MALLOCVAR_NOFAIL(bitmap); + MALLOCVAR_NOFAIL(bitmap); *bitmap = at_bitmap_init(NULL, width, height, planes); @@ -31,10 +31,10 @@ at_bitmap_copy(at_bitmap_type * src) width = at_bitmap_get_width(src); height = at_bitmap_get_height(src); planes = at_bitmap_get_planes(src); - + dist = at_bitmap_new(width, height, planes); - memcpy(dist->bitmap, - src->bitmap, + memcpy(dist->bitmap, + src->bitmap, width * height * planes * sizeof(unsigned char)); return dist; } @@ -48,7 +48,7 @@ at_bitmap_init(unsigned char * area, unsigned int planes) { at_bitmap_type bitmap; - + if (area) bitmap.bitmap = area; else { @@ -63,33 +63,41 @@ at_bitmap_init(unsigned char * area, 0, width * height * planes * sizeof(unsigned char)); } } - + bitmap.width = width; bitmap.height = height; bitmap.np = planes; - return bitmap; + return bitmap; } -void + + +void at_bitmap_free (at_bitmap_type * bitmap) { free_bitmap (bitmap); free(bitmap); } + + unsigned short at_bitmap_get_width (at_bitmap_type * bitmap) { return bitmap->width; } + + unsigned short at_bitmap_get_height (at_bitmap_type * bitmap) { return bitmap->height; } + + unsigned short at_bitmap_get_planes (at_bitmap_type * bitmap) { @@ -104,6 +112,8 @@ new_bitmap (unsigned short width, unsigned short height) return at_bitmap_init(NULL,width,height,1); } + + /* Free the storage that is allocated for a bitmap. On the other hand, the bitmap might not have any storage allocated for it if it is zero in either dimension; in that case, don't free it. */ @@ -114,3 +124,6 @@ free_bitmap (bitmap_type *b) if (b->bitmap != NULL) free (b->bitmap); } + + + diff --git a/converter/other/pamtosvg/bitmap.h b/converter/other/pamtosvg/bitmap.h index b979e0c0..ae5da2a8 100644 --- a/converter/other/pamtosvg/bitmap.h +++ b/converter/other/pamtosvg/bitmap.h @@ -12,16 +12,16 @@ /* at_ prefix removed version */ typedef at_bitmap_type bitmap_type; #define BITMAP_PLANES(b) AT_BITMAP_PLANES(b) -#define BITMAP_BITS(b) AT_BITMAP_BITS(b) -#define BITMAP_WIDTH(b) AT_BITMAP_WIDTH(b) -#define BITMAP_HEIGHT(b) AT_BITMAP_HEIGHT(b) +#define BITMAP_BITS(b) AT_BITMAP_BITS(b) +#define BITMAP_WIDTH(b) AT_BITMAP_WIDTH(b) +#define BITMAP_HEIGHT(b) AT_BITMAP_HEIGHT(b) /* This is the pixel at [ROW,COL]. */ -#define BITMAP_PIXEL(b, row, col) \ +#define BITMAP_PIXEL(b, row, col) \ ((b).bitmap + ((row) * (b).width + (col)) * (b).np) -#define BITMAP_VALID_PIXEL(b, row, col) \ - ((row) < (b).height && (col) < (b).width) +#define BITMAP_VALID_PIXEL(b, row, col) \ + ((row) < (b).height && (col) < (b).width) /* Allocate storage for the bits, set them all to white, and return an initialized structure. */ @@ -32,12 +32,12 @@ extern void free_bitmap (bitmap_type *); at_bitmap_type * at_bitmap_new(unsigned short width, - unsigned short height, - unsigned int planes); + unsigned short height, + unsigned int planes); at_bitmap_type * at_bitmap_copy(at_bitmap_type * src); -/* We have to export functions that allows internal datum - access. Such functions might be useful for +/* We have to export functions that allows internal datum + access. Such functions might be useful for at_bitmap_new user. */ unsigned short at_bitmap_get_width (at_bitmap_type * bitmap); unsigned short at_bitmap_get_height (at_bitmap_type * bitmap); @@ -46,8 +46,8 @@ void at_bitmap_free (at_bitmap_type * bitmap); at_bitmap_type at_bitmap_init(unsigned char * area, - unsigned short width, - unsigned short height, - unsigned int planes); + unsigned short width, + unsigned short height, + unsigned int planes); #endif /* not BITMAP_H */ diff --git a/converter/other/pamtosvg/curve.c b/converter/other/pamtosvg/curve.c index d7fff87d..bd0ca70b 100644 --- a/converter/other/pamtosvg/curve.c +++ b/converter/other/pamtosvg/curve.c @@ -61,6 +61,7 @@ curve_new(void) { } + Curve * curve_copyMost(Curve * const oldCurveP) { /*---------------------------------------------------------------------------- @@ -77,6 +78,8 @@ curve_copyMost(Curve * const oldCurveP) { return curveP; } + + void curve_move(Curve * const dstP, Curve * const srcP) { @@ -285,7 +288,6 @@ curve_logEntire(Curve * const curveP) { - CurveList curve_newList(void) { /*---------------------------------------------------------------------------- diff --git a/converter/other/pamtosvg/curve.h b/converter/other/pamtosvg/curve.h index 65d4e26b..946bb2f3 100644 --- a/converter/other/pamtosvg/curve.h +++ b/converter/other/pamtosvg/curve.h @@ -64,12 +64,12 @@ typedef struct Curve { /* If the curve is cyclic, the next and previous points should wrap around; otherwise, if we get to the end, we return CURVE_LENGTH and -1, respectively. */ -#define CURVE_NEXT(c, n) \ - ((n) + 1 >= CURVE_LENGTH (c) \ - ? CURVE_CYCLIC (c) ? ((n) + 1) % CURVE_LENGTH (c) : CURVE_LENGTH (c) \ +#define CURVE_NEXT(c, n) \ + ((n) + 1 >= CURVE_LENGTH (c) \ + ? CURVE_CYCLIC (c) ? ((n) + 1) % CURVE_LENGTH (c) : CURVE_LENGTH (c) \ : (n) + 1) -#define CURVE_PREV(c, n) \ - ((signed int) (n) - 1 < 0 \ +#define CURVE_PREV(c, n) \ + ((signed int) (n) - 1 < 0 \ ? CURVE_CYCLIC (c) ? (signed int) CURVE_LENGTH (c) + (signed int) (n) - 1 : -1\ : (signed int) (n) - 1) diff --git a/converter/other/pamtosvg/epsilon.c b/converter/other/pamtosvg/epsilon.c index 0c914dae..f5370475 100644 --- a/converter/other/pamtosvg/epsilon.c +++ b/converter/other/pamtosvg/epsilon.c @@ -11,7 +11,9 @@ epsilon_equal(float const v1, float const v2) { return - v1 == v2 /* Usually they'll be exactly equal, anyway. */ + v1 == v2 /* Usually they'll be exactly equal, anyway. */ || fabs(v1 - v2) <= REAL_EPSILON; } + + diff --git a/converter/other/pamtosvg/exception.c b/converter/other/pamtosvg/exception.c index 43761936..bf8228ae 100644 --- a/converter/other/pamtosvg/exception.c +++ b/converter/other/pamtosvg/exception.c @@ -1,4 +1,3 @@ - #include "exception.h" at_exception_type @@ -10,7 +9,7 @@ at_exception_new(at_msg_func client_func, e.msg_type = 0; e.client_func = client_func; e.client_data = client_data; - + return e; } @@ -31,7 +30,7 @@ at_exception_fatal(at_exception_type * const exception, if (exception) { exception->msg_type = AT_MSG_FATAL; if (exception->client_func) { - exception->client_func(message, + exception->client_func(message, AT_MSG_FATAL, exception->client_data); } @@ -47,9 +46,12 @@ at_exception_warning(at_exception_type * const exception, if (exception) { exception->msg_type = AT_MSG_WARNING; if (exception->client_func) { - exception->client_func(message, + exception->client_func(message, AT_MSG_WARNING, exception->client_data); } } } + + + diff --git a/converter/other/pamtosvg/exception.h b/converter/other/pamtosvg/exception.h index 113f65e6..06de7182 100644 --- a/converter/other/pamtosvg/exception.h +++ b/converter/other/pamtosvg/exception.h @@ -1,7 +1,7 @@ /* exception.h: facility to handle error in autotrace */ #ifndef AT_EXCEPTION_H -#define AT_EXCEPTION_H +#define AT_EXCEPTION_H #include "autotrace.h" @@ -10,8 +10,8 @@ extern "C" { #endif /* __cplusplus */ /* Protocol: - If a function raises a FATAL(including propagation), - the function must release resources allocated by the + If a function raises a FATAL(including propagation), + the function must release resources allocated by the function itself. */ typedef struct _at_exception_type at_exception_type; diff --git a/converter/other/pamtosvg/fit.c b/converter/other/pamtosvg/fit.c index d51b010b..ec579584 100644 --- a/converter/other/pamtosvg/fit.c +++ b/converter/other/pamtosvg/fit.c @@ -87,6 +87,7 @@ intCoordFmReal(Point const realCoord) { } + /* Lists of array indices (well, that is what we use it for). */ static IndexList diff --git a/converter/other/pamtosvg/image-header.h b/converter/other/pamtosvg/image-header.h index adcf4771..ef387572 100644 --- a/converter/other/pamtosvg/image-header.h +++ b/converter/other/pamtosvg/image-header.h @@ -9,10 +9,10 @@ the particular formats. */ typedef struct { - unsigned short hres, vres; /* In pixels per inch. */ - unsigned short width, height; /* In bits. */ - unsigned short depth; /* Perhaps the depth? */ - unsigned format; /* (for pbm) Whether packed or not. */ + unsigned short hres, vres; /* In pixels per inch. */ + unsigned short width, height; /* In bits. */ + unsigned short depth; /* Perhaps the depth? */ + unsigned format; /* (for pbm) Whether packed or not. */ } image_header_type; #endif /* not IMAGE_HEADER_H */ diff --git a/converter/other/pamtosvg/image-proc.c b/converter/other/pamtosvg/image-proc.c index d025ee1e..7462219c 100644 --- a/converter/other/pamtosvg/image-proc.c +++ b/converter/other/pamtosvg/image-proc.c @@ -53,7 +53,7 @@ new_distance_map(bitmap_type bitmap, unsigned char target_value, bool padded, at if (dist.d[y] == NULL) pm_error("Unable to get memory for distance map"); memset(dist.d[y], 0, w * sizeof(float)); - + MALLOCARRAY(dist.weight[y], w); if (dist.weight[y] == NULL) pm_error("Unable to get memory for distance map"); @@ -72,7 +72,7 @@ new_distance_map(bitmap_type bitmap, unsigned char target_value, bool padded, at dist.weight[y][x] = 1.0F - fgray; /* dist.weight[y][x] = 1.0F - (fgray * fgray);*/ /* dist.weight[y][x] = (fgray < 0.5F ? 1.0F - fgray : -2.0F * fgray * (fgray - 1.0F));*/ - } + } } } else @@ -158,15 +158,15 @@ new_distance_map(bitmap_type bitmap, unsigned char target_value, bool padded, at /* lower-right neighbor */ d = dist.d[y + 1][x + 1] + (float) M_SQRT2 * dist.weight[y][x]; - if (d < min) min = dist.d[y][x] = d; + if (d < min) min = dist.d[y][x] = d; /* lower neighbor */ d = dist.d[y + 1][x] + dist.weight[y][x]; - if (d < min) min = dist.d[y][x] = d; + if (d < min) min = dist.d[y][x] = d; /* right neighbor */ d = dist.d[y][x + 1] + dist.weight[y][x]; - if (d < min) min = dist.d[y][x] = d; + if (d < min) min = dist.d[y][x] = d; /* lower-left neighbor (except at the first column) */ if (x - 1 >= 0) @@ -180,6 +180,7 @@ new_distance_map(bitmap_type bitmap, unsigned char target_value, bool padded, at } + /* Free the dynamically-allocated storage associated with a distance map. */ void @@ -193,19 +194,20 @@ free_distance_map(distance_map_type *dist) if (dist->d != NULL) { - for (y = 0; y < h; y++) - free(dist->d[y]); + for (y = 0; y < h; y++) + free(dist->d[y]); free(dist->d); } if (dist->weight != NULL) { - for (y = 0; y < h; y++) - free(dist->weight[y]); + for (y = 0; y < h; y++) + free(dist->weight[y]); free(dist->weight); } } + #if 0 void medial_axis(bitmap_type *bitmap, distance_map_type *dist, @@ -233,7 +235,7 @@ medial_axis(bitmap_type *bitmap, distance_map_type *dist, if (bgSpec) bg = bg_color; - else + else PPM_ASSIGN(bg, 255, 255, 255); f = d[0][0] + 0.5; @@ -246,44 +248,44 @@ medial_axis(bitmap_type *bitmap, distance_map_type *dist, for (x = 1; x < w - 1; x++) { - f = d[0][x] + 0.5; - test = (f < d[0][x-1]) + (f < d[0][x+1]) + (f < d[1][x-1]) - + (f < d[1][x]) + (f < d[1][x+1]); - if (test > 1) b[x] = PPM_GETR(bg); + f = d[0][x] + 0.5; + test = (f < d[0][x-1]) + (f < d[0][x+1]) + (f < d[1][x-1]) + + (f < d[1][x]) + (f < d[1][x+1]); + if (test > 1) b[x] = PPM_GETR(bg); } b += w; for (y = 1; y < h - 1; y++) { - f = d[y][0] + 0.5; - test = (f < d[y-1][0]) + (f < d[y-1][1]) + (f < d[y][1]) - + (f < d[y+1][0]) + (f < d[y+1][1]); - if (test > 1) b[0] = PPM_GETR(bg); - - for (x = 1; x < w - 1; x++) - { - f = d[y][x] + 0.5; - test = (f < d[y-1][x-1]) + (f < d[y-1][x]) + (f < d[y-1][x+1]) - + (f < d[y][x-1]) + (f < d[y][x+1]) - + (f < d[y+1][x-1]) + (f < d[y+1][x]) + (f < d[y+1][x+1]); - if (test > 1) b[x] = PPM_GETR(bg) - } - - f = d[y][w-1] + 0.5; - test = (f < d[y-1][w-1]) + (f < d[y-1][w-2]) + (f < d[y][w-2]) - + (f < d[y+1][w-1]) + (f < d[y+1][w-2]); - if (test > 1) - b[w-1] = PPM_GETR(bg); + f = d[y][0] + 0.5; + test = (f < d[y-1][0]) + (f < d[y-1][1]) + (f < d[y][1]) + + (f < d[y+1][0]) + (f < d[y+1][1]); + if (test > 1) b[0] = PPM_GETR(bg); + + for (x = 1; x < w - 1; x++) + { + f = d[y][x] + 0.5; + test = (f < d[y-1][x-1]) + (f < d[y-1][x]) + (f < d[y-1][x+1]) + + (f < d[y][x-1]) + (f < d[y][x+1]) + + (f < d[y+1][x-1]) + (f < d[y+1][x]) + (f < d[y+1][x+1]); + if (test > 1) b[x] = PPM_GETR(bg) + } + + f = d[y][w-1] + 0.5; + test = (f < d[y-1][w-1]) + (f < d[y-1][w-2]) + (f < d[y][w-2]) + + (f < d[y+1][w-1]) + (f < d[y+1][w-2]); + if (test > 1) + b[w-1] = PPM_GETR(bg); b += w; } for (x = 1; x < w - 1; x++) { - f = d[h-1][x] + 0.5; - test = (f < d[h-1][x-1]) + (f < d[h-1][x+1]) - + (f < d[h-2][x-1]) + (f < d[h-2][x]) + (f < d[h-2][x+1]); - if (test > 1) b[x] = PPM_GETR(bg); + f = d[h-1][x] + 0.5; + test = (f < d[h-1][x-1]) + (f < d[h-1][x+1]) + + (f < d[h-2][x-1]) + (f < d[h-2][x]) + (f < d[h-2][x+1]); + if (test > 1) b[x] = PPM_GETR(bg); } f = d[h-1][0] + 0.5; @@ -314,27 +316,28 @@ binarize(bitmap_type *bitmap) if (spp == 1) { - for (i = 0; i < npixels; i++) - b[i] = (b[i] > GRAY_THRESHOLD ? WHITE : BLACK); + for (i = 0; i < npixels; i++) + b[i] = (b[i] > GRAY_THRESHOLD ? WHITE : BLACK); } else if (spp == 3) { - unsigned char *rgb = b; - for (i = 0; i < npixels; i++, rgb += 3) - { - b[i] = (LUMINANCE(rgb[0], rgb[1], rgb[2]) > GRAY_THRESHOLD - ? WHITE : BLACK); - } - REALLOCARRAY_NOFAIL(bitmap->bitmap, npixels); - bitmap->np = 1; + unsigned char *rgb = b; + for (i = 0; i < npixels; i++, rgb += 3) + { + b[i] = (LUMINANCE(rgb[0], rgb[1], rgb[2]) > GRAY_THRESHOLD + ? WHITE : BLACK); + } + REALLOCARRAY_NOFAIL(bitmap->bitmap, npixels); + bitmap->np = 1; } else { - WARNING1("binarize: don't know how to interpret %u-plane images", spp); + WARNING1("binarize: don't know how to interpret %u-plane images", spp); } } + #if 0 /* Thin a binary image, replacing the original image with the thinned one. */ @@ -351,9 +354,9 @@ ip_thin(bitmap_type input_b) if (BITMAP_PLANES(input_b) != 1) { - FATAL1("thin: single-plane image required; " - "%u-plane images cannot be thinned", BITMAP_PLANES(input_b)); - return b; + FATAL1("thin: single-plane image required; " + "%u-plane images cannot be thinned", BITMAP_PLANES(input_b)); + return b; } /* Process and return a copy of the input image. */ @@ -364,149 +367,151 @@ ip_thin(bitmap_type input_b) /* Set background pixels to zero, foreground pixels to one. */ for (i = 0; i < num_bytes; i++) - b.bitmap[i] = (b.bitmap[i] == BLACK ? 1 : 0); + b.bitmap[i] = (b.bitmap[i] == BLACK ? 1 : 0); again = true; while (again) { - again = false; - - for (y = 1; y < h - 1; y++) - { - for (x = 1; x < w - 1; x++) - { - /* During processing, pixels are used to store edge - type codes, so we can't just test for WHITE or BLACK. */ - if (*BITMAP_PIXEL(b, y, x) == 0) continue; - - k = (!get_edge(b, y, x, &t) - || (get_edge(b, y, x+1, &t) && *BITMAP_PIXEL(b, y-1, x) - && *BITMAP_PIXEL(b, y+1, x)) - || (get_edge(b, y+1, x, &t) && *BITMAP_PIXEL(b, y, x-1) - && *BITMAP_PIXEL(b, y, x+1)) - || (get_edge(b, y, x+1, &t) && get_edge(b, y+1, x+1, &t) - && get_edge(b, y+1, x, &t))); - if (k) continue; - - get_edge(b, y, x, &t); - if (t.t01) *BITMAP_PIXEL(b, y, x) |= 4; - *BITMAP_PIXEL(b, y, x) |= 2; - again = true; - } - } - - for (y = 0; y < h; y++) - for (x = 0; x < w; x++) - if (*BITMAP_PIXEL(b, y, x) & 02) *BITMAP_PIXEL(b, y, x) = 0; - - for (y = 1; y < h - 1; y++) - { - for (x = 1; x < w - 1; x++) - { - if (*BITMAP_PIXEL(b, y, x) == 0) continue; - - k = (!get_edge(b, y, x, &t) - || ((*BITMAP_PIXEL(b, y, x) & 04) == 0) - || (get_edge(b, y+1, x, &t) && (*BITMAP_PIXEL(b, y, x-1)) - && *BITMAP_PIXEL(b, y, x+1)) - || (get_edge(b, y, x+1, &t) && *BITMAP_PIXEL(b, y-1, x) - && *BITMAP_PIXEL(b, y+1, x)) - || (get_edge(b, y+1, x, &t) && get_edge(b, y, x+1, &t) - && get_edge(b, y+1, x+1, &t))); - if (k) continue; - - *BITMAP_PIXEL(b, y, x) |= 02; - again = true; - } - } - - for (y = 0; y < h; y++) - { - for (x = 0; x < w; x++) - { - if (*BITMAP_PIXEL(b, y, x) & 02) *BITMAP_PIXEL(b, y, x) = 0; - else if (*BITMAP_PIXEL(b, y, x) > 0) *BITMAP_PIXEL(b, y, x) = 1; - } - } + again = false; + + for (y = 1; y < h - 1; y++) + { + for (x = 1; x < w - 1; x++) + { + /* During processing, pixels are used to store edge + type codes, so we can't just test for WHITE or BLACK. */ + if (*BITMAP_PIXEL(b, y, x) == 0) continue; + + k = (!get_edge(b, y, x, &t) + || (get_edge(b, y, x+1, &t) && *BITMAP_PIXEL(b, y-1, x) + && *BITMAP_PIXEL(b, y+1, x)) + || (get_edge(b, y+1, x, &t) && *BITMAP_PIXEL(b, y, x-1) + && *BITMAP_PIXEL(b, y, x+1)) + || (get_edge(b, y, x+1, &t) && get_edge(b, y+1, x+1, &t) + && get_edge(b, y+1, x, &t))); + if (k) continue; + + get_edge(b, y, x, &t); + if (t.t01) *BITMAP_PIXEL(b, y, x) |= 4; + *BITMAP_PIXEL(b, y, x) |= 2; + again = true; + } + } + + for (y = 0; y < h; y++) + for (x = 0; x < w; x++) + if (*BITMAP_PIXEL(b, y, x) & 02) *BITMAP_PIXEL(b, y, x) = 0; + + for (y = 1; y < h - 1; y++) + { + for (x = 1; x < w - 1; x++) + { + if (*BITMAP_PIXEL(b, y, x) == 0) continue; + + k = (!get_edge(b, y, x, &t) + || ((*BITMAP_PIXEL(b, y, x) & 04) == 0) + || (get_edge(b, y+1, x, &t) && (*BITMAP_PIXEL(b, y, x-1)) + && *BITMAP_PIXEL(b, y, x+1)) + || (get_edge(b, y, x+1, &t) && *BITMAP_PIXEL(b, y-1, x) + && *BITMAP_PIXEL(b, y+1, x)) + || (get_edge(b, y+1, x, &t) && get_edge(b, y, x+1, &t) + && get_edge(b, y+1, x+1, &t))); + if (k) continue; + + *BITMAP_PIXEL(b, y, x) |= 02; + again = true; + } + } + + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + if (*BITMAP_PIXEL(b, y, x) & 02) *BITMAP_PIXEL(b, y, x) = 0; + else if (*BITMAP_PIXEL(b, y, x) > 0) *BITMAP_PIXEL(b, y, x) = 1; + } + } } /* Staircase removal; northward bias. */ for (y = 1; y < h - 1; y++) { - for (x = 1; x < w - 1; x++) - { - if (*BITMAP_PIXEL(b, y, x) == 0) continue; - - k = !(*BITMAP_PIXEL(b, y-1, x) - && ((*BITMAP_PIXEL(b, y, x+1) && !*BITMAP_PIXEL(b, y-1, x+1) - && !*BITMAP_PIXEL(b, y+1, x-1) - && (!*BITMAP_PIXEL(b, y, x-1) || !*BITMAP_PIXEL(b, y+1, x))) - || (*BITMAP_PIXEL(b, y, x-1) && !*BITMAP_PIXEL(b, y-1, x-1) - && !*BITMAP_PIXEL(b, y+1, x+1) && - (!*BITMAP_PIXEL(b, y, x+1) || !*BITMAP_PIXEL(b, y+1, x))))); - if (k) continue; - - *BITMAP_PIXEL(b, y, x) |= 02; - } + for (x = 1; x < w - 1; x++) + { + if (*BITMAP_PIXEL(b, y, x) == 0) continue; + + k = !(*BITMAP_PIXEL(b, y-1, x) + && ((*BITMAP_PIXEL(b, y, x+1) && !*BITMAP_PIXEL(b, y-1, x+1) + && !*BITMAP_PIXEL(b, y+1, x-1) + && (!*BITMAP_PIXEL(b, y, x-1) || !*BITMAP_PIXEL(b, y+1, x))) + || (*BITMAP_PIXEL(b, y, x-1) && !*BITMAP_PIXEL(b, y-1, x-1) + && !*BITMAP_PIXEL(b, y+1, x+1) && + (!*BITMAP_PIXEL(b, y, x+1) || !*BITMAP_PIXEL(b, y+1, x))))); + if (k) continue; + + *BITMAP_PIXEL(b, y, x) |= 02; + } } for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) - { - if (*BITMAP_PIXEL(b, y, x) & 02) *BITMAP_PIXEL(b, y, x) = 0; - else if (*BITMAP_PIXEL(b, y, x) > 0) *BITMAP_PIXEL(b, y, x) = 1; - } + for (x = 0; x < w; x++) + { + if (*BITMAP_PIXEL(b, y, x) & 02) *BITMAP_PIXEL(b, y, x) = 0; + else if (*BITMAP_PIXEL(b, y, x) > 0) *BITMAP_PIXEL(b, y, x) = 1; + } } /* Southward bias */ for (y = 1; y < h - 1; y++) { - for (x = 1; x < w - 1; x++) - { - if (*BITMAP_PIXEL(b, y, x) == 0) continue; - - k = !(*BITMAP_PIXEL(b, y+1, x) - && ((*BITMAP_PIXEL(b, y, x+1) && !*BITMAP_PIXEL(b, y+1, x+1) - && !*BITMAP_PIXEL(b, y-1, x-1) && (!*BITMAP_PIXEL(b, y, x-1) - || !*BITMAP_PIXEL(b, y-1, x))) || (*BITMAP_PIXEL(b, y, x-1) - && !*BITMAP_PIXEL(b, y+1, x-1) && !*BITMAP_PIXEL(b, y-1, x+1) - && (!*BITMAP_PIXEL(b, y, x+1) || !*BITMAP_PIXEL(b, y-1, x)) ))); - if (k) continue; - - *BITMAP_PIXEL(b, y, x) |= 02; - } + for (x = 1; x < w - 1; x++) + { + if (*BITMAP_PIXEL(b, y, x) == 0) continue; + + k = !(*BITMAP_PIXEL(b, y+1, x) + && ((*BITMAP_PIXEL(b, y, x+1) && !*BITMAP_PIXEL(b, y+1, x+1) + && !*BITMAP_PIXEL(b, y-1, x-1) && (!*BITMAP_PIXEL(b, y, x-1) + || !*BITMAP_PIXEL(b, y-1, x))) || (*BITMAP_PIXEL(b, y, x-1) + && !*BITMAP_PIXEL(b, y+1, x-1) && !*BITMAP_PIXEL(b, y-1, x+1) + && (!*BITMAP_PIXEL(b, y, x+1) || !*BITMAP_PIXEL(b, y-1, x)) ))); + if (k) continue; + + *BITMAP_PIXEL(b, y, x) |= 02; + } } for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) - { - if (*BITMAP_PIXEL(b, y, x) & 02) *BITMAP_PIXEL(b, y, x) = 0; - else if (*BITMAP_PIXEL(b, y, x) > 0) *BITMAP_PIXEL(b, y, x) = 1; - } + for (x = 0; x < w; x++) + { + if (*BITMAP_PIXEL(b, y, x) & 02) *BITMAP_PIXEL(b, y, x) = 0; + else if (*BITMAP_PIXEL(b, y, x) > 0) *BITMAP_PIXEL(b, y, x) = 1; + } } /* Set background pixels to WHITE, foreground pixels to BLACK. */ for (i = 0; i < num_bytes; i++) - b.bitmap[i] = (b.bitmap[i] == 0 ? WHITE : BLACK); + b.bitmap[i] = (b.bitmap[i] == 0 ? WHITE : BLACK); return b; } + bool get_edge(bitmap_type b, int y, int x, struct etyp *t) { t->t00 = 0; t->t01 = 0; t->t01s = 0; t->t11 = 0; check(*BITMAP_PIXEL(b, y - 1, x - 1), *BITMAP_PIXEL(b, y - 1, x), - *BITMAP_PIXEL(b, y - 1, x + 1), t); + *BITMAP_PIXEL(b, y - 1, x + 1), t); check(*BITMAP_PIXEL(b, y - 1, x + 1), *BITMAP_PIXEL(b, y, x + 1), - *BITMAP_PIXEL(b, y + 1, x + 1), t); + *BITMAP_PIXEL(b, y + 1, x + 1), t); check(*BITMAP_PIXEL(b, y + 1, x + 1), *BITMAP_PIXEL(b, y + 1, x), - *BITMAP_PIXEL(b, y + 1, x - 1), t); + *BITMAP_PIXEL(b, y + 1, x - 1), t); check(*BITMAP_PIXEL(b, y + 1, x - 1), *BITMAP_PIXEL(b, y, x - 1), - *BITMAP_PIXEL(b, y - 1, x - 1), t); + *BITMAP_PIXEL(b, y - 1, x - 1), t); return *BITMAP_PIXEL(b, y, x) && t->t00 && t->t11 && !t->t01s; } + void check(int v1, int v2, int v3, struct etyp *t) { if (!v2 && (!v1 || !v3)) t->t00 = 1; diff --git a/converter/other/pamtosvg/image-proc.h b/converter/other/pamtosvg/image-proc.h index a5b86ec1..0607d3dd 100644 --- a/converter/other/pamtosvg/image-proc.h +++ b/converter/other/pamtosvg/image-proc.h @@ -25,7 +25,7 @@ typedef struct /* Allocate and compute a new distance map. */ extern distance_map_type new_distance_map(bitmap_type, unsigned char target_value, bool padded, - at_exception_type * exp); + at_exception_type * exp); /* Free the dynamically-allocated storage associated with a distance map. */ extern void free_distance_map(distance_map_type*); diff --git a/converter/other/pamtosvg/logreport.c b/converter/other/pamtosvg/logreport.c index 7d726584..63568b96 100644 --- a/converter/other/pamtosvg/logreport.c +++ b/converter/other/pamtosvg/logreport.c @@ -15,3 +15,5 @@ flush_log_output (void) fflush (log_file); } + + diff --git a/converter/other/pamtosvg/logreport.h b/converter/other/pamtosvg/logreport.h index 577da8df..071d42c3 100644 --- a/converter/other/pamtosvg/logreport.h +++ b/converter/other/pamtosvg/logreport.h @@ -11,17 +11,17 @@ extern FILE *at_log_file; extern void flush_log_output (void); -#define LOG(s) \ +#define LOG(s) \ do { if (log_file) fputs (s, log_file); } while (0) -#define LOG1(s, e) \ +#define LOG1(s, e) \ do { if (log_file) fprintf (log_file, s, e); } while (0) -#define LOG2(s, e1, e2) \ +#define LOG2(s, e1, e2) \ do { if (log_file) fprintf (log_file, s, e1, e2); } while (0) -#define LOG3(s, e1, e2, e3) \ +#define LOG3(s, e1, e2, e3) \ do { if (log_file) fprintf (log_file, s, e1, e2, e3); } while (0) -#define LOG4(s, e1, e2, e3, e4) \ +#define LOG4(s, e1, e2, e3, e4) \ do { if (log_file) fprintf (log_file, s, e1, e2, e3, e4); } while (0) -#define LOG5(s, e1, e2, e3, e4, e5) \ +#define LOG5(s, e1, e2, e3, e4, e5) \ do { if (log_file) fprintf (log_file, s, e1, e2, e3, e4, e5); } while (0) #endif /* not LOGREPORT_H */ diff --git a/converter/other/pamtosvg/message.h b/converter/other/pamtosvg/message.h index 0d0b9db5..e6822432 100644 --- a/converter/other/pamtosvg/message.h +++ b/converter/other/pamtosvg/message.h @@ -13,18 +13,18 @@ #define START_FATAL() do { fputs ("fatal: ", stderr); LOG("fatal: ") #define END_FATAL() fputs (".\n", stderr); exit (1); } while (0) -#define FATAL(s) \ +#define FATAL(s) \ START_FATAL (); fprintf (stderr, "%s", s); LOG (s); END_FATAL () -#define FATAL1(s, e1) \ +#define FATAL1(s, e1) \ START_FATAL (); fprintf (stderr, s, e1); LOG1 (s, e1); END_FATAL () #define START_WARNING() do { fputs ("warning: ", stderr); LOG ("warning: ") #define END_WARNING() fputs (".\n", stderr); } while (0) -#define WARNING(s) \ +#define WARNING(s) \ START_WARNING (); fprintf (stderr, "%s", s); LOG (s); END_WARNING () -#define WARNING1(s, e1) \ +#define WARNING1(s, e1) \ START_WARNING (); fprintf (stderr, s, e1); LOG1 (s, e1); END_WARNING () #endif /* not MESSAGE_H */ diff --git a/converter/other/pamtosvg/output-svg.c b/converter/other/pamtosvg/output-svg.c index 13ac5201..59733094 100644 --- a/converter/other/pamtosvg/output-svg.c +++ b/converter/other/pamtosvg/output-svg.c @@ -26,15 +26,15 @@ static void outSplineList(FILE * const fileP, spline_list_type const splineList, unsigned int const height) { - + unsigned splineSeq; - + for (splineSeq = 0; splineSeq < SPLINE_LIST_LENGTH(splineList); ++splineSeq) { - + spline_type const spline = SPLINE_LIST_ELT(splineList, splineSeq); - + if (SPLINE_DEGREE(spline) == LINEARTYPE) { fprintf(fileP, "L%g %g", END_POINT(spline).x, height - END_POINT(spline).y); @@ -55,13 +55,13 @@ out_splines(FILE * const fileP, unsigned listSeq; pixel lastColor; - + PPM_ASSIGN(lastColor, 0, 0, 0); - + for (listSeq = 0; listSeq < SPLINE_LIST_ARRAY_LENGTH(shape); ++listSeq) { - + spline_list_type const splineList = SPLINE_LIST_ARRAY_ELT(shape, listSeq); spline_type const first = SPLINE_LIST_ELT(splineList, 0); @@ -109,10 +109,10 @@ output_svg_writer(FILE * const fileP, int const llx, int const lly, int const urx, - int const ury, + int const ury, at_output_opts_type * const opts, at_spline_list_array_type const shape, - at_msg_func msg_func, + at_msg_func msg_func, void * const msg_data) { int const width = urx - llx; @@ -125,6 +125,9 @@ output_svg_writer(FILE * const fileP, out_splines(fileP, shape, height); fputs("</svg>\n", fileP); - + return 0; } + + + diff --git a/converter/other/pamtosvg/output-svg.h b/converter/other/pamtosvg/output-svg.h index 46fc8f8f..a02e8334 100644 --- a/converter/other/pamtosvg/output-svg.h +++ b/converter/other/pamtosvg/output-svg.h @@ -26,10 +26,10 @@ output_svg_writer(FILE * const file, int const llx, int const lly, int const urx, - int const ury, + int const ury, at_output_opts_type * const opts, at_spline_list_array_type const shape, - at_msg_func msg_func, + at_msg_func msg_func, void * const msg_data); diff --git a/converter/other/pamtosvg/pamtosvg.c b/converter/other/pamtosvg/pamtosvg.c index adf76801..03b0a80f 100644 --- a/converter/other/pamtosvg/pamtosvg.c +++ b/converter/other/pamtosvg/pamtosvg.c @@ -47,12 +47,12 @@ readImageToBitmap(FILE * const ifP, unsigned int col; pnm_scaletuplerow(&pam, row255, tuples[row], 255); - + for (col = 0; col < pam.width; ++col) { unsigned int plane; for (plane = 0; plane < pam.depth; ++plane) { - unsigned int const bitmapIndex = + unsigned int const bitmapIndex = (row * pam.width + col) * pam.depth + plane; bitmapP->bitmap[bitmapIndex] = row255[col][plane]; } @@ -60,7 +60,7 @@ readImageToBitmap(FILE * const ifP, } pnm_freepamrow(row255); pnm_freepamarray(tuples, &pam); - + *bitmapPP = bitmapP; } @@ -73,7 +73,7 @@ dotPrinter(float const percentage, int * const currentP = (int *)clientData; float const unit = (float)1.0 / (float)(dot_printer_max_column) ; int const maximum = (int)(percentage / unit); - + while (*currentP < maximum) { fputc(dot_printer_char, stderr); (*currentP)++; @@ -120,13 +120,13 @@ struct cmdlineInfo { }; -static void -parseCommandLine(int argc, - char ** argv, +static void +parseCommandLine(int argc, + char ** argv, struct cmdlineInfo * const cmdlineP) { /* -------------------------------------------------------------------------- Parse program command line described in Unix standard form by argc - and argv. Return the information in the options as *cmdlineP. + and argv. Return the information in the options as *cmdlineP. If command line is internally inconsistent (invalid options, etc.), issue error message to stderr and abort program. @@ -139,7 +139,7 @@ parseCommandLine(int argc, optStruct3 opt; const char * background_colorOpt; - + unsigned int option_def_index; MALLOCARRAY_NOFAIL(option_def, 100); @@ -151,7 +151,7 @@ parseCommandLine(int argc, &background_colorOpt, &cmdlineP->backgroundSpec, 0); OPTENT3(0, "centerline", OPT_FLAG, NULL, &cmdlineP->centerline, 0); - OPTENT3(0, "corner-always-threshold", OPT_FLOAT, + OPTENT3(0, "corner-always-threshold", OPT_FLOAT, &cmdlineP->corner_always_threshold, NULL, 0); OPTENT3(0, "corner-surround", OPT_UINT, &cmdlineP->corner_surround, NULL, 0); @@ -173,11 +173,11 @@ parseCommandLine(int argc, NULL, &cmdlineP->preserve_width, 0); OPTENT3(0, "remove-adjacent-corners", OPT_UINT, NULL, &cmdlineP->remove_adjacent_corners, 0); - OPTENT3(0, "tangent-surround", OPT_UINT, + OPTENT3(0, "tangent-surround", OPT_UINT, &cmdlineP->tangent_surround, NULL, 0); OPTENT3(0, "report-progress", OPT_FLAG, NULL, &cmdlineP->report_progress, 0); - OPTENT3(0, "width-weight-factor", OPT_FLOAT, + OPTENT3(0, "width-weight-factor", OPT_FLOAT, &cmdlineP->width_weight_factor, NULL, 0); @@ -207,7 +207,7 @@ parseCommandLine(int argc, cmdlineP->inputFileName = "-"; else { cmdlineP->inputFileName = argv[1]; - + if (argc-1 > 1) pm_error("Too many arguments (%u). The only non-option argument " "is the input file name.", argc-1); @@ -228,7 +228,7 @@ fitSplines(at_bitmap_type * const bitmapP, at_fitting_opts_type * fittingOptsP; progressStat = 0; - + fittingOptsP = at_fitting_opts_new(); fittingOptsP->backgroundSpec = cmdline.backgroundSpec; @@ -253,7 +253,7 @@ fitSplines(at_bitmap_type * const bitmapP, at_fitting_opts_free(fittingOptsP); } - + static void @@ -267,12 +267,12 @@ writeSplines(at_spline_list_array_type * const splinesP, outputOptsP = at_output_opts_new(); outputOptsP->dpi = cmdline.dpi; - + at_splines_write(outputWriter, ofP, outputOptsP, splinesP, exceptionHandler, NULL); at_output_opts_free(outputOptsP); -} +} @@ -315,13 +315,13 @@ filenameRoot(const char * const filename) { rootEnd = strlen(filename); MALLOCARRAY(buffer, rootEnd - rootStart + 1); - + j = 0; for (i = rootStart; i < rootEnd; ++i) buffer[j++] = filename[i]; buffer[j] = '\0'; - + return buffer; } @@ -342,7 +342,7 @@ openLogFile(FILE ** const logFileP, if (inputRootName == NULL) pm_error("Can't find the root portion of file name '%s'", inputFileArg); - + pm_asprintf(&logfileName, "%s.log", inputRootName); pm_strfree(inputRootName); @@ -352,7 +352,7 @@ openLogFile(FILE ** const logFileP, pm_strfree(logfileName); } - + int @@ -374,7 +374,7 @@ main(int argc, char * argv[]) { openLogFile(&log_file, cmdline.inputFileName); readImageToBitmap(ifP, &bitmapP); - + if (cmdline.report_progress) { progressReporter = dotPrinter; fprintf(stderr, "%-15s", cmdline.inputFileName); @@ -397,6 +397,9 @@ main(int argc, char * argv[]) { if (cmdline.report_progress) fputs("\n", stderr); - + return 0; } + + + diff --git a/converter/other/pamtosvg/pxl-outline.c b/converter/other/pamtosvg/pxl-outline.c index 19451c04..ff7d6e25 100644 --- a/converter/other/pamtosvg/pxl-outline.c +++ b/converter/other/pamtosvg/pxl-outline.c @@ -85,7 +85,7 @@ getBitmapColor(bitmap_type const bitmap, unsigned char * const p = BITMAP_PIXEL(bitmap, row, col); pixel pix; - + if (bitmap.np >= 3) PPM_ASSIGN(pix, p[0], p[1], p[2]); else @@ -96,7 +96,6 @@ getBitmapColor(bitmap_type const bitmap, - static void append_outline_pixel(pixel_outline_type * const pixelOutlineP, pm_pixelcoord const coord) { @@ -156,6 +155,7 @@ is_outline_edge (edge_type edge, bitmap_type bitmap, } + /* Is this really an edge and is it still unmarked? */ static bool @@ -173,13 +173,14 @@ is_unmarked_outline_edge(unsigned short row, } + static bool is_valid_dir(unsigned int const row, unsigned int const col, direction_type const dir, bitmap_type const bitmap, bitmap_type const marked) { - + return(!is_marked_dir(row, col, dir, marked) && COMPUTE_DELTA(ROW, dir)+row > 0 && COMPUTE_DELTA(COL, dir)+col > 0 @@ -233,7 +234,7 @@ next_unmarked_pixel(unsigned int * const row, break; } while (1); - if ((*row != orig_row || *col != orig_col) && + if ((*row != orig_row || *col != orig_col) && (!(is_other_dir_marked(orig_row, orig_col, test_dir, *marked) && is_other_dir_marked(orig_row + COMPUTE_DELTA(ROW, test_dir), orig_col + COMPUTE_DELTA(COL, test_dir), @@ -297,7 +298,7 @@ findOneCenterline(bitmap_type const bitmap, if (row == originalRow && col == originalCol) break; - + { /* Add the new pixel to the output list. */ pm_pixelcoord pos; @@ -338,7 +339,7 @@ wrongDirection(unsigned int const row, pixel_outline_list_type find_centerline_pixels(bitmap_type const bitmap, - pixel const bg_color, + pixel const bg_color, at_progress_func notify_progress, void * const progress_data, at_testcancel_func test_cancel, @@ -349,7 +350,7 @@ find_centerline_pixels(bitmap_type const bitmap, signed short row; bitmap_type marked = new_bitmap(bitmap.width, bitmap.height); unsigned int const max_progress = bitmap.height * bitmap.width; - + O_LIST_LENGTH(outline_list) = 0; outline_list.data = NULL; @@ -366,9 +367,9 @@ find_centerline_pixels(bitmap_type const bitmap, ((float) max_progress * (float)3.0), progress_data); - if (PPM_EQUAL(getBitmapColor(bitmap, row, col), bg_color)) { - ++col; - continue; + if (PPM_EQUAL(getBitmapColor(bitmap, row, col), bg_color)) { + ++col; + continue; } dir = EAST; @@ -380,8 +381,8 @@ find_centerline_pixels(bitmap_type const bitmap, if (wrongDirection(row, col, dir, bitmap, marked)) { dir = SOUTHWEST; if (wrongDirection(row, col, dir, bitmap, marked)) { - ++col; - continue; + ++col; + continue; } } } @@ -454,8 +455,8 @@ find_centerline_pixels(bitmap_type const bitmap, free(partial_outline.data); } else ++col; - } - + } + /* Outside outlines will start at a top edge, and move counterclockwise, and inside outlines will start at a bottom edge, and move clockwise. This happens because of @@ -493,6 +494,7 @@ append_pixel_outline (pixel_outline_list_type *outline_list, } + /* Free the list of outline lists. */ void @@ -517,6 +519,7 @@ free_pixel_outline_list (pixel_outline_list_type *outline_list) } + /* Return an empty list of pixels. */ @@ -532,6 +535,8 @@ new_pixel_outline (void) return pixel_outline; } + + static void free_pixel_outline (pixel_outline_type * outline) { @@ -543,6 +548,8 @@ free_pixel_outline (pixel_outline_type * outline) } } + + /* Concatenate two pixel lists. The two lists are assumed to have the same starting pixel and to proceed in opposite directions therefrom. */ @@ -569,6 +576,7 @@ concat_pixel_outline(pixel_outline_type *o1, const pixel_outline_type *o2) } + /* If EDGE is not already marked, we mark it; otherwise, it's a fatal error. The position ROW and COL should be inside the bitmap MARKED. EDGE can be NO_EDGE. */ @@ -581,6 +589,7 @@ mark_edge (edge_type edge, unsigned short row, } + /* Mark the direction of the pixel ROW/COL in MARKED. */ static void @@ -590,6 +599,7 @@ mark_dir(unsigned short row, unsigned short col, direction_type dir, bitmap_type } + /* Test if the direction of pixel at ROW/COL in MARKED is marked. */ static bool @@ -599,6 +609,7 @@ is_marked_dir(unsigned short row, unsigned short col, direction_type dir, bitmap } + static bool is_other_dir_marked(unsigned short row, unsigned short col, direction_type dir, bitmap_type marked) { @@ -606,6 +617,7 @@ is_other_dir_marked(unsigned short row, unsigned short col, direction_type dir, } + /* Return the number of pixels adjacent to pixel ROW/COL that are black. */ static unsigned @@ -615,18 +627,19 @@ num_neighbors(unsigned short row, unsigned short col, bitmap_type bitmap) pixel color = getBitmapColor(bitmap, row, col); for (dir = NORTH; dir <= NORTHEAST; dir++) { - int delta_r = COMPUTE_DELTA(ROW, dir); - int delta_c = COMPUTE_DELTA(COL, dir); - unsigned int test_row = row + delta_r; - unsigned int test_col = col + delta_c; - if (BITMAP_VALID_PIXEL(bitmap, test_row, test_col) - && PPM_EQUAL(getBitmapColor(bitmap, test_row, test_col), color)) - ++count; + int delta_r = COMPUTE_DELTA(ROW, dir); + int delta_c = COMPUTE_DELTA(COL, dir); + unsigned int test_row = row + delta_r; + unsigned int test_col = col + delta_c; + if (BITMAP_VALID_PIXEL(bitmap, test_row, test_col) + && PPM_EQUAL(getBitmapColor(bitmap, test_row, test_col), color)) + ++count; } return count; } + /* Test if the edge EDGE at ROW/COL in MARKED is marked. */ static bool @@ -679,7 +692,7 @@ nextClockwisePointTop(bitmap_type const bitmap, posP->col = *col + 1; posP->row = bitmap.height - *row; return; - } + } RETURN_IF_FATAL(); @@ -714,7 +727,7 @@ nextClockwisePointRight(bitmap_type const bitmap, is_outline_edge(RIGHT, bitmap, *row-1, *col, color, exp))) { /* NORTH */ - + *edge = RIGHT; --*row; posP->col = *col+1; @@ -723,7 +736,7 @@ nextClockwisePointRight(bitmap_type const bitmap, } RETURN_IF_FATAL(); - + if ((*col+1 < marked.width && *row >= 1 && !is_marked_edge(BOTTOM, *row-1, *col+1, marked) && is_outline_edge(BOTTOM, bitmap, *row-1, *col+1, @@ -740,7 +753,7 @@ nextClockwisePointRight(bitmap_type const bitmap, posP->col = *col + 1; posP->row = bitmap.height - *row - 1; return; - } + } RETURN_IF_FATAL(); @@ -769,7 +782,7 @@ nextClockwisePointBottom(bitmap_type const bitmap, bitmap_type const marked, at_exception_type * const exp, pm_pixelcoord * const posP) { - + if ((*col+1 < marked.width && !is_marked_edge(BOTTOM, *row, *col+1, marked) && is_outline_edge(BOTTOM, bitmap, *row, *col+1, color, exp))) { @@ -853,16 +866,16 @@ nextClockwisePointLeft(bitmap_type const bitmap, is_marked_edge(TOP, *row+1, *col, marked)) && !(is_marked_edge(BOTTOM, *row, *col-1, marked) && is_marked_edge(LEFT, *row+1, *col, marked))) { - + /* SOUTHWEST */ - + *edge = TOP; --*col; ++*row; posP->col = *col; posP->row = bitmap.height - *row; return; - } + } RETURN_IF_FATAL(); @@ -889,21 +902,21 @@ nextClockwisePoint(bitmap_type const bitmap, bitmap_type const marked, at_exception_type * const exp, pm_pixelcoord * const posP) { - + switch (*edge) { case TOP: nextClockwisePointTop( bitmap, edge, row, col, color, marked, exp, posP); break; - case RIGHT: + case RIGHT: nextClockwisePointRight(bitmap, edge, row, col, color, marked, exp, posP); break; - case BOTTOM: + case BOTTOM: nextClockwisePointBottom(bitmap, edge, row, col, color, marked, exp, posP); break; - case LEFT: + case LEFT: nextClockwisePointLeft( bitmap, edge, row, col, color, marked, exp, posP); break; @@ -952,7 +965,7 @@ nextCcwPointTop(bitmap_type const bitmap, } RETURN_IF_FATAL(); - + if ((*col >= 1 && *row >= 1 && !is_marked_edge(RIGHT, *row-1, *col-1, marked) && is_outline_edge(RIGHT, bitmap, *row-1, *col-1, color, exp))) { @@ -965,7 +978,7 @@ nextCcwPointTop(bitmap_type const bitmap, posP->col = *col + 1; posP->row = bitmap.height - *row; return; - } + } RETURN_IF_FATAL(); @@ -1000,7 +1013,7 @@ nextCcwPointRight(bitmap_type const bitmap, is_outline_edge(RIGHT, bitmap, *row-1, *col, color, exp))) { /* NORTH */ - + *edge = RIGHT; --*row; posP->col = *col + 1; @@ -1082,7 +1095,7 @@ nextCcwPointBottom(bitmap_type const bitmap, } RETURN_IF_FATAL(); - + *edge = NO_EDGE; } @@ -1124,7 +1137,7 @@ nextCcwPointLeft(bitmap_type const bitmap, } RETURN_IF_FATAL(); - + if ((*col >= 1 && *row + 1 < marked.height && !is_marked_edge(TOP, *row+1, *col-1, marked) && is_outline_edge(TOP, bitmap, *row+1, *col-1, color, exp))) { @@ -1144,6 +1157,8 @@ nextCcwPointLeft(bitmap_type const bitmap, *edge = NO_EDGE; } + + static void nextCounterClockwisePoint(bitmap_type const bitmap, edge_type * const edge, @@ -1158,18 +1173,18 @@ nextCounterClockwisePoint(bitmap_type const bitmap, case TOP: nextCcwPointTop( bitmap, edge, row, col, color, marked, exp, posP); break; - case RIGHT: + case RIGHT: nextCcwPointRight( bitmap, edge, row, col, color, marked, exp, posP); break; - case BOTTOM: + case BOTTOM: nextCcwPointBottom(bitmap, edge, row, col, color, marked, exp, posP); break; - case LEFT: + case LEFT: nextCcwPointLeft( bitmap, edge, row, col, color, marked, exp, posP); break; case NO_EDGE: break; - default: + default: *edge = NO_EDGE; break; } @@ -1218,7 +1233,7 @@ find_one_outline(bitmap_type const bitmap, pixel_outline_type outline; pm_pixelcoord pos; - + outline = new_pixel_outline(); outline.color = getBitmapColor(bitmap, originalRow, originalCol); @@ -1228,7 +1243,7 @@ find_one_outline(bitmap_type const bitmap, /* Set initial position */ pos.col = col + ((edge == RIGHT) || (edge == BOTTOM) ? 1 : 0); - pos.row = bitmap.height - row - 1 + + pos.row = bitmap.height - row - 1 + (edge == TOP || edge == RIGHT ? 1 : 0); do { @@ -1237,7 +1252,7 @@ find_one_outline(bitmap_type const bitmap, LOG2(" (%d,%d)", pos.col, pos.row); append_outline_pixel(&outline, pos); } - + mark_edge(edge, row, col, marked); nextPoint(bitmap, &edge, &row, &col, &pos, outline.color, clockwise, *marked, exp); @@ -1255,7 +1270,7 @@ find_one_outline(bitmap_type const bitmap, pixel_outline_list_type find_outline_pixels(bitmap_type const bitmap, bool const bg_spec, - pixel const bg_color, + pixel const bg_color, at_progress_func notify_progress, void * const progress_data, at_testcancel_func test_cancel, @@ -1273,16 +1288,16 @@ find_outline_pixels(bitmap_type const bitmap, to the list, marking the edges in it as we go. */ unsigned int const max_progress = bitmap.height * bitmap.width; - + pixel_outline_list_type outline_list; unsigned int row; bitmap_type marked; - + marked = new_bitmap (bitmap.width, bitmap.height); - + O_LIST_LENGTH(outline_list) = 0; outline_list.data = NULL; - + for (row = 0; row < bitmap.height; ++row) { unsigned int col; for (col = 0; col < bitmap.width; ++col) { @@ -1303,21 +1318,21 @@ find_outline_pixels(bitmap_type const bitmap, is_unmarked_outline_edge(row, col, TOP, bitmap, marked, color, exp)) { pixel_outline_type outline; - + CHECK_FATAL(); /* FREE(DONE) outline_list */ - + LOG1("#%u: (counterclockwise)", O_LIST_LENGTH(outline_list)); - + outline = find_one_outline(bitmap, TOP, row, col, &marked, false, false, exp); CHECK_FATAL(); /* FREE(DONE) outline_list */ - + O_CLOCKWISE(outline) = false; append_pixel_outline(&outline_list, outline); - + LOG1(" [%u].\n", O_LENGTH (outline)); } else - CHECK_FATAL (); /* FREE(DONE) outline_list */ + CHECK_FATAL (); /* FREE(DONE) outline_list */ /* A valid edge can be BOTTOM for an inside outline. Inside outlines are traced clockwise. @@ -1328,20 +1343,20 @@ find_outline_pixels(bitmap_type const bitmap, is_unmarked_outline_edge(row-1, col, BOTTOM, bitmap, marked, colorAbove,exp)) { CHECK_FATAL(); /* FREE(DONE) outline_list */ - + /* This lines are for debugging only:*/ if (is_background) { pixel_outline_type outline; - + LOG1("#%u: (clockwise)", O_LIST_LENGTH(outline_list)); - + outline = find_one_outline(bitmap, BOTTOM, row-1, col, &marked, true, false, exp); CHECK_FATAL(); /* FREE(DONE) outline_list */ - + O_CLOCKWISE(outline) = true; append_pixel_outline(&outline_list, outline); - + LOG1(" [%u].\n", O_LENGTH(outline)); } else { find_one_outline(bitmap, BOTTOM, row-1, col, @@ -1349,7 +1364,7 @@ find_outline_pixels(bitmap_type const bitmap, CHECK_FATAL(); /* FREE(DONE) outline_list */ } } else - CHECK_FATAL(); /* FREE(DONE) outline_list */ + CHECK_FATAL(); /* FREE(DONE) outline_list */ } if (test_cancel && test_cancel(testcancel_data)) { free_pixel_outline_list(&outline_list); @@ -1366,3 +1381,5 @@ find_outline_pixels(bitmap_type const bitmap, return outline_list; } + + diff --git a/converter/other/pamtosvg/pxl-outline.h b/converter/other/pamtosvg/pxl-outline.h index e37ccaf6..64e312cc 100644 --- a/converter/other/pamtosvg/pxl-outline.h +++ b/converter/other/pamtosvg/pxl-outline.h @@ -34,8 +34,8 @@ typedef struct after the last is the first, and the previous coordinate before the first is the last. */ #define O_NEXT(p_o, n) (((n) + 1) % O_LENGTH (p_o)) -#define O_PREV(p_o, n) ((n) == 0 \ - ? O_LENGTH (p_o) - 1 \ +#define O_PREV(p_o, n) ((n) == 0 \ + ? O_LENGTH (p_o) - 1 \ : (n) - 1) /* And the character turns into a list of such lists. */ @@ -55,7 +55,7 @@ typedef struct pixel_outline_list_type find_outline_pixels (bitmap_type const type, bool const bg_spec, - pixel const bg_color, + pixel const bg_color, at_progress_func notify_progress, void * const progress_data, at_testcancel_func test_cancel, @@ -65,7 +65,7 @@ find_outline_pixels (bitmap_type const type, /* Find all pixels on the center line of the character C. */ pixel_outline_list_type find_centerline_pixels (bitmap_type const type, - pixel const bg_color, + pixel const bg_color, at_progress_func notify_progress, void * const progress_data, at_testcancel_func test_cancel, diff --git a/converter/other/pamtosvg/spline.c b/converter/other/pamtosvg/spline.c index 6d867131..a62ce895 100644 --- a/converter/other/pamtosvg/spline.c +++ b/converter/other/pamtosvg/spline.c @@ -30,6 +30,7 @@ print_spline (FILE *f, spline_type s) } + /* Evaluate the spline S at a given T value. This is an implementation of de Casteljau's algorithm. See Schneider's thesis, p.37. The variable names are taken from there. */ @@ -64,6 +65,7 @@ evaluate_spline (spline_type s, float t) } + /* Return a new, empty, spline list. */ spline_list_type * @@ -76,6 +78,8 @@ new_spline_list (void) return answer; } + + spline_list_type empty_spline_list (void) { @@ -85,6 +89,8 @@ empty_spline_list (void) return answer; } + + /* Return a new spline list with SPLINE as the first element. */ spline_list_type * @@ -101,6 +107,7 @@ new_spline_list_with_spline (spline_type spline) } + /* Free the storage in a spline list. We don't have to free the elements, since they are arrays in automatic storage. And we don't want to free the list if it was empty. */ @@ -115,6 +122,7 @@ free_spline_list(spline_list_type spline_list) { } + /* Append the spline S to the list SPLINE_LIST. */ void @@ -128,6 +136,7 @@ append_spline (spline_list_type *l, spline_type s) } + /* Tack the elements in the list S2 onto the end of S1. S2 is not changed. */ @@ -149,6 +158,7 @@ concat_spline_lists (spline_list_type *s1, spline_list_type s2) } + /* Return a new, empty, spline list array. */ spline_list_array_type @@ -163,6 +173,7 @@ new_spline_list_array (void) } + /* Free the storage in a spline list array. We don't want to free the list if it is empty. */ void @@ -182,6 +193,7 @@ free_spline_list_array (spline_list_array_type *spline_list_array) } + /* Append the spline S to the list SPLINE_LIST_ARRAY. */ void @@ -192,3 +204,6 @@ append_spline_list (spline_list_array_type *l, spline_list_type s) SPLINE_LIST_ARRAY_LENGTH(*l)); LAST_SPLINE_LIST_ARRAY_ELT (*l) = s; } + + + diff --git a/converter/other/pamtosvg/thin-image.c b/converter/other/pamtosvg/thin-image.c index 364f67cc..ad15247f 100644 --- a/converter/other/pamtosvg/thin-image.c +++ b/converter/other/pamtosvg/thin-image.c @@ -27,78 +27,78 @@ #include "logreport.h" #include "message.h" #include "bitmap.h" - + #define PIXEL_SET(p, new) ((void)memcpy((p), (new), sizeof(Pixel))) #define PIXEL_EQUAL(p1, p2) \ ((p1)[0] == (p2)[0] && (p1)[1] == (p2)[1] && (p1)[2] == (p2)[2]) - -typedef unsigned char Pixel[3]; /* RGB pixel data type */ - - -void thin3(bitmap_type *image, Pixel colour); -void thin1(bitmap_type *image, unsigned char colour); - - -/* -------------------------------- ThinImage - Thin binary image. --------------------------- * - * - * Description: - * Thins the supplied binary image using Rosenfeld's parallel - * thinning algorithm. - * - * On Entry: - * image = Image to thin. - * - * -------------------------------------------------------------------------------------------- */ - - -/* Direction masks: */ -/* N S W E */ -static unsigned int masks[] = { 0200, 0002, 0040, 0010 }; - -/* True if pixel neighbor map indicates the pixel is 8-simple and */ -/* not an end point and thus can be deleted. The neighborhood */ -/* map is defined as an integer of bits abcdefghi with a non-zero */ -/* bit representing a non-zero pixel. The bit assignment for the */ -/* neighborhood is: */ -/* */ -/* a b c */ -/* d e f */ -/* g h i */ - -static unsigned char todelete[512] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + +typedef unsigned char Pixel[3]; /* RGB pixel data type */ + + +void thin3(bitmap_type *image, Pixel colour); +void thin1(bitmap_type *image, unsigned char colour); + + +/* -------------------------------- ThinImage - Thin binary image. --------------------------- * + * + * Description: + * Thins the supplied binary image using Rosenfeld's parallel + * thinning algorithm. + * + * On Entry: + * image = Image to thin. + * + * -------------------------------------------------------------------------------------------- */ + + +/* Direction masks: */ +/* N S W E */ +static unsigned int masks[] = { 0200, 0002, 0040, 0010 }; + +/* True if pixel neighbor map indicates the pixel is 8-simple and */ +/* not an end point and thus can be deleted. The neighborhood */ +/* map is defined as an integer of bits abcdefghi with a non-zero */ +/* bit representing a non-zero pixel. The bit assignment for the */ +/* neighborhood is: */ +/* */ +/* a b c */ +/* d e f */ +/* g h i */ + +static unsigned char todelete[512] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; static pixel background; @@ -106,268 +106,273 @@ static pixel background; void thin_image(bitmap_type *image, bool bgSpec, pixel bg, at_exception_type * exp) -{ - /* This is nasty as we need to call thin once for each - * colour in the image the way I do this is to keep a second - * copy of the bitmap and to use this to keep - * track of which colours have not yet been processed, - * trades time for pathological case memory.....*/ +{ + /* This is nasty as we need to call thin once for each + * colour in the image the way I do this is to keep a second + * copy of the bitmap and to use this to keep + * track of which colours have not yet been processed, + * trades time for pathological case memory.....*/ long m, n, num_pixels; - bitmap_type bm; + bitmap_type bm; unsigned int const spp = image->np; - unsigned int const width = image->width; - unsigned int const height = image->height; + unsigned int const width = image->width; + unsigned int const height = image->height; if (bgSpec) background = bg; - else + else PPM_ASSIGN(background, 255, 255, 255); /* Clone the image */ bm.height = image->height; bm.width = image->width; bm.np = image->np; - MALLOCARRAY(bm.bitmap, height * width * spp); + MALLOCARRAY(bm.bitmap, height * width * spp); if (bm.bitmap == NULL) pm_error("Unable to get memory for thin image bitmap clone"); - memcpy(bm.bitmap, image->bitmap, height * width * spp); + memcpy(bm.bitmap, image->bitmap, height * width * spp); num_pixels = height * width; switch (spp) { - case 3: - { - Pixel *ptr = (Pixel*)bm.bitmap; - Pixel bg_color; - bg_color[0] = PPM_GETR(background); - bg_color[1] = PPM_GETG(background); - bg_color[2] = PPM_GETB(background); - - for (n = num_pixels - 1; n >= 0L; --n) - { - Pixel p; - - PIXEL_SET(p, ptr[n]); - if (!PIXEL_EQUAL(p, bg_color)) - { - /* we have a new colour in the image */ - LOG3("Thinning colour (%x, %x, %x)\n", p[0], p[1], p[2]); - for (m = n - 1; m >= 0L; --m) - { - if (PIXEL_EQUAL(ptr[m], p)) - PIXEL_SET(ptr[m], bg_color); - } - thin3(image, p); - } - } - break; - } - - case 1: - { - unsigned char * const ptr = bm.bitmap; - unsigned char bg_color; - - if (PPM_ISGRAY(background)) + case 3: + { + Pixel *ptr = (Pixel*)bm.bitmap; + Pixel bg_color; + bg_color[0] = PPM_GETR(background); + bg_color[1] = PPM_GETG(background); + bg_color[2] = PPM_GETB(background); + + for (n = num_pixels - 1; n >= 0L; --n) + { + Pixel p; + + PIXEL_SET(p, ptr[n]); + if (!PIXEL_EQUAL(p, bg_color)) + { + /* we have a new colour in the image */ + LOG3("Thinning colour (%x, %x, %x)\n", p[0], p[1], p[2]); + for (m = n - 1; m >= 0L; --m) + { + if (PIXEL_EQUAL(ptr[m], p)) + PIXEL_SET(ptr[m], bg_color); + } + thin3(image, p); + } + } + break; + } + + case 1: + { + unsigned char * const ptr = bm.bitmap; + unsigned char bg_color; + + if (PPM_ISGRAY(background)) bg_color = PPM_GETR(background); - else + else bg_color = ppm_luminosity(background); - for (n = num_pixels - 1; n >= 0L; --n) - { - unsigned char c = ptr[n]; - if (c != bg_color) - { - LOG1 ("Thinning colour %x\n", c); - for (m = n - 1; m >= 0L; --m) - if (ptr[m] == c) ptr[m] = bg_color; - thin1(image, c); - } - } - break; - } - - default: - { - LOG1 ("thin_image: Don't know how to interpret %u-plane images", spp); - at_exception_fatal(exp, "thin_image: wrong plane images are passed"); - goto cleanup; - } + for (n = num_pixels - 1; n >= 0L; --n) + { + unsigned char c = ptr[n]; + if (c != bg_color) + { + LOG1 ("Thinning colour %x\n", c); + for (m = n - 1; m >= 0L; --m) + if (ptr[m] == c) ptr[m] = bg_color; + thin1(image, c); + } + } + break; + } + + default: + { + LOG1 ("thin_image: Don't know how to interpret %u-plane images", spp); + at_exception_fatal(exp, "thin_image: wrong plane images are passed"); + goto cleanup; + } } cleanup: - free (bm.bitmap); -} + free (bm.bitmap); +} + - -void thin3(bitmap_type *image, Pixel colour) -{ + +void thin3(bitmap_type *image, Pixel colour) +{ Pixel *ptr, *y_ptr, *y1_ptr; Pixel bg_color; - unsigned int xsize, ysize; /* Image resolution */ - unsigned int x, y; /* Pixel location */ - unsigned int i; /* Pass index */ - unsigned int pc = 0; /* Pass count */ - unsigned int count = 1; /* Deleted pixel count */ - unsigned int p, q; /* Neighborhood maps of adjacent*/ - /* cells */ - unsigned char *qb; /* Neighborhood maps of previous*/ - /* scanline */ - unsigned int m; /* Deletion direction mask */ - + unsigned int xsize, ysize; /* Image resolution */ + unsigned int x, y; /* Pixel location */ + unsigned int i; /* Pass index */ + unsigned int pc = 0; /* Pass count */ + unsigned int count = 1; /* Deleted pixel count */ + unsigned int p, q; /* Neighborhood maps of adjacent*/ + /* cells */ + unsigned char *qb; /* Neighborhood maps of previous*/ + /* scanline */ + unsigned int m; /* Deletion direction mask */ + bg_color[0] = PPM_GETR(background); bg_color[1] = PPM_GETG(background); bg_color[2] = PPM_GETB(background); - LOG (" Thinning image.....\n "); + LOG (" Thinning image.....\n "); xsize = image->width; ysize = image->height; - MALLOCARRAY_NOFAIL(qb, xsize); - qb[xsize-1] = 0; /* Used for lower-right pixel */ + MALLOCARRAY_NOFAIL(qb, xsize); + qb[xsize-1] = 0; /* Used for lower-right pixel */ ptr = (Pixel*)image->bitmap; - - while ( count ) { /* Scan image while deletions */ - pc++; - count = 0; - - for ( i = 0 ; i < 4 ; i++ ) { - - m = masks[i]; - - /* Build initial previous scan buffer. */ - p = PIXEL_EQUAL(ptr[0], colour); - for ( x = 0 ; x < xsize-1 ; x++ ) + + while ( count ) { /* Scan image while deletions */ + pc++; + count = 0; + + for ( i = 0 ; i < 4 ; i++ ) { + + m = masks[i]; + + /* Build initial previous scan buffer. */ + p = PIXEL_EQUAL(ptr[0], colour); + for ( x = 0 ; x < xsize-1 ; x++ ) qb[x] = (unsigned char) (p = ((p<<1)&0006) | (unsigned int) PIXEL_EQUAL(ptr[x+1], - colour)); - - /* Scan image for pixel deletion candidates. */ - y_ptr = ptr; y1_ptr = ptr + xsize; + colour)); + + /* Scan image for pixel deletion candidates. */ + y_ptr = ptr; y1_ptr = ptr + xsize; for (y = 0; y < ysize - 1; y++, y_ptr += xsize, y1_ptr += xsize) - { - q = qb[0]; - p = ((q<<2)&0330) | (unsigned int) PIXEL_EQUAL(y1_ptr[0], colour); - - for ( x = 0 ; x < xsize-1 ; x++ ) { - q = qb[x]; - p = ((p<<1)&0666) | ((q<<3)&0110) | - (unsigned int) PIXEL_EQUAL(y1_ptr[x+1], colour); - qb[x] = (unsigned char) p; - if ((i != 2 || x != 0) && ((p&m) == 0) && todelete[p] ) { - count++; /* delete the pixel */ - PIXEL_SET(y_ptr[x], bg_color); - } - } - - /* Process right edge pixel. */ - p = (p<<1)&0666; - if (i != 3 && (p&m) == 0 && todelete[p] ) { - count++; - PIXEL_SET(y_ptr[xsize-1], bg_color); - } - } - - if (i != 1) - { - /* Process bottom scan line. */ - q = qb[0]; - p = ((q<<2)&0330); + { + q = qb[0]; + p = ((q<<2)&0330) | (unsigned int) PIXEL_EQUAL(y1_ptr[0], colour); + + for ( x = 0 ; x < xsize-1 ; x++ ) { + q = qb[x]; + p = ((p<<1)&0666) | ((q<<3)&0110) | + (unsigned int) PIXEL_EQUAL(y1_ptr[x+1], colour); + qb[x] = (unsigned char) p; + if ((i != 2 || x != 0) && ((p&m) == 0) && todelete[p] ) { + count++; /* delete the pixel */ + PIXEL_SET(y_ptr[x], bg_color); + } + } + + /* Process right edge pixel. */ + p = (p<<1)&0666; + if (i != 3 && (p&m) == 0 && todelete[p] ) { + count++; + PIXEL_SET(y_ptr[xsize-1], bg_color); + } + } + + if (i != 1) + { + /* Process bottom scan line. */ + q = qb[0]; + p = ((q<<2)&0330); y_ptr = ptr + xsize * (ysize - 1); - for ( x = 0 ; x < xsize ; x++ ) { - q = qb[x]; - p = ((p<<1)&0666) | ((q<<3)&0110); - if ((i != 2 || x != 0) && (p&m) == 0 && todelete[p]) { - count++; + for ( x = 0 ; x < xsize ; x++ ) { + q = qb[x]; + p = ((p<<1)&0666) | ((q<<3)&0110); + if ((i != 2 || x != 0) && (p&m) == 0 && todelete[p]) { + count++; PIXEL_SET(y_ptr[x], bg_color); - } - } + } + } } - } - LOG2 ("ThinImage: pass %d, %d pixels deleted\n", pc, count); - } - free (qb); -} - - -void thin1(bitmap_type *image, unsigned char colour) -{ + } + LOG2 ("ThinImage: pass %d, %d pixels deleted\n", pc, count); + } + free (qb); +} + + + +void thin1(bitmap_type *image, unsigned char colour) +{ unsigned char *ptr, *y_ptr, *y1_ptr; unsigned char bg_color; - unsigned int xsize, ysize; /* Image resolution */ - unsigned int x, y; /* Pixel location */ - unsigned int i; /* Pass index */ - unsigned int pc = 0; /* Pass count */ - unsigned int count = 1; /* Deleted pixel count */ - unsigned int p, q; /* Neighborhood maps of adjacent*/ - /* cells */ - unsigned char *qb; /* Neighborhood maps of previous*/ - /* scanline */ - unsigned int m; /* Deletion direction mask */ + unsigned int xsize, ysize; /* Image resolution */ + unsigned int x, y; /* Pixel location */ + unsigned int i; /* Pass index */ + unsigned int pc = 0; /* Pass count */ + unsigned int count = 1; /* Deleted pixel count */ + unsigned int p, q; /* Neighborhood maps of adjacent*/ + /* cells */ + unsigned char *qb; /* Neighborhood maps of previous*/ + /* scanline */ + unsigned int m; /* Deletion direction mask */ if (PPM_ISGRAY(background)) bg_color = PPM_GETR(background); else bg_color = ppm_luminosity(background); - LOG (" Thinning image.....\n "); + LOG (" Thinning image.....\n "); xsize = image->width; ysize = image->height; - MALLOCARRAY_NOFAIL(qb, xsize); - qb[xsize-1] = 0; /* Used for lower-right pixel */ + MALLOCARRAY_NOFAIL(qb, xsize); + qb[xsize-1] = 0; /* Used for lower-right pixel */ ptr = image->bitmap; - - while ( count ) { /* Scan image while deletions */ - pc++; - count = 0; - - for ( i = 0 ; i < 4 ; i++ ) { - - m = masks[i]; - - /* Build initial previous scan buffer. */ - p = (ptr[0] == colour); - for ( x = 0 ; x < xsize-1 ; x++ ) - qb[x] = (unsigned char) (p = ((p<<1)&0006) | (unsigned int)(ptr[x+1] == colour)); - - /* Scan image for pixel deletion candidates. */ - y_ptr = ptr; y1_ptr = ptr + xsize; + + while ( count ) { /* Scan image while deletions */ + pc++; + count = 0; + + for ( i = 0 ; i < 4 ; i++ ) { + + m = masks[i]; + + /* Build initial previous scan buffer. */ + p = (ptr[0] == colour); + for ( x = 0 ; x < xsize-1 ; x++ ) + qb[x] = (unsigned char) (p = ((p<<1)&0006) | (unsigned int)(ptr[x+1] == colour)); + + /* Scan image for pixel deletion candidates. */ + y_ptr = ptr; y1_ptr = ptr + xsize; for (y = 0; y < ysize - 1; y++, y_ptr += xsize, y1_ptr += xsize) - { - q = qb[0]; - p = ((q<<2)&0330) | (y1_ptr[0] == colour); - - for ( x = 0 ; x < xsize-1 ; x++ ) { - q = qb[x]; - p = ((p<<1)&0666) | ((q<<3)&0110) | (unsigned int) (y1_ptr[x+1]==colour); - qb[x] = (unsigned char) p; - if ( ((p&m) == 0) && todelete[p] ) { - count++; - y_ptr[x] = bg_color; /* delete the pixel */ - } - } - - /* Process right edge pixel. */ - p = (p<<1)&0666; - if ( (p&m) == 0 && todelete[p] ) { - count++; + { + q = qb[0]; + p = ((q<<2)&0330) | (y1_ptr[0] == colour); + + for ( x = 0 ; x < xsize-1 ; x++ ) { + q = qb[x]; + p = ((p<<1)&0666) | ((q<<3)&0110) | (unsigned int) (y1_ptr[x+1]==colour); + qb[x] = (unsigned char) p; + if ( ((p&m) == 0) && todelete[p] ) { + count++; + y_ptr[x] = bg_color; /* delete the pixel */ + } + } + + /* Process right edge pixel. */ + p = (p<<1)&0666; + if ( (p&m) == 0 && todelete[p] ) { + count++; y_ptr[xsize-1] = bg_color; - } - } - - /* Process bottom scan line. */ - q = qb[0]; - p = ((q<<2)&0330); - - y_ptr = ptr + xsize * (ysize - 1); - for ( x = 0 ; x < xsize ; x++ ) { - q = qb[x]; - p = ((p<<1)&0666) | ((q<<3)&0110); - if ( (p&m) == 0 && todelete[p] ) { - count++; + } + } + + /* Process bottom scan line. */ + q = qb[0]; + p = ((q<<2)&0330); + + y_ptr = ptr + xsize * (ysize - 1); + for ( x = 0 ; x < xsize ; x++ ) { + q = qb[x]; + p = ((p<<1)&0666) | ((q<<3)&0110); + if ( (p&m) == 0 && todelete[p] ) { + count++; y_ptr[x] = bg_color; - } - } - } - LOG2("thin1: pass %d, %d pixels deleted\n", pc, count); - } - free (qb); -} + } + } + } + LOG2("thin1: pass %d, %d pixels deleted\n", pc, count); + } + free (qb); +} + + + diff --git a/converter/other/pamtosvg/vector.c b/converter/other/pamtosvg/vector.c index 8972f4a5..a02b933b 100644 --- a/converter/other/pamtosvg/vector.c +++ b/converter/other/pamtosvg/vector.c @@ -271,6 +271,7 @@ vector_horizontal(void) { } + Vector vector_zero(void) { @@ -284,6 +285,7 @@ vector_zero(void) { } + bool vector_equal(Vector const comparand, Vector const comparator) { |