--- ray/src/common/tmapcolrs.c 1998/10/27 09:16:53 3.7 +++ ray/src/common/tmapcolrs.c 2005/09/24 20:15:54 3.21 @@ -1,33 +1,38 @@ -/* Copyright (c) 1998 Silicon Graphics, Inc. */ - #ifndef lint -static char SCCSid[] = "$SunId$ SGI"; +static const char RCSid[] = "$Id: tmapcolrs.c,v 3.21 2005/09/24 20:15:54 greg Exp $"; #endif - /* * Routines for tone mapping on Radiance RGBE and XYZE pictures. - * See tonemap.h for detailed function descriptions. + * + * Externals declared in tonemap.h */ +#include "copyright.h" + #include +#include #include +#include + #include "tmprivat.h" #include "resolu.h" +#ifdef PCOND +#include "rtprocess.h" +#endif - -extern char *tempbuffer(); - #define GAMTSZ 1024 typedef struct { BYTE gamb[GAMTSZ]; /* gamma lookup table */ - COLR clfb; /* encoded tm->clf */ + int clfb[3]; /* encoded tm->clf */ + int32 cmatb[3][3]; /* encoded color transform */ TMbright inpsfb; /* encoded tm->inpsf */ } COLRDATA; -static MEM_PTR colrInit(); -static void colrNewSpace(); -extern void free(); +static MEM_PTR colrInit(TMstruct *); +static void colrNewSpace(TMstruct *); +static gethfunc headline; + static struct tmPackage colrPkg = { /* our package functions */ colrInit, colrNewSpace, free }; @@ -35,34 +40,27 @@ static int colrReg = -1; /* our package registration #define LOGISZ 260 static TMbright logi[LOGISZ]; -static BYTE photofact[BMESUPPER-BMESLOWER]; int -tmCvColrs(ls, cs, scan, len) /* convert RGBE/XYZE colors */ -TMbright *ls; -BYTE *cs; -COLR *scan; -int len; +tmCvColrs( /* convert RGBE/XYZE colors */ +TMstruct *tms, +TMbright *ls, +BYTE *cs, +COLR *scan, +int len +) { - static char funcName[] = "tmCvColrs"; - COLR cmon; + static const char funcName[] = "tmCvColrs"; + int cmon[4]; register COLRDATA *cd; - register int i, bi, li; + register int i, j, li, bi; + int32 vl; - if (tmTop == NULL) + if (tms == NULL) returnErr(TM_E_TMINVAL); - if (ls == NULL | scan == NULL | len < 0) + if ((ls == NULL) | (scan == NULL) | (len < 0)) returnErr(TM_E_ILLEGAL); - if (tmNeedMatrix(tmTop)) { /* need floating point */ - register COLOR *newscan; - newscan = (COLOR *)tempbuffer(len*sizeof(COLOR)); - if (newscan == NULL) - returnErr(TM_E_NOMEM); - for (i = len; i--; ) - colr_color(newscan[i], scan[i]); - return(tmCvColors(ls, cs, newscan, len)); - } if (colrReg < 0) { /* build tables if necessary */ colrReg = tmRegPkg(&colrPkg); if (colrReg < 0) @@ -70,49 +68,66 @@ int len; for (i = 256; i--; ) logi[i] = TM_BRTSCALE*log((i+.5)/256.) - .5; for (i = 256; i < LOGISZ; i++) - logi[i] = logi[255]; - for (i = BMESLOWER; i < BMESUPPER; i++) - photofact[i-BMESLOWER] = 256. * - (tmLuminance(i) - LMESLOWER) / - (LMESUPPER - LMESLOWER); + logi[i] = 0; + tmMkMesofact(); } - if ((cd = (COLRDATA *)tmPkgData(tmTop,colrReg)) == NULL) + if ((cd = (COLRDATA *)tmPkgData(tms,colrReg)) == NULL) returnErr(TM_E_NOMEM); for (i = len; i--; ) { - copycolr(cmon, scan[i]); + if (tmNeedMatrix(tms)) { /* apply color xform */ + for (j = 3; j--; ) { + vl = cd->cmatb[j][RED]*(int32)scan[i][RED] + + cd->cmatb[j][GRN]*(int32)scan[i][GRN] + + cd->cmatb[j][BLU]*(int32)scan[i][BLU] ; + if (vl < 0) cmon[j] = vl/0x10000; + else cmon[j] = vl>>16; + } + cmon[EXP] = scan[i][EXP]; + } else + copycolr(cmon, scan[i]); /* world luminance */ - li = ( cd->clfb[RED]*cmon[RED] + + li = cd->clfb[RED]*cmon[RED] + cd->clfb[GRN]*cmon[GRN] + - cd->clfb[BLU]*cmon[BLU] ) >> 8; - bi = BRT2SCALE*(cmon[EXP]-COLXS) + + cd->clfb[BLU]*cmon[BLU] ; + if (li >= 0xff00) li = 255; + else li >>= 8; + if (li <= 0) { + bi = TM_NOBRT; /* bogus value */ + li = 1; /* avoid li==0 */ + } else { + bi = BRT2SCALE(cmon[EXP]-COLXS) + logi[li] + cd->inpsfb; - if (bi < MINBRT) { - bi = MINBRT-1; /* bogus value */ - li++; /* avoid li==0 */ } 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) + if (tms->flags & TM_F_MESOPIC && bi < BMESUPPER) { + int pf, sli = normscot(cmon); + if (bi < BMESLOWER) { cmon[RED] = cmon[GRN] = cmon[BLU] = sli; - else { - pf = photofact[bi-BMESLOWER]; + } else { + if (tms->flags & TM_F_BW) + cmon[RED] = cmon[GRN] = cmon[BLU] = li; + pf = tmMesofact[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; + for (j = 3; j--; ) { + cmon[j] = sli + pf*cmon[j]; + if (cmon[j] <= 0) cmon[j] = 0; + else cmon[j] >>= 8; + } } + } else if (tms->flags & TM_F_BW) { + cmon[RED] = cmon[GRN] = cmon[BLU] = li; + } else { + for (j = 3; j--; ) + if (cmon[j] < 0) cmon[j] = 0; } - bi = ( (int4)GAMTSZ*cd->clfb[RED]*cmon[RED]/li ) >> 8; + bi = ( (int32)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; + bi = ( (int32)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; + bi = ( (int32)GAMTSZ*cd->clfb[BLU]*cmon[BLU]/li ) >> 8; cs[3*i+2] = bi>=GAMTSZ ? 255 : cd->gamb[bi]; } returnOK; @@ -133,11 +148,13 @@ static struct radhead { static int -headline(s, rh) /* grok a header line */ -register char *s; -register struct radhead *rh; +headline( /* grok a header line */ + register char *s, + void *vrh +) { char fmt[32]; + register struct radhead *rh = vrh; if (formatval(fmt, s)) { if (!strcmp(fmt, COLRFMT)) @@ -162,12 +179,15 @@ register struct radhead *rh; int -tmLoadPicture(lpp, cpp, xp, yp, fname, fp) /* convert Radiance picture */ -TMbright **lpp; -BYTE **cpp; -int *xp, *yp; -char *fname; -FILE *fp; +tmLoadPicture( /* convert Radiance picture */ +TMstruct *tms, +TMbright **lpp, +BYTE **cpp, +int *xp, +int *yp, +char *fname, +FILE *fp +) { char *funcName = fname==NULL ? "tmLoadPicture" : fname; FILE *inpf; @@ -176,19 +196,19 @@ FILE *fp; COLR *scanin = NULL; int i; /* check arguments */ - if (tmTop == NULL) + if (tms == NULL) returnErr(TM_E_TMINVAL); - if (lpp == NULL | xp == NULL | yp == NULL | - (fname == NULL & fp == TM_GETFILE)) + if ((lpp == NULL) | (xp == NULL) | (yp == NULL) | + ((fname == NULL) & (fp == TM_GETFILE))) returnErr(TM_E_ILLEGAL); *xp = *yp = 0; /* error precaution */ - if ((inpf = fp) == TM_GETFILE && (inpf = fopen(fname, "r")) == NULL) + if ((inpf = fp) == TM_GETFILE && (inpf = fopen(fname, "rb")) == NULL) returnErr(TM_E_BADFILE); *lpp = NULL; if (cpp != TM_NOCHROMP) *cpp = NULL; info = rhdefault; /* get our header */ - getheader(inpf, headline, (MEM_PTR)&info); - if (info.format == FMTBAD | info.expos <= 0. || + getheader(inpf, headline, &info); + if ((info.format == FMTBAD) | (info.expos <= 0.) || fgetresolu(xp, yp, inpf) < 0) { err = TM_E_BADFILE; goto done; } @@ -199,7 +219,7 @@ FILE *fp; else if (info.format == FMTCIE) info.primp = TM_XYZPRIM; /* prepare library */ - if ((err = tmSetSpace(info.primp, 1./info.expos)) != TM_E_OK) + if ((err = tmSetSpace(tms, info.primp, 1./info.expos, NULL)) != TM_E_OK) goto done; err = TM_E_NOMEM; /* allocate arrays */ *lpp = (TMbright *)malloc(sizeof(TMbright) * *xp * *yp); @@ -218,7 +238,7 @@ FILE *fp; if (freadcolrs(scanin, *xp, inpf) < 0) { err = TM_E_BADFILE; break; } - err = tmCvColrs(*lpp + (i * *xp), + err = tmCvColrs(tms, *lpp + (i * *xp), cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp + (i * 3 * *xp), scanin, *xp); if (err != TM_E_OK) @@ -240,7 +260,8 @@ done: /* clean up */ } -int /* run pcond to map picture */ +#ifdef PCOND +static int /* run pcond to map picture */ dopcond(psp, xp, yp, flags, monpri, gamval, Lddyn, Ldmax, fname) BYTE **psp; int *xp, *yp; @@ -250,7 +271,8 @@ double gamval, Lddyn, Ldmax; char *fname; { char *funcName = fname; - char cmdbuf[512]; + TMstruct *tms = NULL; + char cmdbuf[1024]; FILE *infp; register COLR *scan; register BYTE *rp; @@ -260,26 +282,26 @@ char *fname; if (setcolrcor(pow, 1./gamval) < 0) returnErr(TM_E_NOMEM); /* create command */ - strcpy(cmdbuf, "pcond "); + strcpy(cmdbuf, PCOND); if (flags & TM_F_HCONTR) - strcat(cmdbuf, "-s "); + strcat(cmdbuf, " -s"); if (flags & TM_F_MESOPIC) - strcat(cmdbuf, "-c "); + strcat(cmdbuf, " -c"); if (flags & TM_F_LINEAR) - strcat(cmdbuf, "-l "); + strcat(cmdbuf, " -l"); if (flags & TM_F_ACUITY) - strcat(cmdbuf, "-a "); + strcat(cmdbuf, " -a"); if (flags & TM_F_VEIL) - strcat(cmdbuf, "-v "); + strcat(cmdbuf, " -v"); if (flags & TM_F_CWEIGHT) - strcat(cmdbuf, "-w "); - sprintf(cmdbuf+strlen(cmdbuf), - "-p %f %f %f %f %f %f %f %f -d %f -u %f %s", - monpri[RED][CIEX], monpri[RED][CIEY], - monpri[GRN][CIEX], monpri[GRN][CIEY], - monpri[BLU][CIEX], monpri[BLU][CIEY], - monpri[WHT][CIEX], monpri[WHT][CIEY], - Lddyn, Ldmax, fname); + strcat(cmdbuf, " -w"); + if (monpri != stdprims) + sprintf(cmdbuf+strlen(cmdbuf), " -p %f %f %f %f %f %f %f %f", + monpri[RED][CIEX], monpri[RED][CIEY], + monpri[GRN][CIEX], monpri[GRN][CIEY], + monpri[BLU][CIEX], monpri[BLU][CIEY], + monpri[WHT][CIEX], monpri[WHT][CIEY]); + sprintf(cmdbuf+strlen(cmdbuf), " -d %f -u %f %s", Lddyn, Ldmax, fname); /* start pcond */ if ((infp = popen(cmdbuf, "r")) == NULL) returnErr(TM_E_BADFILE); @@ -295,7 +317,7 @@ char *fname; rp = (BYTE *)malloc(sizeof(BYTE) * *xp * *yp); else rp = (BYTE *)malloc(3*sizeof(BYTE) * *xp * *yp); - if ((*psp = rp) == NULL | scan == NULL) { + if (((*psp = rp) == NULL) | (scan == NULL)) { pclose(infp); returnErr(TM_E_NOMEM); } @@ -323,6 +345,7 @@ char *fname; pclose(infp); returnOK; } +#endif int /* map a Radiance picture */ @@ -336,30 +359,33 @@ char *fname; FILE *fp; { char *funcName = fname==NULL ? "tmMapPicture" : fname; + TMstruct *tms; BYTE *cp; TMbright *lp; int err; /* check arguments */ - if (psp == NULL | xp == NULL | yp == NULL | monpri == NULL | - (fname == NULL & fp == TM_GETFILE)) + if ((psp == NULL) | (xp == NULL) | (yp == NULL) | (monpri == NULL) | + ((fname == NULL) & (fp == TM_GETFILE))) returnErr(TM_E_ILLEGAL); /* set defaults */ if (gamval < MINGAM) gamval = DEFGAM; if (Lddyn < MINLDDYN) Lddyn = DEFLDDYN; if (Ldmax < MINLDMAX) Ldmax = DEFLDMAX; if (flags & TM_F_BW) monpri = stdprims; +#ifdef PCOND /* check for pcond run */ if (fp == TM_GETFILE && flags & TM_F_UNIMPL) return( dopcond(psp, xp, yp, flags, monpri, gamval, Lddyn, Ldmax, fname) ); +#endif /* initialize tone mapping */ - if (tmInit(flags, monpri, gamval) == NULL) + if ((tms = tmInit(flags, monpri, gamval)) == NULL) returnErr(TM_E_NOMEM); /* load & convert picture */ - err = tmLoadPicture(&lp, (flags&TM_F_BW) ? TM_NOCHROMP : &cp, + err = tmLoadPicture(tms, &lp, (flags&TM_F_BW) ? TM_NOCHROMP : &cp, xp, yp, fname, fp); if (err != TM_E_OK) { - tmDone(NULL); + tmDone(tms); return(err); } /* allocate space for result */ @@ -367,25 +393,25 @@ FILE *fp; *psp = (BYTE *)malloc(sizeof(BYTE) * *xp * *yp); if (*psp == NULL) { free((MEM_PTR)lp); - tmDone(NULL); + tmDone(tms); returnErr(TM_E_NOMEM); } cp = TM_NOCHROM; } else *psp = cp; /* compute color mapping */ - err = tmAddHisto(lp, *xp * *yp, 1); + err = tmAddHisto(tms, lp, *xp * *yp, 1); if (err != TM_E_OK) goto done; - err = tmComputeMapping(gamval, Lddyn, Ldmax); + err = tmComputeMapping(tms, gamval, Lddyn, Ldmax); if (err != TM_E_OK) goto done; /* map colors */ - err = tmMapPixels(*psp, lp, cp, *xp * *yp); + err = tmMapPixels(tms, *psp, lp, cp, *xp * *yp); done: /* clean up */ free((MEM_PTR)lp); - tmDone(NULL); + tmDone(tms); if (err != TM_E_OK) { /* free memory on error */ free((MEM_PTR)*psp); *psp = NULL; @@ -397,24 +423,28 @@ done: /* clean up */ static void colrNewSpace(tms) /* color space changed for tone mapping */ -register struct tmStruct *tms; +register TMstruct *tms; { register COLRDATA *cd; double d; + int i, j; 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; + for (i = 3; i--; ) + cd->clfb[i] = 0x100*tms->clf[i] + .5; d = TM_BRTSCALE*log(tms->inpsf); cd->inpsfb = d<0. ? d-.5 : d+.5; + for (i = 3; i--; ) + for (j = 3; j--; ) { + d = tms->cmat[i][j] / tms->inpsf; + cd->cmatb[i][j] = 0x10000*d + (d<0. ? -.5 : .5); + } } static MEM_PTR colrInit(tms) /* initialize private data for tone mapping */ -register struct tmStruct *tms; +register TMstruct *tms; { register COLRDATA *cd; register int i;