--- ray/src/common/tmapcolrs.c 1997/04/16 20:28:05 3.2 +++ ray/src/common/tmapcolrs.c 1998/10/27 09:16:53 3.7 @@ -1,7 +1,7 @@ -/* Copyright (c) 1997 Regents of the University of California */ +/* Copyright (c) 1998 Silicon Graphics, Inc. */ #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static char SCCSid[] = "$SunId$ SGI"; #endif /* @@ -17,13 +17,29 @@ static char SCCSid[] = "$SunId$ LBL"; extern char *tempbuffer(); +#define GAMTSZ 1024 + +typedef struct { + BYTE gamb[GAMTSZ]; /* gamma lookup table */ + COLR clfb; /* encoded tm->clf */ + TMbright inpsfb; /* encoded tm->inpsf */ +} COLRDATA; + +static MEM_PTR colrInit(); +static void colrNewSpace(); +extern void free(); +static struct tmPackage colrPkg = { /* our package functions */ + colrInit, colrNewSpace, free +}; +static int colrReg = -1; /* our package registration number */ + #define LOGISZ 260 static TMbright logi[LOGISZ]; static BYTE photofact[BMESUPPER-BMESLOWER]; int -tmCvColrs(ls, cs, scan, len) /* tone map RGBE/XYZE colors */ +tmCvColrs(ls, cs, scan, len) /* convert RGBE/XYZE colors */ TMbright *ls; BYTE *cs; COLR *scan; @@ -31,13 +47,14 @@ int len; { static char funcName[] = "tmCvColrs"; COLR cmon; + register COLRDATA *cd; register int i, bi, li; if (tmTop == NULL) returnErr(TM_E_TMINVAL); - if (ls == NULL | scan == NULL | len <= 0) + if (ls == NULL | scan == NULL | len < 0) returnErr(TM_E_ILLEGAL); - if (tmTop->flags & TM_F_NEEDMAT) { /* need floating point */ + if (tmNeedMatrix(tmTop)) { /* need floating point */ register COLOR *newscan; newscan = (COLOR *)tempbuffer(len*sizeof(COLOR)); if (newscan == NULL) @@ -46,7 +63,10 @@ int len; colr_color(newscan[i], scan[i]); return(tmCvColors(ls, cs, newscan, len)); } - if (logi[0] == 0) { /* build tables if necessary */ + if (colrReg < 0) { /* build tables if necessary */ + colrReg = tmRegPkg(&colrPkg); + if (colrReg < 0) + returnErr(TM_E_CODERR1); for (i = 256; i--; ) logi[i] = TM_BRTSCALE*log((i+.5)/256.) - .5; for (i = 256; i < LOGISZ; i++) @@ -56,14 +76,16 @@ int len; (tmLuminance(i) - LMESLOWER) / (LMESUPPER - LMESLOWER); } + if ((cd = (COLRDATA *)tmPkgData(tmTop,colrReg)) == NULL) + returnErr(TM_E_NOMEM); for (i = len; i--; ) { copycolr(cmon, scan[i]); /* world luminance */ - li = ( tmTop->clfb[RED]*cmon[RED] + - tmTop->clfb[GRN]*cmon[GRN] + - tmTop->clfb[BLU]*cmon[BLU] ) >> 8; + li = ( cd->clfb[RED]*cmon[RED] + + cd->clfb[GRN]*cmon[GRN] + + cd->clfb[BLU]*cmon[BLU] ) >> 8; bi = BRT2SCALE*(cmon[EXP]-COLXS) + - logi[li] + tmTop->inpsfb; + logi[li] + cd->inpsfb; if (bi < MINBRT) { bi = MINBRT-1; /* bogus value */ li++; /* avoid li==0 */ @@ -71,29 +93,27 @@ int len; ls[i] = bi; if (cs == TM_NOCHROM) /* no color? */ continue; + if (tmTop->flags & TM_F_BW) + cmon[RED] = cmon[GRN] = cmon[BLU] = li; /* mesopic adj. */ if (tmTop->flags & TM_F_MESOPIC && bi < BMESUPPER) { register int pf, sli = normscot(cmon); if (bi < BMESLOWER) cmon[RED] = cmon[GRN] = cmon[BLU] = sli; else { - if (tmTop->flags & TM_F_BW) - cmon[RED] = cmon[GRN] = cmon[BLU] = li; pf = photofact[bi-BMESLOWER]; sli *= 256 - pf; cmon[RED] = ( sli + pf*cmon[RED] ) >> 8; cmon[GRN] = ( sli + pf*cmon[GRN] ) >> 8; cmon[BLU] = ( sli + pf*cmon[BLU] ) >> 8; } - } else if (tmTop->flags & TM_F_BW) { - cmon[RED] = cmon[GRN] = cmon[BLU] = li; } - bi = ( (int4)TM_GAMTSZ*tmTop->clfb[RED]*cmon[RED]/li ) >> 8; - cs[3*i ] = bi>=TM_GAMTSZ ? 255 : tmTop->gamb[bi]; - bi = ( (int4)TM_GAMTSZ*tmTop->clfb[GRN]*cmon[GRN]/li ) >> 8; - cs[3*i+1] = bi>=TM_GAMTSZ ? 255 : tmTop->gamb[bi]; - bi = ( (int4)TM_GAMTSZ*tmTop->clfb[BLU]*cmon[BLU]/li ) >> 8; - cs[3*i+2] = bi>=TM_GAMTSZ ? 255 : tmTop->gamb[bi]; + bi = ( (int4)GAMTSZ*cd->clfb[RED]*cmon[RED]/li ) >> 8; + cs[3*i ] = bi>=GAMTSZ ? 255 : cd->gamb[bi]; + bi = ( (int4)GAMTSZ*cd->clfb[GRN]*cmon[GRN]/li ) >> 8; + cs[3*i+1] = bi>=GAMTSZ ? 255 : cd->gamb[bi]; + bi = ( (int4)GAMTSZ*cd->clfb[BLU]*cmon[BLU]/li ) >> 8; + cs[3*i+2] = bi>=GAMTSZ ? 255 : cd->gamb[bi]; } returnOK; } @@ -126,17 +146,18 @@ register struct radhead *rh; rh->format = FMTCIE; else rh->format = FMTBAD; - return; + return(0); } if (isexpos(s)) { rh->expos *= exposval(s); - return; + return(0); } if (isprims(s)) { primsval(rh->mypri, s); rh->primp = rh->mypri; - return; + return(0); } + return(0); } @@ -163,8 +184,10 @@ FILE *fp; *xp = *yp = 0; /* error precaution */ if ((inpf = fp) == TM_GETFILE && (inpf = fopen(fname, "r")) == NULL) returnErr(TM_E_BADFILE); + *lpp = NULL; + if (cpp != TM_NOCHROMP) *cpp = NULL; info = rhdefault; /* get our header */ - getheader(inpf, headline, (char *)&info); + getheader(inpf, headline, (MEM_PTR)&info); if (info.format == FMTBAD | info.expos <= 0. || fgetresolu(xp, yp, inpf) < 0) { err = TM_E_BADFILE; goto done; @@ -205,9 +228,14 @@ done: /* clean up */ if (fp == NULL) fclose(inpf); if (scanin != NULL) - free((char *)scanin); - if (err != TM_E_OK) + free((MEM_PTR)scanin); + if (err != TM_E_OK) { + if (*lpp != NULL) + free((MEM_PTR)*lpp); + if (cpp != TM_NOCHROMP && *cpp != NULL) + free((MEM_PTR)*cpp); returnErr(err); + } returnOK; } @@ -275,8 +303,8 @@ char *fname; for (y = 0; y < *yp; y++) { if (freadcolrs(scan, *xp, infp) < 0) { pclose(infp); - free((char *)scan); - free((char *)*psp); + free((MEM_PTR)scan); + free((MEM_PTR)*psp); *psp = NULL; returnErr(TM_E_BADFILE); } @@ -291,7 +319,7 @@ char *fname; *rp++ = scan[x][BLU]; } } - free((char *)scan); + free((MEM_PTR)scan); pclose(infp); returnOK; } @@ -308,7 +336,6 @@ char *fname; FILE *fp; { char *funcName = fname==NULL ? "tmMapPicture" : fname; - FILE *inpf; BYTE *cp; TMbright *lp; int err; @@ -339,7 +366,7 @@ FILE *fp; if (flags & TM_F_BW) { *psp = (BYTE *)malloc(sizeof(BYTE) * *xp * *yp); if (*psp == NULL) { - free((char *)lp); + free((MEM_PTR)lp); tmDone(NULL); returnErr(TM_E_NOMEM); } @@ -357,12 +384,49 @@ FILE *fp; err = tmMapPixels(*psp, lp, cp, *xp * *yp); done: /* clean up */ - free((char *)lp); + free((MEM_PTR)lp); tmDone(NULL); if (err != TM_E_OK) { /* free memory on error */ - free((char *)*psp); + free((MEM_PTR)*psp); *psp = NULL; returnErr(err); } returnOK; +} + + +static void +colrNewSpace(tms) /* color space changed for tone mapping */ +register struct tmStruct *tms; +{ + register COLRDATA *cd; + double d; + + cd = (COLRDATA *)tms->pd[colrReg]; + cd->clfb[RED] = 256.*tms->clf[RED] + .5; + cd->clfb[GRN] = 256.*tms->clf[GRN] + .5; + cd->clfb[BLU] = 256.*tms->clf[BLU] + .5; + cd->clfb[EXP] = COLXS; + d = TM_BRTSCALE*log(tms->inpsf); + cd->inpsfb = d<0. ? d-.5 : d+.5; +} + + +static MEM_PTR +colrInit(tms) /* initialize private data for tone mapping */ +register struct tmStruct *tms; +{ + register COLRDATA *cd; + register int i; + /* allocate our data */ + cd = (COLRDATA *)malloc(sizeof(COLRDATA)); + if (cd == NULL) + return(NULL); + tms->pd[colrReg] = (MEM_PTR)cd; + /* compute gamma table */ + for (i = GAMTSZ; i--; ) + cd->gamb[i] = 256.*pow((i+.5)/GAMTSZ, 1./tms->mongam); + /* compute color and scale factors */ + colrNewSpace(tms); + return((MEM_PTR)cd); }