/*-------------------------------------------------------------------------- 3dscan - author: Oliver Knill - version: November 2001, Math 21a class of Fall 2001 - compile: gcc -O -o 3dscan -L/usr/X11R6/lib 3dscan.c -lX11 - run: 3dscan image.ppm image.dat - warning: use with care: this is an ad-hoc program used demo purposes only - thanks: some Xwindows stuff taken from xtoys: (creutz@wind.phy.bnl.gov) ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Libraries */ /*---------------------------------------------------------------------------*/ # include # include # include # include # include # include # include # include # include # include /*---------------------------------------------------------------------------*/ /* Constants and variables */ /*---------------------------------------------------------------------------*/ # define TOP 80 # define LEFT 14 # define P 5000 // maximal number of points int nn; // number of points int p; // index for points int point[P]; int point1[P]; int point2[P]; int point3[P]; int point4[P]; Display *display; Window window; Window quitbutton,readfile_button,writefile_button,addpoint_button; Window playground,makebutton(); XColor xcolor,colorcell; Colormap cmap; GC gc,gcpen; XFontStruct *font=NULL; XSizeHints size_hints; XImage *photoimage=NULL; int font_height,font_width; int windowwidth,windowheight; int screen; int darkcolor,lightcolor,redcolor,bluecolor; int black,white; char stringbuffer[256]; char *progname; char *image_filename="image.ppm"; char *data_filename="image.dat"; int *image, *ptr; /* image and point on image */ int x_size, y_size, c_size; /* picture size colormap size */ void draw_button(); void openwindow(); void make_buttons(); void repaint(); void clean_up(); void showpic(); void write_points(); void plot_point(int i,int j,int red, int green, int blue); void plot_grid(); void plot_old_points(); void read_points(); void read_ppm_image(char *filename); /*---------------------------------------------------------------------------*/ /* Main program */ /*---------------------------------------------------------------------------*/ int main(int argc,char **argv) { int i,j,jj; int i_left=1, j_left=1; int i_right=1, j_right=1; int clicked; int read_file=0; XEvent report; progname=argv[0]; if ( (argc<2) || (argc>3)) { fprintf(stderr,"Usage: scan [ppmfile] [datafile] \n"); exit(1); } image_filename=argv[1]; if (argc ==3) { data_filename=argv[2]; read_file=1; } i_left=1; j_left=1; i_right=1; j_right=1; clicked=0; nn=0; read_ppm_image(image_filename); openwindow(argc,argv); make_buttons(); plot_grid(); if (read_file==1) { read_points(); plot_old_points(); } while(0==0) { XNextEvent(display,&report); switch (report.type) { case Expose: if ((report.xexpose.window)!=window) break; if (report.xexpose.count!=0) break; showpic(); break; case ConfigureNotify: break; case ButtonPress: if (report.xbutton.window==quitbutton) { clean_up(); } else if (report.xbutton.window==addpoint_button) { //draw_button(addpoint_button,0,0,70,18, "store",-1); break; } else if (report.xbutton.window==readfile_button) { //draw_button(readfile_button,0,0,70,18, "read",-1); clicked=0; if (read_file==0) { read_points(); plot_old_points(); } read_file=1; break; } else if (report.xbutton.window==writefile_button) { draw_button(writefile_button,0,0,70,18, "write",-1); clicked=0; write_points(); break; } else { i=report.xbutton.x; j=report.xbutton.y; plot_point(i,j,254,0,0); clicked=1; break; } case ButtonRelease: clicked=0; break; default: break; } if (clicked==1) { if (i<(x_size/2)) { i_left=i; j_left=j; sprintf(stringbuffer,"x=%d,y=%d ",i_left,j_left); XDrawImageString(display,window,gc,30,52, stringbuffer,strlen(stringbuffer)); } if (i>=(x_size/2)) { i_right=i-floor(x_size/2); j_right=j; sprintf(stringbuffer,"x=%d,y=%d ",i_right,j_right); XDrawImageString(display,window,gc,floor(x_size/2)+30,52, stringbuffer,strlen(stringbuffer)); point1[nn]=i_left; point2[nn]=j_left; point3[nn]=i_right; point4[nn]=j_right; nn++; } sprintf(stringbuffer,"points=%d",nn); XDrawImageString(display,window,gc,x_size-150,52, stringbuffer,strlen(stringbuffer)); repaint(); } } return 0; } /*---------------------------------------------------------------------------*/ /* Show the picture */ /*---------------------------------------------------------------------------*/ void showpic() { int i,j,jj; int *phi,*psi,*eta; for (i=0;iascent+font->descent; font_width=font ->max_bounds.width; gc=XCreateGC(display,window,0,NULL); XSetFont(display,gc,font->fid); XSetForeground(display,gc,black); XSetBackground(display,gc,lightcolor); gcpen=XCreateGC(display,window,0,NULL); XSetFont(display,gcpen,font->fid); XSetForeground(display,gcpen,darkcolor); XSetBackground(display,gcpen,lightcolor); XMapWindow(display,window); return; } /*---------------------------------------------------------------------------*/ /* Function make_button */ /*---------------------------------------------------------------------------*/ Window make_button(int xoffset,int yoffset,int xsize,int ysize) { Window bwindow; long event_mask; bwindow=XCreateSimpleWindow(display,window,xoffset,yoffset,xsize,ysize,0,black,lightcolor); event_mask=ButtonPressMask|ExposureMask; XSelectInput(display,bwindow,event_mask); XMapWindow(display,bwindow); return bwindow; } /*---------------------------------------------------------------------------*/ /* Function make_buttons */ /*---------------------------------------------------------------------------*/ void make_buttons() { int i; long event_mask; XEvent report; Cursor cursor; XDestroySubwindows(display,window); quitbutton = make_button(310,4,70,18); readfile_button = make_button(110,4,70,18); writefile_button = make_button(210,4,70,18); addpoint_button = make_button(10,4,70,18); playground=XCreateSimpleWindow(display,window,LEFT,TOP,x_size,y_size,0,black,white); event_mask=ExposureMask|ButtonReleaseMask|ButtonPressMask|PointerMotionHintMask|ButtonMotionMask; XSelectInput(display,playground,event_mask); XMapWindow(display,playground); i=1; while (i) { XNextEvent(display,&report); switch (report.type) { case Expose: if (report.xexpose.window!=playground) i=0; default: break; } } if (NULL!=photoimage) {XDestroyImage(photoimage); photoimage=NULL; } photoimage=XGetImage((Display *) display, (Drawable) playground, 0,0,x_size,y_size,AllPlanes,ZPixmap); if (NULL==photoimage) { fprintf(stderr,"trouble creating image \n"); exit(-1);} cursor=XCreateFontCursor(display,XC_diamond_cross); // XC_diamond_cross XDefineCursor(display,playground,cursor); cursor=XCreateFontCursor(display,XC_hand2); XDefineCursor(display,quitbutton,cursor); XDefineCursor(display,addpoint_button,cursor); repaint(); return; } /*---------------------------------------------------------------------------*/ /* Function draw_button */ /*---------------------------------------------------------------------------*/ void draw_button(Window bwindow,int xoffset,int yoffset,int xsize,int ysize,char * text,int state) { int textlength,i,j; int cdark,clight,cup,cdown; int cleft,cright,cbutton,ctext; cup=redcolor; cdown=bluecolor; cdark=black; clight=white; if (state<0) { cbutton=cdown; ctext=cdark; cleft=cdark; cright=clight; } else { cbutton=cup; ctext=cdark; cleft=clight; cright=cdark; } j=abs(state); XSetForeground(display,gcpen,cbutton); XFillRectangle(display,bwindow,gcpen,xoffset+j,yoffset+j,xsize-2*j,ysize-2*j); XSetForeground(display,gcpen,cleft); XFillRectangle(display,bwindow,gcpen,xoffset,yoffset,xsize,j); XFillRectangle(display,bwindow,gcpen,xoffset,yoffset,j,ysize); XSetForeground(display,gcpen,cright); for (i=0;ifid); XFreeGC(display,gc); XFreeGC(display,gcpen); XCloseDisplay(display); XDestroyImage(photoimage); if (NULL!=image) free((char *) image); exit(1); } /*---------------------------------------------------------------------------*/ /* Function read_ppm_image */ /*---------------------------------------------------------------------------*/ void read_ppm_image(char *filename) { FILE *in; int i; int l,m,n; char buffer[1025]; if((in = fopen(filename,"rb")) == NULL){ fprintf(stderr,"Can't open file %s\n", filename); exit(1); } fgets(buffer,1025,in); if(strncmp(buffer,"P6",2)){ fprintf(stderr,"Unsupported file format (need PPM raw)\n"); exit(1); } do fgets(buffer,1025,in); while(*buffer == '#'); x_size = atoi(strtok(buffer," ")); y_size = atoi(strtok(NULL," ")); fgets(buffer,1025,in); c_size = atoi(buffer); if((image = (int *) malloc((3*x_size*y_size+1)*sizeof(int))) == NULL){ fprintf(stderr,"Can't load image (memory allocation error)\n"); exit(1); } i = 0; ptr = image; while(!feof(in) && i<3*x_size*y_size){*ptr++=fgetc(in);i++;} fclose(in); if(i=x_size) {i1--;} if (j1>=y_size) {j1--;} if (i1<0) {i1++;} if (j1<0) {j1++;} jj=j1*x_size; ptr = image+3*(jj+i1); *ptr++=red; *ptr++=green; *ptr+=blue; } } /*---------------------------------------------------------------------------*/ /* Function plot_old_points */ /*---------------------------------------------------------------------------*/ void plot_old_points(){ int k; for (k=0; k