ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ximage.c
Revision: 2.10
Committed: Wed Apr 23 00:52:34 2003 UTC (21 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.9: +1 -1 lines
Log Message:
Added (void *) cast to realloc calls

File Contents

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