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

Comparing ray/src/px/x11image.c (file contents):
Revision 1.2 by greg, Thu Mar 1 18:13:31 1990 UTC vs.
Revision 2.4 by greg, Tue Apr 28 09:40:32 1992 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1990 Regents of the University of California */
1 > /* Copyright (c) 1991 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 30 | Line 30 | static char SCCSid[] = "$SunId$ LBL";
30   #include  "pic.h"
31   #include  "x11raster.h"
32   #include  "random.h"
33 + #include  "resolu.h"
34  
35   #define  FONTNAME       "8x13"          /* text font we'll use */
36  
37 < #define  CTRL(c)        ('c'-'@')
37 > #define  CTRL(c)        ((c)-'@')
38  
39   #define  BORWIDTH       5               /* border width */
40  
41 + #define  ICONSIZ        (8*10)          /* maximum icon dimension (even 8) */
42 +
43   #define  ourscreen      DefaultScreen(thedisplay)
44   #define  ourblack       BlackPixel(thedisplay,ourscreen)
45   #define  ourwhite       WhitePixel(thedisplay,ourscreen)
46   #define  ourroot        RootWindow(thedisplay,ourscreen)
47   #define  ourgc          DefaultGC(thedisplay,ourscreen)
48  
49 + #define  revline(x0,y0,x1,y1)   XDrawLine(thedisplay,wind,revgc,x0,y0,x1,y1)
50 +
51   #define  redraw(x,y,w,h) patch_raster(wind,(x)-xoff,(y)-yoff,x,y,w,h,ourras)
52  
53   double  gamcor = 2.2;                   /* gamma correction */
# Line 66 | Line 71 | int  gotview = 0;                      /* got parameters from file */
71  
72   COLR  *scanline;                        /* scan line buffer */
73  
74 < int  xmax, ymax;                        /* picture resolution */
74 > RESOLU  inpres;                         /* input resolution and ordering */
75 > int  xmax, ymax;                        /* picture dimensions */
76   int  width, height;                     /* window size */
77   char  *fname = NULL;                    /* input file name */
78   FILE  *fin = stdin;                     /* input file */
# Line 75 | Line 81 | int  cury = 0;                         /* current scan location */
81  
82   double  exposure = 1.0;                 /* exposure compensation used */
83  
84 + int  wrongformat = 0;                   /* input in another format? */
85 +
86 + GC      revgc;                          /* graphics context with GXinvert */
87 +
88   XRASTER *ourras;                        /* our stored image */
89   unsigned char   *ourdata;               /* our image data */
90  
# Line 84 | Line 94 | struct {
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];
# Line 92 | Line 105 | extern long  ftell();
105  
106   extern char  *malloc(), *calloc();
107  
108 < extern double  atof(), pow(), log();
108 > extern double  pow(), log();
109  
110   Display  *thedisplay;
111  
# Line 137 | Line 150 | char  *argv[];
150                          default:
151                                  goto userr;
152                          }
153 +                else if (argv[i][0] == '=')
154 +                        geometry = argv[i];
155                  else
156                          break;
157  
158 <        if (argc-i == 1) {
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 <        }
165 >        } else if (i != argc)
166 >                goto userr;
167                                  /* get header */
168 <        getheader(fin, headline);
168 >        getheader(fin, headline, NULL);
169                                  /* get picture dimensions */
170 <        if (fgetresolu(&xmax, &ymax, fin) != (YMAJOR|YDECR))
171 <                quiterr("bad picture size");
170 >        if (wrongformat || !fgetsresolu(&inpres, fin))
171 >                quiterr("bad picture format");
172 >        xmax = scanlen(&inpres);
173 >        ymax = numscans(&inpres);
174                                  /* set view parameters */
175          if (gotview && setview(&ourview) != NULL)
176                  gotview = 0;
# Line 174 | Line 192 | userr:
192   headline(s)             /* get relevant info from header */
193   char  *s;
194   {
195 <        static char  *altname[] = {"rview","rpict","pinterp",VIEWSTR,NULL};
178 <        register char  **an;
195 >        char  fmt[32];
196  
197          if (isexpos(s))
198                  exposure *= exposval(s);
199 <        else
200 <                for (an = altname; *an != NULL; an++)
201 <                        if (!strncmp(*an, s, strlen(*an))) {
202 <                                if (sscanview(&ourview, s+strlen(*an)) > 0)
203 <                                        gotview++;
187 <                                return;
188 <                        }
199 >        else if (isformat(s)) {
200 >                formatval(fmt, s);
201 >                wrongformat = strcmp(fmt, COLRFMT);
202 >        } else if (isview(s) && sscanview(&ourview, s) > 0)
203 >                gotview++;
204   }
205  
206  
207   init()                  /* get data and open window */
208   {
209 +        XWMHints        ourxwmhints;
210 +        XSetWindowAttributes    ourwinattr;
211          XSizeHints  oursizhints;
212          register int  i;
213          
# Line 203 | Line 220 | init()                 /* get data and open window */
220          }
221          if ((thedisplay = XOpenDisplay(NULL)) == NULL)
222                  quiterr("can't open display; DISPLAY variable set?");
206        wind = XCreateSimpleWindow(thedisplay,
207                ourroot, 0, 0, xmax, ymax, BORWIDTH, ourblack, ourwhite);
208        if (wind == 0)
209                quiterr("can't create window");
223          if (maxcolors == 0) {           /* get number of available colors */
224                  i = DisplayPlanes(thedisplay,ourscreen);
225                  maxcolors = i > 8 ? 256 : 1<<i;
226                  if (maxcolors > 4) maxcolors -= 2;
227          }
228 +                                /* store image */
229 +        getras();
230 +                                /* open window */
231 +        ourwinattr.border_pixel = ourblack;
232 +        ourwinattr.background_pixel = ourwhite;
233 +        wind = XCreateWindow(thedisplay, ourroot, 0, 0, xmax, ymax, BORWIDTH,
234 +                        0, InputOutput, ourras->visual,
235 +                        CWBackPixel|CWBorderPixel, &ourwinattr);
236 +        if (wind == 0)
237 +                quiterr("can't create window");
238 +        width = xmax;
239 +        height = ymax;
240          fontid = XLoadFont(thedisplay, FONTNAME);
241          if (fontid == 0)
242                  quiterr("can't get font");
243          XSetFont(thedisplay, ourgc, fontid);
244 <        XStoreName(thedisplay, wind, fname == NULL ? progname : fname);
244 >        revgc = XCreateGC(thedisplay, wind, 0, 0);
245 >        XSetFunction(thedisplay, revgc, GXinvert);
246          XDefineCursor(thedisplay, wind, XCreateFontCursor(thedisplay,
247                          XC_diamond_cross));
248 +        XStoreName(thedisplay, wind, fname == NULL ? progname : fname);
249          if (geometry != NULL) {
250                  bzero((char *)&oursizhints, sizeof(oursizhints));
251                  i = XParseGeometry(geometry, &oursizhints.x, &oursizhints.y,
252 <                                &oursizhints.width, &oursizhints.height);
253 <                if (i & (XValue|YValue) == (XValue|YValue)) {
252 >                                (unsigned *)&oursizhints.width,
253 >                                (unsigned *)&oursizhints.height);
254 >                if ((i&(WidthValue|HeightValue)) == (WidthValue|HeightValue))
255 >                        oursizhints.flags |= USSize;
256 >                else {
257 >                        oursizhints.width = xmax;
258 >                        oursizhints.height = ymax;
259 >                        oursizhints.flags |= PSize;
260 >                }
261 >                if ((i&(XValue|YValue)) == (XValue|YValue)) {
262                          oursizhints.flags |= USPosition;
263                          if (i & XNegative)
264 <                                oursizhints.x += DisplayWidth(thedisplay,ourscreen)-1;
264 >                                oursizhints.x += DisplayWidth(thedisplay,
265 >                                ourscreen)-1-oursizhints.width-2*BORWIDTH;
266                          if (i & YNegative)
267 <                                oursizhints.y += DisplayHeight(thedisplay,ourscreen)-1;
267 >                                oursizhints.y += DisplayHeight(thedisplay,
268 >                                ourscreen)-1-oursizhints.height-2*BORWIDTH;
269                  }
233                if (i & (WidthValue|HeightValue) == (WidthValue|HeightValue))
234                        oursizhints.flags |= USSize;
270                  XSetNormalHints(thedisplay, wind, &oursizhints);
271          }
272 <                                /* store image */
273 <        getras();
272 >        ourxwmhints.flags = InputHint|IconPixmapHint;
273 >        ourxwmhints.input = True;
274 >        ourxwmhints.icon_pixmap = XCreateBitmapFromData(thedisplay,
275 >                        wind, icondata, iconwidth, iconheight);
276 >        XSetWMHints(thedisplay, wind, &ourxwmhints);
277          XSelectInput(thedisplay, wind, ButtonPressMask|ButtonReleaseMask
278                          |ButtonMotionMask|StructureNotifyMask
279                          |KeyPressMask|ExposureMask);
# Line 274 | Line 312 | int  code;
312   getras()                                /* get raster file */
313   {
314          colormap        ourmap;
277        unsigned char   rmap[256], gmap[256], bmap[256];
315          XVisualInfo     vinfo;
279        register int  i;
316  
317          if (maxcolors <= 2) {           /* monochrome */
318                  ourdata = (unsigned char *)malloc(ymax*((xmax+7)/8));
# Line 287 | Line 323 | getras()                               /* get raster file */
323                  if (ourras == NULL)
324                          goto fail;
325                  getmono();
326 <        } else if (XMatchVisualInfo(thedisplay,ourscreen,24,TrueColor,&vinfo)) {
326 >        } else if (XMatchVisualInfo(thedisplay,ourscreen,24,TrueColor,&vinfo)
327 >                                                /* kludge for DirectColor */
328 >        || XMatchVisualInfo(thedisplay,ourscreen,24,DirectColor,&vinfo)) {
329                  ourdata = (unsigned char *)malloc(xmax*ymax*3);
330                  if (ourdata == NULL)
331                          goto fail;
# Line 308 | Line 346 | getras()                               /* get raster file */
346                          biq(dither,maxcolors,1,ourmap);
347                  else
348                          ciq(dither,maxcolors,1,ourmap);
349 <                for (i = 0; i < 256; i++) {
312 <                        rmap[i] = ourmap[0][i];
313 <                        gmap[i] = ourmap[1][i];
314 <                        bmap[i] = ourmap[2][i];
315 <                }
316 <                if (init_rcolors(ourras, rmap, gmap, bmap) == 0)
349 >                if (init_rcolors(ourras, ourmap[0], ourmap[1], ourmap[2]) == 0)
350                          goto fail;
351          }
352          return;
353   fail:
354 <        quit("could not create raster image");
354 >        quiterr("could not create raster image");
355   }
356  
357  
# Line 370 | Line 403 | XKeyPressedEvent  *ekey;
403          XColor  cvx;
404          int  com, n;
405          double  comp;
406 +        FLOAT  hv[2];
407          FVECT  rorg, rdir;
408  
409          n = XLookupString(ekey, buf, sizeof(buf), NULL, NULL);
# Line 378 | Line 412 | XKeyPressedEvent  *ekey;
412          com = buf[0];
413          switch (com) {                  /* interpret command */
414          case 'q':
415 <        case CTRL(D):                           /* quit */
415 >        case CTRL('D'):                         /* quit */
416                  quit(0);
417          case '\n':
418          case '\r':
# Line 392 | Line 426 | XKeyPressedEvent  *ekey;
426                          sprintf(buf, "%.3f", intens(cval)/exposure);
427                          break;
428                  case 'l':                               /* luminance */
429 <                        sprintf(buf, "%.0fn", bright(cval)*683.0/exposure);
429 >                        sprintf(buf, "%.0fL", luminance(cval)/exposure);
430                          break;
431                  case 'c':                               /* color */
432                          comp = pow(2.0, (double)scale);
# Line 402 | Line 436 | XKeyPressedEvent  *ekey;
436                                          colval(cval,BLU)*comp);
437                          break;
438                  }
439 <                XDrawImageString(thedisplay, wind, ourgc, box.xmin, box.ymin,
440 <                                buf, strlen(buf));
439 >                XDrawImageString(thedisplay, wind, ourgc,
440 >                                box.xmin, box.ymin+box.ysiz, buf, strlen(buf));
441                  return(0);
442          case 'i':                               /* identify (contour) */
443                  if (ourras->pixels == NULL)
# Line 418 | Line 452 | XKeyPressedEvent  *ekey;
452                  XStoreColor(thedisplay, ourras->cmap, &cvx);
453                  return(0);
454          case 'p':                               /* position */
455 <                sprintf(buf, "(%d,%d)", ekey->x-xoff, ymax-1-ekey->y+yoff);
455 >                pix2loc(hv, &inpres, ekey->x-xoff, ekey->y-yoff);
456 >                sprintf(buf, "(%d,%d)", (int)(hv[0]*inpres.xr),
457 >                                (int)(hv[1]*inpres.yr));
458                  XDrawImageString(thedisplay, wind, ourgc, ekey->x, ekey->y,
459                                          buf, strlen(buf));
460                  return(0);
# Line 427 | Line 463 | XKeyPressedEvent  *ekey;
463                          XBell(thedisplay, 0);
464                          return(-1);
465                  }
466 <                viewray(rorg, rdir, &ourview,
467 <                                (ekey->x-xoff+.5)/xmax,
468 <                                (ymax-1-ekey->y+yoff+.5)/ymax);
466 >                pix2loc(hv, &inpres, ekey->x-xoff, ekey->y-yoff);
467 >                if (viewray(rorg, rdir, &ourview, hv[0], hv[1]) < 0)
468 >                        return(-1);
469                  printf("%e %e %e ", rorg[0], rorg[1], rorg[2]);
470                  printf("%e %e %e\n", rdir[0], rdir[1], rdir[2]);
471                  fflush(stdout);
# Line 443 | Line 479 | XKeyPressedEvent  *ekey;
479                  scale_rcolors(ourras, pow(2.0, (double)n));
480                  scale += n;
481                  sprintf(buf, "%+d", scale);
482 <                XDrawImageString(thedisplay, wind, ourgc, box.xmin, box.ymin,
483 <                                buf, strlen(buf));
482 >                XDrawImageString(thedisplay, wind, ourgc,
483 >                                box.xmin, box.ymin+box.ysiz, buf, strlen(buf));
484                  XFlush(thedisplay);
485                  free(ourdata);
486                  free_raster(ourras);
487                  getras();
488          /* fall through */
489 <        case CTRL(R):                           /* redraw */
490 <        case CTRL(L):
489 >        case CTRL('R'):                         /* redraw */
490 >        case CTRL('L'):
491                  unmap_rcolors(ourras);
492                  XClearWindow(thedisplay, wind);
493                  map_rcolors(ourras, wind);
# Line 473 | Line 509 | moveimage(ebut)                                /* shift the image */
509   XButtonPressedEvent  *ebut;
510   {
511          union {
512 <                XEvent  u;
513 <                XButtonReleasedEvent    b;
514 <        } e;
512 >                XEvent  u;
513 >                XButtonReleasedEvent  b;
514 >                XPointerMovedEvent  m;
515 >        }  e;
516 >        int     mxo, myo;
517  
518 <        XMaskEvent(thedisplay, ButtonReleaseMask, &e.u);
518 >        XMaskEvent(thedisplay, ButtonReleaseMask|ButtonMotionMask, &e.u);
519 >        while (e.u.type == MotionNotify) {
520 >                mxo = e.m.x;
521 >                myo = e.m.y;
522 >                revline(ebut->x, ebut->y, mxo, myo);
523 >                revbox(xoff+mxo-ebut->x, yoff+myo-ebut->y,
524 >                                xoff+mxo-ebut->x+xmax, yoff+myo-ebut->y+ymax);
525 >                XMaskEvent(thedisplay,ButtonReleaseMask|ButtonMotionMask,&e.u);
526 >                revline(ebut->x, ebut->y, mxo, myo);
527 >                revbox(xoff+mxo-ebut->x, yoff+myo-ebut->y,
528 >                                xoff+mxo-ebut->x+xmax, yoff+myo-ebut->y+ymax);
529 >        }
530          xoff += e.b.x - ebut->x;
531          yoff += e.b.y - ebut->y;
532          XClearWindow(thedisplay, wind);
# Line 520 | Line 569 | XButtonPressedEvent  *ebut;
569   revbox(x0, y0, x1, y1)                  /* draw box with reversed lines */
570   int  x0, y0, x1, y1;
571   {
572 <        static GC       mygc = 0;
572 >        revline(x0, y0, x1, y0);
573 >        revline(x0, y1, x1, y1);
574 >        revline(x0, y0, x0, y1);
575 >        revline(x1, y0, x1, y1);
576 > }
577  
525        if (mygc == 0) {
526                mygc = XCreateGC(thedisplay, wind, 0, 0);
527                XSetFunction(thedisplay, mygc, GXinvert);
528        }
529        XDrawLine(thedisplay, wind, mygc, x0, y0, x1, y0);
530        XDrawLine(thedisplay, wind, mygc, x0, y1, x1, y1);
531        XDrawLine(thedisplay, wind, mygc, x0, y0, x0, y1);
532        XDrawLine(thedisplay, wind, mygc, x1, y0, x1, y1);
533 } /* end of revbox */
578  
535
579   avgbox(clr)                             /* average color over current box */
580   COLOR  clr;
581   {
582 +        static COLOR  lc;
583 +        static int  ll, lr, lt, lb;
584          int  left, right, top, bottom;
585          int  y;
586          double  d;
# Line 559 | Line 604 | COLOR  clr;
604                  bottom = ymax;
605          if (top >= bottom)
606                  return(-1);
607 +        if (left == ll && right == lr && top == lt && bottom == lb) {
608 +                copycolor(clr, lc);
609 +                return;
610 +        }
611          for (y = top; y < bottom; y++) {
612                  if (getscan(y) == -1)
613                          return(-1);
# Line 569 | Line 618 | COLOR  clr;
618          }
619          d = 1.0/((right-left)*(bottom-top));
620          scalecolor(clr, d);
621 +        ll = left; lr = right; lt = top; lb = bottom;
622 +        copycolor(lc, clr);
623          return(0);
624   }
625  
# Line 577 | Line 628 | getmono()                      /* get monochrome data */
628   {
629          register unsigned char  *dp;
630          register int    x, err;
631 <        int     y;
581 <        rgbpixel        *inline;
631 >        int     y, errp;
632          short   *cerr;
633  
634 <        if ((inline = (rgbpixel *)malloc(xmax*sizeof(rgbpixel))) == NULL
635 <                        || (cerr = (short *)calloc(xmax,sizeof(short))) == NULL)
586 <                quit("out of memory in getmono");
634 >        if ((cerr = (short *)calloc(xmax,sizeof(short))) == NULL)
635 >                quiterr("out of memory in getmono");
636          dp = ourdata - 1;
637          for (y = 0; y < ymax; y++) {
638 <                picreadline3(y, inline);
638 >                if (getscan(y) < 0)
639 >                        quiterr("seek error in getmono");
640 >                normcolrs(scanline, xmax, scale);
641 >                add2icon(y, scanline);
642                  err = 0;
643                  for (x = 0; x < xmax; x++) {
644                          if (!(x&7))
645                                  *++dp = 0;
646 <                        err += rgb_bright(&inline[x]) + cerr[x];
646 >                        errp = err;
647 >                        err += normbright(scanline[x]) + cerr[x];
648                          if (err > 127)
649                                  err -= 255;
650                          else
651 <                                *dp |= 1<<(x&07);
652 <                        cerr[x] = err >>= 1;
651 >                                *dp |= 1<<(7-(x&07));
652 >                        err /= 3;
653 >                        cerr[x] = err + errp;
654                  }
655          }
602        free((char *)inline);
656          free((char *)cerr);
657   }
658  
659  
660 + add2icon(y, scan)               /* add a scanline to our icon data */
661 + int  y;
662 + COLR  *scan;
663 + {
664 +        static short  cerr[ICONSIZ];
665 +        static int  ynext;
666 +        static char  *dp;
667 +        register int  err;
668 +        register int    x, ti;
669 +        int  errp;
670 +
671 +        if (iconheight == 0) {          /* initialize */
672 +                if (xmax <= ICONSIZ && ymax <= ICONSIZ) {
673 +                        iconwidth = xmax;
674 +                        iconheight = ymax;
675 +                } else if (xmax > ymax) {
676 +                        iconwidth = ICONSIZ;
677 +                        iconheight = ICONSIZ*ymax/xmax;
678 +                        if (iconheight < 1)
679 +                                iconheight = 1;
680 +                } else {
681 +                        iconwidth = ICONSIZ*xmax/ymax;
682 +                        if (iconwidth < 1)
683 +                                iconwidth = 1;
684 +                        iconheight = ICONSIZ;
685 +                }
686 +                ynext = 0;
687 +                dp = icondata - 1;
688 +        }
689 +        if (y < ynext*ymax/iconheight)  /* skip this one */
690 +                return;
691 +        err = 0;
692 +        for (x = 0; x < iconwidth; x++) {
693 +                if (!(x&7))
694 +                        *++dp = 0;
695 +                errp = err;
696 +                ti = x*xmax/iconwidth;
697 +                err += normbright(scan[ti]) + cerr[x];
698 +                if (err > 127)
699 +                        err -= 255;
700 +                else
701 +                        *dp |= 1<<(x&07);
702 +                err /= 3;
703 +                cerr[x] = err + errp;
704 +        }
705 +        ynext++;
706 + }
707 +
708 +
709   getfull()                       /* get full (24-bit) data */
710   {
711          int     y;
712 <
713 <        for (y = 0; y < ymax; y++)
714 <                picreadline3(y, (rgbpixel *)(ourdata+y*xmax*3));
712 >        register unsigned char  *dp;
713 >        register int    x;
714 >                                        /* set gamma correction */
715 >        setcolrgam(gamcor);
716 >                                        /* read and convert file */
717 >        dp = ourdata;
718 >        for (y = 0; y < ymax; y++) {
719 >                if (getscan(y) < 0)
720 >                        quiterr("seek error in getfull");
721 >                if (scale)
722 >                        shiftcolrs(scanline, xmax, scale);
723 >                colrs_gambs(scanline, xmax);
724 >                add2icon(y, scanline);
725 >                for (x = 0; x < xmax; x++) {
726 >                        *dp++ = scanline[x][RED];
727 >                        *dp++ = scanline[x][GRN];
728 >                        *dp++ = scanline[x][BLU];
729 >                }
730 >        }
731   }
732  
733  
# Line 648 | Line 766 | int  y;
766                  if (scanpos == NULL || scanpos[y] == -1)
767                          return(-1);
768                  if (fseek(fin, scanpos[y], 0) == -1)
769 <                        quit("fseek error");
769 >                        quiterr("fseek error");
770                  cury = y;
771          } else if (scanpos != NULL)
772                  scanpos[y] = ftell(fin);
# Line 671 | Line 789 | register rgbpixel  *l3;
789                  quiterr("cannot seek for picreadline");
790                                                          /* convert scanline */
791          normcolrs(scanline, xmax, scale);
792 +        add2icon(y, scanline);
793          for (i = 0; i < xmax; i++) {
794                  l3[i].r = scanline[i][RED];
795                  l3[i].g = scanline[i][GRN];
# Line 694 | Line 813 | colormap  map;
813          register int  i, val;
814  
815          for (i = 0; i < 256; i++) {
816 <                val = pow(i/256.0, 1.0/gamcor) * 256.0;
816 >                val = pow((i+0.5)/256.0, 1.0/gamcor) * 256.0;
817                  map[0][i] = map[1][i] = map[2][i] = val;
818          }
819   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines