[BACK]Return to smoothing.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / plot

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>