ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ximage.c
Revision: 2.3
Committed: Mon Dec 23 23:20:06 1991 UTC (32 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +4 -4 lines
Log Message:
fixed CTRL(c) for ANSII preprocessors

File Contents

# User Rev Content
1 greg 1.1 /* Copyright (c) 1987 Regents of the University of California */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * ximage.c - driver for X-windows
9     *
10     * 4/30/87
11     * 3/3/88 Added calls to xraster & Paul Heckbert's ciq routines
12     */
13    
14     #include "standard.h"
15    
16     #include <X/Xlib.h>
17     #include <X/cursors/bcross.cursor>
18     #include <X/cursors/bcross_mask.cursor>
19    
20     #include <sys/types.h>
21    
22     #include <ctype.h>
23    
24     #include "color.h"
25    
26 greg 2.1 #include "resolu.h"
27    
28 greg 1.1 #include "xraster.h"
29    
30     #include "view.h"
31    
32     #include "pic.h"
33    
34 greg 1.15 #include "random.h"
35    
36 greg 1.1 #define controlshift(e) (((XButtonEvent *)(e))->detail & (ShiftMask|ControlMask))
37    
38     #define FONTNAME "9x15" /* text font we'll use */
39    
40 greg 2.3 #define CTRL(c) ((c)-'@')
41 greg 1.1
42     #define BORWIDTH 5 /* border width */
43     #define BARHEIGHT 25 /* menu bar size */
44    
45 greg 1.11 double gamcor = 2.2; /* gamma correction */
46 greg 1.1
47 greg 1.2 XRASTER *ourras = NULL; /* our stored raster image */
48 greg 1.1
49     int dither = 1; /* dither colors? */
50     int fast = 0; /* keep picture in Pixmap? */
51    
52     Window wind = 0; /* our output window */
53     Font fontid; /* our font */
54    
55     int maxcolors = 0; /* maximum colors */
56     int greyscale = 0; /* in grey */
57    
58 greg 1.2 int scale = 0; /* scalefactor; power of two */
59    
60 greg 1.1 int xoff = 0; /* x image offset */
61     int yoff = 0; /* y image offset */
62    
63 greg 1.21 VIEW ourview = STDVIEW; /* image view parameters */
64 greg 1.1 int gotview = 0; /* got parameters from file */
65    
66     COLR *scanline; /* scan line buffer */
67    
68     int xmax, ymax; /* picture resolution */
69     int width, height; /* window size */
70     char *fname = NULL; /* input file name */
71     FILE *fin = stdin; /* input file */
72     long *scanpos = NULL; /* scan line positions in file */
73     int cury = 0; /* current scan location */
74    
75     double exposure = 1.0; /* exposure compensation used */
76    
77 greg 1.29 int wrongformat = 0; /* input in another format */
78    
79 greg 1.1 struct {
80     int xmin, ymin, xsiz, ysiz;
81     } box = {0, 0, 0, 0}; /* current box */
82    
83     char *geometry = NULL; /* geometry specification */
84    
85     char *progname;
86    
87     char errmsg[128];
88    
89     extern long ftell();
90    
91     extern char *malloc(), *calloc();
92    
93 greg 2.2 extern double pow(), log();
94 greg 1.1
95    
96     main(argc, argv)
97     int argc;
98     char *argv[];
99     {
100     int headline();
101     int i;
102    
103     progname = argv[0];
104    
105     for (i = 1; i < argc; i++)
106     if (argv[i][0] == '-')
107     switch (argv[i][1]) {
108     case 'c':
109     maxcolors = atoi(argv[++i]);
110     break;
111     case 'b':
112     greyscale = !greyscale;
113     break;
114     case 'm':
115     maxcolors = 2;
116     break;
117     case 'd':
118     dither = !dither;
119     break;
120     case 'f':
121     fast = !fast;
122     break;
123 greg 1.2 case 'e':
124     if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
125     goto userr;
126     scale = atoi(argv[++i]);
127     break;
128 greg 1.1 case 'g':
129     gamcor = atof(argv[++i]);
130     break;
131     default:
132     goto userr;
133     }
134     else if (argv[i][0] == '=')
135     geometry = argv[i];
136     else
137     break;
138    
139     if (argc-i == 1) {
140     fname = argv[i];
141     fin = fopen(fname, "r");
142     if (fin == NULL) {
143     sprintf(errmsg, "can't open file \"%s\"", fname);
144     quiterr(errmsg);
145     }
146 greg 1.6 }
147 greg 1.1 /* get header */
148 greg 1.29 getheader(fin, headline, NULL);
149 greg 1.1 /* get picture dimensions */
150 greg 1.29 if (wrongformat || fgetresolu(&xmax, &ymax, fin) != (YMAJOR|YDECR))
151 greg 1.1 quiterr("bad picture size");
152     /* set view parameters */
153 greg 1.21 if (gotview && setview(&ourview) != NULL)
154     gotview = 0;
155 greg 1.1 if ((scanline = (COLR *)malloc(xmax*sizeof(COLR))) == NULL)
156     quiterr("out of memory");
157    
158     init(); /* get file and open window */
159    
160     for ( ; ; )
161     getevent(); /* main loop */
162     userr:
163     fprintf(stderr,
164 greg 1.2 "Usage: %s [=geometry][-b][-m][-d][-f][-c ncolors][-e +/-stops] file\n",
165 greg 1.1 progname);
166     quit(1);
167     }
168    
169    
170     headline(s) /* get relevant info from header */
171     char *s;
172     {
173 greg 1.4 static char *altname[] = {"rview","rpict",VIEWSTR,NULL};
174 greg 1.1 register char **an;
175 greg 1.29 char fmt[32];
176 greg 1.1
177 greg 1.20 if (isexpos(s))
178     exposure *= exposval(s);
179 greg 1.29 else if (isformat(s)) {
180     formatval(fmt, s);
181     wrongformat = strcmp(fmt, COLRFMT);
182     } else
183 greg 1.1 for (an = altname; *an != NULL; an++)
184     if (!strncmp(*an, s, strlen(*an))) {
185 greg 1.21 if (sscanview(&ourview, s+strlen(*an)) > 0)
186 greg 1.1 gotview++;
187     return;
188     }
189     }
190    
191    
192     init() /* get data and open window */
193     {
194     register int i;
195     OpaqueFrame mainframe;
196     char defgeom[32];
197    
198     if (fname != NULL) {
199     scanpos = (long *)malloc(ymax*sizeof(long));
200     if (scanpos == NULL)
201     goto memerr;
202     for (i = 0; i < ymax; i++)
203     scanpos[i] = -1;
204     }
205     if (XOpenDisplay(NULL) == NULL)
206     quiterr("can't open display; DISPLAY variable set?");
207     #ifdef notdef
208     if (DisplayWidth() - 2*BORWIDTH < xmax ||
209     DisplayHeight() - 2*BORWIDTH - BARHEIGHT < ymax)
210     quiterr("resolution mismatch");
211     #endif
212     if (maxcolors == 0) { /* get number of available colors */
213     maxcolors = 1<<DisplayPlanes();
214     if (maxcolors > 4) maxcolors -= 2;
215     }
216     /* store image */
217 greg 1.2 getras();
218    
219 greg 1.1 mainframe.bdrwidth = BORWIDTH;
220     mainframe.border = WhitePixmap;
221     mainframe.background = BlackPixmap;
222     sprintf(defgeom, "=%dx%d+0+22", xmax, ymax);
223     wind = XCreate("Radiance Image", progname, geometry, defgeom,
224     &mainframe, 16, 16);
225     if (wind == 0)
226     quiterr("can't create window");
227     width = mainframe.width;
228     height = mainframe.height;
229     fontid = XGetFont(FONTNAME);
230     if (fontid == 0)
231     quiterr("can't get font");
232     XStoreName(wind, fname == NULL ? progname : fname);
233     XDefineCursor(wind, XCreateCursor(bcross_width, bcross_height,
234     bcross_bits, bcross_mask_bits,
235     bcross_x_hot, bcross_y_hot,
236     BlackPixel, WhitePixel, GXcopy));
237     XSelectInput(wind, ButtonPressed|ButtonReleased|UnmapWindow
238     |RightDownMotion|MiddleDownMotion|LeftDownMotion
239     |KeyPressed|ExposeWindow|ExposeRegion);
240     XMapWindow(wind);
241     return;
242     memerr:
243     quiterr("out of memory");
244     }
245    
246    
247     quiterr(err) /* print message and exit */
248     char *err;
249     {
250     if (err != NULL)
251     fprintf(stderr, "%s: %s\n", progname, err);
252    
253     exit(err == NULL ? 0 : 1);
254     }
255    
256    
257     eputs(s)
258     char *s;
259     {
260     fputs(s, stderr);
261     }
262    
263    
264     quit(code)
265     int code;
266     {
267     exit(code);
268     }
269    
270    
271 greg 1.2 getras() /* get raster file */
272     {
273     colormap ourmap;
274    
275     ourras = (XRASTER *)calloc(1, sizeof(XRASTER));
276     if (ourras == NULL)
277     goto memerr;
278     ourras->width = xmax;
279     ourras->height = ymax;
280     if (maxcolors <= 2) { /* monochrome */
281     ourras->data.m = (unsigned short *)malloc(BitmapSize(xmax,ymax));
282     if (ourras->data.m == NULL)
283     goto memerr;
284     getmono();
285     } else {
286     ourras->data.bz = (unsigned char *)malloc(BZPixmapSize(xmax,ymax));
287     if (ourras->data.bz == NULL)
288     goto memerr;
289     if (greyscale)
290     biq(dither,maxcolors,1,ourmap);
291     else
292     ciq(dither,maxcolors,1,ourmap);
293     if (init_rcolors(ourras, ourmap) == 0)
294     goto memerr;
295     }
296     return;
297     memerr:
298 greg 1.26 quiterr("out of memory");
299 greg 1.2 }
300    
301    
302 greg 1.1 getevent() /* process the next event */
303     {
304     WindowInfo info;
305     XEvent e;
306    
307     XNextEvent(&e);
308     switch (e.type) {
309     case KeyPressed:
310     docom(&e);
311     break;
312     case ExposeWindow:
313     XQueryWindow(wind, &info); /* in case resized */
314     width = info.width;
315     height = info.height;
316     /* fall through */
317     case ExposeRegion:
318     fixwindow(&e);
319     break;
320     case UnmapWindow:
321 greg 1.2 unmap_rcolors(ourras);
322 greg 1.1 break;
323     case ButtonPressed:
324     if (controlshift(&e))
325     moveimage(&e);
326     else
327     getbox(&e);
328     break;
329     }
330     }
331    
332    
333     fixwindow(eexp) /* fix new or stepped-on window */
334     XExposeEvent *eexp;
335     {
336     redraw(eexp->x, eexp->y, eexp->width, eexp->height);
337     }
338    
339    
340     redraw(x, y, w, h) /* redraw section of window */
341     int x, y;
342     int w, h;
343     {
344 greg 1.7 if (ourras->ncolors && map_rcolors(ourras) == NULL) {
345 greg 1.2 fprintf(stderr, "%s: cannot allocate colors\n", progname);
346     return(-1);
347     }
348 greg 1.1 if (fast)
349 greg 1.2 make_rpixmap(ourras);
350     return(patch_raster(wind,x-xoff,y-yoff,x,y,w,h,ourras) ? 0 : -1);
351 greg 1.1 }
352    
353    
354     docom(ekey) /* execute command */
355     XKeyEvent *ekey;
356     {
357     char buf[80];
358     COLOR cval;
359 greg 1.15 Color cvx;
360 greg 1.1 char *cp;
361     int n;
362 greg 1.2 double comp;
363 greg 1.1 FVECT rorg, rdir;
364    
365     cp = XLookupMapping(ekey, &n);
366     if (n == 0)
367     return(0);
368     switch (*cp) { /* interpret command */
369     case 'q':
370 greg 2.3 case CTRL('D'): /* quit */
371 greg 1.1 quit(0);
372     case '\n':
373     case '\r':
374     case 'l':
375     case 'c': /* value */
376     if (avgbox(cval) == -1)
377     return(-1);
378     switch (*cp) {
379     case '\n':
380     case '\r': /* radiance */
381 greg 1.17 sprintf(buf, "%.3f", intens(cval)/exposure);
382 greg 1.1 break;
383     case 'l': /* luminance */
384 greg 1.30 sprintf(buf, "%.0fL", luminance(cval)/exposure);
385 greg 1.1 break;
386     case 'c': /* color */
387 greg 1.2 comp = pow(2.0, (double)scale);
388 greg 1.1 sprintf(buf, "(%.2f,%.2f,%.2f)",
389 greg 1.2 colval(cval,RED)*comp,
390     colval(cval,GRN)*comp,
391     colval(cval,BLU)*comp);
392 greg 1.1 break;
393     }
394     XText(wind, box.xmin, box.ymin, buf, strlen(buf),
395     fontid, BlackPixel, WhitePixel);
396     return(0);
397 greg 1.15 case 'i': /* identify (contour) */
398 greg 1.16 if (ourras->pixels == NULL)
399 greg 1.15 return(-1);
400     n = ourras->data.bz[ekey->x-xoff+BZPixmapSize(xmax,ekey->y-yoff)];
401     n = ourras->pmap[n];
402     cvx.pixel = ourras->cdefs[n].pixel;
403     cvx.red = random() & 65535;
404     cvx.green = random() & 65535;
405     cvx.blue = random() & 65535;
406     XStoreColor(&cvx);
407     return(0);
408 greg 1.1 case 'p': /* position */
409     sprintf(buf, "(%d,%d)", ekey->x-xoff, ymax-1-ekey->y+yoff);
410     XText(wind, ekey->x, ekey->y, buf, strlen(buf),
411     fontid, BlackPixel, WhitePixel);
412     return(0);
413     case 't': /* trace */
414     if (!gotview) {
415     XFeep(0);
416     return(-1);
417     }
418 greg 1.25 if (viewray(rorg, rdir, &ourview, (ekey->x-xoff+.5)/xmax,
419     (ymax-1-ekey->y+yoff+.5)/ymax) < 0)
420     return(-1);
421 greg 1.1 printf("%e %e %e ", rorg[0], rorg[1], rorg[2]);
422     printf("%e %e %e\n", rdir[0], rdir[1], rdir[2]);
423     fflush(stdout);
424     return(0);
425 greg 1.2 case '=': /* adjust exposure */
426     if (avgbox(cval) == -1)
427     return(-1);
428     n = log(.5/bright(cval))/.69315 - scale; /* truncate */
429 greg 1.5 if (n == 0)
430 greg 1.2 return(0);
431     scale_rcolors(ourras, pow(2.0, (double)n));
432     scale += n;
433     sprintf(buf, "%+d", scale);
434     XText(wind, box.xmin, box.ymin, buf, strlen(buf),
435     fontid, BlackPixel, WhitePixel);
436     XFlush();
437     free_raster(ourras);
438     getras();
439 greg 1.3 /* fall through */
440 greg 2.3 case CTRL('R'): /* redraw */
441     case CTRL('L'):
442 greg 1.16 unmap_rcolors(ourras);
443 greg 1.1 XClear(wind);
444     return(redraw(0, 0, width, height));
445     case ' ': /* clear */
446     return(redraw(box.xmin, box.ymin, box.xsiz, box.ysiz));
447     default:
448     XFeep(0);
449     return(-1);
450     }
451     }
452    
453    
454     moveimage(ep) /* shift the image */
455     XButtonEvent *ep;
456     {
457     XButtonEvent eb;
458    
459     XMaskEvent(ButtonReleased, &eb);
460     xoff += eb.x - ep->x;
461     yoff += eb.y - ep->y;
462     XClear(wind);
463     return(redraw(0, 0, width, height));
464     }
465    
466    
467     getbox(ebut) /* get new box */
468     XButtonEvent *ebut;
469     {
470     union {
471     XEvent e;
472     XButtonEvent b;
473     XMouseMovedEvent m;
474     } e;
475    
476     XMaskEvent(ButtonReleased|MouseMoved, &e.e);
477     while (e.e.type == MouseMoved) {
478     revbox(ebut->x, ebut->y, box.xmin = e.m.x, box.ymin = e.m.y);
479     XMaskEvent(ButtonReleased|MouseMoved, &e.e);
480     revbox(ebut->x, ebut->y, box.xmin, box.ymin);
481     }
482     box.xmin = e.b.x<0 ? 0 : (e.b.x>=width ? width-1 : e.b.x);
483     box.ymin = e.b.y<0 ? 0 : (e.b.y>=height ? height-1 : e.b.y);
484     if (box.xmin > ebut->x) {
485     box.xsiz = box.xmin - ebut->x + 1;
486     box.xmin = ebut->x;
487     } else {
488     box.xsiz = ebut->x - box.xmin + 1;
489     }
490     if (box.ymin > ebut->y) {
491     box.ysiz = box.ymin - ebut->y + 1;
492     box.ymin = ebut->y;
493     } else {
494     box.ysiz = ebut->y - box.ymin + 1;
495     }
496     }
497    
498    
499     revbox(x0, y0, x1, y1) /* draw box with reversed lines */
500     int x0, y0, x1, y1;
501     {
502     XLine(wind, x0, y0, x1, y0, 1, 1, 0, GXinvert, AllPlanes);
503     XLine(wind, x0, y1, x1, y1, 1, 1, 0, GXinvert, AllPlanes);
504     XLine(wind, x0, y0, x0, y1, 1, 1, 0, GXinvert, AllPlanes);
505     XLine(wind, x1, y0, x1, y1, 1, 1, 0, GXinvert, AllPlanes);
506     }
507    
508    
509     avgbox(clr) /* average color over current box */
510     COLOR clr;
511     {
512     int left, right, top, bottom;
513     int y;
514     double d;
515     COLOR ctmp;
516     register int x;
517    
518     setcolor(clr, 0.0, 0.0, 0.0);
519     left = box.xmin - xoff;
520     right = left + box.xsiz;
521     if (left < 0)
522     left = 0;
523     if (right > xmax)
524     right = xmax;
525     if (left >= right)
526     return(-1);
527     top = box.ymin - yoff;
528     bottom = top + box.ysiz;
529     if (top < 0)
530     top = 0;
531     if (bottom > ymax)
532     bottom = ymax;
533     if (top >= bottom)
534     return(-1);
535     for (y = top; y < bottom; y++) {
536     if (getscan(y) == -1)
537     return(-1);
538     for (x = left; x < right; x++) {
539     colr_color(ctmp, scanline[x]);
540     addcolor(clr, ctmp);
541     }
542     }
543     d = 1.0/((right-left)*(bottom-top));
544     scalecolor(clr, d);
545     return(0);
546     }
547    
548    
549     getmono() /* get monochrome data */
550     {
551     register unsigned short *dp;
552     register int x, err;
553 greg 1.31 int y, errp;
554 greg 1.24 rgbpixel *inl;
555 greg 1.1 short *cerr;
556    
557 greg 1.24 if ((inl = (rgbpixel *)malloc(xmax*sizeof(rgbpixel))) == NULL
558 greg 1.1 || (cerr = (short *)calloc(xmax,sizeof(short))) == NULL)
559 greg 1.26 quiterr("out of memory in getmono");
560 greg 1.2 dp = ourras->data.m - 1;
561 greg 1.1 for (y = 0; y < ymax; y++) {
562 greg 1.24 picreadline3(y, inl);
563 greg 1.1 err = 0;
564     for (x = 0; x < xmax; x++) {
565     if (!(x&0xf))
566     *++dp = 0;
567 greg 1.31 errp = err;
568 greg 1.24 err += rgb_bright(&inl[x]) + cerr[x];
569 greg 1.1 if (err > 127)
570     err -= 255;
571     else
572     *dp |= 1<<(x&0xf);
573 greg 1.31 err /= 3;
574     cerr[x] = err + errp;
575 greg 1.1 }
576     }
577 greg 1.24 free((char *)inl);
578 greg 1.1 free((char *)cerr);
579     }
580    
581    
582 greg 1.2 init_rcolors(xr, cmap) /* (re)assign color values */
583 greg 1.1 register XRASTER *xr;
584     colormap cmap;
585     {
586     register int i;
587     register unsigned char *p;
588    
589     xr->pmap = (int *)malloc(256*sizeof(int));
590     if (xr->pmap == NULL)
591     return(0);
592     xr->cdefs = (Color *)malloc(256*sizeof(Color));
593     if (xr->cdefs == NULL)
594     return(0);
595     for (i = 0; i < 256; i++)
596     xr->pmap[i] = -1;
597     xr->ncolors = 0;
598     for (p = xr->data.bz, i = BZPixmapSize(xr->width,xr->height); i--; p++)
599     if (xr->pmap[*p] == -1) {
600     xr->cdefs[xr->ncolors].red = cmap[0][*p] << 8;
601     xr->cdefs[xr->ncolors].green = cmap[1][*p] << 8;
602     xr->cdefs[xr->ncolors].blue = cmap[2][*p] << 8;
603     xr->cdefs[xr->ncolors].pixel = *p;
604     xr->pmap[*p] = xr->ncolors++;
605     }
606     xr->cdefs = (Color *)realloc((char *)xr->cdefs, xr->ncolors*sizeof(Color));
607     if (xr->cdefs == NULL)
608     return(0);
609     return(1);
610     }
611    
612    
613 greg 1.2 scale_rcolors(xr, sf) /* scale color map */
614     register XRASTER *xr;
615     double sf;
616     {
617     register int i;
618 greg 1.16 long maxv;
619 greg 1.2
620 greg 1.16 if (xr->pixels == NULL)
621     return;
622    
623 greg 1.2 sf = pow(sf, 1.0/gamcor);
624 greg 1.16 maxv = 65535/sf;
625 greg 1.2
626     for (i = xr->ncolors; i--; ) {
627 greg 1.16 xr->cdefs[i].red = xr->cdefs[i].red > maxv ?
628     65535 :
629 greg 1.2 xr->cdefs[i].red * sf;
630 greg 1.16 xr->cdefs[i].green = xr->cdefs[i].green > maxv ?
631     65535 :
632 greg 1.2 xr->cdefs[i].green * sf;
633 greg 1.16 xr->cdefs[i].blue = xr->cdefs[i].blue > maxv ?
634     65535 :
635 greg 1.2 xr->cdefs[i].blue * sf;
636     }
637 greg 1.16 XStoreColors(xr->ncolors, xr->cdefs);
638 greg 1.2 }
639    
640    
641 greg 1.1 getscan(y)
642     int y;
643     {
644     if (y != cury) {
645     if (scanpos == NULL || scanpos[y] == -1)
646     return(-1);
647     if (fseek(fin, scanpos[y], 0) == -1)
648 greg 1.26 quiterr("fseek error");
649 greg 1.1 cury = y;
650     } else if (scanpos != NULL)
651     scanpos[y] = ftell(fin);
652    
653     if (freadcolrs(scanline, xmax, fin) < 0)
654     quiterr("read error");
655    
656     cury++;
657     return(0);
658     }
659    
660    
661     picreadline3(y, l3) /* read in 3-byte scanline */
662     int y;
663     register rgbpixel *l3;
664     {
665 greg 1.12 register int i;
666     /* read scanline */
667 greg 1.1 if (getscan(y) < 0)
668     quiterr("cannot seek for picreadline");
669     /* convert scanline */
670 greg 1.23 normcolrs(scanline, xmax, scale);
671 greg 1.12 for (i = 0; i < xmax; i++) {
672     l3[i].r = scanline[i][RED];
673     l3[i].g = scanline[i][GRN];
674     l3[i].b = scanline[i][BLU];
675 greg 1.1 }
676     }
677    
678    
679     picwriteline(y, l) /* add 8-bit scanline to image */
680     int y;
681     pixel *l;
682     {
683 greg 1.22 bcopy((char *)l, (char *)ourras->data.bz+BZPixmapSize(xmax,y), BZPixmapSize(xmax,1));
684 greg 1.1 }
685    
686    
687 greg 1.8 picreadcm(map) /* do gamma correction */
688 greg 1.1 colormap map;
689     {
690     extern double pow();
691     register int i, val;
692    
693     for (i = 0; i < 256; i++) {
694 greg 1.27 val = pow((i+0.5)/256.0, 1.0/gamcor) * 256.0;
695 greg 1.1 map[0][i] = map[1][i] = map[2][i] = val;
696     }
697     }
698    
699    
700     picwritecm(map) /* handled elsewhere */
701     colormap map;
702     {
703 greg 1.2 #ifdef DEBUG
704     register int i;
705    
706     for (i = 0; i < 256; i++)
707     printf("%d %d %d\n", map[0][i],map[1][i],map[2][i]);
708     #endif
709 greg 1.1 }