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 1.30 by greg, Wed May 1 12:40:03 1991 UTC

# Line 29 | Line 29 | static char SCCSid[] = "$SunId$ LBL";
29  
30   #include  "pic.h"
31  
32 + #include  "random.h"
33 +
34   #define  controlshift(e)        (((XButtonEvent *)(e))->detail & (ShiftMask|ControlMask))
35  
36   #define  FONTNAME       "9x15"          /* text font we'll use */
# Line 38 | Line 40 | static char SCCSid[] = "$SunId$ LBL";
40   #define  BORWIDTH       5               /* border width */
41   #define  BARHEIGHT      25              /* menu bar size */
42  
43 < double  gamcor = 2.0;                   /* gamcor correction */
43 > double  gamcor = 2.2;                   /* gamma correction */
44  
45 < XRASTER  ourras;                        /* our stored raster image */
45 > XRASTER  *ourras = NULL;                /* our stored raster image */
46  
47   int  dither = 1;                        /* dither colors? */
48   int  fast = 0;                          /* keep picture in Pixmap? */
# Line 51 | Line 53 | Font  fontid;                          /* our font */
53   int  maxcolors = 0;                     /* maximum colors */
54   int  greyscale = 0;                     /* in grey */
55  
56 + int  scale = 0;                         /* scalefactor; power of two */
57 +
58   int  xoff = 0;                          /* x image offset */
59   int  yoff = 0;                          /* y image offset */
60  
61 < VIEW  ourview = STDVIEW(0);             /* image view parameters */
61 > VIEW  ourview = STDVIEW;                /* image view parameters */
62   int  gotview = 0;                       /* got parameters from file */
63  
64   COLR  *scanline;                        /* scan line buffer */
# Line 68 | Line 72 | int  cury = 0;                         /* current scan location */
72  
73   double  exposure = 1.0;                 /* exposure compensation used */
74  
75 + int  wrongformat = 0;                   /* input in another format */
76 +
77   struct {
78          int  xmin, ymin, xsiz, ysiz;
79   }  box = {0, 0, 0, 0};                  /* current box */
# Line 82 | Line 88 | extern long  ftell();
88  
89   extern char  *malloc(), *calloc();
90  
91 < extern double  atof();
91 > extern double  atof(), pow(), log();
92  
93  
94   main(argc, argv)
# Line 112 | Line 118 | char  *argv[];
118                          case 'f':
119                                  fast = !fast;
120                                  break;
121 +                        case 'e':
122 +                                if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
123 +                                        goto userr;
124 +                                scale = atoi(argv[++i]);
125 +                                break;
126                          case 'g':
127                                  gamcor = atof(argv[++i]);
128                                  break;
# Line 130 | Line 141 | char  *argv[];
141                          sprintf(errmsg, "can't open file \"%s\"", fname);
142                          quiterr(errmsg);
143                  }
144 <        } else
134 <                goto userr;
135 <
144 >        }
145                                  /* get header */
146 <        getheader(fin, headline);
146 >        getheader(fin, headline, NULL);
147                                  /* get picture dimensions */
148 <        if (fscanf(fin, "-Y %d +X %d\n", &ymax, &xmax) != 2)
148 >        if (wrongformat || fgetresolu(&xmax, &ymax, fin) != (YMAJOR|YDECR))
149                  quiterr("bad picture size");
150                                  /* set view parameters */
151 <        if (gotview) {
152 <                ourview.hresolu = xmax;
144 <                ourview.vresolu = ymax;
145 <                if (setview(&ourview) != NULL)
146 <                        gotview = 0;
147 <        }
151 >        if (gotview && setview(&ourview) != NULL)
152 >                gotview = 0;
153          if ((scanline = (COLR *)malloc(xmax*sizeof(COLR))) == NULL)
154                  quiterr("out of memory");
155  
# Line 154 | Line 159 | char  *argv[];
159                  getevent();             /* main loop */
160   userr:
161          fprintf(stderr,
162 <        "Usage: %s [=geometry][-b][-m][-d][-f][-c ncolors] file\n",
162 >        "Usage: %s [=geometry][-b][-m][-d][-f][-c ncolors][-e +/-stops] file\n",
163                          progname);
164          quit(1);
165   }
# Line 163 | Line 168 | userr:
168   headline(s)             /* get relevant info from header */
169   char  *s;
170   {
171 <        static char  *altname[] = {"rview","rpict","VIEW=",NULL};
171 >        static char  *altname[] = {"rview","rpict",VIEWSTR,NULL};
172          register char  **an;
173 +        char  fmt[32];
174  
175 <        if (!strncmp(s, "EXPOSURE=", 9))
176 <                exposure *= atof(s+9);
177 <        else
175 >        if (isexpos(s))
176 >                exposure *= exposval(s);
177 >        else if (isformat(s)) {
178 >                formatval(fmt, s);
179 >                wrongformat = strcmp(fmt, COLRFMT);
180 >        } else
181                  for (an = altname; *an != NULL; an++)
182                          if (!strncmp(*an, s, strlen(*an))) {
183 <                                if (sscanview(&ourview, s+strlen(*an)) == 0)
183 >                                if (sscanview(&ourview, s+strlen(*an)) > 0)
184                                          gotview++;
185                                  return;
186                          }
187   }
188  
189  
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
190   init()                  /* get data and open window */
191   {
192          register int  i;
194        colormap  ourmap;
193          OpaqueFrame  mainframe;
194          char  defgeom[32];
195          
# Line 213 | Line 211 | init()                 /* get data and open window */
211                  maxcolors = 1<<DisplayPlanes();
212                  if (maxcolors > 4) maxcolors -= 2;
213          }
216        ourras.width = xmax;
217        ourras.height = ymax;
214                                  /* store image */
215 <        if (maxcolors <= 2) {           /* monochrome */
216 <                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 <        }
215 >        getras();
216 >
217          mainframe.bdrwidth = BORWIDTH;
218          mainframe.border = WhitePixmap;
219          mainframe.background = BlackPixmap;
# Line 284 | Line 266 | int  code;
266   }
267  
268  
269 + getras()                                /* get raster file */
270 + {
271 +        colormap        ourmap;
272 +
273 +        ourras = (XRASTER *)calloc(1, sizeof(XRASTER));
274 +        if (ourras == NULL)
275 +                goto memerr;
276 +        ourras->width = xmax;
277 +        ourras->height = ymax;
278 +        if (maxcolors <= 2) {           /* monochrome */
279 +                ourras->data.m = (unsigned short *)malloc(BitmapSize(xmax,ymax));
280 +                if (ourras->data.m == NULL)
281 +                        goto memerr;
282 +                getmono();
283 +        } else {
284 +                ourras->data.bz = (unsigned char *)malloc(BZPixmapSize(xmax,ymax));
285 +                if (ourras->data.bz == NULL)
286 +                        goto memerr;
287 +                if (greyscale)
288 +                        biq(dither,maxcolors,1,ourmap);
289 +                else
290 +                        ciq(dither,maxcolors,1,ourmap);
291 +                if (init_rcolors(ourras, ourmap) == 0)
292 +                        goto memerr;
293 +        }
294 +        return;
295 + memerr:
296 +        quiterr("out of memory");
297 + }
298 +
299 +
300   getevent()                              /* process the next event */
301   {
302          WindowInfo  info;
# Line 303 | Line 316 | getevent()                             /* process the next event */
316                  fixwindow(&e);
317                  break;
318          case UnmapWindow:
319 <                unmap_rcolors(&ourras);
319 >                unmap_rcolors(ourras);
320                  break;
321          case ButtonPressed:
322                  if (controlshift(&e))
# Line 326 | Line 339 | redraw(x, y, w, h)                     /* redraw section of window */
339   int  x, y;
340   int  w, h;
341   {
342 <        map_rcolors(&ourras);
342 >        if (ourras->ncolors && map_rcolors(ourras) == NULL) {
343 >                fprintf(stderr, "%s: cannot allocate colors\n", progname);
344 >                return(-1);
345 >        }
346          if (fast)
347 <                make_rpixmap(&ourras);
348 <        return(patch_raster(wind,x-xoff,y-yoff,x,y,w,h,&ourras) ? 0 : -1);
347 >                make_rpixmap(ourras);
348 >        return(patch_raster(wind,x-xoff,y-yoff,x,y,w,h,ourras) ? 0 : -1);
349   }
350  
351  
# Line 338 | Line 354 | XKeyEvent  *ekey;
354   {
355          char  buf[80];
356          COLOR  cval;
357 +        Color  cvx;
358          char  *cp;
359          int  n;
360 +        double  comp;
361          FVECT  rorg, rdir;
362  
363          cp = XLookupMapping(ekey, &n);
# Line 347 | Line 365 | XKeyEvent  *ekey;
365                  return(0);
366          switch (*cp) {                  /* interpret command */
367          case 'q':
368 <        case CTRL(D):                           /* quiterr */
368 >        case CTRL(D):                           /* quit */
369                  quit(0);
370          case '\n':
371          case '\r':
# Line 358 | Line 376 | XKeyEvent  *ekey;
376                  switch (*cp) {
377                  case '\n':
378                  case '\r':                              /* radiance */
379 <                        sprintf(buf, "%-3g", intens(cval)/exposure);
379 >                        sprintf(buf, "%.3f", intens(cval)/exposure);
380                          break;
381                  case 'l':                               /* luminance */
382 <                        sprintf(buf, "%-3gL", bright(cval)*683.0/exposure);
382 >                        sprintf(buf, "%.0fL", luminance(cval)/exposure);
383                          break;
384                  case 'c':                               /* color */
385 +                        comp = pow(2.0, (double)scale);
386                          sprintf(buf, "(%.2f,%.2f,%.2f)",
387 <                                        colval(cval,RED),
388 <                                        colval(cval,GRN),
389 <                                        colval(cval,BLU));
387 >                                        colval(cval,RED)*comp,
388 >                                        colval(cval,GRN)*comp,
389 >                                        colval(cval,BLU)*comp);
390                          break;
391                  }
392                  XText(wind, box.xmin, box.ymin, buf, strlen(buf),
393                                  fontid, BlackPixel, WhitePixel);
394                  return(0);
395 +        case 'i':                               /* identify (contour) */
396 +                if (ourras->pixels == NULL)
397 +                        return(-1);
398 +                n = ourras->data.bz[ekey->x-xoff+BZPixmapSize(xmax,ekey->y-yoff)];
399 +                n = ourras->pmap[n];
400 +                cvx.pixel = ourras->cdefs[n].pixel;
401 +                cvx.red = random() & 65535;
402 +                cvx.green = random() & 65535;
403 +                cvx.blue = random() & 65535;
404 +                XStoreColor(&cvx);
405 +                return(0);
406          case 'p':                               /* position */
407                  sprintf(buf, "(%d,%d)", ekey->x-xoff, ymax-1-ekey->y+yoff);
408                  XText(wind, ekey->x, ekey->y, buf, strlen(buf),
# Line 383 | Line 413 | XKeyEvent  *ekey;
413                          XFeep(0);
414                          return(-1);
415                  }
416 <                rayview(rorg, rdir, &ourview,
417 <                                ekey->x-xoff + .5, ymax-1-ekey->y+yoff + .5);
416 >                if (viewray(rorg, rdir, &ourview, (ekey->x-xoff+.5)/xmax,
417 >                                (ymax-1-ekey->y+yoff+.5)/ymax) < 0)
418 >                        return(-1);
419                  printf("%e %e %e ", rorg[0], rorg[1], rorg[2]);
420                  printf("%e %e %e\n", rdir[0], rdir[1], rdir[2]);
421                  fflush(stdout);
422                  return(0);
423 +        case '=':                               /* adjust exposure */
424 +                if (avgbox(cval) == -1)
425 +                        return(-1);
426 +                n = log(.5/bright(cval))/.69315 - scale;        /* truncate */
427 +                if (n == 0)
428 +                        return(0);
429 +                scale_rcolors(ourras, pow(2.0, (double)n));
430 +                scale += n;
431 +                sprintf(buf, "%+d", scale);
432 +                XText(wind, box.xmin, box.ymin, buf, strlen(buf),
433 +                                fontid, BlackPixel, WhitePixel);
434 +                XFlush();
435 +                free_raster(ourras);
436 +                getras();
437 +        /* fall through */
438          case CTRL(R):                           /* redraw */
439 +        case CTRL(L):
440 +                unmap_rcolors(ourras);
441                  XClear(wind);
442                  return(redraw(0, 0, width, height));
443          case ' ':                               /* clear */
# Line 501 | Line 549 | getmono()                      /* get monochrome data */
549          register unsigned short *dp;
550          register int    x, err;
551          int     y;
552 <        rgbpixel        *inline;
552 >        rgbpixel        *inl;
553          short   *cerr;
554  
555 <        if ((inline = (rgbpixel *)malloc(xmax*sizeof(rgbpixel))) == NULL
555 >        if ((inl = (rgbpixel *)malloc(xmax*sizeof(rgbpixel))) == NULL
556                          || (cerr = (short *)calloc(xmax,sizeof(short))) == NULL)
557 <                quit("out of memory in getmono");
558 <        dp = ourras.data.m - 1;
557 >                quiterr("out of memory in getmono");
558 >        dp = ourras->data.m - 1;
559          for (y = 0; y < ymax; y++) {
560 <                picreadline3(y, inline);
560 >                picreadline3(y, inl);
561                  err = 0;
562                  for (x = 0; x < xmax; x++) {
563                          if (!(x&0xf))
564                                  *++dp = 0;
565 <                        err += rgb_bright(&inline[x]) + cerr[x];
565 >                        err += rgb_bright(&inl[x]) + cerr[x];
566                          if (err > 127)
567                                  err -= 255;
568                          else
# Line 522 | Line 570 | getmono()                      /* get monochrome data */
570                          cerr[x] = err >>= 1;
571                  }
572          }
573 <        free((char *)inline);
573 >        free((char *)inl);
574          free((char *)cerr);
575   }
576  
577  
578 < init_rcolors(xr, cmap)                          /* assign color values */
578 > init_rcolors(xr, cmap)                          /* (re)assign color values */
579   register XRASTER        *xr;
580   colormap        cmap;
581   {
# Line 558 | Line 606 | colormap       cmap;
606   }
607  
608  
609 + scale_rcolors(xr, sf)                   /* scale color map */
610 + register XRASTER        *xr;
611 + double  sf;
612 + {
613 +        register int    i;
614 +        long    maxv;
615 +
616 +        if (xr->pixels == NULL)
617 +                return;
618 +
619 +        sf = pow(sf, 1.0/gamcor);
620 +        maxv = 65535/sf;
621 +
622 +        for (i = xr->ncolors; i--; ) {
623 +                xr->cdefs[i].red = xr->cdefs[i].red > maxv ?
624 +                                65535 :
625 +                                xr->cdefs[i].red * sf;
626 +                xr->cdefs[i].green = xr->cdefs[i].green > maxv ?
627 +                                65535 :
628 +                                xr->cdefs[i].green * sf;
629 +                xr->cdefs[i].blue = xr->cdefs[i].blue > maxv ?
630 +                                65535 :
631 +                                xr->cdefs[i].blue * sf;
632 +        }
633 +        XStoreColors(xr->ncolors, xr->cdefs);
634 + }
635 +
636 +
637   getscan(y)
638   int  y;
639   {
# Line 565 | Line 641 | int  y;
641                  if (scanpos == NULL || scanpos[y] == -1)
642                          return(-1);
643                  if (fseek(fin, scanpos[y], 0) == -1)
644 <                        quit("fseek error");
644 >                        quiterr("fseek error");
645                  cury = y;
646          } else if (scanpos != NULL)
647                  scanpos[y] = ftell(fin);
# Line 582 | Line 658 | picreadline3(y, l3)                    /* read in 3-byte scanline */
658   int  y;
659   register rgbpixel  *l3;
660   {
661 <        register BYTE   *l4;
662 <        register int    shift, c;
587 <        int     i;
588 <
661 >        register int    i;
662 >                                                        /* read scanline */
663          if (getscan(y) < 0)
664                  quiterr("cannot seek for picreadline");
665                                                          /* convert scanline */
666 <        for (l4=scanline[0], i=xmax; i--; l4+=4, l3++) {
667 <                shift = l4[EXP] - COLXS;
668 <                if (shift >= 8) {
669 <                        l3->r = l3->g = l3->b = 255;
670 <                } 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 <                }
666 >        normcolrs(scanline, xmax, scale);
667 >        for (i = 0; i < xmax; i++) {
668 >                l3[i].r = scanline[i][RED];
669 >                l3[i].g = scanline[i][GRN];
670 >                l3[i].b = scanline[i][BLU];
671          }
672   }
673  
# Line 619 | Line 676 | picwriteline(y, l)             /* add 8-bit scanline to image */
676   int  y;
677   pixel  *l;
678   {
679 <        bcopy(l, ourras.data.bz+BZPixmapSize(xmax,y), BZPixmapSize(xmax,1));
679 >        bcopy((char *)l, (char *)ourras->data.bz+BZPixmapSize(xmax,y), BZPixmapSize(xmax,1));
680   }
681  
682  
683 < picreadcm(map)                  /* do gamcor correction */
683 > picreadcm(map)                  /* do gamma correction */
684   colormap  map;
685   {
686          extern double  pow();
687          register int  i, val;
688  
689          for (i = 0; i < 256; i++) {
690 <                val = pow(i/256.0, 1.0/gamcor) * 256.0;
690 >                val = pow((i+0.5)/256.0, 1.0/gamcor) * 256.0;
691                  map[0][i] = map[1][i] = map[2][i] = val;
692          }
693   }
# Line 639 | Line 696 | colormap  map;
696   picwritecm(map)                 /* handled elsewhere */
697   colormap  map;
698   {
699 + #ifdef DEBUG
700 +        register int i;
701 +
702 +        for (i = 0; i < 256; i++)
703 +                printf("%d %d %d\n", map[0][i],map[1][i],map[2][i]);
704 + #endif
705   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines