ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/x11image.c
Revision: 1.17
Committed: Thu May 2 17:24:54 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.16: +52 -2 lines
Log Message:
added bitmap icon from image

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