ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/x11image.c
Revision: 2.4
Committed: Tue Apr 28 09:40:32 1992 UTC (32 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.3: +2 -9 lines
Log Message:
changed calls to get view parameters from files

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 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 char fmt[32];
196
197 if (isexpos(s))
198 exposure *= exposval(s);
199 else if (isformat(s)) {
200 formatval(fmt, s);
201 wrongformat = strcmp(fmt, COLRFMT);
202 } else if (isview(s) && sscanview(&ourview, s) > 0)
203 gotview++;
204 }
205
206
207 init() /* get data and open window */
208 {
209 XWMHints ourxwmhints;
210 XSetWindowAttributes ourwinattr;
211 XSizeHints oursizhints;
212 register int i;
213
214 if (fname != NULL) {
215 scanpos = (long *)malloc(ymax*sizeof(long));
216 if (scanpos == NULL)
217 goto memerr;
218 for (i = 0; i < ymax; i++)
219 scanpos[i] = -1;
220 }
221 if ((thedisplay = XOpenDisplay(NULL)) == NULL)
222 quiterr("can't open display; DISPLAY variable set?");
223 if (maxcolors == 0) { /* get number of available colors */
224 i = DisplayPlanes(thedisplay,ourscreen);
225 maxcolors = i > 8 ? 256 : 1<<i;
226 if (maxcolors > 4) maxcolors -= 2;
227 }
228 /* store image */
229 getras();
230 /* open window */
231 ourwinattr.border_pixel = ourblack;
232 ourwinattr.background_pixel = ourwhite;
233 wind = XCreateWindow(thedisplay, ourroot, 0, 0, xmax, ymax, BORWIDTH,
234 0, InputOutput, ourras->visual,
235 CWBackPixel|CWBorderPixel, &ourwinattr);
236 if (wind == 0)
237 quiterr("can't create window");
238 width = xmax;
239 height = ymax;
240 fontid = XLoadFont(thedisplay, FONTNAME);
241 if (fontid == 0)
242 quiterr("can't get font");
243 XSetFont(thedisplay, ourgc, fontid);
244 revgc = XCreateGC(thedisplay, wind, 0, 0);
245 XSetFunction(thedisplay, revgc, GXinvert);
246 XDefineCursor(thedisplay, wind, XCreateFontCursor(thedisplay,
247 XC_diamond_cross));
248 XStoreName(thedisplay, wind, fname == NULL ? progname : fname);
249 if (geometry != NULL) {
250 bzero((char *)&oursizhints, sizeof(oursizhints));
251 i = XParseGeometry(geometry, &oursizhints.x, &oursizhints.y,
252 (unsigned *)&oursizhints.width,
253 (unsigned *)&oursizhints.height);
254 if ((i&(WidthValue|HeightValue)) == (WidthValue|HeightValue))
255 oursizhints.flags |= USSize;
256 else {
257 oursizhints.width = xmax;
258 oursizhints.height = ymax;
259 oursizhints.flags |= PSize;
260 }
261 if ((i&(XValue|YValue)) == (XValue|YValue)) {
262 oursizhints.flags |= USPosition;
263 if (i & XNegative)
264 oursizhints.x += DisplayWidth(thedisplay,
265 ourscreen)-1-oursizhints.width-2*BORWIDTH;
266 if (i & YNegative)
267 oursizhints.y += DisplayHeight(thedisplay,
268 ourscreen)-1-oursizhints.height-2*BORWIDTH;
269 }
270 XSetNormalHints(thedisplay, wind, &oursizhints);
271 }
272 ourxwmhints.flags = InputHint|IconPixmapHint;
273 ourxwmhints.input = True;
274 ourxwmhints.icon_pixmap = XCreateBitmapFromData(thedisplay,
275 wind, icondata, iconwidth, iconheight);
276 XSetWMHints(thedisplay, wind, &ourxwmhints);
277 XSelectInput(thedisplay, wind, ButtonPressMask|ButtonReleaseMask
278 |ButtonMotionMask|StructureNotifyMask
279 |KeyPressMask|ExposureMask);
280 XMapWindow(thedisplay, wind);
281 return;
282 memerr:
283 quiterr("out of memory");
284 } /* end of init */
285
286
287 quiterr(err) /* print message and exit */
288 char *err;
289 {
290 if (err != NULL) {
291 fprintf(stderr, "%s: %s\n", progname, err);
292 exit(1);
293 }
294 exit(0);
295 }
296
297
298 eputs(s)
299 char *s;
300 {
301 fputs(s, stderr);
302 }
303
304
305 quit(code)
306 int code;
307 {
308 exit(code);
309 }
310
311
312 getras() /* get raster file */
313 {
314 colormap ourmap;
315 XVisualInfo vinfo;
316
317 if (maxcolors <= 2) { /* monochrome */
318 ourdata = (unsigned char *)malloc(ymax*((xmax+7)/8));
319 if (ourdata == NULL)
320 goto fail;
321 ourras = make_raster(thedisplay, ourscreen, 1, ourdata,
322 xmax, ymax, 8);
323 if (ourras == NULL)
324 goto fail;
325 getmono();
326 } else if (XMatchVisualInfo(thedisplay,ourscreen,24,TrueColor,&vinfo)
327 /* kludge for DirectColor */
328 || XMatchVisualInfo(thedisplay,ourscreen,24,DirectColor,&vinfo)) {
329 ourdata = (unsigned char *)malloc(xmax*ymax*3);
330 if (ourdata == NULL)
331 goto fail;
332 ourras = make_raster(thedisplay, ourscreen, 24, ourdata,
333 xmax, ymax, 8);
334 if (ourras == NULL)
335 goto fail;
336 getfull();
337 } else {
338 ourdata = (unsigned char *)malloc(xmax*ymax);
339 if (ourdata == NULL)
340 goto fail;
341 ourras = make_raster(thedisplay, ourscreen, 8, ourdata,
342 xmax, ymax, 8);
343 if (ourras == NULL)
344 goto fail;
345 if (greyscale)
346 biq(dither,maxcolors,1,ourmap);
347 else
348 ciq(dither,maxcolors,1,ourmap);
349 if (init_rcolors(ourras, ourmap[0], ourmap[1], ourmap[2]) == 0)
350 goto fail;
351 }
352 return;
353 fail:
354 quiterr("could not create raster image");
355 }
356
357
358 getevent() /* process the next event */
359 {
360 union {
361 XEvent u;
362 XConfigureEvent c;
363 XExposeEvent e;
364 XButtonPressedEvent b;
365 XKeyPressedEvent k;
366 } e;
367
368 XNextEvent(thedisplay, &e.u);
369 switch (e.u.type) {
370 case KeyPress:
371 docom(&e.k);
372 break;
373 case ConfigureNotify:
374 width = e.c.width;
375 height = e.c.height;
376 break;
377 case MapNotify:
378 map_rcolors(ourras, wind);
379 if (fast)
380 make_rpixmap(ourras);
381 break;
382 case UnmapNotify:
383 unmap_rcolors(ourras);
384 break;
385 case Expose:
386 redraw(e.e.x, e.e.y, e.e.width, e.e.height);
387 break;
388 case ButtonPress:
389 if (e.b.state & (ShiftMask|ControlMask))
390 moveimage(&e.b);
391 else
392 getbox(&e.b);
393 break;
394 }
395 }
396
397
398 docom(ekey) /* execute command */
399 XKeyPressedEvent *ekey;
400 {
401 char buf[80];
402 COLOR cval;
403 XColor cvx;
404 int com, n;
405 double comp;
406 FLOAT hv[2];
407 FVECT rorg, rdir;
408
409 n = XLookupString(ekey, buf, sizeof(buf), NULL, NULL);
410 if (n == 0)
411 return(0);
412 com = buf[0];
413 switch (com) { /* interpret command */
414 case 'q':
415 case CTRL('D'): /* quit */
416 quit(0);
417 case '\n':
418 case '\r':
419 case 'l':
420 case 'c': /* value */
421 if (avgbox(cval) == -1)
422 return(-1);
423 switch (com) {
424 case '\n':
425 case '\r': /* radiance */
426 sprintf(buf, "%.3f", intens(cval)/exposure);
427 break;
428 case 'l': /* luminance */
429 sprintf(buf, "%.0fL", luminance(cval)/exposure);
430 break;
431 case 'c': /* color */
432 comp = pow(2.0, (double)scale);
433 sprintf(buf, "(%.2f,%.2f,%.2f)",
434 colval(cval,RED)*comp,
435 colval(cval,GRN)*comp,
436 colval(cval,BLU)*comp);
437 break;
438 }
439 XDrawImageString(thedisplay, wind, ourgc,
440 box.xmin, box.ymin+box.ysiz, buf, strlen(buf));
441 return(0);
442 case 'i': /* identify (contour) */
443 if (ourras->pixels == NULL)
444 return(-1);
445 n = ourdata[ekey->x-xoff+xmax*(ekey->y-yoff)];
446 n = ourras->pmap[n];
447 cvx.pixel = ourras->cdefs[n].pixel;
448 cvx.red = random() & 65535;
449 cvx.green = random() & 65535;
450 cvx.blue = random() & 65535;
451 cvx.flags = DoRed|DoGreen|DoBlue;
452 XStoreColor(thedisplay, ourras->cmap, &cvx);
453 return(0);
454 case 'p': /* position */
455 pix2loc(hv, &inpres, ekey->x-xoff, ekey->y-yoff);
456 sprintf(buf, "(%d,%d)", (int)(hv[0]*inpres.xr),
457 (int)(hv[1]*inpres.yr));
458 XDrawImageString(thedisplay, wind, ourgc, ekey->x, ekey->y,
459 buf, strlen(buf));
460 return(0);
461 case 't': /* trace */
462 if (!gotview) {
463 XBell(thedisplay, 0);
464 return(-1);
465 }
466 pix2loc(hv, &inpres, ekey->x-xoff, ekey->y-yoff);
467 if (viewray(rorg, rdir, &ourview, hv[0], hv[1]) < 0)
468 return(-1);
469 printf("%e %e %e ", rorg[0], rorg[1], rorg[2]);
470 printf("%e %e %e\n", rdir[0], rdir[1], rdir[2]);
471 fflush(stdout);
472 return(0);
473 case '=': /* adjust exposure */
474 if (avgbox(cval) == -1)
475 return(-1);
476 n = log(.5/bright(cval))/.69315 - scale; /* truncate */
477 if (n == 0)
478 return(0);
479 scale_rcolors(ourras, pow(2.0, (double)n));
480 scale += n;
481 sprintf(buf, "%+d", scale);
482 XDrawImageString(thedisplay, wind, ourgc,
483 box.xmin, box.ymin+box.ysiz, buf, strlen(buf));
484 XFlush(thedisplay);
485 free(ourdata);
486 free_raster(ourras);
487 getras();
488 /* fall through */
489 case CTRL('R'): /* redraw */
490 case CTRL('L'):
491 unmap_rcolors(ourras);
492 XClearWindow(thedisplay, wind);
493 map_rcolors(ourras, wind);
494 if (fast)
495 make_rpixmap(ourras);
496 redraw(0, 0, width, height);
497 return(0);
498 case ' ': /* clear */
499 redraw(box.xmin, box.ymin, box.xsiz, box.ysiz);
500 return(0);
501 default:
502 XBell(thedisplay, 0);
503 return(-1);
504 }
505 }
506
507
508 moveimage(ebut) /* shift the image */
509 XButtonPressedEvent *ebut;
510 {
511 union {
512 XEvent u;
513 XButtonReleasedEvent b;
514 XPointerMovedEvent m;
515 } e;
516 int mxo, myo;
517
518 XMaskEvent(thedisplay, ButtonReleaseMask|ButtonMotionMask, &e.u);
519 while (e.u.type == MotionNotify) {
520 mxo = e.m.x;
521 myo = e.m.y;
522 revline(ebut->x, ebut->y, mxo, myo);
523 revbox(xoff+mxo-ebut->x, yoff+myo-ebut->y,
524 xoff+mxo-ebut->x+xmax, yoff+myo-ebut->y+ymax);
525 XMaskEvent(thedisplay,ButtonReleaseMask|ButtonMotionMask,&e.u);
526 revline(ebut->x, ebut->y, mxo, myo);
527 revbox(xoff+mxo-ebut->x, yoff+myo-ebut->y,
528 xoff+mxo-ebut->x+xmax, yoff+myo-ebut->y+ymax);
529 }
530 xoff += e.b.x - ebut->x;
531 yoff += e.b.y - ebut->y;
532 XClearWindow(thedisplay, wind);
533 redraw(0, 0, width, height);
534 }
535
536
537 getbox(ebut) /* get new box */
538 XButtonPressedEvent *ebut;
539 {
540 union {
541 XEvent u;
542 XButtonReleasedEvent b;
543 XPointerMovedEvent m;
544 } e;
545
546 XMaskEvent(thedisplay, ButtonReleaseMask|ButtonMotionMask, &e.u);
547 while (e.u.type == MotionNotify) {
548 revbox(ebut->x, ebut->y, box.xmin = e.m.x, box.ymin = e.m.y);
549 XMaskEvent(thedisplay,ButtonReleaseMask|ButtonMotionMask,&e.u);
550 revbox(ebut->x, ebut->y, box.xmin, box.ymin);
551 }
552 box.xmin = e.b.x<0 ? 0 : (e.b.x>=width ? width-1 : e.b.x);
553 box.ymin = e.b.y<0 ? 0 : (e.b.y>=height ? height-1 : e.b.y);
554 if (box.xmin > ebut->x) {
555 box.xsiz = box.xmin - ebut->x + 1;
556 box.xmin = ebut->x;
557 } else {
558 box.xsiz = ebut->x - box.xmin + 1;
559 }
560 if (box.ymin > ebut->y) {
561 box.ysiz = box.ymin - ebut->y + 1;
562 box.ymin = ebut->y;
563 } else {
564 box.ysiz = ebut->y - box.ymin + 1;
565 }
566 }
567
568
569 revbox(x0, y0, x1, y1) /* draw box with reversed lines */
570 int x0, y0, x1, y1;
571 {
572 revline(x0, y0, x1, y0);
573 revline(x0, y1, x1, y1);
574 revline(x0, y0, x0, y1);
575 revline(x1, y0, x1, y1);
576 }
577
578
579 avgbox(clr) /* average color over current box */
580 COLOR clr;
581 {
582 static COLOR lc;
583 static int ll, lr, lt, lb;
584 int left, right, top, bottom;
585 int y;
586 double d;
587 COLOR ctmp;
588 register int x;
589
590 setcolor(clr, 0.0, 0.0, 0.0);
591 left = box.xmin - xoff;
592 right = left + box.xsiz;
593 if (left < 0)
594 left = 0;
595 if (right > xmax)
596 right = xmax;
597 if (left >= right)
598 return(-1);
599 top = box.ymin - yoff;
600 bottom = top + box.ysiz;
601 if (top < 0)
602 top = 0;
603 if (bottom > ymax)
604 bottom = ymax;
605 if (top >= bottom)
606 return(-1);
607 if (left == ll && right == lr && top == lt && bottom == lb) {
608 copycolor(clr, lc);
609 return;
610 }
611 for (y = top; y < bottom; y++) {
612 if (getscan(y) == -1)
613 return(-1);
614 for (x = left; x < right; x++) {
615 colr_color(ctmp, scanline[x]);
616 addcolor(clr, ctmp);
617 }
618 }
619 d = 1.0/((right-left)*(bottom-top));
620 scalecolor(clr, d);
621 ll = left; lr = right; lt = top; lb = bottom;
622 copycolor(lc, clr);
623 return(0);
624 }
625
626
627 getmono() /* get monochrome data */
628 {
629 register unsigned char *dp;
630 register int x, err;
631 int y, errp;
632 short *cerr;
633
634 if ((cerr = (short *)calloc(xmax,sizeof(short))) == NULL)
635 quiterr("out of memory in getmono");
636 dp = ourdata - 1;
637 for (y = 0; y < ymax; y++) {
638 if (getscan(y) < 0)
639 quiterr("seek error in getmono");
640 normcolrs(scanline, xmax, scale);
641 add2icon(y, scanline);
642 err = 0;
643 for (x = 0; x < xmax; x++) {
644 if (!(x&7))
645 *++dp = 0;
646 errp = err;
647 err += normbright(scanline[x]) + cerr[x];
648 if (err > 127)
649 err -= 255;
650 else
651 *dp |= 1<<(7-(x&07));
652 err /= 3;
653 cerr[x] = err + errp;
654 }
655 }
656 free((char *)cerr);
657 }
658
659
660 add2icon(y, scan) /* add a scanline to our icon data */
661 int y;
662 COLR *scan;
663 {
664 static short cerr[ICONSIZ];
665 static int ynext;
666 static char *dp;
667 register int err;
668 register int x, ti;
669 int errp;
670
671 if (iconheight == 0) { /* initialize */
672 if (xmax <= ICONSIZ && ymax <= ICONSIZ) {
673 iconwidth = xmax;
674 iconheight = ymax;
675 } else if (xmax > ymax) {
676 iconwidth = ICONSIZ;
677 iconheight = ICONSIZ*ymax/xmax;
678 if (iconheight < 1)
679 iconheight = 1;
680 } else {
681 iconwidth = ICONSIZ*xmax/ymax;
682 if (iconwidth < 1)
683 iconwidth = 1;
684 iconheight = ICONSIZ;
685 }
686 ynext = 0;
687 dp = icondata - 1;
688 }
689 if (y < ynext*ymax/iconheight) /* skip this one */
690 return;
691 err = 0;
692 for (x = 0; x < iconwidth; x++) {
693 if (!(x&7))
694 *++dp = 0;
695 errp = err;
696 ti = x*xmax/iconwidth;
697 err += normbright(scan[ti]) + cerr[x];
698 if (err > 127)
699 err -= 255;
700 else
701 *dp |= 1<<(x&07);
702 err /= 3;
703 cerr[x] = err + errp;
704 }
705 ynext++;
706 }
707
708
709 getfull() /* get full (24-bit) data */
710 {
711 int y;
712 register unsigned char *dp;
713 register int x;
714 /* set gamma correction */
715 setcolrgam(gamcor);
716 /* read and convert file */
717 dp = ourdata;
718 for (y = 0; y < ymax; y++) {
719 if (getscan(y) < 0)
720 quiterr("seek error in getfull");
721 if (scale)
722 shiftcolrs(scanline, xmax, scale);
723 colrs_gambs(scanline, xmax);
724 add2icon(y, scanline);
725 for (x = 0; x < xmax; x++) {
726 *dp++ = scanline[x][RED];
727 *dp++ = scanline[x][GRN];
728 *dp++ = scanline[x][BLU];
729 }
730 }
731 }
732
733
734 scale_rcolors(xr, sf) /* scale color map */
735 register XRASTER *xr;
736 double sf;
737 {
738 register int i;
739 long maxv;
740
741 if (xr->pixels == NULL)
742 return;
743
744 sf = pow(sf, 1.0/gamcor);
745 maxv = 65535/sf;
746
747 for (i = xr->ncolors; i--; ) {
748 xr->cdefs[i].red = xr->cdefs[i].red > maxv ?
749 65535 :
750 xr->cdefs[i].red * sf;
751 xr->cdefs[i].green = xr->cdefs[i].green > maxv ?
752 65535 :
753 xr->cdefs[i].green * sf;
754 xr->cdefs[i].blue = xr->cdefs[i].blue > maxv ?
755 65535 :
756 xr->cdefs[i].blue * sf;
757 }
758 XStoreColors(thedisplay, xr->cmap, xr->cdefs, xr->ncolors);
759 }
760
761
762 getscan(y)
763 int y;
764 {
765 if (y != cury) {
766 if (scanpos == NULL || scanpos[y] == -1)
767 return(-1);
768 if (fseek(fin, scanpos[y], 0) == -1)
769 quiterr("fseek error");
770 cury = y;
771 } else if (scanpos != NULL)
772 scanpos[y] = ftell(fin);
773
774 if (freadcolrs(scanline, xmax, fin) < 0)
775 quiterr("read error");
776
777 cury++;
778 return(0);
779 }
780
781
782 picreadline3(y, l3) /* read in 3-byte scanline */
783 int y;
784 register rgbpixel *l3;
785 {
786 register int i;
787 /* read scanline */
788 if (getscan(y) < 0)
789 quiterr("cannot seek for picreadline");
790 /* convert scanline */
791 normcolrs(scanline, xmax, scale);
792 add2icon(y, scanline);
793 for (i = 0; i < xmax; i++) {
794 l3[i].r = scanline[i][RED];
795 l3[i].g = scanline[i][GRN];
796 l3[i].b = scanline[i][BLU];
797 }
798 }
799
800
801 picwriteline(y, l) /* add 8-bit scanline to image */
802 int y;
803 pixel *l;
804 {
805 bcopy((char *)l, (char *)ourdata+y*xmax, xmax);
806 }
807
808
809 picreadcm(map) /* do gamma correction */
810 colormap map;
811 {
812 extern double pow();
813 register int i, val;
814
815 for (i = 0; i < 256; i++) {
816 val = pow((i+0.5)/256.0, 1.0/gamcor) * 256.0;
817 map[0][i] = map[1][i] = map[2][i] = val;
818 }
819 }
820
821
822 picwritecm(map) /* handled elsewhere */
823 colormap map;
824 {
825 #ifdef DEBUG
826 register int i;
827
828 for (i = 0; i < 256; i++)
829 printf("%d %d %d\n", map[0][i],map[1][i],map[2][i]);
830 #endif
831 }