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.16 by greg, Wed May 1 12:40:00 1991 UTC vs.
Revision 2.6 by greg, Wed May 27 14:28:50 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  "x11icon.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)
45 #define  ourgc          DefaultGC(thedisplay,ourscreen)
47  
48   #define  revline(x0,y0,x1,y1)   XDrawLine(thedisplay,wind,revgc,x0,y0,x1,y1)
49  
# Line 53 | Line 54 | double  gamcor = 2.2;                  /* gamma correction */
54   int  dither = 1;                        /* dither colors? */
55   int  fast = 0;                          /* keep picture in Pixmap? */
56  
57 + char    *dispname = NULL;               /* our display name */
58 +
59   Window  wind = 0;                       /* our output window */
60   Font  fontid;                           /* our font */
61  
# Line 69 | Line 72 | int  gotview = 0;                      /* got parameters from file */
72  
73   COLR  *scanline;                        /* scan line buffer */
74  
75 < int  xmax, ymax;                        /* picture resolution */
75 > RESOLU  inpres;                         /* input resolution and ordering */
76 > int  xmax, ymax;                        /* picture dimensions */
77   int  width, height;                     /* window size */
78   char  *fname = NULL;                    /* input file name */
79   FILE  *fin = stdin;                     /* input file */
# Line 80 | Line 84 | double  exposure = 1.0;                        /* exposure compensation use
84  
85   int  wrongformat = 0;                   /* input in another format? */
86  
87 + GC      ourgc;                          /* standard graphics context */
88   GC      revgc;                          /* graphics context with GXinvert */
89  
90 < XRASTER *ourras;                        /* our stored image */
90 > int             *ourrank;               /* our visual class ranking */
91 > XVisualInfo     ourvis;                 /* our visual */
92 > XRASTER         *ourras;                /* our stored image */
93   unsigned char   *ourdata;               /* our image data */
94  
95   struct {
# Line 91 | Line 98 | struct {
98  
99   char  *geometry = NULL;                 /* geometry specification */
100  
101 + char  icondata[ICONSIZ*ICONSIZ/8];      /* icon bitmap data */
102 + int  iconwidth = 0, iconheight = 0;
103 +
104   char  *progname;
105  
106   char  errmsg[128];
# Line 99 | Line 109 | extern long  ftell();
109  
110   extern char  *malloc(), *calloc();
111  
112 < extern double  atof(), pow(), log();
112 > extern double  pow(), log();
113  
114   Display  *thedisplay;
115  
# Line 125 | Line 135 | char  *argv[];
135                                  maxcolors = 2;
136                                  break;
137                          case 'd':
138 +                                if (argv[i][2] == 'i') {
139 +                                        dispname = argv[++i];
140 +                                        break;
141 +                                }
142                                  dither = !dither;
143                                  break;
144                          case 'f':
# Line 153 | Line 167 | char  *argv[];
167                  fname = argv[i];
168                  fin = fopen(fname, "r");
169                  if (fin == NULL) {
170 <                        sprintf(errmsg, "can't open file \"%s\"", fname);
170 >                        sprintf(errmsg, "cannot open file \"%s\"", fname);
171                          quiterr(errmsg);
172                  }
173          } else if (i != argc)
# Line 161 | Line 175 | char  *argv[];
175                                  /* get header */
176          getheader(fin, headline, NULL);
177                                  /* get picture dimensions */
178 <        if (wrongformat || fgetresolu(&xmax, &ymax, fin) != (YMAJOR|YDECR))
178 >        if (wrongformat || !fgetsresolu(&inpres, fin))
179                  quiterr("bad picture format");
180 +        xmax = scanlen(&inpres);
181 +        ymax = numscans(&inpres);
182                                  /* set view parameters */
183          if (gotview && setview(&ourview) != NULL)
184                  gotview = 0;
# Line 184 | Line 200 | userr:
200   headline(s)             /* get relevant info from header */
201   char  *s;
202   {
187        static char  *altname[] = {"rview","rpict","pinterp",VIEWSTR,NULL};
188        register char  **an;
203          char  fmt[32];
204  
205          if (isexpos(s))
# Line 193 | Line 207 | char  *s;
207          else if (isformat(s)) {
208                  formatval(fmt, s);
209                  wrongformat = strcmp(fmt, COLRFMT);
210 <        } else
211 <                for (an = altname; *an != NULL; an++)
198 <                        if (!strncmp(*an, s, strlen(*an))) {
199 <                                if (sscanview(&ourview, s+strlen(*an)) > 0)
200 <                                        gotview++;
201 <                                return;
202 <                        }
210 >        } else if (isview(s) && sscanview(&ourview, s) > 0)
211 >                gotview++;
212   }
213  
214  
# Line 207 | Line 216 | init()                 /* get data and open window */
216   {
217          XWMHints        ourxwmhints;
218          XSetWindowAttributes    ourwinattr;
219 <        XSizeHints  oursizhints;
220 <        register int  i;
219 >        XSizeHints      oursizhints;
220 >        register int    i;
221          
222          if (fname != NULL) {
223                  scanpos = (long *)malloc(ymax*sizeof(long));
# Line 217 | Line 226 | init()                 /* get data and open window */
226                  for (i = 0; i < ymax; i++)
227                          scanpos[i] = -1;
228          }
229 <        if ((thedisplay = XOpenDisplay(NULL)) == NULL)
230 <                quiterr("can't open display; DISPLAY variable set?");
231 <        if (maxcolors == 0) {           /* get number of available colors */
232 <                i = DisplayPlanes(thedisplay,ourscreen);
224 <                maxcolors = i > 8 ? 256 : 1<<i;
225 <                if (maxcolors > 4) maxcolors -= 2;
226 <        }
229 >        if ((thedisplay = XOpenDisplay(dispname)) == NULL)
230 >                quiterr("cannot open display");
231 >                                /* get best visual for default screen */
232 >        getbestvis();
233                                  /* store image */
234          getras();
235                                  /* open window */
236          ourwinattr.border_pixel = ourblack;
237          ourwinattr.background_pixel = ourwhite;
238 +        ourwinattr.colormap = XCreateColormap(thedisplay, ourroot,
239 +                        ourvis.visual, AllocNone);
240          wind = XCreateWindow(thedisplay, ourroot, 0, 0, xmax, ymax, BORWIDTH,
241 <                        0, InputOutput, ourras->visual,
242 <                        CWBackPixel|CWBorderPixel, &ourwinattr);
241 >                        ourvis.depth, InputOutput, ourvis.visual,
242 >                        CWBackPixel|CWBorderPixel|CWColormap, &ourwinattr);
243          if (wind == 0)
244 <                quiterr("can't create window");
244 >                quiterr("cannot create window");
245          width = xmax;
246          height = ymax;
247 +        ourgc = XCreateGC(thedisplay, wind, 0, 0);
248 +        XSetState(thedisplay, ourgc, BlackPixel(thedisplay,ourscreen),
249 +                        WhitePixel(thedisplay,ourscreen), GXcopy, AllPlanes);
250 +        revgc = XCreateGC(thedisplay, wind, 0, 0);
251 +        XSetFunction(thedisplay, revgc, GXinvert);
252          fontid = XLoadFont(thedisplay, FONTNAME);
253          if (fontid == 0)
254 <                quiterr("can't get font");
254 >                quiterr("cannot get font");
255          XSetFont(thedisplay, ourgc, fontid);
243        revgc = XCreateGC(thedisplay, wind, 0, 0);
244        XSetFunction(thedisplay, revgc, GXinvert);
245        XStoreName(thedisplay, wind, fname == NULL ? progname : fname);
256          XDefineCursor(thedisplay, wind, XCreateFontCursor(thedisplay,
257                          XC_diamond_cross));
258 +        XStoreName(thedisplay, wind, fname == NULL ? progname : fname);
259          if (geometry != NULL) {
260                  bzero((char *)&oursizhints, sizeof(oursizhints));
261                  i = XParseGeometry(geometry, &oursizhints.x, &oursizhints.y,
# Line 271 | Line 282 | init()                 /* get data and open window */
282          ourxwmhints.flags = InputHint|IconPixmapHint;
283          ourxwmhints.input = True;
284          ourxwmhints.icon_pixmap = XCreateBitmapFromData(thedisplay,
285 <                        wind, x11icon_bits, x11icon_width, x11icon_height);
285 >                        wind, icondata, iconwidth, iconheight);
286          XSetWMHints(thedisplay, wind, &ourxwmhints);
287          XSelectInput(thedisplay, wind, ButtonPressMask|ButtonReleaseMask
288                          |ButtonMotionMask|StructureNotifyMask
# Line 308 | Line 319 | int  code;
319   }
320  
321  
322 + static int
323 + viscmp(v1,v2)           /* compare visual to see which is better, descending */
324 + register XVisualInfo    *v1, *v2;
325 + {
326 +        int     bad1 = 0, bad2 = 0;
327 +        register int  *rp;
328 +
329 +        if (v1->class == v2->class) {
330 +                if (v1->class == TrueColor || v1->class == DirectColor) {
331 +                                        /* prefer 24-bit to 32-bit */
332 +                        if (v1->depth == 24 && v2->depth == 32)
333 +                                return(-1);
334 +                        if (v1->depth == 32 && v2->depth == 24)
335 +                                return(1);
336 +                        return(0);
337 +                }
338 +                                        /* don't be too greedy */
339 +                if (maxcolors <= 1<<v1->depth && maxcolors <= 1<<v2->depth)
340 +                        return(v1->depth - v2->depth);
341 +                return(v2->depth - v1->depth);
342 +        }
343 +                                        /* prefer Pseudo when < 24-bit */
344 +        if ((v1->class == TrueColor || v1->class == DirectColor) &&
345 +                        v1->depth < 24)
346 +                bad1 = 1;
347 +        if ((v2->class == TrueColor || v2->class == DirectColor) &&
348 +                        v2->depth < 24)
349 +                bad2 = -1;
350 +        if (bad1 | bad2)
351 +                return(bad1+bad2);
352 +                                        /* otherwise, use class ranking */
353 +        for (rp = ourrank; *rp != -1; rp++) {
354 +                if (v1->class == *rp)
355 +                        return(-1);
356 +                if (v2->class == *rp)
357 +                        return(1);
358 +        }
359 +        return(0);
360 + }
361 +
362 +
363 + getbestvis()                    /* get the best visual for this screen */
364 + {
365 + static char  vistype[][12] = {
366 +                "StaticGray",
367 +                "GrayScale",
368 +                "StaticColor",
369 +                "PseudoColor",
370 +                "TrueColor",
371 +                "DirectColor"
372 + };
373 +        static int      rankings[3][6] = {
374 +                {TrueColor,DirectColor,PseudoColor,GrayScale,StaticGray,-1},
375 +                {PseudoColor,GrayScale,-1},
376 +                {PseudoColor,GrayScale,-1}
377 +        };
378 +        XVisualInfo     *xvi;
379 +        int     vismatched;
380 +        register int    i, j;
381 +
382 +        if (greyscale) {
383 +                ourrank = rankings[2];
384 +                if (maxcolors < 2) maxcolors = 256;
385 +        } else if (maxcolors >= 2 && maxcolors <= 256)
386 +                ourrank = rankings[1];
387 +        else {
388 +                ourrank = rankings[0];
389 +                maxcolors = 256;
390 +        }
391 +                                        /* find best visual */
392 +        ourvis.screen = ourscreen;
393 +        xvi = XGetVisualInfo(thedisplay,VisualScreenMask,&ourvis,&vismatched);
394 +        if (xvi == NULL)
395 +                quiterr("no visuals for this screen!");
396 + for (i = 0; i < vismatched; i++)
397 + fprintf(stderr, "Type %s, depth %d\n", vistype[xvi[i].class], xvi[i].depth);
398 +        for (i = 0, j = 1; j < vismatched; j++)
399 +                if (viscmp(&xvi[i],&xvi[j]) > 0)
400 +                        i = j;
401 +                                        /* compare to least acceptable */
402 +        for (j = 0; ourrank[j++] != -1; )
403 +                ;
404 +        ourvis.class = ourrank[--j];
405 +        ourvis.depth = 1;
406 +        if (viscmp(&xvi[i],&ourvis) > 0)
407 +                quiterr("inadequate visuals on this screen");
408 +                                        /* OK, we'll use it */
409 +        copystruct(&ourvis, &xvi[i]);
410 + fprintf(stderr, "Selected visual type %s, depth %d\n", vistype[ourvis.class],
411 + ourvis.depth);
412 +        if (ourvis.class == GrayScale || ourvis.class == StaticGray)
413 +                greyscale = 1;
414 +        if (1<<ourvis.depth < maxcolors)
415 +                maxcolors = 1<<ourvis.depth;
416 +        if (maxcolors > 4)
417 +                maxcolors -= 2;
418 +        XFree((char *)xvi);
419 + }
420 +
421 +
422   getras()                                /* get raster file */
423   {
424          colormap        ourmap;
# Line 317 | Line 428 | getras()                               /* get raster file */
428                  ourdata = (unsigned char *)malloc(ymax*((xmax+7)/8));
429                  if (ourdata == NULL)
430                          goto fail;
431 <                ourras = make_raster(thedisplay, ourscreen, 1, ourdata,
431 >                ourras = make_raster(thedisplay, &ourvis, 1, ourdata,
432                                  xmax, ymax, 8);
433                  if (ourras == NULL)
434                          goto fail;
435                  getmono();
436 <        } else if (XMatchVisualInfo(thedisplay,ourscreen,24,TrueColor,&vinfo)
437 <                                                /* kludge for DirectColor */
327 <        || XMatchVisualInfo(thedisplay,ourscreen,24,DirectColor,&vinfo)) {
328 <                ourdata = (unsigned char *)malloc(xmax*ymax*3);
436 >        } else if (ourvis.class == TrueColor || ourvis.class == DirectColor) {
437 >                ourdata = (unsigned char *)malloc(4*xmax*ymax);
438                  if (ourdata == NULL)
439                          goto fail;
440 <                ourras = make_raster(thedisplay, ourscreen, 24, ourdata,
441 <                                xmax, ymax, 8);
440 >                ourras = make_raster(thedisplay, &ourvis, 32,
441 >                                ourdata, xmax, ymax, 32);
442                  if (ourras == NULL)
443                          goto fail;
444                  getfull();
# Line 337 | Line 446 | getras()                               /* get raster file */
446                  ourdata = (unsigned char *)malloc(xmax*ymax);
447                  if (ourdata == NULL)
448                          goto fail;
449 <                ourras = make_raster(thedisplay, ourscreen, 8, ourdata,
449 >                ourras = make_raster(thedisplay, &ourvis, 8, ourdata,
450                                  xmax, ymax, 8);
451                  if (ourras == NULL)
452                          goto fail;
# Line 376 | Line 485 | getevent()                             /* process the next event */
485          case MapNotify:
486                  map_rcolors(ourras, wind);
487                  if (fast)
488 <                        make_rpixmap(ourras);
488 >                        make_rpixmap(ourras, wind);
489                  break;
490          case UnmapNotify:
491                  unmap_rcolors(ourras);
# Line 402 | Line 511 | XKeyPressedEvent  *ekey;
511          XColor  cvx;
512          int  com, n;
513          double  comp;
514 +        FLOAT  hv[2];
515          FVECT  rorg, rdir;
516  
517          n = XLookupString(ekey, buf, sizeof(buf), NULL, NULL);
# Line 410 | Line 520 | XKeyPressedEvent  *ekey;
520          com = buf[0];
521          switch (com) {                  /* interpret command */
522          case 'q':
523 <        case CTRL(D):                           /* quit */
523 >        case CTRL('D'):                         /* quit */
524                  quit(0);
525          case '\n':
526          case '\r':
# Line 450 | Line 560 | XKeyPressedEvent  *ekey;
560                  XStoreColor(thedisplay, ourras->cmap, &cvx);
561                  return(0);
562          case 'p':                               /* position */
563 <                sprintf(buf, "(%d,%d)", ekey->x-xoff, ymax-1-ekey->y+yoff);
563 >                pix2loc(hv, &inpres, ekey->x-xoff, ekey->y-yoff);
564 >                sprintf(buf, "(%d,%d)", (int)(hv[0]*inpres.xr),
565 >                                (int)(hv[1]*inpres.yr));
566                  XDrawImageString(thedisplay, wind, ourgc, ekey->x, ekey->y,
567                                          buf, strlen(buf));
568                  return(0);
# Line 459 | Line 571 | XKeyPressedEvent  *ekey;
571                          XBell(thedisplay, 0);
572                          return(-1);
573                  }
574 <                if (viewray(rorg, rdir, &ourview,
575 <                                (ekey->x-xoff+.5)/xmax,
464 <                                (ymax-1-ekey->y+yoff+.5)/ymax) < 0)
574 >                pix2loc(hv, &inpres, ekey->x-xoff, ekey->y-yoff);
575 >                if (viewray(rorg, rdir, &ourview, hv[0], hv[1]) < 0)
576                          return(-1);
577                  printf("%e %e %e ", rorg[0], rorg[1], rorg[2]);
578                  printf("%e %e %e\n", rdir[0], rdir[1], rdir[2]);
# Line 483 | Line 594 | XKeyPressedEvent  *ekey;
594                  free_raster(ourras);
595                  getras();
596          /* fall through */
597 <        case CTRL(R):                           /* redraw */
598 <        case CTRL(L):
597 >        case CTRL('R'):                         /* redraw */
598 >        case CTRL('L'):
599                  unmap_rcolors(ourras);
600                  XClearWindow(thedisplay, wind);
601                  map_rcolors(ourras, wind);
# Line 576 | Line 687 | int  x0, y0, x1, y1;
687   avgbox(clr)                             /* average color over current box */
688   COLOR  clr;
689   {
690 +        static COLOR  lc;
691 +        static int  ll, lr, lt, lb;
692          int  left, right, top, bottom;
693          int  y;
694          double  d;
# Line 599 | Line 712 | COLOR  clr;
712                  bottom = ymax;
713          if (top >= bottom)
714                  return(-1);
715 +        if (left == ll && right == lr && top == lt && bottom == lb) {
716 +                copycolor(clr, lc);
717 +                return;
718 +        }
719          for (y = top; y < bottom; y++) {
720                  if (getscan(y) == -1)
721                          return(-1);
# Line 609 | Line 726 | COLOR  clr;
726          }
727          d = 1.0/((right-left)*(bottom-top));
728          scalecolor(clr, d);
729 +        ll = left; lr = right; lt = top; lb = bottom;
730 +        copycolor(lc, clr);
731          return(0);
732   }
733  
# Line 617 | Line 736 | getmono()                      /* get monochrome data */
736   {
737          register unsigned char  *dp;
738          register int    x, err;
739 <        int     y;
739 >        int     y, errp;
740          short   *cerr;
741  
742          if ((cerr = (short *)calloc(xmax,sizeof(short))) == NULL)
# Line 627 | Line 746 | getmono()                      /* get monochrome data */
746                  if (getscan(y) < 0)
747                          quiterr("seek error in getmono");
748                  normcolrs(scanline, xmax, scale);
749 +                add2icon(y, scanline);
750                  err = 0;
751                  for (x = 0; x < xmax; x++) {
752                          if (!(x&7))
753                                  *++dp = 0;
754 +                        errp = err;
755                          err += normbright(scanline[x]) + cerr[x];
756                          if (err > 127)
757                                  err -= 255;
758                          else
759                                  *dp |= 1<<(7-(x&07));
760 <                        cerr[x] = err >>= 1;
760 >                        err /= 3;
761 >                        cerr[x] = err + errp;
762                  }
763          }
764          free((char *)cerr);
765   }
766  
767  
768 + add2icon(y, scan)               /* add a scanline to our icon data */
769 + int  y;
770 + COLR  *scan;
771 + {
772 +        static short  cerr[ICONSIZ];
773 +        static int  ynext;
774 +        static char  *dp;
775 +        register int  err;
776 +        register int    x, ti;
777 +        int  errp;
778 +
779 +        if (iconheight == 0) {          /* initialize */
780 +                if (xmax <= ICONSIZ && ymax <= ICONSIZ) {
781 +                        iconwidth = xmax;
782 +                        iconheight = ymax;
783 +                } else if (xmax > ymax) {
784 +                        iconwidth = ICONSIZ;
785 +                        iconheight = ICONSIZ*ymax/xmax;
786 +                        if (iconheight < 1)
787 +                                iconheight = 1;
788 +                } else {
789 +                        iconwidth = ICONSIZ*xmax/ymax;
790 +                        if (iconwidth < 1)
791 +                                iconwidth = 1;
792 +                        iconheight = ICONSIZ;
793 +                }
794 +                ynext = 0;
795 +                dp = icondata - 1;
796 +        }
797 +        if (y < ynext*ymax/iconheight)  /* skip this one */
798 +                return;
799 +        err = 0;
800 +        for (x = 0; x < iconwidth; x++) {
801 +                if (!(x&7))
802 +                        *++dp = 0;
803 +                errp = err;
804 +                ti = x*xmax/iconwidth;
805 +                err += normbright(scan[ti]) + cerr[x];
806 +                if (err > 127)
807 +                        err -= 255;
808 +                else
809 +                        *dp |= 1<<(x&07);
810 +                err /= 3;
811 +                cerr[x] = err + errp;
812 +        }
813 +        ynext++;
814 + }
815 +
816 +
817   getfull()                       /* get full (24-bit) data */
818   {
819          int     y;
820 <        register unsigned char  *dp;
820 >        register unsigned long  *dp;
821          register int    x;
822                                          /* set gamma correction */
823          setcolrgam(gamcor);
824                                          /* read and convert file */
825 <        dp = ourdata;
825 >        dp = (unsigned long *)ourdata;
826          for (y = 0; y < ymax; y++) {
827                  if (getscan(y) < 0)
828                          quiterr("seek error in getfull");
829                  if (scale)
830                          shiftcolrs(scanline, xmax, scale);
831                  colrs_gambs(scanline, xmax);
832 <                for (x = 0; x < xmax; x++) {
833 <                        *dp++ = scanline[x][RED];
834 <                        *dp++ = scanline[x][GRN];
835 <                        *dp++ = scanline[x][BLU];
836 <                }
832 >                add2icon(y, scanline);
833 >                if (ourras->image->blue_mask & 1)
834 >                        for (x = 0; x < xmax; x++)
835 >                                *dp++ = scanline[x][RED] << 16 |
836 >                                        scanline[x][GRN] << 8 |
837 >                                        scanline[x][BLU] ;
838 >                else
839 >                        for (x = 0; x < xmax; x++)
840 >                                *dp++ = scanline[x][RED] |
841 >                                        scanline[x][GRN] << 8 |
842 >                                        scanline[x][BLU] << 16 ;
843          }
844   }
845  
# Line 725 | Line 902 | register rgbpixel  *l3;
902                  quiterr("cannot seek for picreadline");
903                                                          /* convert scanline */
904          normcolrs(scanline, xmax, scale);
905 +        add2icon(y, scanline);
906          for (i = 0; i < xmax; i++) {
907                  l3[i].r = scanline[i][RED];
908                  l3[i].g = scanline[i][GRN];

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines