[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.2

1.2     ! takayama    1: /* $OpenXM: OpenXM_contrib2/asir2000/plot/smoothing.c,v 1.1 2000/10/15 06:56:53 takayama Exp $ */
1.1       takayama    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:
1.2     ! takayama   44: static void polyLine_outputPS_dashed_line(int x0,int y0,int x1,int y1);
        !            45: static int polyLine_pline(struct canvas *can);
        !            46:
        !            47:
1.1       takayama   48: static void *gcmalloc(a)  {
                     49:   void *m;
                     50:   /* BUG:  interruption must be locked. */
                     51:   m = (void *) GC_malloc(a);
                     52:   if (m == NULL) polyLine_error("no memory");
                     53:   return(m);
                     54: }
                     55:
                     56: #define MINIMAL_POLYLINE_SIZE  10
                     57: static struct polyLine *polyLine_new_with_size(int size) {
                     58:   struct polyLine *pl;
                     59:   pl = (struct polyLine *)gcmalloc(sizeof(struct polyLine));
                     60:   pl-> limit = (size > 0? size: 1);
                     61:   pl-> numberOfSegments = 0;
                     62:   pl->x = (int *)gcmalloc(sizeof(int)*(pl->limit));
                     63:   pl->y = (int *)gcmalloc(sizeof(int)*(pl->limit));
                     64:   return(pl);
                     65: }
                     66:
                     67: static struct polyLine *polyLine_new(void) {
                     68:   return( polyLine_new_with_size(MINIMAL_POLYLINE_SIZE));
                     69: }
                     70:
                     71: static struct polyLine *polyLine_addNewSegment(struct polyLine *pl,
                     72:                                                                                                int x,int y) {
                     73:   int n,limit,i;
                     74:   struct polyLine *new_pl;
                     75:   limit = pl->limit;
                     76:   n = pl->numberOfSegments;
                     77:   if (n >= limit) {
                     78:        new_pl = polyLine_new_with_size( 2*limit );
                     79:        new_pl -> numberOfSegments = pl->numberOfSegments;
                     80:        for (i=0; i<pl->numberOfSegments; i++) {
                     81:          new_pl->x[i] = pl->x[i];
                     82:          new_pl->y[i] = pl->y[i];
                     83:        }
                     84:        pl = new_pl;
                     85:   }
                     86:   pl->numberOfSegments++;
                     87:   pl->x[n] = x;
                     88:   pl->y[n] = y;
                     89:   return(pl);
                     90: }
                     91:
                     92: static int polyLine_lastY(struct polyLine *pl) {
                     93:   int n;
                     94:   n = pl->numberOfSegments;
                     95:   if (n == 0) {
                     96:        polyLine_error("polyLine_lastY:  empty polyLine.");
                     97:   }
                     98:   return(pl->y[n-1]);
                     99: }
                    100:
                    101:
                    102: static void polyLine_outputPS(struct polyLine *pl) {
                    103:   int n,i;
                    104:   n = pl->numberOfSegments;
                    105:   if (n == 1) {
                    106:        fprintf(Fp," %d %d ifplot_putpixel\n",translateX(pl->x[0]),translateY(pl->y[0]));
                    107:   }else if (n > 1) {
                    108:        fprintf(Fp," newpath ");
                    109:        for (i=0; i<n; i++) {
                    110:          fprintf(Fp," %d %d ",translateX(pl->x[i]),translateY(pl->y[i]));
                    111:          if (i==0) fprintf(Fp," moveto ");
                    112:          else fprintf(Fp," lineto ");
                    113:        }
                    114:        fprintf(Fp," stroke\n");
                    115:   }
                    116:   fflush(Fp);
                    117: }
                    118: static void polyLine_outputProlog(int xmin, int ymin,int xmax, int ymax) {
                    119:   fprintf(Fp,"%%!PS-Adobe-1.0\n");
                    120:   fprintf(Fp,"%%%%BoundingBox: %d %d %d %d \n",
                    121:                  PRINT_XOFFSET+xmin*MAG,PRINT_YOFFSET+ymin*MAG,
                    122:                  PRINT_XOFFSET+xmax*MAG, PRINT_YOFFSET+ymax*MAG);
                    123:   fprintf(Fp,"%%%%Creator: This is generated by ifplot\n");
                    124:   fprintf(Fp,"%%%%Title: ifplot\n");
                    125:   fprintf(Fp,"%%%%EndComments: \n");
                    126:   fprintf(Fp,"/ifplot_putpixel {  \n");
                    127:   fprintf(Fp,"    /yyy 2 1 roll def /xxx 2 1 roll def \n");
                    128:   fprintf(Fp,"    gsave newpath xxx yyy .5 0 360 arc \n");
                    129:   fprintf(Fp,"    fill grestore \n");
                    130:   fprintf(Fp,"} def \n");
                    131:   fflush(Fp);
                    132: }
                    133: static void polyLine_outputEpilog(void) {
                    134:   fprintf(Fp,"showpage \n"); fflush(Fp);
                    135: }
                    136: static void polyLine_error(char *s) {
                    137:   fprintf(stderr,"Error in smoothing: %s\n",s);
                    138:   exit(-1);
                    139: }
                    140: static int updatePolyLine(struct polyLine *pl[], int plSize,
                    141:                                                  int prev[], int curr[],int x) {
                    142:   /*  1 <= y <= Ysize ,  curr[0], curr[Ysize+1]  = 0 ,  i=y .
                    143:          prev = {-1, -1, -1, 0, 1, -1, 2, -1}  -1: no polyLine. 0:pl[0], 1:pl[1],
                    144:          curr = {0,  1,  0,  1, 1, 1,  0, 0}    0: no dot, 1: dot.
                    145:   */
                    146:   /* Return Value:  plSize, pl, prev */
                    147:   int i;
                    148:   static int *prevHasNext = NULL;
                    149:   static struct polyLine **tmpPl = NULL;
                    150:   static struct polyLine **newPl = NULL;
                    151:   int tmpPlSize = 0;
                    152:   static int *tmpPrev = NULL;
                    153:   int newPlSize = 0;
                    154:   extern int Ysize;
                    155:   if (prevHasNext == NULL) prevHasNext = (int *)gcmalloc(sizeof(int)*(Ysize+2));
                    156:   if (tmpPl == NULL)
                    157:        tmpPl = (struct polyLine **)gcmalloc(sizeof(struct polyLine *)*(Ysize+2));
                    158:   if (newPl == NULL)
                    159:        newPl = (struct polyLine **)gcmalloc(sizeof(struct polyLine *)*(Ysize+2));
                    160:   if (tmpPrev == NULL) tmpPrev = (int *)gcmalloc(sizeof(int)*(Ysize+2));
                    161:   for (i=0; i<Ysize+2; i++) {
                    162:        prevHasNext[i] = NO; newPl[i] = NULL; tmpPl[i] = NULL;
                    163:        tmpPrev[i] = -1;
                    164:   }
                    165:   prev[0] = prev[Ysize+1] = -1;
                    166:   for (i=1; i <= Ysize; i++) {
                    167:        if (curr[i] IS_DOT) {
                    168:          if (prev[i-1] IS_POLYLINE && !prevHasNext[i-1]) {
                    169:                pl[prev[i-1]] = polyLine_addNewSegment(pl[prev[i-1]],x,i);
                    170:                prevHasNext[i-1] = YES;
                    171:          }else if (prev[i] IS_POLYLINE && !prevHasNext[i]) {
                    172:                pl[prev[i]] = polyLine_addNewSegment(pl[prev[i]],x,i);
                    173:                prevHasNext[i] = YES;
                    174:          }else if (prev[i+1] IS_POLYLINE && !prevHasNext[i+1]) {
                    175:                pl[prev[i+1]] = polyLine_addNewSegment(pl[prev[i+1]],x,i);
                    176:                prevHasNext[i+1] = YES;
                    177:          }else{
                    178:                newPl[newPlSize] = polyLine_new();
                    179:                newPl[newPlSize] = polyLine_addNewSegment(newPl[newPlSize],x,i);
                    180:                newPlSize++;
                    181:          }
                    182:        }
                    183:   }
                    184:   for (i=1; i<=Ysize; i++) {
                    185:        if (prevHasNext[i] == NO && prev[i] IS_POLYLINE) {
                    186:          polyLine_outputPS(pl[prev[i]]);
                    187:        }
                    188:   }
                    189:
                    190:   /* generate new pl and new prev */
                    191:   tmpPlSize = 0; tmpPrev[0] = tmpPrev[Ysize+1] = -1;
                    192:   for (i = 1; i<=Ysize; i++) {
                    193:        if (prevHasNext[i] == YES) {
                    194:          tmpPl[tmpPlSize] = pl[prev[i]];
                    195:          tmpPrev[polyLine_lastY(pl[prev[i]])] = tmpPlSize;
                    196:          tmpPlSize++;
                    197:        }
                    198:   }
                    199:   for (i=0; i<newPlSize; i++) {
                    200:        tmpPl[tmpPlSize] = newPl[i];
                    201:        tmpPrev[polyLine_lastY(newPl[i])] = tmpPlSize;
                    202:        tmpPlSize++;
                    203:   }
                    204:
                    205:   /* copy and update for the next step.  */
                    206:   for (i=0; i< Ysize+2; i++) {
                    207:        prev[i] = tmpPrev[i];
                    208:   }
                    209:   for (i=0; i<tmpPlSize; i++) {
                    210:        pl[i] = tmpPl[i];
                    211:   }
                    212:   return(tmpPlSize);
                    213: }
                    214:
                    215: /*
                    216: #define TEST_YSIZE 12
                    217: #define TEST_XSIZE 5
                    218: generatePS_from_image(FILE *fp) {
                    219:   int image_test[TEST_XSIZE][TEST_YSIZE] =
                    220:                           {{0,0,1,0,0,0,0,0,0,0,0,0},
                    221:                            {0,1,0,1,0,0,0,0,0,1,0,0},
                    222:                            {0,1,0,1,1,0,0,0,1,0,1,0},
                    223:                            {0,0,1,0,0,0,0,0,0,1,0,1},
                    224:                            {0,0,0,0,0,0,1,0,0,1,0,0}};
                    225:   struct polyLine **pl;
                    226:   int plSize = 0;
                    227:   int *prev;
                    228:   int *curr;
                    229:   int i,x,y;
                    230:
                    231:   Xsize = TEST_XSIZE;
                    232:   Ysize = TEST_YSIZE;
                    233:   pl = (struct polyLine **)gcmalloc(sizeof(struct polyLine *)*(Ysize+2));
                    234:   prev = (int *)gcmalloc(sizeof(int)*(Ysize+2));
                    235:   curr = (int *)gcmalloc(sizeof(int)*(Ysize+2));
                    236:   Fp = fp;
                    237:   polyLine_outputProlog(0,0,Xsize,Ysize);
                    238:   for (i=0; i<= Ysize+1; i++) {
                    239:        prev[i] = -1;
                    240:   }
                    241:   for (x=0; x<Xsize; x++) {
                    242:        curr[0] = curr[Ysize+1] = 0;
                    243:        for (y=0; y<Ysize; y++) {
                    244:          if (image_test[x][y]) curr[y+1]=1;
                    245:          else curr[y+1] = 0;
                    246:        }
                    247:        plSize = updatePolyLine(pl,plSize,prev,curr,x);
                    248:   }
                    249:   for (y=0; y<Ysize+2; y++) {
                    250:        curr[y] = 0;
                    251:   }
                    252:   plSize = updatePolyLine(pl,plSize,prev,curr,Xsize);
                    253:   polyLine_outputEpilog();
                    254: }
                    255: main() {
                    256:   generatePS_from_image(stdout);
                    257: }
                    258:
                    259: */
1.2     ! takayama  260: static void polyLine_outputPS_dashed_line(int x0,int y0,int x1,int y1) {
        !           261:   extern FILE *Fp;
        !           262:   fprintf(Fp," gsave [3] 0 setdash newpath \n");
        !           263:   fprintf(Fp," %d %d moveto %d %d lineto stroke \n",x0,y0,x1,y1);
        !           264:   fprintf(Fp," stroke grestore \n");
        !           265: }
        !           266:
        !           267: #define D 5
        !           268: static int polyLine_pline(can)
        !           269: struct canvas *can;
        !           270: {
        !           271:        double w,w1,k,e,n;
        !           272:        int x0,y0,x,y,xadj,yadj;
        !           273:        char buf[BUFSIZ];
        !           274:        double adjust_scale();
        !           275:
        !           276:        if ( can->noaxis )
        !           277:                return;
        !           278:
        !           279:        xadj = yadj = 0;
        !           280:        if ( (can->xmin < 0) && (can->xmax > 0) ) {
        !           281:                x0 = (int)((can->width-1)*(-can->xmin/(can->xmax-can->xmin)));
        !           282:                polyLine_outputPS_dashed_line(translateX(x0),translateY(0),
        !           283:                                                                          translateX(x0),translateY(can->height));
        !           284:        } else if ( can->xmin >= 0 )
        !           285:                x0 = 0;
        !           286:        else
        !           287:                x0 = can->width-1-D;
        !           288:        if ( (can->ymin < 0) && (can->ymax > 0) ) {
        !           289:                y0 = (int)((can->height-1)*(can->ymax/(can->ymax-can->ymin)));
        !           290:                polyLine_outputPS_dashed_line(translateX(0),translateY(y0),
        !           291:                                                                          translateX(can->width),translateY(y0));
        !           292:        } else if ( can->ymin >= 0 )
        !           293:                y0 = can->height-1;
        !           294:        else
        !           295:                y0 = D;
        !           296:        /* BUG:  not written yet a code for PS.
        !           297:        w = can->xmax-can->xmin;
        !           298:        w1 = w * DEFAULTWIDTH/can->width;
        !           299:        e = adjust_scale(EXP10(floor(log10(w1))),w1);
        !           300:        for ( n = ceil(can->xmin/e); n*e<= can->xmax; n++ ) {
        !           301:                x = (int)can->width*(n*e-can->xmin)/w;
        !           302:                DRAWLINE(display,d,drawGC,x,y0,x,y0-D);
        !           303:                sprintf(buf,"%g",n*e);
        !           304:                DRAWSTRING(display,d,scaleGC,x+2,y0,buf,strlen(buf));
        !           305:        }
        !           306:        w = can->ymax-can->ymin;
        !           307:        w1 = w * DEFAULTHEIGHT/can->height;
        !           308:        e = adjust_scale(EXP10(floor(log10(w1))),w1);
        !           309:        for ( n = ceil(can->ymin/e); n*e<= can->ymax; n++ ) {
        !           310:                y = (int)can->height*(1-(n*e-can->ymin)/w);
        !           311:                DRAWLINE(display,d,drawGC,x0,y,x0+D,y);
        !           312:                sprintf(buf,"%g",n*e);
        !           313:                if ( can->xmax <= 0 )
        !           314:                        xadj = TEXTWIDTH(sffs,buf,strlen(buf));
        !           315:                DRAWSTRING(display,d,scaleGC,x0-xadj,y,buf,strlen(buf));
        !           316:        }
        !           317:        */
        !           318: }
1.1       takayama  319:
                    320: generatePS_from_image(FILE *fp,XImage *image,int xsize, int ysize,
1.2     ! takayama  321:                                          int color[],int colorSize,
        !           322:                                          struct canvas *can) {
1.1       takayama  323:   struct polyLine **pl;
                    324:   int plSize = 0;
                    325:   int *prev;
                    326:   int *curr;
                    327:   int i,x,y,c;
                    328:
                    329:   Xsize = xsize;
                    330:   Ysize = ysize;
                    331:   pl = (struct polyLine **)gcmalloc(sizeof(struct polyLine *)*(Ysize+2));
                    332:   prev = (int *)gcmalloc(sizeof(int)*(Ysize+2));
                    333:   curr = (int *)gcmalloc(sizeof(int)*(Ysize+2));
                    334:   Fp = fp;
                    335:   polyLine_outputProlog(0,0,Xsize,Ysize);
                    336:   for (c=0; c<colorSize; c++) {
                    337:        /* Set color if necessary */
                    338:        for (i=0; i<= Ysize+1; i++) {
                    339:          prev[i] = -1;
                    340:        }
                    341:        for (x=0; x<Xsize; x++) {
                    342:          curr[0] = curr[Ysize+1] = 0;
                    343:          for (y=0; y<Ysize; y++) {
                    344:                if ((int) XGetPixel(image,x,y) == color[c]) curr[y+1]=1;
                    345:                else curr[y+1] = 0;
                    346:          }
                    347:          plSize = updatePolyLine(pl,plSize,prev,curr,x);
                    348:        }
                    349:        for (y=0; y<Ysize+2; y++) {
                    350:          curr[y] = 0;
                    351:        }
                    352:        plSize = updatePolyLine(pl,plSize,prev,curr,Xsize);
                    353:   }
1.2     ! takayama  354:   polyLine_pline(can);
1.1       takayama  355:   polyLine_outputEpilog();
                    356: }
1.2     ! takayama  357:
1.1       takayama  358:
                    359:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>