Annotation of OpenXM_contrib2/asir2000/plot/smoothing.c, Revision 1.1
1.1 ! takayama 1: /* $OpenXM$ */
! 2: #include "ca.h"
! 3: #include "parse.h"
! 4: #include "ox.h"
! 5: #include "ifplot.h"
! 6: #include "cursor.h"
! 7:
! 8: #define MAG 1
! 9: #define PRINT_XOFFSET 100
! 10: #define PRINT_YOFFSET 100
! 11:
! 12: struct polyLine {
! 13: int numberOfSegments;
! 14: int limit;
! 15: int *x;
! 16: int *y;
! 17: };
! 18:
! 19: static FILE *Fp = NULL;
! 20:
! 21: static void *gcmalloc(int a);
! 22: static struct polyLine *polyLine_new(void);
! 23: static struct polyLine *polyLine_addNewSegment(struct polyLine *pl,
! 24: int x,int y);
! 25: static int polyLine_lastY(struct polyLine *pl);
! 26: static void polyLine_outputPS(struct polyLine *pl);
! 27: static void polyLine_outputProlog(int xmin, int ymin, int xmax, int ymax);
! 28: static void polyLine_outputEpilog(void);
! 29: static void polyLine_error(char *s);
! 30: #define translateX(x) (x*MAG+PRINT_XOFFSET)
! 31: #define translateY(y) (y*MAG+PRINT_YOFFSET)
! 32: /* #define translateY(y) ((Ysize-y)*MAG+PRINT_YOFFSET) */
! 33: #define IS_DOT != 0
! 34: #define IS_POLYLINE > -1
! 35: #define YES 1
! 36: #define NO 0
! 37:
! 38:
! 39: static int Xsize = 0;
! 40: static int Ysize = 0;
! 41: static int updatePolyLine(struct polyLine *pl[], int plSize,
! 42: int prev[], int Curr[], int x);
! 43:
! 44: static void *gcmalloc(a) {
! 45: void *m;
! 46: /* BUG: interruption must be locked. */
! 47: m = (void *) GC_malloc(a);
! 48: if (m == NULL) polyLine_error("no memory");
! 49: return(m);
! 50: }
! 51:
! 52: #define MINIMAL_POLYLINE_SIZE 10
! 53: static struct polyLine *polyLine_new_with_size(int size) {
! 54: struct polyLine *pl;
! 55: pl = (struct polyLine *)gcmalloc(sizeof(struct polyLine));
! 56: pl-> limit = (size > 0? size: 1);
! 57: pl-> numberOfSegments = 0;
! 58: pl->x = (int *)gcmalloc(sizeof(int)*(pl->limit));
! 59: pl->y = (int *)gcmalloc(sizeof(int)*(pl->limit));
! 60: return(pl);
! 61: }
! 62:
! 63: static struct polyLine *polyLine_new(void) {
! 64: return( polyLine_new_with_size(MINIMAL_POLYLINE_SIZE));
! 65: }
! 66:
! 67: static struct polyLine *polyLine_addNewSegment(struct polyLine *pl,
! 68: int x,int y) {
! 69: int n,limit,i;
! 70: struct polyLine *new_pl;
! 71: limit = pl->limit;
! 72: n = pl->numberOfSegments;
! 73: if (n >= limit) {
! 74: new_pl = polyLine_new_with_size( 2*limit );
! 75: new_pl -> numberOfSegments = pl->numberOfSegments;
! 76: for (i=0; i<pl->numberOfSegments; i++) {
! 77: new_pl->x[i] = pl->x[i];
! 78: new_pl->y[i] = pl->y[i];
! 79: }
! 80: pl = new_pl;
! 81: }
! 82: pl->numberOfSegments++;
! 83: pl->x[n] = x;
! 84: pl->y[n] = y;
! 85: return(pl);
! 86: }
! 87:
! 88: static int polyLine_lastY(struct polyLine *pl) {
! 89: int n;
! 90: n = pl->numberOfSegments;
! 91: if (n == 0) {
! 92: polyLine_error("polyLine_lastY: empty polyLine.");
! 93: }
! 94: return(pl->y[n-1]);
! 95: }
! 96:
! 97:
! 98: static void polyLine_outputPS(struct polyLine *pl) {
! 99: int n,i;
! 100: n = pl->numberOfSegments;
! 101: if (n == 1) {
! 102: fprintf(Fp," %d %d ifplot_putpixel\n",translateX(pl->x[0]),translateY(pl->y[0]));
! 103: }else if (n > 1) {
! 104: fprintf(Fp," newpath ");
! 105: for (i=0; i<n; i++) {
! 106: fprintf(Fp," %d %d ",translateX(pl->x[i]),translateY(pl->y[i]));
! 107: if (i==0) fprintf(Fp," moveto ");
! 108: else fprintf(Fp," lineto ");
! 109: }
! 110: fprintf(Fp," stroke\n");
! 111: }
! 112: fflush(Fp);
! 113: }
! 114: static void polyLine_outputProlog(int xmin, int ymin,int xmax, int ymax) {
! 115: fprintf(Fp,"%%!PS-Adobe-1.0\n");
! 116: fprintf(Fp,"%%%%BoundingBox: %d %d %d %d \n",
! 117: PRINT_XOFFSET+xmin*MAG,PRINT_YOFFSET+ymin*MAG,
! 118: PRINT_XOFFSET+xmax*MAG, PRINT_YOFFSET+ymax*MAG);
! 119: fprintf(Fp,"%%%%Creator: This is generated by ifplot\n");
! 120: fprintf(Fp,"%%%%Title: ifplot\n");
! 121: fprintf(Fp,"%%%%EndComments: \n");
! 122: fprintf(Fp,"/ifplot_putpixel { \n");
! 123: fprintf(Fp," /yyy 2 1 roll def /xxx 2 1 roll def \n");
! 124: fprintf(Fp," gsave newpath xxx yyy .5 0 360 arc \n");
! 125: fprintf(Fp," fill grestore \n");
! 126: fprintf(Fp,"} def \n");
! 127: fflush(Fp);
! 128: }
! 129: static void polyLine_outputEpilog(void) {
! 130: fprintf(Fp,"showpage \n"); fflush(Fp);
! 131: }
! 132: static void polyLine_error(char *s) {
! 133: fprintf(stderr,"Error in smoothing: %s\n",s);
! 134: exit(-1);
! 135: }
! 136: static int updatePolyLine(struct polyLine *pl[], int plSize,
! 137: int prev[], int curr[],int x) {
! 138: /* 1 <= y <= Ysize , curr[0], curr[Ysize+1] = 0 , i=y .
! 139: prev = {-1, -1, -1, 0, 1, -1, 2, -1} -1: no polyLine. 0:pl[0], 1:pl[1],
! 140: curr = {0, 1, 0, 1, 1, 1, 0, 0} 0: no dot, 1: dot.
! 141: */
! 142: /* Return Value: plSize, pl, prev */
! 143: int i;
! 144: static int *prevHasNext = NULL;
! 145: static struct polyLine **tmpPl = NULL;
! 146: static struct polyLine **newPl = NULL;
! 147: int tmpPlSize = 0;
! 148: static int *tmpPrev = NULL;
! 149: int newPlSize = 0;
! 150: extern int Ysize;
! 151: if (prevHasNext == NULL) prevHasNext = (int *)gcmalloc(sizeof(int)*(Ysize+2));
! 152: if (tmpPl == NULL)
! 153: tmpPl = (struct polyLine **)gcmalloc(sizeof(struct polyLine *)*(Ysize+2));
! 154: if (newPl == NULL)
! 155: newPl = (struct polyLine **)gcmalloc(sizeof(struct polyLine *)*(Ysize+2));
! 156: if (tmpPrev == NULL) tmpPrev = (int *)gcmalloc(sizeof(int)*(Ysize+2));
! 157: for (i=0; i<Ysize+2; i++) {
! 158: prevHasNext[i] = NO; newPl[i] = NULL; tmpPl[i] = NULL;
! 159: tmpPrev[i] = -1;
! 160: }
! 161: prev[0] = prev[Ysize+1] = -1;
! 162: for (i=1; i <= Ysize; i++) {
! 163: if (curr[i] IS_DOT) {
! 164: if (prev[i-1] IS_POLYLINE && !prevHasNext[i-1]) {
! 165: pl[prev[i-1]] = polyLine_addNewSegment(pl[prev[i-1]],x,i);
! 166: prevHasNext[i-1] = YES;
! 167: }else if (prev[i] IS_POLYLINE && !prevHasNext[i]) {
! 168: pl[prev[i]] = polyLine_addNewSegment(pl[prev[i]],x,i);
! 169: prevHasNext[i] = YES;
! 170: }else if (prev[i+1] IS_POLYLINE && !prevHasNext[i+1]) {
! 171: pl[prev[i+1]] = polyLine_addNewSegment(pl[prev[i+1]],x,i);
! 172: prevHasNext[i+1] = YES;
! 173: }else{
! 174: newPl[newPlSize] = polyLine_new();
! 175: newPl[newPlSize] = polyLine_addNewSegment(newPl[newPlSize],x,i);
! 176: newPlSize++;
! 177: }
! 178: }
! 179: }
! 180: for (i=1; i<=Ysize; i++) {
! 181: if (prevHasNext[i] == NO && prev[i] IS_POLYLINE) {
! 182: polyLine_outputPS(pl[prev[i]]);
! 183: }
! 184: }
! 185:
! 186: /* generate new pl and new prev */
! 187: tmpPlSize = 0; tmpPrev[0] = tmpPrev[Ysize+1] = -1;
! 188: for (i = 1; i<=Ysize; i++) {
! 189: if (prevHasNext[i] == YES) {
! 190: tmpPl[tmpPlSize] = pl[prev[i]];
! 191: tmpPrev[polyLine_lastY(pl[prev[i]])] = tmpPlSize;
! 192: tmpPlSize++;
! 193: }
! 194: }
! 195: for (i=0; i<newPlSize; i++) {
! 196: tmpPl[tmpPlSize] = newPl[i];
! 197: tmpPrev[polyLine_lastY(newPl[i])] = tmpPlSize;
! 198: tmpPlSize++;
! 199: }
! 200:
! 201: /* copy and update for the next step. */
! 202: for (i=0; i< Ysize+2; i++) {
! 203: prev[i] = tmpPrev[i];
! 204: }
! 205: for (i=0; i<tmpPlSize; i++) {
! 206: pl[i] = tmpPl[i];
! 207: }
! 208: return(tmpPlSize);
! 209: }
! 210:
! 211: /*
! 212: #define TEST_YSIZE 12
! 213: #define TEST_XSIZE 5
! 214: generatePS_from_image(FILE *fp) {
! 215: int image_test[TEST_XSIZE][TEST_YSIZE] =
! 216: {{0,0,1,0,0,0,0,0,0,0,0,0},
! 217: {0,1,0,1,0,0,0,0,0,1,0,0},
! 218: {0,1,0,1,1,0,0,0,1,0,1,0},
! 219: {0,0,1,0,0,0,0,0,0,1,0,1},
! 220: {0,0,0,0,0,0,1,0,0,1,0,0}};
! 221: struct polyLine **pl;
! 222: int plSize = 0;
! 223: int *prev;
! 224: int *curr;
! 225: int i,x,y;
! 226:
! 227: Xsize = TEST_XSIZE;
! 228: Ysize = TEST_YSIZE;
! 229: pl = (struct polyLine **)gcmalloc(sizeof(struct polyLine *)*(Ysize+2));
! 230: prev = (int *)gcmalloc(sizeof(int)*(Ysize+2));
! 231: curr = (int *)gcmalloc(sizeof(int)*(Ysize+2));
! 232: Fp = fp;
! 233: polyLine_outputProlog(0,0,Xsize,Ysize);
! 234: for (i=0; i<= Ysize+1; i++) {
! 235: prev[i] = -1;
! 236: }
! 237: for (x=0; x<Xsize; x++) {
! 238: curr[0] = curr[Ysize+1] = 0;
! 239: for (y=0; y<Ysize; y++) {
! 240: if (image_test[x][y]) curr[y+1]=1;
! 241: else curr[y+1] = 0;
! 242: }
! 243: plSize = updatePolyLine(pl,plSize,prev,curr,x);
! 244: }
! 245: for (y=0; y<Ysize+2; y++) {
! 246: curr[y] = 0;
! 247: }
! 248: plSize = updatePolyLine(pl,plSize,prev,curr,Xsize);
! 249: polyLine_outputEpilog();
! 250: }
! 251: main() {
! 252: generatePS_from_image(stdout);
! 253: }
! 254:
! 255: */
! 256:
! 257: generatePS_from_image(FILE *fp,XImage *image,int xsize, int ysize,
! 258: int color[],int colorSize) {
! 259: struct polyLine **pl;
! 260: int plSize = 0;
! 261: int *prev;
! 262: int *curr;
! 263: int i,x,y,c;
! 264:
! 265: Xsize = xsize;
! 266: Ysize = ysize;
! 267: pl = (struct polyLine **)gcmalloc(sizeof(struct polyLine *)*(Ysize+2));
! 268: prev = (int *)gcmalloc(sizeof(int)*(Ysize+2));
! 269: curr = (int *)gcmalloc(sizeof(int)*(Ysize+2));
! 270: Fp = fp;
! 271: polyLine_outputProlog(0,0,Xsize,Ysize);
! 272: for (c=0; c<colorSize; c++) {
! 273: /* Set color if necessary */
! 274: for (i=0; i<= Ysize+1; i++) {
! 275: prev[i] = -1;
! 276: }
! 277: for (x=0; x<Xsize; x++) {
! 278: curr[0] = curr[Ysize+1] = 0;
! 279: for (y=0; y<Ysize; y++) {
! 280: if ((int) XGetPixel(image,x,y) == color[c]) curr[y+1]=1;
! 281: else curr[y+1] = 0;
! 282: }
! 283: plSize = updatePolyLine(pl,plSize,prev,curr,x);
! 284: }
! 285: for (y=0; y<Ysize+2; y++) {
! 286: curr[y] = 0;
! 287: }
! 288: plSize = updatePolyLine(pl,plSize,prev,curr,Xsize);
! 289: }
! 290: polyLine_outputEpilog();
! 291: }
! 292:
! 293:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>