ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ximage.c
(Generate patch)

Comparing ray/src/px/ximage.c (file contents):
Revision 1.1 by greg, Thu Feb 2 10:49:43 1989 UTC vs.
Revision 2.12 by schorsch, Mon Jun 30 14:59:12 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1987 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  ximage.c - driver for X-windows
6   *
# Line 18 | Line 15 | static char SCCSid[] = "$SunId$ LBL";
15   #include  <X/cursors/bcross_mask.cursor>
16  
17   #include  <sys/types.h>
18 <
18 > #include  <string.h>
19   #include  <ctype.h>
20 + #include  <time.h>
21  
22   #include  "color.h"
23 <
23 > #include  "resolu.h"
24   #include  "xraster.h"
27
25   #include  "view.h"
29
26   #include  "pic.h"
27 + #include  "random.h"
28  
29   #define  controlshift(e)        (((XButtonEvent *)(e))->detail & (ShiftMask|ControlMask))
30  
31   #define  FONTNAME       "9x15"          /* text font we'll use */
32  
33 < #define  CTRL(c)        ('c'-'@')
33 > #define  CTRL(c)        ((c)-'@')
34  
35   #define  BORWIDTH       5               /* border width */
36   #define  BARHEIGHT      25              /* menu bar size */
37  
38 < double  gamcor = 2.0;                   /* gamcor correction */
38 > double  gamcor = 2.2;                   /* gamma correction */
39  
40 < XRASTER  ourras;                        /* our stored raster image */
40 > XRASTER  *ourras = NULL;                /* our stored raster image */
41  
42   int  dither = 1;                        /* dither colors? */
43   int  fast = 0;                          /* keep picture in Pixmap? */
# Line 51 | Line 48 | Font  fontid;                          /* our font */
48   int  maxcolors = 0;                     /* maximum colors */
49   int  greyscale = 0;                     /* in grey */
50  
51 + int  scale = 0;                         /* scalefactor; power of two */
52 +
53   int  xoff = 0;                          /* x image offset */
54   int  yoff = 0;                          /* y image offset */
55  
56 < VIEW  ourview = STDVIEW(0);             /* image view parameters */
56 > VIEW  ourview = STDVIEW;                /* image view parameters */
57   int  gotview = 0;                       /* got parameters from file */
58  
59   COLR  *scanline;                        /* scan line buffer */
# Line 68 | Line 67 | int  cury = 0;                         /* current scan location */
67  
68   double  exposure = 1.0;                 /* exposure compensation used */
69  
70 + int  wrongformat = 0;                   /* input in another format */
71 +
72   struct {
73          int  xmin, ymin, xsiz, ysiz;
74   }  box = {0, 0, 0, 0};                  /* current box */
# Line 78 | Line 79 | char  *progname;
79  
80   char  errmsg[128];
81  
81 extern long  ftell();
82  
83 extern char  *malloc(), *calloc();
84
85 extern double  atof();
86
87
83   main(argc, argv)
84   int  argc;
85   char  *argv[];
86   {
87 +        extern char  *getenv();
88 +        char  *gv;
89          int  headline();
90          int  i;
91          
92          progname = argv[0];
93 +        if ((gv = getenv("DISPLAY_GAMMA")) != NULL)
94 +                gamcor = atof(gv);
95  
96          for (i = 1; i < argc; i++)
97                  if (argv[i][0] == '-')
# Line 112 | Line 111 | char  *argv[];
111                          case 'f':
112                                  fast = !fast;
113                                  break;
114 +                        case 'e':
115 +                                if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
116 +                                        goto userr;
117 +                                scale = atoi(argv[++i]);
118 +                                break;
119                          case 'g':
120                                  gamcor = atof(argv[++i]);
121                                  break;
# Line 130 | Line 134 | char  *argv[];
134                          sprintf(errmsg, "can't open file \"%s\"", fname);
135                          quiterr(errmsg);
136                  }
137 <        } else
134 <                goto userr;
135 <
137 >        }
138                                  /* get header */
139 <        getheader(fin, headline);
139 >        getheader(fin, headline, NULL);
140                                  /* get picture dimensions */
141 <        if (fscanf(fin, "-Y %d +X %d\n", &ymax, &xmax) != 2)
141 >        if (wrongformat || fgetresolu(&xmax, &ymax, fin) != (YMAJOR|YDECR))
142                  quiterr("bad picture size");
143                                  /* set view parameters */
144 <        if (gotview) {
145 <                ourview.hresolu = xmax;
144 <                ourview.vresolu = ymax;
145 <                if (setview(&ourview) != NULL)
146 <                        gotview = 0;
147 <        }
144 >        if (gotview && setview(&ourview) != NULL)
145 >                gotview = 0;
146          if ((scanline = (COLR *)malloc(xmax*sizeof(COLR))) == NULL)
147                  quiterr("out of memory");
148  
# Line 154 | Line 152 | char  *argv[];
152                  getevent();             /* main loop */
153   userr:
154          fprintf(stderr,
155 <        "Usage: %s [=geometry][-b][-m][-d][-f][-c ncolors] file\n",
155 >        "Usage: %s [=geometry][-b][-m][-d][-f][-c ncolors][-e +/-stops] file\n",
156                          progname);
157          quit(1);
158   }
159  
160  
161 + int
162   headline(s)             /* get relevant info from header */
163   char  *s;
164   {
165 <        static char  *altname[] = {"rview","rpict","VIEW=",NULL};
167 <        register char  **an;
165 >        char  fmt[32];
166  
167 <        if (!strncmp(s, "EXPOSURE=", 9))
168 <                exposure *= atof(s+9);
169 <        else
170 <                for (an = altname; *an != NULL; an++)
171 <                        if (!strncmp(*an, s, strlen(*an))) {
172 <                                if (sscanview(&ourview, s+strlen(*an)) == 0)
173 <                                        gotview++;
174 <                                return;
177 <                        }
167 >        if (isexpos(s))
168 >                exposure *= exposval(s);
169 >        else if (isformat(s)) {
170 >                formatval(fmt, s);
171 >                wrongformat = strcmp(fmt, COLRFMT);
172 >        } else if (isview(s) && sscanview(&ourview, s) > 0)
173 >                gotview++;
174 >        return(0);
175   }
176  
177  
181 char *
182 sskip(s)                /* skip a word */
183 register char  *s;
184 {
185        while (isspace(*s)) s++;
186        while (*s && !isspace(*s)) s++;
187        return(s);
188 }
189
190
178   init()                  /* get data and open window */
179   {
180          register int  i;
194        colormap  ourmap;
181          OpaqueFrame  mainframe;
182          char  defgeom[32];
183          
# Line 213 | Line 199 | init()                 /* get data and open window */
199                  maxcolors = 1<<DisplayPlanes();
200                  if (maxcolors > 4) maxcolors -= 2;
201          }
216        ourras.width = xmax;
217        ourras.height = ymax;
202                                  /* store image */
203 <        if (maxcolors <= 2) {           /* monochrome */
204 <                ourras.data.m = (unsigned short *)malloc(BitmapSize(xmax,ymax));
221 <                if (ourras.data.m == NULL)
222 <                        goto memerr;
223 <                getmono();
224 <        } else {
225 <                ourras.data.bz = (unsigned char *)malloc(BZPixmapSize(xmax,ymax));
226 <                if (ourras.data.bz == NULL)
227 <                        goto memerr;
228 <                if (greyscale)
229 <                        biq(dither,maxcolors,1,ourmap);
230 <                else
231 <                        ciq(dither,maxcolors,1,ourmap);
232 <                if (init_rcolors(&ourras, ourmap) == 0)
233 <                        goto memerr;
234 <        }
203 >        getras();
204 >
205          mainframe.bdrwidth = BORWIDTH;
206          mainframe.border = WhitePixmap;
207          mainframe.background = BlackPixmap;
# Line 270 | Line 240 | char  *err;
240   }
241  
242  
243 + void
244   eputs(s)
245   char    *s;
246   {
# Line 277 | Line 248 | char   *s;
248   }
249  
250  
251 + void
252   quit(code)
253   int  code;
254   {
# Line 284 | Line 256 | int  code;
256   }
257  
258  
259 + getras()                                /* get raster file */
260 + {
261 +        colormap        ourmap;
262 +
263 +        ourras = (XRASTER *)calloc(1, sizeof(XRASTER));
264 +        if (ourras == NULL)
265 +                goto memerr;
266 +        ourras->width = xmax;
267 +        ourras->height = ymax;
268 +        if (maxcolors <= 2) {           /* monochrome */
269 +                ourras->data.m = (unsigned short *)malloc(BitmapSize(xmax,ymax));
270 +                if (ourras->data.m == NULL)
271 +                        goto memerr;
272 +                getmono();
273 +        } else {
274 +                ourras->data.bz = (unsigned char *)malloc(BZPixmapSize(xmax,ymax));
275 +                if (ourras->data.bz == NULL)
276 +                        goto memerr;
277 +                if (greyscale)
278 +                        biq(dither,maxcolors,1,ourmap);
279 +                else
280 +                        ciq(dither,maxcolors,1,ourmap);
281 +                if (init_rcolors(ourras, ourmap) == 0)
282 +                        goto memerr;
283 +        }
284 +        return;
285 + memerr:
286 +        quiterr("out of memory");
287 + }
288 +
289 +
290   getevent()                              /* process the next event */
291   {
292          WindowInfo  info;
# Line 303 | Line 306 | getevent()                             /* process the next event */
306                  fixwindow(&e);
307                  break;
308          case UnmapWindow:
309 <                unmap_rcolors(&ourras);
309 >                unmap_rcolors(ourras);
310                  break;
311          case ButtonPressed:
312                  if (controlshift(&e))
# Line 326 | Line 329 | redraw(x, y, w, h)                     /* redraw section of window */
329   int  x, y;
330   int  w, h;
331   {
332 <        map_rcolors(&ourras);
332 >        if (ourras->ncolors && map_rcolors(ourras) == NULL) {
333 >                fprintf(stderr, "%s: cannot allocate colors\n", progname);
334 >                return(-1);
335 >        }
336          if (fast)
337 <                make_rpixmap(&ourras);
338 <        return(patch_raster(wind,x-xoff,y-yoff,x,y,w,h,&ourras) ? 0 : -1);
337 >                make_rpixmap(ourras);
338 >        return(patch_raster(wind,x-xoff,y-yoff,x,y,w,h,ourras) ? 0 : -1);
339   }
340  
341  
# Line 338 | Line 344 | XKeyEvent  *ekey;
344   {
345          char  buf[80];
346          COLOR  cval;
347 +        Color  cvx;
348          char  *cp;
349          int  n;
350 +        double  comp;
351          FVECT  rorg, rdir;
352  
353          cp = XLookupMapping(ekey, &n);
# Line 347 | Line 355 | XKeyEvent  *ekey;
355                  return(0);
356          switch (*cp) {                  /* interpret command */
357          case 'q':
358 <        case CTRL(D):                           /* quiterr */
358 >        case CTRL('D'):                         /* quit */
359                  quit(0);
360          case '\n':
361          case '\r':
# Line 358 | Line 366 | XKeyEvent  *ekey;
366                  switch (*cp) {
367                  case '\n':
368                  case '\r':                              /* radiance */
369 <                        sprintf(buf, "%-3g", intens(cval)/exposure);
369 >                        sprintf(buf, "%.3f", intens(cval)/exposure);
370                          break;
371                  case 'l':                               /* luminance */
372 <                        sprintf(buf, "%-3gL", bright(cval)*683.0/exposure);
372 >                        sprintf(buf, "%.0fL", luminance(cval)/exposure);
373                          break;
374                  case 'c':                               /* color */
375 +                        comp = pow(2.0, (double)scale);
376                          sprintf(buf, "(%.2f,%.2f,%.2f)",
377 <                                        colval(cval,RED),
378 <                                        colval(cval,GRN),
379 <                                        colval(cval,BLU));
377 >                                        colval(cval,RED)*comp,
378 >                                        colval(cval,GRN)*comp,
379 >                                        colval(cval,BLU)*comp);
380                          break;
381                  }
382                  XText(wind, box.xmin, box.ymin, buf, strlen(buf),
383                                  fontid, BlackPixel, WhitePixel);
384                  return(0);
385 +        case 'i':                               /* identify (contour) */
386 +                if (ourras->pixels == NULL)
387 +                        return(-1);
388 +                n = ourras->data.bz[ekey->x-xoff+BZPixmapSize(xmax,ekey->y-yoff)];
389 +                n = ourras->pmap[n];
390 +                cvx.pixel = ourras->cdefs[n].pixel;
391 +                cvx.red = random() & 65535;
392 +                cvx.green = random() & 65535;
393 +                cvx.blue = random() & 65535;
394 +                XStoreColor(&cvx);
395 +                return(0);
396          case 'p':                               /* position */
397                  sprintf(buf, "(%d,%d)", ekey->x-xoff, ymax-1-ekey->y+yoff);
398                  XText(wind, ekey->x, ekey->y, buf, strlen(buf),
# Line 383 | Line 403 | XKeyEvent  *ekey;
403                          XFeep(0);
404                          return(-1);
405                  }
406 <                rayview(rorg, rdir, &ourview,
407 <                                ekey->x-xoff + .5, ymax-1-ekey->y+yoff + .5);
406 >                if (viewray(rorg, rdir, &ourview, (ekey->x-xoff+.5)/xmax,
407 >                                (ymax-1-ekey->y+yoff+.5)/ymax) < 0)
408 >                        return(-1);
409                  printf("%e %e %e ", rorg[0], rorg[1], rorg[2]);
410                  printf("%e %e %e\n", rdir[0], rdir[1], rdir[2]);
411                  fflush(stdout);
412                  return(0);
413 <        case CTRL(R):                           /* redraw */
413 >        case '=':                               /* adjust exposure */
414 >                if (avgbox(cval) == -1)
415 >                        return(-1);
416 >                n = log(.5/bright(cval))/.69315 - scale;        /* truncate */
417 >                if (n == 0)
418 >                        return(0);
419 >                scale_rcolors(ourras, pow(2.0, (double)n));
420 >                scale += n;
421 >                sprintf(buf, "%+d", scale);
422 >                XText(wind, box.xmin, box.ymin, buf, strlen(buf),
423 >                                fontid, BlackPixel, WhitePixel);
424 >                XFlush();
425 >                free_raster(ourras);
426 >                getras();
427 >        /* fall through */
428 >        case CTRL('R'):                         /* redraw */
429 >        case CTRL('L'):
430 >                unmap_rcolors(ourras);
431                  XClear(wind);
432                  return(redraw(0, 0, width, height));
433          case ' ':                               /* clear */
# Line 500 | Line 538 | getmono()                      /* get monochrome data */
538   {
539          register unsigned short *dp;
540          register int    x, err;
541 <        int     y;
542 <        rgbpixel        *inline;
541 >        int     y, errp;
542 >        rgbpixel        *inl;
543          short   *cerr;
544  
545 <        if ((inline = (rgbpixel *)malloc(xmax*sizeof(rgbpixel))) == NULL
545 >        if ((inl = (rgbpixel *)malloc(xmax*sizeof(rgbpixel))) == NULL
546                          || (cerr = (short *)calloc(xmax,sizeof(short))) == NULL)
547 <                quit("out of memory in getmono");
548 <        dp = ourras.data.m - 1;
547 >                quiterr("out of memory in getmono");
548 >        dp = ourras->data.m - 1;
549          for (y = 0; y < ymax; y++) {
550 <                picreadline3(y, inline);
550 >                picreadline3(y, inl);
551                  err = 0;
552                  for (x = 0; x < xmax; x++) {
553                          if (!(x&0xf))
554                                  *++dp = 0;
555 <                        err += rgb_bright(&inline[x]) + cerr[x];
555 >                        errp = err;
556 >                        err += rgb_bright(&inl[x]) + cerr[x];
557                          if (err > 127)
558                                  err -= 255;
559                          else
560                                  *dp |= 1<<(x&0xf);
561 <                        cerr[x] = err >>= 1;
561 >                        err /= 3;
562 >                        cerr[x] = err + errp;
563                  }
564          }
565 <        free((char *)inline);
566 <        free((char *)cerr);
565 >        free((void *)inl);
566 >        free((void *)cerr);
567   }
568  
569  
570 < init_rcolors(xr, cmap)                          /* assign color values */
570 > init_rcolors(xr, cmap)                          /* (re)assign color values */
571   register XRASTER        *xr;
572   colormap        cmap;
573   {
# Line 551 | Line 591 | colormap       cmap;
591                          xr->cdefs[xr->ncolors].pixel = *p;
592                          xr->pmap[*p] = xr->ncolors++;
593                  }
594 <        xr->cdefs = (Color *)realloc((char *)xr->cdefs, xr->ncolors*sizeof(Color));
594 >        xr->cdefs = (Color *)realloc((void *)xr->cdefs, xr->ncolors*sizeof(Color));
595          if (xr->cdefs == NULL)
596                  return(0);
597          return(1);
598   }
599  
600  
601 + scale_rcolors(xr, sf)                   /* scale color map */
602 + register XRASTER        *xr;
603 + double  sf;
604 + {
605 +        register int    i;
606 +        long    maxv;
607 +
608 +        if (xr->pixels == NULL)
609 +                return;
610 +
611 +        sf = pow(sf, 1.0/gamcor);
612 +        maxv = 65535/sf;
613 +
614 +        for (i = xr->ncolors; i--; ) {
615 +                xr->cdefs[i].red = xr->cdefs[i].red > maxv ?
616 +                                65535 :
617 +                                xr->cdefs[i].red * sf;
618 +                xr->cdefs[i].green = xr->cdefs[i].green > maxv ?
619 +                                65535 :
620 +                                xr->cdefs[i].green * sf;
621 +                xr->cdefs[i].blue = xr->cdefs[i].blue > maxv ?
622 +                                65535 :
623 +                                xr->cdefs[i].blue * sf;
624 +        }
625 +        XStoreColors(xr->ncolors, xr->cdefs);
626 + }
627 +
628 +
629   getscan(y)
630   int  y;
631   {
# Line 565 | Line 633 | int  y;
633                  if (scanpos == NULL || scanpos[y] == -1)
634                          return(-1);
635                  if (fseek(fin, scanpos[y], 0) == -1)
636 <                        quit("fseek error");
636 >                        quiterr("fseek error");
637                  cury = y;
638 <        } else if (scanpos != NULL)
638 >        } else if (scanpos != NULL && scanpos[y] == -1)
639                  scanpos[y] = ftell(fin);
640  
641          if (freadcolrs(scanline, xmax, fin) < 0)
# Line 582 | Line 650 | picreadline3(y, l3)                    /* read in 3-byte scanline */
650   int  y;
651   register rgbpixel  *l3;
652   {
653 <        register BYTE   *l4;
654 <        register int    shift, c;
587 <        int     i;
588 <
653 >        register int    i;
654 >                                                        /* read scanline */
655          if (getscan(y) < 0)
656                  quiterr("cannot seek for picreadline");
657                                                          /* convert scanline */
658 <        for (l4=scanline[0], i=xmax; i--; l4+=4, l3++) {
659 <                shift = l4[EXP] - COLXS;
660 <                if (shift >= 8) {
661 <                        l3->r = l3->g = l3->b = 255;
662 <                } else if (shift <= -8) {
597 <                        l3->r = l3->g = l3->b = 0;
598 <                } else if (shift > 0) {
599 <                        c = l4[RED] << shift;
600 <                        l3->r = c > 255 ? 255 : c;
601 <                        c = l4[GRN] << shift;
602 <                        l3->g = c > 255 ? 255 : c;
603 <                        c = l4[BLU] << shift;
604 <                        l3->b = c > 255 ? 255 : c;
605 <                } else if (shift < 0) {
606 <                        l3->r = l4[RED] >> -shift;
607 <                        l3->g = l4[GRN] >> -shift;
608 <                        l3->b = l4[BLU] >> -shift;
609 <                } else {
610 <                        l3->r = l4[RED];
611 <                        l3->g = l4[GRN];
612 <                        l3->b = l4[BLU];
613 <                }
658 >        normcolrs(scanline, xmax, scale);
659 >        for (i = 0; i < xmax; i++) {
660 >                l3[i].r = scanline[i][RED];
661 >                l3[i].g = scanline[i][GRN];
662 >                l3[i].b = scanline[i][BLU];
663          }
664   }
665  
# Line 619 | Line 668 | picwriteline(y, l)             /* add 8-bit scanline to image */
668   int  y;
669   pixel  *l;
670   {
671 <        bcopy(l, ourras.data.bz+BZPixmapSize(xmax,y), BZPixmapSize(xmax,1));
671 >        memcpy((void *)ourras->data.bz+BZPixmapSize(xmax,y), (void *)l, BZPixmapSize(xmax,1));
672   }
673  
674  
675 < picreadcm(map)                  /* do gamcor correction */
675 > picreadcm(map)                  /* do gamma correction */
676   colormap  map;
677   {
678          extern double  pow();
679          register int  i, val;
680  
681          for (i = 0; i < 256; i++) {
682 <                val = pow(i/256.0, 1.0/gamcor) * 256.0;
682 >                val = pow((i+0.5)/256.0, 1.0/gamcor) * 256.0;
683                  map[0][i] = map[1][i] = map[2][i] = val;
684          }
685   }
# Line 639 | Line 688 | colormap  map;
688   picwritecm(map)                 /* handled elsewhere */
689   colormap  map;
690   {
691 + #ifdef DEBUG
692 +        register int i;
693 +
694 +        for (i = 0; i < 256; i++)
695 +                printf("%d %d %d\n", map[0][i],map[1][i],map[2][i]);
696 + #endif
697   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines