ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/x11image.c
Revision: 2.1
Committed: Tue Nov 12 16:04:23 1991 UTC (32 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.26: +0 -0 lines
Log Message:
updated revision number for release 2.0

File Contents

# Content
1 /* Copyright (c) 1991 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * x11image.c - driver for X-windows
9 *
10 * 3/1/90
11 */
12
13 /*
14 * Modified for X11
15 *
16 * January 1990
17 *
18 * Anat Grynberg and Greg Ward
19 */
20
21
22 #include "standard.h"
23
24 #include <X11/Xlib.h>
25 #include <X11/cursorfont.h>
26 #include <X11/Xutil.h>
27
28 #include "color.h"
29 #include "view.h"
30 #include "pic.h"
31 #include "x11raster.h"
32 #include "random.h"
33 #include "resolu.h"
34
35 #define FONTNAME "8x13" /* text font we'll use */
36
37 #define CTRL(c) ('c'-'@')
38
39 #define BORWIDTH 5 /* border width */
40
41 #define ICONSIZ (8*10) /* maximum icon dimension (even 8) */
42
43 #define ourscreen DefaultScreen(thedisplay)
44 #define ourblack BlackPixel(thedisplay,ourscreen)
45 #define ourwhite WhitePixel(thedisplay,ourscreen)
46 #define ourroot RootWindow(thedisplay,ourscreen)
47 #define ourgc DefaultGC(thedisplay,ourscreen)
48
49 #define revline(x0,y0,x1,y1) XDrawLine(thedisplay,wind,revgc,x0,y0,x1,y1)
50
51 #define redraw(x,y,w,h) patch_raster(wind,(x)-xoff,(y)-yoff,x,y,w,h,ourras)
52
53 double gamcor = 2.2; /* gamma correction */
54
55 int dither = 1; /* dither colors? */
56 int fast = 0; /* keep picture in Pixmap? */
57
58 Window wind = 0; /* our output window */
59 Font fontid; /* our font */
60
61 int maxcolors = 0; /* maximum colors */
62 int greyscale = 0; /* in grey */
63
64 int scale = 0; /* scalefactor; power of two */
65
66 int xoff = 0; /* x image offset */
67 int yoff = 0; /* y image offset */
68
69 VIEW ourview = STDVIEW; /* image view parameters */
70 int gotview = 0; /* got parameters from file */
71
72 COLR *scanline; /* scan line buffer */
73
74 RESOLU inpres; /* input resolution and ordering */
75 int xmax, ymax; /* picture dimensions */
76 int width, height; /* window size */
77 char *fname = NULL; /* input file name */
78 FILE *fin = stdin; /* input file */
79 long *scanpos = NULL; /* scan line positions in file */
80 int cury = 0; /* current scan location */
81
82 double exposure = 1.0; /* exposure compensation used */
83
84 int wrongformat = 0; /* input in another format? */
85
86 GC revgc; /* graphics context with GXinvert */
87
88 XRASTER *ourras; /* our stored image */
89 unsigned char *ourdata; /* our image data */
90
91 struct {
92 int xmin, ymin, xsiz, ysiz;
93 } box = {0, 0, 0, 0}; /* current box */
94
95 char *geometry = NULL; /* geometry specification */
96
97 char icondata[ICONSIZ*ICONSIZ/8]; /* icon bitmap data */
98 int iconwidth = 0, iconheight = 0;
99
100 char *progname;
101
102 char errmsg[128];
103
104 extern long ftell();
105
106 extern char *malloc(), *calloc();
107
108 extern double atof(), pow(), log();
109
110 Display *thedisplay;
111
112 main(argc, argv)
113 int argc;
114 char *argv[];
115 {
116 int headline();
117 int i;
118
119 progname = argv[0];
120
121 for (i = 1; i < argc; i++)
122 if (argv[i][0] == '-')
123 switch (argv[i][1]) {
124 case 'c':
125 maxcolors = atoi(argv[++i]);
126 break;
127 case 'b':
128 greyscale = !greyscale;
129 break;
130 case 'm':
131 maxcolors = 2;
132 break;
133 case 'd':
134 dither = !dither;
135 break;
136 case 'f':
137 fast = !fast;
138 break;
139 case 'e':
140 if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
141 goto userr;
142 scale = atoi(argv[++i]);
143 break;
144 case 'g':
145 if (!strcmp(argv[i], "-geometry"))
146 geometry = argv[++i];
147 else
148 gamcor = atof(argv[++i]);
149 break;
150 default:
151 goto userr;
152 }
153 else if (argv[i][0] == '=')
154 geometry = argv[i];
155 else
156 break;
157
158 if (i == argc-1) {
159 fname = argv[i];
160 fin = fopen(fname, "r");
161 if (fin == NULL) {
162 sprintf(errmsg, "can't open file \"%s\"", fname);
163 quiterr(errmsg);
164 }
165 } else if (i != argc)
166 goto userr;
167 /* get header */
168 getheader(fin, headline, NULL);
169 /* get picture dimensions */
170 if (wrongformat || !fgetsresolu(&inpres, fin))
171 quiterr("bad picture format");
172 xmax = scanlen(&inpres);
173 ymax = numscans(&inpres);
174 /* set view parameters */
175 if (gotview && setview(&ourview) != NULL)
176 gotview = 0;
177 if ((scanline = (COLR *)malloc(xmax*sizeof(COLR))) == NULL)
178 quiterr("out of memory");
179
180 init(); /* get file and open window */
181
182 for ( ; ; )
183 getevent(); /* main loop */
184 userr:
185 fprintf(stderr,
186 "Usage: %s [-geometry spec][-b][-m][-d][-f][-c ncolors][-e +/-stops] file\n",
187 progname);
188 quit(1);
189 }
190
191
192 headline(s) /* get relevant info from header */
193 char *s;
194 {
195 static char *altname[] = {"rview","rpict","pinterp",VIEWSTR,NULL};
196 register char **an;
197 char fmt[32];
198
199 if (isexpos(s))
200 exposure *= exposval(s);
201 else if (isformat(s)) {
202 formatval(fmt, s);
203 wrongformat = strcmp(fmt, COLRFMT);
204 } else
205 for (an = altname; *an != NULL; an++)
206 if (!strncmp(*an, s, strlen(*an))) {
207 if (sscanview(&ourview, s+strlen(*an)) > 0)
208 gotview++;
209 return;
210 }
211 }
212
213
214 init() /* get data and open window */
215 {
216 XWMHints ourxwmhints;
217 XSetWindowAttributes ourwinattr;
218 XSizeHints oursizhints;
219 register int i;
220
221 if (fname != NULL) {
222 scanpos = (long *)malloc(ymax*sizeof(long));
223 if (scanpos == NULL)
224 goto memerr;
225 for (i = 0; i < ymax; i++)
226 scanpos[i] = -1;
227 }
228 if ((thedisplay = XOpenDisplay(NULL)) == NULL)
229 quiterr("can't open display; DISPLAY variable set?");
230 if (maxcolors == 0) { /* get number of available colors */
231 i = DisplayPlanes(thedisplay,ourscreen);
232 maxcolors = i > 8 ? 256 : 1<<i;
233 if (maxcolors > 4) maxcolors -= 2;
234 }
235 /* store image */
236 getras();
237 /* open window */
238 ourwinattr.border_pixel = ourblack;
239 ourwinattr.background_pixel = ourwhite;
240 wind = XCreateWindow(thedisplay, ourroot, 0, 0, xmax, ymax, BORWIDTH,
241 0, InputOutput, ourras->visual,
242 CWBackPixel|CWBorderPixel, &ourwinattr);
243 if (wind == 0)
244 quiterr("can't create window");
245 width = xmax;
246 height = ymax;
247 fontid = XLoadFont(thedisplay, FONTNAME);
248 if (fontid == 0)
249 quiterr("can't get font");
250 XSetFont(thedisplay, ourgc, fontid);
251 revgc = XCreateGC(thedisplay, wind, 0, 0);
252 XSetFunction(thedisplay, revgc, GXinvert);
253 XDefineCursor(thedisplay, wind, XCreateFontCursor(thedisplay,
254 XC_diamond_cross));
255 XStoreName(thedisplay, wind, fname == NULL ? progname : fname);
256 if (geometry != NULL) {
257 bzero((char *)&oursizhints, sizeof(oursizhints));
258 i = XParseGeometry(geometry, &oursizhints.x, &oursizhints.y,
259 (unsigned *)&oursizhints.width,
260 (unsigned *)&oursizhints.height);
261 if ((i&(WidthValue|HeightValue)) == (WidthValue|HeightValue))
262 oursizhints.flags |= USSize;
263 else {
264 oursizhints.width = xmax;
265 oursizhints.height = ymax;
266 oursizhints.flags |= PSize;
267 }
268 if ((i&(XValue|YValue)) == (XValue|YValue)) {
269 oursizhints.flags |= USPosition;
270 if (i & XNegative)
271 oursizhints.x += DisplayWidth(thedisplay,
272 ourscreen)-1-oursizhints.width-2*BORWIDTH;
273 if (i & YNegative)
274 oursizhints.y += DisplayHeight(thedisplay,
275 ourscreen)-1-oursizhints.height-2*BORWIDTH;
276 }
277 XSetNormalHints(thedisplay, wind, &oursizhints);
278 }
279 ourxwmhints.flags = InputHint|IconPixmapHint;
280 ourxwmhints.input = True;
281 ourxwmhints.icon_pixmap = XCreateBitmapFromData(thedisplay,
282 wind, icondata, iconwidth, iconheight);
283 XSetWMHints(thedisplay, wind, &ourxwmhints);
284 XSelectInput(thedisplay, wind, ButtonPressMask|ButtonReleaseMask
285 |ButtonMotionMask|StructureNotifyMask
286 |KeyPressMask|ExposureMask);
287 XMapWindow(thedisplay, wind);
288 return;
289 memerr:
290 quiterr("out of memory");
291 } /* end of init */
292
293
294 quiterr(err) /* print message and exit */
295 char *err;
296 {
297 if (err != NULL) {
298 fprintf(stderr, "%s: %s\n", progname, err);
299 exit(1);
300 }
301 exit(0);
302 }
303
304
305 eputs(s)
306 char *s;
307 {
308 fputs(s, stderr);
309 }
310
311
312 quit(code)
313 int code;
314 {
315 exit(code);
316 }
317
318
319 getras() /* get raster file */
320 {
321 colormap ourmap;
322 XVisualInfo vinfo;
323
324 if (maxcolors <= 2) { /* monochrome */
325 ourdata = (unsigned char *)malloc(ymax*((xmax+7)/8));
326 if (ourdata == NULL)
327 goto fail;
328 ourras = make_raster(thedisplay, ourscreen, 1, ourdata,
329 xmax, ymax, 8);
330 if (ourras == NULL)
331 goto fail;
332 getmono();
333 } else if (XMatchVisualInfo(thedisplay,ourscreen,24,TrueColor,&vinfo)
334 /* kludge for DirectColor */
335 || XMatchVisualInfo(thedisplay,ourscreen,24,DirectColor,&vinfo)) {
336 ourdata = (unsigned char *)malloc(xmax*ymax*3);
337 if (ourdata == NULL)
338 goto fail;
339 ourras = make_raster(thedisplay, ourscreen, 24, ourdata,
340 xmax, ymax, 8);
341 if (ourras == NULL)
342 goto fail;
343 getfull();
344 } else {
345 ourdata = (unsigned char *)malloc(xmax*ymax);
346 if (ourdata == NULL)
347 goto fail;
348 ourras = make_raster(thedisplay, ourscreen, 8, ourdata,
349 xmax, ymax, 8);
350 if (ourras == NULL)
351 goto fail;
352 if (greyscale)
353 biq(dither,maxcolors,1,ourmap);
354 else
355 ciq(dither,maxcolors,1,ourmap);
356 if (init_rcolors(ourras, ourmap[0], ourmap[1], ourmap[2]) == 0)
357 goto fail;
358 }
359 return;
360 fail:
361 quiterr("could not create raster image");
362 }
363
364
365 getevent() /* process the next event */
366 {
367 union {
368 XEvent u;
369 XConfigureEvent c;
370 XExposeEvent e;
371 XButtonPressedEvent b;
372 XKeyPressedEvent k;
373 } e;
374
375 XNextEvent(thedisplay, &e.u);
376 switch (e.u.type) {
377 case KeyPress:
378 docom(&e.k);
379 break;
380 case ConfigureNotify:
381 width = e.c.width;
382 height = e.c.height;
383 break;
384 case MapNotify:
385 map_rcolors(ourras, wind);
386 if (fast)
387 make_rpixmap(ourras);
388 break;
389 case UnmapNotify:
390 unmap_rcolors(ourras);
391 break;
392 case Expose:
393 redraw(e.e.x, e.e.y, e.e.width, e.e.height);
394 break;
395 case ButtonPress:
396 if (e.b.state & (ShiftMask|ControlMask))
397 moveimage(&e.b);
398 else
399 getbox(&e.b);
400 break;
401 }
402 }
403
404
405 docom(ekey) /* execute command */
406 XKeyPressedEvent *ekey;
407 {
408 char buf[80];
409 COLOR cval;
410 XColor cvx;
411 int com, n;
412 double comp;
413 FLOAT hv[2];
414 FVECT rorg, rdir;
415
416 n = XLookupString(ekey, buf, sizeof(buf), NULL, NULL);
417 if (n == 0)
418 return(0);
419 com = buf[0];
420 switch (com) { /* interpret command */
421 case 'q':
422 case CTRL(D): /* quit */
423 quit(0);
424 case '\n':
425 case '\r':
426 case 'l':
427 case 'c': /* value */
428 if (avgbox(cval) == -1)
429 return(-1);
430 switch (com) {
431 case '\n':
432 case '\r': /* radiance */
433 sprintf(buf, "%.3f", intens(cval)/exposure);
434 break;
435 case 'l': /* luminance */
436 sprintf(buf, "%.0fL", luminance(cval)/exposure);
437 break;
438 case 'c': /* color */
439 comp = pow(2.0, (double)scale);
440 sprintf(buf, "(%.2f,%.2f,%.2f)",
441 colval(cval,RED)*comp,
442 colval(cval,GRN)*comp,
443 colval(cval,BLU)*comp);
444 break;
445 }
446 XDrawImageString(thedisplay, wind, ourgc,
447 box.xmin, box.ymin+box.ysiz, buf, strlen(buf));
448 return(0);
449 case 'i': /* identify (contour) */
450 if (ourras->pixels == NULL)
451 return(-1);
452 n = ourdata[ekey->x-xoff+xmax*(ekey->y-yoff)];
453 n = ourras->pmap[n];
454 cvx.pixel = ourras->cdefs[n].pixel;
455 cvx.red = random() & 65535;
456 cvx.green = random() & 65535;
457 cvx.blue = random() & 65535;
458 cvx.flags = DoRed|DoGreen|DoBlue;
459 XStoreColor(thedisplay, ourras->cmap, &cvx);
460 return(0);
461 case 'p': /* position */
462 pix2loc(hv, &inpres, ekey->x-xoff, ekey->y-yoff);
463 sprintf(buf, "(%d,%d)", (int)(hv[0]*inpres.xr),
464 (int)(hv[1]*inpres.yr));
465 XDrawImageString(thedisplay, wind, ourgc, ekey->x, ekey->y,
466 buf, strlen(buf));
467 return(0);
468 case 't': /* trace */
469 if (!gotview) {
470 XBell(thedisplay, 0);
471 return(-1);
472 }
473 pix2loc(hv, &inpres, ekey->x-xoff, ekey->y-yoff);
474 if (viewray(rorg, rdir, &ourview, hv[0], hv[1]) < 0)
475 return(-1);
476 printf("%e %e %e ", rorg[0], rorg[1], rorg[2]);
477 printf("%e %e %e\n", rdir[0], rdir[1], rdir[2]);
478 fflush(stdout);
479 return(0);
480 case '=': /* adjust exposure */
481 if (avgbox(cval) == -1)
482 return(-1);
483 n = log(.5/bright(cval))/.69315 - scale; /* truncate */
484 if (n == 0)
485 return(0);
486 scale_rcolors(ourras, pow(2.0, (double)n));
487 scale += n;
488 sprintf(buf, "%+d", scale);
489 XDrawImageString(thedisplay, wind, ourgc,
490 box.xmin, box.ymin+box.ysiz, buf, strlen(buf));
491 XFlush(thedisplay);
492 free(ourdata);
493 free_raster(ourras);
494 getras();
495 /* fall through */
496 case CTRL(R): /* redraw */
497 case CTRL(L):
498 unmap_rcolors(ourras);
499 XClearWindow(thedisplay, wind);
500 map_rcolors(ourras, wind);
501 if (fast)
502 make_rpixmap(ourras);
503 redraw(0, 0, width, height);
504 return(0);
505 case ' ': /* clear */
506 redraw(box.xmin, box.ymin, box.xsiz, box.ysiz);
507 return(0);
508 default:
509 XBell(thedisplay, 0);
510 return(-1);
511 }
512 }
513
514
515 moveimage(ebut) /* shift the image */
516 XButtonPressedEvent *ebut;
517 {
518 union {
519 XEvent u;
520 XButtonReleasedEvent b;
521 XPointerMovedEvent m;
522 } e;
523 int mxo, myo;
524
525 XMaskEvent(thedisplay, ButtonReleaseMask|ButtonMotionMask, &e.u);
526 while (e.u.type == MotionNotify) {
527 mxo = e.m.x;
528 myo = e.m.y;
529 revline(ebut->x, ebut->y, mxo, myo);
530 revbox(xoff+mxo-ebut->x, yoff+myo-ebut->y,
531 xoff+mxo-ebut->x+xmax, yoff+myo-ebut->y+ymax);
532 XMaskEvent(thedisplay,ButtonReleaseMask|ButtonMotionMask,&e.u);
533 revline(ebut->x, ebut->y, mxo, myo);
534 revbox(xoff+mxo-ebut->x, yoff+myo-ebut->y,
535 xoff+mxo-ebut->x+xmax, yoff+myo-ebut->y+ymax);
536 }
537 xoff += e.b.x - ebut->x;
538 yoff += e.b.y - ebut->y;
539 XClearWindow(thedisplay, wind);
540 redraw(0, 0, width, height);
541 }
542
543
544 getbox(ebut) /* get new box */
545 XButtonPressedEvent *ebut;
546 {
547 union {
548 XEvent u;
549 XButtonReleasedEvent b;
550 XPointerMovedEvent m;
551 } e;
552
553 XMaskEvent(thedisplay, ButtonReleaseMask|ButtonMotionMask, &e.u);
554 while (e.u.type == MotionNotify) {
555 revbox(ebut->x, ebut->y, box.xmin = e.m.x, box.ymin = e.m.y);
556 XMaskEvent(thedisplay,ButtonReleaseMask|ButtonMotionMask,&e.u);
557 revbox(ebut->x, ebut->y, box.xmin, box.ymin);
558 }
559 box.xmin = e.b.x<0 ? 0 : (e.b.x>=width ? width-1 : e.b.x);
560 box.ymin = e.b.y<0 ? 0 : (e.b.y>=height ? height-1 : e.b.y);
561 if (box.xmin > ebut->x) {
562 box.xsiz = box.xmin - ebut->x + 1;
563 box.xmin = ebut->x;
564 } else {
565 box.xsiz = ebut->x - box.xmin + 1;
566 }
567 if (box.ymin > ebut->y) {
568 box.ysiz = box.ymin - ebut->y + 1;
569 box.ymin = ebut->y;
570 } else {
571 box.ysiz = ebut->y - box.ymin + 1;
572 }
573 }
574
575
576 revbox(x0, y0, x1, y1) /* draw box with reversed lines */
577 int x0, y0, x1, y1;
578 {
579 revline(x0, y0, x1, y0);
580 revline(x0, y1, x1, y1);
581 revline(x0, y0, x0, y1);
582 revline(x1, y0, x1, y1);
583 }
584
585
586 avgbox(clr) /* average color over current box */
587 COLOR clr;
588 {
589 static COLOR lc;
590 static int ll, lr, lt, lb;
591 int left, right, top, bottom;
592 int y;
593 double d;
594 COLOR ctmp;
595 register int x;
596
597 setcolor(clr, 0.0, 0.0, 0.0);
598 left = box.xmin - xoff;
599 right = left + box.xsiz;
600 if (left < 0)
601 left = 0;
602 if (right > xmax)
603 right = xmax;
604 if (left >= right)
605 return(-1);
606 top = box.ymin - yoff;
607 bottom = top + box.ysiz;
608 if (top < 0)
609 top = 0;
610 if (bottom > ymax)
611 bottom = ymax;
612 if (top >= bottom)
613 return(-1);
614 if (left == ll && right == lr && top == lt && bottom == lb) {
615 copycolor(clr, lc);
616 return;
617 }
618 for (y = top; y < bottom; y++) {
619 if (getscan(y) == -1)
620 return(-1);
621 for (x = left; x < right; x++) {
622 colr_color(ctmp, scanline[x]);
623 addcolor(clr, ctmp);
624 }
625 }
626 d = 1.0/((right-left)*(bottom-top));
627 scalecolor(clr, d);
628 ll = left; lr = right; lt = top; lb = bottom;
629 copycolor(lc, clr);
630 return(0);
631 }
632
633
634 getmono() /* get monochrome data */
635 {
636 register unsigned char *dp;
637 register int x, err;
638 int y, errp;
639 short *cerr;
640
641 if ((cerr = (short *)calloc(xmax,sizeof(short))) == NULL)
642 quiterr("out of memory in getmono");
643 dp = ourdata - 1;
644 for (y = 0; y < ymax; y++) {
645 if (getscan(y) < 0)
646 quiterr("seek error in getmono");
647 normcolrs(scanline, xmax, scale);
648 add2icon(y, scanline);
649 err = 0;
650 for (x = 0; x < xmax; x++) {
651 if (!(x&7))
652 *++dp = 0;
653 errp = err;
654 err += normbright(scanline[x]) + cerr[x];
655 if (err > 127)
656 err -= 255;
657 else
658 *dp |= 1<<(7-(x&07));
659 err /= 3;
660 cerr[x] = err + errp;
661 }
662 }
663 free((char *)cerr);
664 }
665
666
667 add2icon(y, scan) /* add a scanline to our icon data */
668 int y;
669 COLR *scan;
670 {
671 static short cerr[ICONSIZ];
672 static int ynext;
673 static char *dp;
674 register int err;
675 register int x, ti;
676 int errp;
677
678 if (iconheight == 0) { /* initialize */
679 if (xmax <= ICONSIZ && ymax <= ICONSIZ) {
680 iconwidth = xmax;
681 iconheight = ymax;
682 } else if (xmax > ymax) {
683 iconwidth = ICONSIZ;
684 iconheight = ICONSIZ*ymax/xmax;
685 if (iconheight < 1)
686 iconheight = 1;
687 } else {
688 iconwidth = ICONSIZ*xmax/ymax;
689 if (iconwidth < 1)
690 iconwidth = 1;
691 iconheight = ICONSIZ;
692 }
693 ynext = 0;
694 dp = icondata - 1;
695 }
696 if (y < ynext*ymax/iconheight) /* skip this one */
697 return;
698 err = 0;
699 for (x = 0; x < iconwidth; x++) {
700 if (!(x&7))
701 *++dp = 0;
702 errp = err;
703 ti = x*xmax/iconwidth;
704 err += normbright(scan[ti]) + cerr[x];
705 if (err > 127)
706 err -= 255;
707 else
708 *dp |= 1<<(x&07);
709 err /= 3;
710 cerr[x] = err + errp;
711 }
712 ynext++;
713 }
714
715
716 getfull() /* get full (24-bit) data */
717 {
718 int y;
719 register unsigned char *dp;
720 register int x;
721 /* set gamma correction */
722 setcolrgam(gamcor);
723 /* read and convert file */
724 dp = ourdata;
725 for (y = 0; y < ymax; y++) {
726 if (getscan(y) < 0)
727 quiterr("seek error in getfull");
728 if (scale)
729 shiftcolrs(scanline, xmax, scale);
730 colrs_gambs(scanline, xmax);
731 add2icon(y, scanline);
732 for (x = 0; x < xmax; x++) {
733 *dp++ = scanline[x][RED];
734 *dp++ = scanline[x][GRN];
735 *dp++ = scanline[x][BLU];
736 }
737 }
738 }
739
740
741 scale_rcolors(xr, sf) /* scale color map */
742 register XRASTER *xr;
743 double sf;
744 {
745 register int i;
746 long maxv;
747
748 if (xr->pixels == NULL)
749 return;
750
751 sf = pow(sf, 1.0/gamcor);
752 maxv = 65535/sf;
753
754 for (i = xr->ncolors; i--; ) {
755 xr->cdefs[i].red = xr->cdefs[i].red > maxv ?
756 65535 :
757 xr->cdefs[i].red * sf;
758 xr->cdefs[i].green = xr->cdefs[i].green > maxv ?
759 65535 :
760 xr->cdefs[i].green * sf;
761 xr->cdefs[i].blue = xr->cdefs[i].blue > maxv ?
762 65535 :
763 xr->cdefs[i].blue * sf;
764 }
765 XStoreColors(thedisplay, xr->cmap, xr->cdefs, xr->ncolors);
766 }
767
768
769 getscan(y)
770 int y;
771 {
772 if (y != cury) {
773 if (scanpos == NULL || scanpos[y] == -1)
774 return(-1);
775 if (fseek(fin, scanpos[y], 0) == -1)
776 quiterr("fseek error");
777 cury = y;
778 } else if (scanpos != NULL)
779 scanpos[y] = ftell(fin);
780
781 if (freadcolrs(scanline, xmax, fin) < 0)
782 quiterr("read error");
783
784 cury++;
785 return(0);
786 }
787
788
789 picreadline3(y, l3) /* read in 3-byte scanline */
790 int y;
791 register rgbpixel *l3;
792 {
793 register int i;
794 /* read scanline */
795 if (getscan(y) < 0)
796 quiterr("cannot seek for picreadline");
797 /* convert scanline */
798 normcolrs(scanline, xmax, scale);
799 add2icon(y, scanline);
800 for (i = 0; i < xmax; i++) {
801 l3[i].r = scanline[i][RED];
802 l3[i].g = scanline[i][GRN];
803 l3[i].b = scanline[i][BLU];
804 }
805 }
806
807
808 picwriteline(y, l) /* add 8-bit scanline to image */
809 int y;
810 pixel *l;
811 {
812 bcopy((char *)l, (char *)ourdata+y*xmax, xmax);
813 }
814
815
816 picreadcm(map) /* do gamma correction */
817 colormap map;
818 {
819 extern double pow();
820 register int i, val;
821
822 for (i = 0; i < 256; i++) {
823 val = pow((i+0.5)/256.0, 1.0/gamcor) * 256.0;
824 map[0][i] = map[1][i] = map[2][i] = val;
825 }
826 }
827
828
829 picwritecm(map) /* handled elsewhere */
830 colormap map;
831 {
832 #ifdef DEBUG
833 register int i;
834
835 for (i = 0; i < 256; i++)
836 printf("%d %d %d\n", map[0][i],map[1][i],map[2][i]);
837 #endif
838 }