void compavg( /* recompute averages */ PNODE *p ) { int i, navg; if (p->kid == NULL) return; setcolor(p->v, .0, .0, .0); navg = 0; for (i = 0; i < 4; i++) { if (p->kid[i].xmin >= p->kid[i].xmax) continue; if (p->kid[i].ymin >= p->kid[i].ymax) continue; compavg(p->kid+i); addcolor(p->v, p->kid[i].v); navg++; } if (navg > 1) scalecolor(p->v, 1./navg); }
void getexposure( /* get new exposure */ char *s ) { char buf[128]; char *cp; int x, y; PNODE *p = &ptrunk; int adapt = 0; double e = 1.0; for (cp = s; isspace(*cp); cp++) ; if (*cp == '@') { adapt++; while (isspace(*++cp)) ; } if (*cp == '\0') { /* normalize to point */ if (dev->getcur == NULL) return; (*dev->comout)("Pick point for exposure\n"); if ((*dev->getcur)(&x, &y) == ABORT) return; p = findrect(x, y, &ptrunk, -1); } else { if (*cp == '=') { /* absolute setting */ p = NULL; e = 1.0/exposure; for (cp++; isspace(*cp); cp++) ; if (*cp == '\0') { /* interactive */ sprintf(buf, "exposure (%f): ", exposure); (*dev->comout)(buf); (*dev->comin)(buf, NULL); for (cp = buf; isspace(*cp); cp++) ; if (*cp == '\0') return; } } if (*cp == '+' || *cp == '-') /* f-stops */ e *= pow(2.0, atof(cp)); else /* multiplier */ e *= atof(cp); } if (p != NULL) { /* relative setting */ compavg(p); if (bright(p->v) < 1e-15) { error(COMMAND, "cannot normalize to zero"); return; } if (adapt) e *= 106./pow(1.219+pow(luminance(p->v)/exposure,.4),2.5)/exposure; else e *= 0.5 / bright(p->v); } if (e <= FTINY || fabs(1.0 - e) <= FTINY) return; scalepict(&ptrunk, e); exposure *= e; redraw(); }