ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/x11image.c
Revision: 1.21
Committed: Fri May 3 12:01:44 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.20: +8 -1 lines
Log Message:
makes sure that image is up before StoreName() call

File Contents

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