--- ray/src/common/tonemap.c 2005/01/07 22:05:30 3.18 +++ ray/src/common/tonemap.c 2006/03/23 22:01:43 3.22 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: tonemap.c,v 3.18 2005/01/07 22:05:30 greg Exp $"; +static const char RCSid[] = "$Id: tonemap.c,v 3.22 2006/03/23 22:01:43 greg Exp $"; #endif /* * Tone mapping functions. @@ -171,6 +171,8 @@ int len { static const char funcName[] = "tmCvColors"; static COLOR csmall = {.5*MINLUM, .5*MINLUM, .5*MINLUM}; + static BYTE gamtab[1024]; + static double curgam = .0; COLOR cmon; double lum, slum; double d; @@ -180,6 +182,11 @@ int len returnErr(TM_E_TMINVAL); if ((ls == NULL) | (scan == NULL) | (len < 0)) returnErr(TM_E_ILLEGAL); + if (cs != TM_NOCHROM && fabs(tms->mongam - curgam) > .02) { + curgam = tms->mongam; /* (re)build table */ + for (i = 1024; i--; ) + gamtab[i] = (int)(256.*pow((i+.5)/1024., 1./curgam)); + } for (i = len; i--; ) { if (tmNeedMatrix(tms)) { /* get monitor RGB */ colortrans(cmon, tms->cmat, scan[i]); @@ -188,6 +195,11 @@ int len cmon[GRN] = tms->inpsf*scan[i][GRN]; cmon[BLU] = tms->inpsf*scan[i][BLU]; } +#ifdef isnan + if (isnan(cmon[RED]) || isinf(cmon[RED])) cmon[RED] = .0f; + if (isnan(cmon[GRN]) || isinf(cmon[GRN])) cmon[GRN] = .0f; + if (isnan(cmon[BLU]) || isinf(cmon[BLU])) cmon[BLU] = .0f; +#endif /* world luminance */ lum = tms->clf[RED]*cmon[RED] + tms->clf[GRN]*cmon[GRN] + @@ -226,16 +238,29 @@ int len cmon[RED] = cmon[GRN] = cmon[BLU] = lum; } d = tms->clf[RED]*cmon[RED]/lum; - cs[3*i ] = d>=.999 ? 255 : - (int)(256.*pow(d, 1./tms->mongam)); + cs[3*i ] = d>=.999 ? 255 : gamtab[(int)(1024.*d)]; d = tms->clf[GRN]*cmon[GRN]/lum; - cs[3*i+1] = d>=.999 ? 255 : - (int)(256.*pow(d, 1./tms->mongam)); + cs[3*i+1] = d>=.999 ? 255 : gamtab[(int)(1024.*d)]; d = tms->clf[BLU]*cmon[BLU]/lum; - cs[3*i+2] = d>=.999 ? 255 : - (int)(256.*pow(d, 1./tms->mongam)); + cs[3*i+2] = d>=.999 ? 255 : gamtab[(int)(1024.*d)]; } returnOK; +} + + +TMbright +tmCvLuminance( /* convert a single luminance */ +double lum +) +{ + double d; + + if (lum <= TM_NOLUM) + return(TM_NOBRT); + d = TM_BRTSCALE*log(lum); + if (d > 0.) + return((TMbright)(d+.5)); + return((TMbright)(d-.5)); }