ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/x11image.c
Revision: 1.20
Committed: Fri May 3 10:54:47 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.19: +8 -9 lines
Log Message:
fixed major bug in add2icon()

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 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*ICONSIZ/8]; /* 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 XDefineCursor(thedisplay, wind, XCreateFontCursor(thedisplay,
250 XC_diamond_cross));
251 if (geometry != NULL) {
252 bzero((char *)&oursizhints, sizeof(oursizhints));
253 i = XParseGeometry(geometry, &oursizhints.x, &oursizhints.y,
254 (unsigned *)&oursizhints.width,
255 (unsigned *)&oursizhints.height);
256 if ((i&(WidthValue|HeightValue)) == (WidthValue|HeightValue))
257 oursizhints.flags |= USSize;
258 else {
259 oursizhints.width = xmax;
260 oursizhints.height = ymax;
261 oursizhints.flags |= PSize;
262 }
263 if ((i&(XValue|YValue)) == (XValue|YValue)) {
264 oursizhints.flags |= USPosition;
265 if (i & XNegative)
266 oursizhints.x += DisplayWidth(thedisplay,
267 ourscreen)-1-oursizhints.width-2*BORWIDTH;
268 if (i & YNegative)
269 oursizhints.y += DisplayHeight(thedisplay,
270 ourscreen)-1-oursizhints.height-2*BORWIDTH;
271 }
272 XSetNormalHints(thedisplay, wind, &oursizhints);
273 }
274 ourxwmhints.flags = InputHint|IconPixmapHint;
275 ourxwmhints.input = True;
276 ourxwmhints.icon_pixmap = XCreateBitmapFromData(thedisplay,
277 wind, icondata, iconwidth, iconheight);
278 XSetWMHints(thedisplay, wind, &ourxwmhints);
279 XSelectInput(thedisplay, wind, ButtonPressMask|ButtonReleaseMask
280 |ButtonMotionMask|StructureNotifyMask
281 |KeyPressMask|ExposureMask);
282 XMapWindow(thedisplay, wind);
283 /* store name last as ready signal */
284 XStoreName(thedisplay, wind, fname == NULL ? progname : fname);
285 return;
286 memerr:
287 quiterr("out of memory");
288 } /* end of init */
289
290
291 quiterr(err) /* print message and exit */
292 char *err;
293 {
294 if (err != NULL) {
295 fprintf(stderr, "%s: %s\n", progname, err);
296 exit(1);
297 }
298 exit(0);
299 }
300
301
302 eputs(s)
303 char *s;
304 {
305 fputs(s, stderr);
306 }
307
308
309 quit(code)
310 int code;
311 {
312 exit(code);
313 }
314
315
316 getras() /* get raster file */
317 {
318 colormap ourmap;
319 XVisualInfo vinfo;
320
321 if (maxcolors <= 2) { /* monochrome */
322 ourdata = (unsigned char *)malloc(ymax*((xmax+7)/8));
323 if (ourdata == NULL)
324 goto fail;
325 ourras = make_raster(thedisplay, ourscreen, 1, ourdata,
326 xmax, ymax, 8);
327 if (ourras == NULL)
328 goto fail;
329 getmono();
330 } else if (XMatchVisualInfo(thedisplay,ourscreen,24,TrueColor,&vinfo)
331 /* kludge for DirectColor */
332 || XMatchVisualInfo(thedisplay,ourscreen,24,DirectColor,&vinfo)) {
333 ourdata = (unsigned char *)malloc(xmax*ymax*3);
334 if (ourdata == NULL)
335 goto fail;
336 ourras = make_raster(thedisplay, ourscreen, 24, ourdata,
337 xmax, ymax, 8);
338 if (ourras == NULL)
339 goto fail;
340 getfull();
341 } else {
342 ourdata = (unsigned char *)malloc(xmax*ymax);
343 if (ourdata == NULL)
344 goto fail;
345 ourras = make_raster(thedisplay, ourscreen, 8, ourdata,
346 xmax, ymax, 8);
347 if (ourras == NULL)
348 goto fail;
349 if (greyscale)
350 biq(dither,maxcolors,1,ourmap);
351 else
352 ciq(dither,maxcolors,1,ourmap);
353 if (init_rcolors(ourras, ourmap[0], ourmap[1], ourmap[2]) == 0)
354 goto fail;
355 }
356 return;
357 fail:
358 quiterr("could not create raster image");
359 }
360
361
362 getevent() /* process the next event */
363 {
364 union {
365 XEvent u;
366 XConfigureEvent c;
367 XExposeEvent e;
368 XButtonPressedEvent b;
369 XKeyPressedEvent k;
370 } e;
371
372 XNextEvent(thedisplay, &e.u);
373 switch (e.u.type) {
374 case KeyPress:
375 docom(&e.k);
376 break;
377 case ConfigureNotify:
378 width = e.c.width;
379 height = e.c.height;
380 break;
381 case MapNotify:
382 map_rcolors(ourras, wind);
383 if (fast)
384 make_rpixmap(ourras);
385 break;
386 case UnmapNotify:
387 unmap_rcolors(ourras);
388 break;
389 case Expose:
390 redraw(e.e.x, e.e.y, e.e.width, e.e.height);
391 break;
392 case ButtonPress:
393 if (e.b.state & (ShiftMask|ControlMask))
394 moveimage(&e.b);
395 else
396 getbox(&e.b);
397 break;
398 }
399 }
400
401
402 docom(ekey) /* execute command */
403 XKeyPressedEvent *ekey;
404 {
405 char buf[80];
406 COLOR cval;
407 XColor cvx;
408 int com, n;
409 double comp;
410 FVECT rorg, rdir;
411
412 n = XLookupString(ekey, buf, sizeof(buf), NULL, NULL);
413 if (n == 0)
414 return(0);
415 com = buf[0];
416 switch (com) { /* interpret command */
417 case 'q':
418 case CTRL(D): /* quit */
419 quit(0);
420 case '\n':
421 case '\r':
422 case 'l':
423 case 'c': /* value */
424 if (avgbox(cval) == -1)
425 return(-1);
426 switch (com) {
427 case '\n':
428 case '\r': /* radiance */
429 sprintf(buf, "%.3f", intens(cval)/exposure);
430 break;
431 case 'l': /* luminance */
432 sprintf(buf, "%.0fL", luminance(cval)/exposure);
433 break;
434 case 'c': /* color */
435 comp = pow(2.0, (double)scale);
436 sprintf(buf, "(%.2f,%.2f,%.2f)",
437 colval(cval,RED)*comp,
438 colval(cval,GRN)*comp,
439 colval(cval,BLU)*comp);
440 break;
441 }
442 XDrawImageString(thedisplay, wind, ourgc,
443 box.xmin, box.ymin+box.ysiz, buf, strlen(buf));
444 return(0);
445 case 'i': /* identify (contour) */
446 if (ourras->pixels == NULL)
447 return(-1);
448 n = ourdata[ekey->x-xoff+xmax*(ekey->y-yoff)];
449 n = ourras->pmap[n];
450 cvx.pixel = ourras->cdefs[n].pixel;
451 cvx.red = random() & 65535;
452 cvx.green = random() & 65535;
453 cvx.blue = random() & 65535;
454 cvx.flags = DoRed|DoGreen|DoBlue;
455 XStoreColor(thedisplay, ourras->cmap, &cvx);
456 return(0);
457 case 'p': /* position */
458 sprintf(buf, "(%d,%d)", ekey->x-xoff, ymax-1-ekey->y+yoff);
459 XDrawImageString(thedisplay, wind, ourgc, ekey->x, ekey->y,
460 buf, strlen(buf));
461 return(0);
462 case 't': /* trace */
463 if (!gotview) {
464 XBell(thedisplay, 0);
465 return(-1);
466 }
467 if (viewray(rorg, rdir, &ourview,
468 (ekey->x-xoff+.5)/xmax,
469 (ymax-1-ekey->y+yoff+.5)/ymax) < 0)
470 return(-1);
471 printf("%e %e %e ", rorg[0], rorg[1], rorg[2]);
472 printf("%e %e %e\n", rdir[0], rdir[1], rdir[2]);
473 fflush(stdout);
474 return(0);
475 case '=': /* adjust exposure */
476 if (avgbox(cval) == -1)
477 return(-1);
478 n = log(.5/bright(cval))/.69315 - scale; /* truncate */
479 if (n == 0)
480 return(0);
481 scale_rcolors(ourras, pow(2.0, (double)n));
482 scale += n;
483 sprintf(buf, "%+d", scale);
484 XDrawImageString(thedisplay, wind, ourgc,
485 box.xmin, box.ymin+box.ysiz, buf, strlen(buf));
486 XFlush(thedisplay);
487 free(ourdata);
488 free_raster(ourras);
489 getras();
490 /* fall through */
491 case CTRL(R): /* redraw */
492 case CTRL(L):
493 unmap_rcolors(ourras);
494 XClearWindow(thedisplay, wind);
495 map_rcolors(ourras, wind);
496 if (fast)
497 make_rpixmap(ourras);
498 redraw(0, 0, width, height);
499 return(0);
500 case ' ': /* clear */
501 redraw(box.xmin, box.ymin, box.xsiz, box.ysiz);
502 return(0);
503 default:
504 XBell(thedisplay, 0);
505 return(-1);
506 }
507 }
508
509
510 moveimage(ebut) /* shift the image */
511 XButtonPressedEvent *ebut;
512 {
513 union {
514 XEvent u;
515 XButtonReleasedEvent b;
516 XPointerMovedEvent m;
517 } e;
518 int mxo, myo;
519
520 XMaskEvent(thedisplay, ButtonReleaseMask|ButtonMotionMask, &e.u);
521 while (e.u.type == MotionNotify) {
522 mxo = e.m.x;
523 myo = e.m.y;
524 revline(ebut->x, ebut->y, mxo, myo);
525 revbox(xoff+mxo-ebut->x, yoff+myo-ebut->y,
526 xoff+mxo-ebut->x+xmax, yoff+myo-ebut->y+ymax);
527 XMaskEvent(thedisplay,ButtonReleaseMask|ButtonMotionMask,&e.u);
528 revline(ebut->x, ebut->y, mxo, myo);
529 revbox(xoff+mxo-ebut->x, yoff+myo-ebut->y,
530 xoff+mxo-ebut->x+xmax, yoff+myo-ebut->y+ymax);
531 }
532 xoff += e.b.x - ebut->x;
533 yoff += e.b.y - ebut->y;
534 XClearWindow(thedisplay, wind);
535 redraw(0, 0, width, height);
536 }
537
538
539 getbox(ebut) /* get new box */
540 XButtonPressedEvent *ebut;
541 {
542 union {
543 XEvent u;
544 XButtonReleasedEvent b;
545 XPointerMovedEvent m;
546 } e;
547
548 XMaskEvent(thedisplay, ButtonReleaseMask|ButtonMotionMask, &e.u);
549 while (e.u.type == MotionNotify) {
550 revbox(ebut->x, ebut->y, box.xmin = e.m.x, box.ymin = e.m.y);
551 XMaskEvent(thedisplay,ButtonReleaseMask|ButtonMotionMask,&e.u);
552 revbox(ebut->x, ebut->y, box.xmin, box.ymin);
553 }
554 box.xmin = e.b.x<0 ? 0 : (e.b.x>=width ? width-1 : e.b.x);
555 box.ymin = e.b.y<0 ? 0 : (e.b.y>=height ? height-1 : e.b.y);
556 if (box.xmin > ebut->x) {
557 box.xsiz = box.xmin - ebut->x + 1;
558 box.xmin = ebut->x;
559 } else {
560 box.xsiz = ebut->x - box.xmin + 1;
561 }
562 if (box.ymin > ebut->y) {
563 box.ysiz = box.ymin - ebut->y + 1;
564 box.ymin = ebut->y;
565 } else {
566 box.ysiz = ebut->y - box.ymin + 1;
567 }
568 }
569
570
571 revbox(x0, y0, x1, y1) /* draw box with reversed lines */
572 int x0, y0, x1, y1;
573 {
574 revline(x0, y0, x1, y0);
575 revline(x0, y1, x1, y1);
576 revline(x0, y0, x0, y1);
577 revline(x1, y0, x1, y1);
578 }
579
580
581 avgbox(clr) /* average color over current box */
582 COLOR clr;
583 {
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 for (y = top; y < bottom; y++) {
608 if (getscan(y) == -1)
609 return(-1);
610 for (x = left; x < right; x++) {
611 colr_color(ctmp, scanline[x]);
612 addcolor(clr, ctmp);
613 }
614 }
615 d = 1.0/((right-left)*(bottom-top));
616 scalecolor(clr, d);
617 return(0);
618 }
619
620
621 getmono() /* get monochrome data */
622 {
623 register unsigned char *dp;
624 register int x, err;
625 int y;
626 short *cerr;
627
628 if ((cerr = (short *)calloc(xmax,sizeof(short))) == NULL)
629 quiterr("out of memory in getmono");
630 dp = ourdata - 1;
631 for (y = 0; y < ymax; y++) {
632 if (getscan(y) < 0)
633 quiterr("seek error in getmono");
634 normcolrs(scanline, xmax, scale);
635 add2icon(y, scanline);
636 err = 0;
637 for (x = 0; x < xmax; x++) {
638 if (!(x&7))
639 *++dp = 0;
640 err += normbright(scanline[x]) + cerr[x];
641 if (err > 127)
642 err -= 255;
643 else
644 *dp |= 1<<(7-(x&07));
645 cerr[x] = err >>= 1;
646 }
647 }
648 free((char *)cerr);
649 }
650
651
652 add2icon(y, scan) /* add a scanline to our icon data */
653 int y;
654 COLR *scan;
655 {
656 static short cerr[ICONSIZ];
657 static int ynext;
658 static char *dp;
659 register int err;
660 register int x, ti;
661
662 if (iconheight == 0) { /* initialize */
663 if (xmax <= ICONSIZ && ymax <= ICONSIZ) {
664 iconwidth = xmax;
665 iconheight = ymax;
666 } else if (xmax > ymax) {
667 iconwidth = ICONSIZ;
668 iconheight = ICONSIZ*ymax/xmax;
669 } else {
670 iconwidth = ICONSIZ*xmax/ymax;
671 iconheight = ICONSIZ;
672 }
673 ynext = 0;
674 dp = icondata - 1;
675 }
676 if (y < ynext*ymax/iconheight) /* skip this one */
677 return;
678 err = 0;
679 for (x = 0; x < iconwidth; x++) {
680 if (!(x&7))
681 *++dp = 0;
682 ti = x*xmax/iconwidth;
683 err += normbright(scan[ti]) + cerr[x];
684 if (err > 127)
685 err -= 255;
686 else
687 *dp |= 1<<(x&07);
688 cerr[x] = err >>= 1;
689 }
690 ynext++;
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 }