--- ray/src/px/x11image.c 1993/06/18 10:22:26 2.27 +++ ray/src/px/x11image.c 1993/12/14 20:43:42 2.36 @@ -21,6 +21,7 @@ static char SCCSid[] = "$SunId$ LBL"; #include "standard.h" +#include #include #include #include @@ -32,6 +33,13 @@ static char SCCSid[] = "$SunId$ LBL"; #include "random.h" #include "resolu.h" +#ifdef __alpha +#define int4 int +#endif +#ifndef int4 +#define int4 long +#endif + #define FONTNAME "8x13" /* text font we'll use */ #define CTRL(c) ((c)-'@') @@ -48,6 +56,7 @@ static char SCCSid[] = "$SunId$ LBL"; #define redraw(x,y,w,h) patch_raster(wind,(x)-xoff,(y)-yoff,x,y,w,h,ourras) double gamcor = 2.2; /* gamma correction */ +char *gamstr = NULL; /* gamma value override */ int dither = 1; /* dither colors? */ int fast = 0; /* keep picture in Pixmap? */ @@ -64,6 +73,8 @@ int scale = 0; /* scalefactor; power of two */ int xoff = 0; /* x image offset */ int yoff = 0; /* y image offset */ +int parent = 0; /* number of children, -1 if child */ + VIEW ourview = STDVIEW; /* image view parameters */ int gotview = 0; /* got parameters from file */ @@ -106,22 +117,25 @@ extern BYTE clrtab[256][3]; /* global color map */ extern long ftell(); +extern char *getenv(); + Display *thedisplay; Atom closedownAtom, wmProtocolsAtom; +int sigrecv; +int onsig() { sigrecv++; } + + main(argc, argv) int argc; char *argv[]; { - extern char *getenv(); - char *gv; int headline(); int i; + int pid; progname = argv[0]; - if ((gv = getenv("GAMMA")) != NULL) - gamcor = atof(gv); for (i = 1; i < argc; i++) if (argv[i][0] == '-') @@ -153,7 +167,7 @@ char *argv[]; if (argv[i][2] == 'e') geometry = argv[++i]; else - gamcor = atof(argv[++i]); + gamstr = argv[++i]; break; default: goto userr; @@ -163,15 +177,28 @@ char *argv[]; else break; - if (i == argc-1) { + if (i > argc) + goto userr; + while (i < argc-1) { + sigrecv = 0; + signal(SIGCONT, onsig); + if ((pid=fork()) == 0) { /* a child for each picture */ + parent = -1; + break; + } + if (pid < 0) + quiterr("fork failed"); + parent++; + while (!sigrecv) + pause(); /* wait for wake-up call */ + i++; + } + if (i < argc) { /* open picture file */ fname = argv[i]; fin = fopen(fname, "r"); - if (fin == NULL) { - sprintf(errmsg, "cannot open file \"%s\"", fname); - quiterr(errmsg); - } - } else if (i != argc) - goto userr; + if (fin == NULL) + quiterr("cannot open picture file"); + } /* get header */ getheader(fin, headline, NULL); /* get picture dimensions */ @@ -187,11 +214,15 @@ char *argv[]; init(argc, argv); /* get file and open window */ + if (parent < 0) { + kill(getppid(), SIGCONT); /* signal parent if child */ + sigrecv--; + } for ( ; ; ) getevent(); /* main loop */ userr: fprintf(stderr, -"Usage: %s [-di disp][[-ge] spec][-b][-m][-d][-f][-c nclrs][-e +/-stops] pic\n", +"Usage: %s [-di disp][[-ge] spec][-b][-m][-d][-f][-c nclrs][-e +/-stops][-g gamcor] pic ..\n", progname); exit(1); } @@ -241,6 +272,13 @@ char **argv; name += i+1; if ((thedisplay = XOpenDisplay(dispname)) == NULL) quiterr("cannot open display"); + /* set gamma value */ + if (gamstr == NULL) /* get it from the X server */ + gamstr = XGetDefault(thedisplay, "radiance", "gamma"); + if (gamstr == NULL) /* get it from the environment */ + gamstr = getenv("GAMMA"); + if (gamstr != NULL) + gamcor = atof(gamstr); /* get best visual for default screen */ getbestvis(); /* store image */ @@ -282,10 +320,11 @@ char **argv; quiterr("cannot create window"); width = xmax; height = ymax; - xgcv.foreground = ourblack; - xgcv.background = ourwhite; + /* prepare graphics drawing context */ if ((xgcv.font = XLoadFont(thedisplay, FONTNAME)) == 0) quiterr("cannot get font"); + xgcv.foreground = ourblack; + xgcv.background = ourwhite; ourgc = XCreateGC(thedisplay, wind, GCForeground|GCBackground| GCFont, &xgcv); xgcv.function = GXinvert; @@ -321,11 +360,22 @@ char **argv; quiterr(err) /* print message and exit */ char *err; { - if (err != NULL) { - fprintf(stderr, "%s: %s\n", progname, err); - exit(1); + register int es; + int cs; + + if (es = err != NULL) + fprintf(stderr, "%s: %s: %s\n", progname, + fname==NULL?"":fname, err); + if (thedisplay != NULL) + XCloseDisplay(thedisplay); + if (parent < 0 & sigrecv == 0) + kill(getppid(), SIGCONT); + while (parent > 0 && wait(&cs) != -1) { /* wait for any children */ + if (es == 0) + es = cs>>8 & 0xff; + parent--; } - exit(0); + exit(es); } @@ -466,10 +516,10 @@ getras() /* get raster file */ goto fail; getmono(); } else if (ourvis.class == TrueColor | ourvis.class == DirectColor) { - ourdata = (unsigned char *)malloc(4*xmax*ymax); + ourdata = (unsigned char *)malloc(sizeof(int4)*xmax*ymax); if (ourdata == NULL) goto fail; - ourras = make_raster(thedisplay, &ourvis, 32, + ourras = make_raster(thedisplay, &ourvis, sizeof(int4)*8, ourdata, xmax, ymax, 32); if (ourras == NULL) goto fail; @@ -529,7 +579,7 @@ getevent() /* process the next event */ else getbox(&xev.xbutton); break; - case ClientMessage: + case ClientMessage: if ((xev.xclient.message_type == wmProtocolsAtom) && (xev.xclient.data.l[0] == closedownAtom)) quiterr(NULL); @@ -627,9 +677,16 @@ XKeyPressedEvent *ekey; case '@': /* adaptation level */ if (avgbox(cval) == -1) return(-1); - comp = com=='@' - ? 106./pow(1.219+pow(luminance(cval)/exposure,.4),2.5)/exposure - : .5/bright(cval) ; + comp = bright(cval); + if (comp < 1e-20) { + XBell(thedisplay, 0); + return(-1); + } + if (com == '@') + comp = 106./exposure/ + pow(1.219+pow(comp*WHTEFFICACY/exposure,.4),2.5); + else + comp = .5/comp; comp = log(comp)/.69315 - scale; n = comp < 0 ? comp-.5 : comp+.5 ; /* round */ if (n == 0) @@ -876,12 +933,12 @@ COLR *scan; getfull() /* get full (24-bit) data */ { int y; - register unsigned long *dp; + register unsigned int4 *dp; register int x; /* set gamma correction */ setcolrgam(gamcor); /* read and convert file */ - dp = (unsigned long *)ourdata; + dp = (unsigned int4 *)ourdata; for (y = 0; y < ymax; y++) { getscan(y); add2icon(y, scanline); @@ -890,14 +947,14 @@ getfull() /* get full (24-bit) data */ colrs_gambs(scanline, xmax); if (ourras->image->blue_mask & 1) for (x = 0; x < xmax; x++) - *dp++ = scanline[x][RED] << 16 | - scanline[x][GRN] << 8 | - scanline[x][BLU] ; + *dp++ = (unsigned int4)scanline[x][RED] << 16 | + (unsigned int4)scanline[x][GRN] << 8 | + (unsigned int4)scanline[x][BLU] ; else for (x = 0; x < xmax; x++) - *dp++ = scanline[x][RED] | - scanline[x][GRN] << 8 | - scanline[x][BLU] << 16 ; + *dp++ = (unsigned int4)scanline[x][RED] | + (unsigned int4)scanline[x][GRN] << 8 | + (unsigned int4)scanline[x][BLU] << 16 ; } } @@ -936,13 +993,16 @@ getgrey() /* get greyscale data */ getmapped() /* get color-mapped data */ { int y; + /* make sure we can do it first */ + if (fname == NULL) + quiterr("cannot map colors from standard input"); /* set gamma correction */ setcolrgam(gamcor); /* make histogram */ new_histo(); for (y = 0; y < ymax; y++) { if (getscan(y) < 0) - quiterr("seek error in getmapped"); + break; add2icon(y, scanline); if (scale) shiftcolrs(scanline, xmax, scale); @@ -953,8 +1013,7 @@ getmapped() /* get color-mapped data */ if (!new_clrtab(maxcolors)) quiterr("cannot create color map"); for (y = 0; y < ymax; y++) { - if (getscan(y) < 0) - quiterr("seek error in getmapped"); + getscan(y); if (scale) shiftcolrs(scanline, xmax, scale); colrs_gambs(scanline, xmax); @@ -997,6 +1056,12 @@ double sf; getscan(y) int y; { + static int trunced = -1; /* truncated file? */ +skipit: + if (trunced >= 0 && y >= trunced) { + bzero(scanline, xmax*sizeof(COLR)); + return(-1); + } if (y != cury) { if (scanpos == NULL || scanpos[y] == -1) return(-1); @@ -1006,9 +1071,12 @@ int y; } else if (scanpos != NULL && scanpos[y] == -1) scanpos[y] = ftell(fin); - if (freadcolrs(scanline, xmax, fin) < 0) - quiterr("read error"); - + if (freadcolrs(scanline, xmax, fin) < 0) { + fprintf(stderr, "%s: %s: unfinished picture\n", + progname, fname==NULL?"":fname); + trunced = y; + goto skipit; + } cury++; return(0); }