--- ray/src/common/tmapcolrs.c 2003/02/22 02:07:22 3.10
+++ ray/src/common/tmapcolrs.c 2009/02/09 20:48:08 3.26
@@ -1,5 +1,5 @@
#ifndef lint
-static const char RCSid[] = "$Id: tmapcolrs.c,v 3.10 2003/02/22 02:07:22 greg Exp $";
+static const char RCSid[] = "$Id: tmapcolrs.c,v 3.26 2009/02/09 20:48:08 greg Exp $";
#endif
/*
* Routines for tone mapping on Radiance RGBE and XYZE pictures.
@@ -7,89 +7,33 @@ static const char RCSid[] = "$Id: tmapcolrs.c,v 3.10 2
* Externals declared in tonemap.h
*/
-/* ====================================================================
- * The Radiance Software License, Version 1.0
- *
- * Copyright (c) 1990 - 2002 The Regents of the University of California,
- * through Lawrence Berkeley National Laboratory. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes Radiance software
- * (http://radsite.lbl.gov/)
- * developed by the Lawrence Berkeley National Laboratory
- * (http://www.lbl.gov/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
- * and "The Regents of the University of California" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact radiance@radsite.lbl.gov.
- *
- * 5. Products derived from this software may not be called "Radiance",
- * nor may "Radiance" appear in their name, without prior written
- * permission of Lawrence Berkeley National Laboratory.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of Lawrence Berkeley National Laboratory. For more
- * information on Lawrence Berkeley National Laboratory, please see
- * .
- */
+#include "copyright.h"
#include
+#include
#include
#include
#include
+
#include "tmprivat.h"
#include "resolu.h"
-
-#ifndef TM_PIC_CTRANS
-#define TM_PIC_CTRANS 1 /* transform colors? (expensive) */
+#ifdef PCOND
+#include "rtprocess.h"
#endif
#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;
-#ifdef NOPROTO
-static MEM_PTR colrInit();
-static void colrNewSpace();
-#else
-static MEM_PTR colrInit(struct tmStruct *);
-static void colrNewSpace(struct tmStruct *);
-#endif
+static MEM_PTR colrInit(TMstruct *);
+static void colrNewSpace(TMstruct *);
+static gethfunc headline;
+
static struct tmPackage colrPkg = { /* our package functions */
colrInit, colrNewSpace, free
};
@@ -100,34 +44,24 @@ static TMbright logi[LOGISZ];
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 TM_PIC_CTRANS
- if (tmNeedMatrix(tmTop)) { /* need floating point */
-#else
- if (tmTop->inppri == TM_XYZPRIM) { /* no way around this */
-#endif
- 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)
@@ -138,45 +72,63 @@ int len;
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) +
- logi[li] + cd->inpsfb;
- if (li <= 0) {
- bi = TM_NOBRT; /* bogus value */
- li = 1; /* avoid li==0 */
+ cd->clfb[BLU]*cmon[BLU] ;
+ if (li >= 0xfff00) li = 255;
+ else li >>= 12;
+ bi = BRT2SCALE(cmon[EXP]-COLXS) + cd->inpsfb;
+ if (li > 0)
+ bi += logi[li];
+ else {
+ bi += logi[0];
+ li = 1; /* avoid /0 */
}
ls[i] = bi;
if (cs == TM_NOCHROM) /* no color? */
continue;
/* 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 {
- if (tmTop->flags & TM_F_BW)
+ } 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 (tmTop->flags & TM_F_BW) {
+ } 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 ) >> 12;
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 ) >> 12;
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 ) >> 12;
cs[3*i+2] = bi>=GAMTSZ ? 255 : cd->gamb[bi];
}
returnOK;
@@ -197,11 +149,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))
@@ -226,12 +180,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;
@@ -240,19 +197,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, (char *)&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;
}
@@ -263,7 +220,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);
@@ -282,7 +239,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)
@@ -305,7 +262,7 @@ done: /* clean up */
#ifdef PCOND
-int /* run pcond to map picture */
+static int /* run pcond to map picture */
dopcond(psp, xp, yp, flags, monpri, gamval, Lddyn, Ldmax, fname)
BYTE **psp;
int *xp, *yp;
@@ -315,6 +272,7 @@ double gamval, Lddyn, Ldmax;
char *fname;
{
char *funcName = fname;
+ TMstruct *tms = NULL;
char cmdbuf[1024];
FILE *infp;
register COLR *scan;
@@ -360,7 +318,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);
}
@@ -402,12 +360,13 @@ 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;
@@ -421,13 +380,13 @@ FILE *fp;
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 */
@@ -435,25 +394,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;
@@ -465,24 +424,27 @@ 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;
- d = TM_BRTSCALE*log(tms->inpsf);
- cd->inpsfb = d<0. ? d-.5 : d+.5;
+ for (i = 3; i--; )
+ cd->clfb[i] = 0x1000*tms->clf[i] + .5;
+ cd->inpsfb = tmCvLuminance(tms->inpsf);
+ 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;