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

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

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