--- ray/src/px/x11image.c 1991/05/03 09:49:02 1.18 +++ ray/src/px/x11image.c 1991/12/19 14:52:27 2.2 @@ -1,4 +1,4 @@ -/* Copyright (c) 1990 Regents of the University of California */ +/* Copyright (c) 1991 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -30,6 +30,7 @@ static char SCCSid[] = "$SunId$ LBL"; #include "pic.h" #include "x11raster.h" #include "random.h" +#include "resolu.h" #define FONTNAME "8x13" /* text font we'll use */ @@ -70,7 +71,8 @@ int gotview = 0; /* got parameters from file */ COLR *scanline; /* scan line buffer */ -int xmax, ymax; /* picture resolution */ +RESOLU inpres; /* input resolution and ordering */ +int xmax, ymax; /* picture dimensions */ int width, height; /* window size */ char *fname = NULL; /* input file name */ FILE *fin = stdin; /* input file */ @@ -103,7 +105,7 @@ extern long ftell(); extern char *malloc(), *calloc(); -extern double atof(), pow(), log(); +extern double pow(), log(); Display *thedisplay; @@ -165,8 +167,10 @@ char *argv[]; /* get header */ getheader(fin, headline, NULL); /* get picture dimensions */ - if (wrongformat || fgetresolu(&xmax, &ymax, fin) != (YMAJOR|YDECR)) + if (wrongformat || !fgetsresolu(&inpres, fin)) quiterr("bad picture format"); + xmax = scanlen(&inpres); + ymax = numscans(&inpres); /* set view parameters */ if (gotview && setview(&ourview) != NULL) gotview = 0; @@ -246,9 +250,9 @@ init() /* get data and open window */ XSetFont(thedisplay, ourgc, fontid); revgc = XCreateGC(thedisplay, wind, 0, 0); XSetFunction(thedisplay, revgc, GXinvert); - XStoreName(thedisplay, wind, fname == NULL ? progname : fname); XDefineCursor(thedisplay, wind, XCreateFontCursor(thedisplay, XC_diamond_cross)); + XStoreName(thedisplay, wind, fname == NULL ? progname : fname); if (geometry != NULL) { bzero((char *)&oursizhints, sizeof(oursizhints)); i = XParseGeometry(geometry, &oursizhints.x, &oursizhints.y, @@ -406,6 +410,7 @@ XKeyPressedEvent *ekey; XColor cvx; int com, n; double comp; + FLOAT hv[2]; FVECT rorg, rdir; n = XLookupString(ekey, buf, sizeof(buf), NULL, NULL); @@ -454,7 +459,9 @@ XKeyPressedEvent *ekey; XStoreColor(thedisplay, ourras->cmap, &cvx); return(0); case 'p': /* position */ - sprintf(buf, "(%d,%d)", ekey->x-xoff, ymax-1-ekey->y+yoff); + pix2loc(hv, &inpres, ekey->x-xoff, ekey->y-yoff); + sprintf(buf, "(%d,%d)", (int)(hv[0]*inpres.xr), + (int)(hv[1]*inpres.yr)); XDrawImageString(thedisplay, wind, ourgc, ekey->x, ekey->y, buf, strlen(buf)); return(0); @@ -463,9 +470,8 @@ XKeyPressedEvent *ekey; XBell(thedisplay, 0); return(-1); } - if (viewray(rorg, rdir, &ourview, - (ekey->x-xoff+.5)/xmax, - (ymax-1-ekey->y+yoff+.5)/ymax) < 0) + pix2loc(hv, &inpres, ekey->x-xoff, ekey->y-yoff); + if (viewray(rorg, rdir, &ourview, hv[0], hv[1]) < 0) return(-1); printf("%e %e %e ", rorg[0], rorg[1], rorg[2]); printf("%e %e %e\n", rdir[0], rdir[1], rdir[2]); @@ -580,6 +586,8 @@ int x0, y0, x1, y1; avgbox(clr) /* average color over current box */ COLOR clr; { + static COLOR lc; + static int ll, lr, lt, lb; int left, right, top, bottom; int y; double d; @@ -603,6 +611,10 @@ COLOR clr; bottom = ymax; if (top >= bottom) return(-1); + if (left == ll && right == lr && top == lt && bottom == lb) { + copycolor(clr, lc); + return; + } for (y = top; y < bottom; y++) { if (getscan(y) == -1) return(-1); @@ -613,6 +625,8 @@ COLOR clr; } d = 1.0/((right-left)*(bottom-top)); scalecolor(clr, d); + ll = left; lr = right; lt = top; lb = bottom; + copycolor(lc, clr); return(0); } @@ -621,7 +635,7 @@ getmono() /* get monochrome data */ { register unsigned char *dp; register int x, err; - int y; + int y, errp; short *cerr; if ((cerr = (short *)calloc(xmax,sizeof(short))) == NULL) @@ -636,12 +650,14 @@ getmono() /* get monochrome data */ for (x = 0; x < xmax; x++) { if (!(x&7)) *++dp = 0; + errp = err; err += normbright(scanline[x]) + cerr[x]; if (err > 127) err -= 255; else *dp |= 1<<(7-(x&07)); - cerr[x] = err >>= 1; + err /= 3; + cerr[x] = err + errp; } } free((char *)cerr); @@ -652,10 +668,12 @@ add2icon(y, scan) /* add a scanline to our icon data int y; COLR *scan; { - static char *dp = NULL; static short cerr[ICONSIZ]; + static int ynext; + static char *dp; register int err; - register int x, xi; + register int x, ti; + int errp; if (iconheight == 0) { /* initialize */ if (xmax <= ICONSIZ && ymax <= ICONSIZ) { @@ -664,30 +682,34 @@ COLR *scan; } else if (xmax > ymax) { iconwidth = ICONSIZ; iconheight = ICONSIZ*ymax/xmax; + if (iconheight < 1) + iconheight = 1; } else { iconwidth = ICONSIZ*xmax/ymax; + if (iconwidth < 1) + iconwidth = 1; iconheight = ICONSIZ; } + ynext = 0; dp = icondata - 1; } - if (dp == NULL) /* done already */ + if (y < ynext*ymax/iconheight) /* skip this one */ return; - if (y % (ymax/iconheight)) /* skip this one */ - return; err = 0; for (x = 0; x < iconwidth; x++) { if (!(x&7)) *++dp = 0; - xi = x*xmax/iconwidth; - err += normbright(scan[xi]) + cerr[x]; + errp = err; + ti = x*xmax/iconwidth; + err += normbright(scan[ti]) + cerr[x]; if (err > 127) err -= 255; else *dp |= 1<<(x&07); - cerr[x] = err >>= 1; + err /= 3; + cerr[x] = err + errp; } - if (y >= ymax - ymax/iconheight) /* all done */ - dp = NULL; + ynext++; }