Back to index

radiance  4R0+20100331
Defines | Functions | Variables
tonemap.c File Reference
#include "copyright.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "tmprivat.h"
#include "tmerrmsg.h"

Go to the source code of this file.

Defines

#define exp10(x)   exp(M_LN10*(x))
#define tmCvLumLUfp(pf)   tmFloat2BrtLUT[*(int32 *)(pf) >> 15]

Functions

TMstructtmInit (int flags, RGBPRIMP monpri, double gamval)
int tmSetSpace (TMstruct *tms, RGBPRIMP pri, double sf, MEM_PTR dat)
void tmClearHisto (TMstruct *tms)
TMbright tmCvLuminance (double lum)
int tmCvLums (TMbright *ls, float *scan, int len)
int tmCvGrays (TMstruct *tms, TMbright *ls, float *scan, int len)
int tmCvColors (TMstruct *tms, TMbright *ls, BYTE *cs, COLOR *scan, int len)
int tmAddHisto (TMstruct *tms, TMbright *ls, int len, int wt)
static double htcontrs (double La)
int tmFixedMapping (TMstruct *tms, double expmult, double gamval)
int tmComputeMapping (TMstruct *tms, double gamval, double Lddyn, double Ldmax)
int tmMapPixels (TMstruct *tms, BYTE *ps, TMbright *ls, BYTE *cs, int len)
TMstructtmDup (TMstruct *tms)
void tmDone (TMstruct *tms)
void tmMkMesofact ()
int tmNewMap (TMstruct *tms)
int tmErrorReturn (const char *func, TMstruct *tms, int err)

Variables

static const char RCSid [] = "$Id: tonemap.c,v 3.34 2009/02/09 20:48:08 greg Exp $"
struct tmPackagetmPkg [TM_MAXPKG]
int tmNumPkgs = 0
static TMbrighttmFloat2BrtLUT = NULL
BYTE tmMesofact [BMESUPPER-BMESLOWER]

Define Documentation

#define exp10 (   x)    exp(M_LN10*(x))

Definition at line 20 of file tonemap.c.

#define tmCvLumLUfp (   pf)    tmFloat2BrtLUT[*(int32 *)(pf) >> 15]

Definition at line 29 of file tonemap.c.


Function Documentation

static double htcontrs ( double  La) [static]

Definition at line 401 of file tonemap.c.

{
       double l10La, l10dL;
                            /* formula taken from Ferwerda et al. [SG96] */
       if (La < 1.148e-4)
              return(1.38e-3);
       l10La = log10(La);
       if (l10La < -1.44)          /* rod response regime */
              l10dL = pow(.405*l10La + 1.6, 2.18) - 2.86;
       else if (l10La < -.0184)
              l10dL = l10La - .395;
       else if (l10La < 1.9)              /* cone response regime */
              l10dL = pow(.249*l10La + .65, 2.7) - .72;
       else
              l10dL = l10La - 1.255;

       return(exp10(l10dL));
}

Here is the caller graph for this function:

int tmAddHisto ( TMstruct tms,
TMbright ls,
int  len,
int  wt 
)

Definition at line 341 of file tonemap.c.

{
       static const char funcName[] = "tmAddHisto";
       int    oldorig=0, oldlen, horig, hlen;
       int    i, j;

       if (tms == NULL)
              returnErr(TM_E_TMINVAL);
       if (len < 0)
              returnErr(TM_E_ILLEGAL);
       if (len == 0)
              returnOK;
                                          /* first, grow limits */
       if (tms->histo == NULL) {
              for (i = len; i-- && ls[i] < MINBRT; )
                     ;
              if (i < 0)
                     returnOK;
              tms->hbrmin = tms->hbrmax = ls[i];
              oldlen = 0;
       } else {
              oldorig = HISTI(tms->hbrmin);
              oldlen = HISTI(tms->hbrmax) + 1 - oldorig;
       }
       for (i = len; i--; ) {
              if ((j = ls[i]) < MINBRT)
                     continue;
              if (j < tms->hbrmin)
                     tms->hbrmin = j;
              else if (j > tms->hbrmax)
                     tms->hbrmax = j;
       }
       horig = HISTI(tms->hbrmin);
       hlen = HISTI(tms->hbrmax) + 1 - horig;
       if (hlen > oldlen) {               /* (re)allocate histogram */
              int    *newhist = (int *)calloc(hlen, sizeof(int));
              if (newhist == NULL)
                     returnErr(TM_E_NOMEM);
              if (oldlen) {               /* copy and free old */
                     for (i = oldlen, j = i+oldorig-horig; i; )
                            newhist[--j] = tms->histo[--i];
                     free((MEM_PTR)tms->histo);
              }
              tms->histo = newhist;
       }
       if (wt == 0)
              returnOK;
       for (i = len; i--; )               /* add in new counts */
              if (ls[i] >= MINBRT)
                     tms->histo[ HISTI(ls[i]) - horig ] += wt;
       returnOK;
}

Here is the caller graph for this function:

void tmClearHisto ( TMstruct tms)

Definition at line 158 of file tonemap.c.

{
       if (tms == NULL || tms->histo == NULL)
              return;
       free((MEM_PTR)tms->histo);
       tms->histo = NULL;
}

Here is the caller graph for this function:

int tmComputeMapping ( TMstruct tms,
double  gamval,
double  Lddyn,
double  Ldmax 
)

Definition at line 452 of file tonemap.c.

{
       static const char funcName[] = "tmComputeMapping";
       int    *histo;
       float  *cumf;
       int    brt0, histlen, threshold, ceiling, trimmings;
       double logLddyn, Ldmin, Ldavg, Lwavg, Tr, Lw, Ld;
       int32  histot;
       double sum;
       double d;
       int    i, j;

       if (tms == NULL || tms->histo == NULL)
              returnErr(TM_E_TMINVAL);
                                   /* check arguments */
       if (Lddyn < MINLDDYN) Lddyn = DEFLDDYN;
       if (Ldmax < MINLDMAX) Ldmax = DEFLDMAX;
       if (gamval < MINGAM) gamval = tms->mongam;
                                   /* compute handy values */
       Ldmin = Ldmax/Lddyn;
       logLddyn = log(Lddyn);
       Ldavg = sqrt(Ldmax*Ldmin);
       i = HISTI(tms->hbrmin);
       brt0 = HISTV(i);
       histlen = HISTI(tms->hbrmax) + 1 - i;
                                   /* histogram total and mean */
       histot = 0; sum = 0;
       j = brt0 + histlen*HISTEP;
       for (i = histlen; i--; ) {
              histot += tms->histo[i];
              sum += (double)(j -= HISTEP) * tms->histo[i];
       }
       threshold = histot*0.005 + .5;
       if (!histot)
              returnErr(TM_E_TMFAIL);
       Lwavg = tmLuminance( (double)sum / histot );
                                   /* use linear tone mapping? */
       if (tms->flags & TM_F_LINEAR || threshold < 4 ||
                     tms->hbrmax - tms->hbrmin < TM_BRTSCALE*logLddyn)
              goto linearmap;
                                   /* clamp histogram */
       histo = (int *)malloc(histlen*sizeof(int));
       cumf = (float *)malloc((histlen+2)*sizeof(float));
       if ((histo == NULL) | (cumf == NULL))
              returnErr(TM_E_NOMEM);
       cumf[histlen+1] = 1.;              /* guard for assignment code */
       for (i = histlen; i--; )    /* make malleable copy */
              histo[i] = tms->histo[i];
       do {                        /* iterate to solution */
              sum = 0;             /* cumulative probability */
              for (i = 0; i < histlen; i++) {
                     cumf[i] = (double)sum/histot;
                     sum += histo[i];
              }
              cumf[histlen] = 1.;
              Tr = histot * (double)(tms->hbrmax - tms->hbrmin) /
                     ((double)histlen*TM_BRTSCALE) / logLddyn;
              ceiling = Tr + 1.;
              trimmings = 0;              /* clip to envelope */
              for (i = histlen; i--; ) {
                     if (tms->flags & TM_F_HCONTR) {
                            Lw = tmLuminance(brt0 + i*HISTEP);
                            Ld = Ldmin * exp( logLddyn *
                                   .5*(cumf[i]+cumf[i+1]) );
                            ceiling = Tr * (htcontrs(Ld) * Lw) /
                                   (htcontrs(Lw) * Ld) + 1.;
                     }
                     if (histo[i] > ceiling) {
                            trimmings += histo[i] - ceiling;
                            histo[i] = ceiling;
                     }
              }
                                   /* check if we're out of data */
              if ((histot -= trimmings) <= threshold) {
                     free((MEM_PTR)histo);
                     free((MEM_PTR)cumf);
                     goto linearmap;
              }
       } while (trimmings > threshold);
                                   /* allocate space for mapping */
       if (!tmNewMap(tms))
              returnErr(TM_E_NOMEM);
                                   /* assign tone-mapping */
       for (i = tms->mbrmax-tms->mbrmin+1; i--; ) {
              j = d = (double)i/(tms->mbrmax-tms->mbrmin)*histlen;
              d -= (double)j;
              Ld = Ldmin*exp(logLddyn*((1.-d)*cumf[j]+d*cumf[j+1]));
              d = (Ld - Ldmin)/(Ldmax - Ldmin);
              tms->lumap[i] = 256.*pow(d, 1./gamval);
       }
       free((MEM_PTR)histo);              /* clean up and return */
       free((MEM_PTR)cumf);
       returnOK;
linearmap:                         /* linear tone-mapping */
       if (tms->flags & TM_F_HCONTR)
              d = htcontrs(Ldavg) / htcontrs(Lwavg);
       else
              d = Ldavg / Lwavg;
       return(tmFixedMapping(tms, tms->inpsf*d/Ldmax, gamval));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tmCvColors ( TMstruct tms,
TMbright ls,
BYTE cs,
COLOR scan,
int  len 
)

Definition at line 256 of file tonemap.c.

{
       static const char funcName[] = "tmCvColors";
       static BYTE   gamtab[1024];
       static double curgam = .0;
       COLOR  cmon;
       float  lum, slum, d;
       int    i;

       if (tms == NULL)
              returnErr(TM_E_TMINVAL);
       if ((ls == NULL) | (scan == NULL) | (len < 0))
              returnErr(TM_E_ILLEGAL);
       if (tmFloat2BrtLUT == NULL)               /* initialize */
              tmCvLums(NULL, NULL, 0);
       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]);
              } else {
                     cmon[RED] = tms->inpsf*scan[i][RED];
                     cmon[GRN] = tms->inpsf*scan[i][GRN];
                     cmon[BLU] = tms->inpsf*scan[i][BLU];
              }
#ifdef isfinite
              if (!isfinite(cmon[RED]) || cmon[RED] < .0f) cmon[RED] = .0f;
              if (!isfinite(cmon[GRN]) || cmon[GRN] < .0f) cmon[GRN] = .0f;
              if (!isfinite(cmon[BLU]) || cmon[BLU] < .0f) cmon[BLU] = .0f;
#else
              if (cmon[RED] < .0f) cmon[RED] = .0f;
              if (cmon[GRN] < .0f) cmon[GRN] = .0f;
              if (cmon[BLU] < .0f) cmon[BLU] = .0f;
#endif
                                                 /* world luminance */
              lum =  tms->clf[RED]*cmon[RED] +
                     tms->clf[GRN]*cmon[GRN] +
                     tms->clf[BLU]*cmon[BLU] ;
              if (lum <= TM_NOLUM) {                    /* convert brightness */
                     lum = cmon[RED] = cmon[GRN] = cmon[BLU] = TM_NOLUM;
                     ls[i] = TM_NOBRT;
              } else
                     ls[i] = tmCvLumLUfp(&lum);
              if (cs == TM_NOCHROM)                     /* no color? */
                     continue;
              if (tms->flags & TM_F_MESOPIC && lum < LMESUPPER) {
                     slum = scotlum(cmon);              /* mesopic adj. */
                     if (lum < LMESLOWER) {
                            cmon[RED] = cmon[GRN] = cmon[BLU] = slum;
                     } else {
                            d = (lum - LMESLOWER)/(LMESUPPER - LMESLOWER);
                            if (tms->flags & TM_F_BW)
                                   cmon[RED] = cmon[GRN] =
                                                 cmon[BLU] = d*lum;
                            else
                                   scalecolor(cmon, d);
                            d = (1.f-d)*slum;
                            cmon[RED] += d;
                            cmon[GRN] += d;
                            cmon[BLU] += d;
                     }
              } else if (tms->flags & TM_F_BW) {
                     cmon[RED] = cmon[GRN] = cmon[BLU] = lum;
              }
              d = tms->clf[RED]*cmon[RED]/lum;
              cs[3*i  ] = d>=.999f ? 255 : gamtab[(int)(1024.f*d)];
              d = tms->clf[GRN]*cmon[GRN]/lum;
              cs[3*i+1] = d>=.999f ? 255 : gamtab[(int)(1024.f*d)];
              d = tms->clf[BLU]*cmon[BLU]/lum;
              cs[3*i+2] = d>=.999f ? 255 : gamtab[(int)(1024.f*d)];
       }
       returnOK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tmCvGrays ( TMstruct tms,
TMbright ls,
float *  scan,
int  len 
)

Definition at line 228 of file tonemap.c.

{
       static const char funcName[] = "tmCvGrays";
       int    i;

       if (tms == NULL)
              returnErr(TM_E_TMINVAL);
       if ((ls == NULL) | (scan == NULL) | (len < 0))
              returnErr(TM_E_ILLEGAL);
       if (tmFloat2BrtLUT == NULL)               /* initialize */
              tmCvLums(NULL, NULL, 0);
       for (i = len; i--; ) {
              float  lum = tms->inpsf * scan[i];
              if (lum <= TM_NOLUM)
                     ls[i] = TM_NOBRT;
              else
                     ls[i] = tmCvLumLUfp(&lum);
       }
       returnOK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

TMbright tmCvLuminance ( double  lum)

Definition at line 170 of file tonemap.c.

{
       double d;

#ifdef isfinite
       if (!isfinite(lum) || lum <= TM_NOLUM)
#else
       if (lum <= TM_NOLUM)
#endif
              return(TM_NOBRT);
       d = TM_BRTSCALE*log(lum);
       if (d > 0.)
              return((TMbright)(d+.5));
       return((TMbright)(d-.5));
}

Here is the caller graph for this function:

int tmCvLums ( TMbright ls,
float *  scan,
int  len 
)

Definition at line 190 of file tonemap.c.

{
       if (tmFloat2BrtLUT == NULL) {      /* initialize lookup table */
              int32  i;
              tmFloat2BrtLUT = (TMbright *)malloc(sizeof(TMbright)*0x10000);
              if (tmFloat2BrtLUT == NULL)
                     return(TM_E_NOMEM);
              for (i = 0; i < 0x10000; i++) {
                     int32  l = (i<<1 | 1) << 14;
#ifndef isfinite
                     if ((l & 0x7f800000) == 0x7f800000)
                            tmFloat2BrtLUT[i] = TM_NOBRT;
                     else
#endif
                     tmFloat2BrtLUT[i] = tmCvLuminance(*(float *)&l);
              }
       }
       if (len <= 0)
              return(TM_E_OK);
       if ((ls == NULL) | (scan == NULL))
              return(TM_E_ILLEGAL);
       while (len--) {
              if (*scan <= TM_NOLUM) {
                     *ls++ = TM_NOBRT;
                     ++scan;
                     continue;
              }
              *ls++ = tmCvLumLUfp(scan++);
       }
       return(TM_E_OK);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void tmDone ( TMstruct tms)

Definition at line 637 of file tonemap.c.

{
       int    i;
                                   /* NULL arg. is equiv. to tms */
       if (tms == NULL)
              return;
                                   /* free tables */
       if (tms->histo != NULL)
              free((MEM_PTR)tms->histo);
       if (tms->lumap != NULL)
              free((MEM_PTR)tms->lumap);
                                   /* free private data */
       for (i = tmNumPkgs; i--; )
              if (tms->pd[i] != NULL)
                     (*tmPkg[i]->Free)(tms->pd[i]);
       free((MEM_PTR)tms);         /* free basic structure */
}

Here is the caller graph for this function:

TMstruct* tmDup ( TMstruct tms)

Definition at line 599 of file tonemap.c.

{
       int    len;
       int    i;
       TMstruct      *tmnew;

       if (tms == NULL)            /* anything to duplicate? */
              return(NULL);
       tmnew = (TMstruct *)malloc(sizeof(TMstruct));
       if (tmnew == NULL)
              return(NULL);
       *tmnew = *tms;              /* copy everything */
       if (tmnew->histo != NULL) { /* duplicate histogram */
              len = HISTI(tmnew->hbrmax) + 1 - HISTI(tmnew->hbrmin);
              tmnew->histo = (int *)malloc(len*sizeof(int));
              if (tmnew->histo != NULL)
                     for (i = len; i--; )
                            tmnew->histo[i] = tms->histo[i];
       }
       if (tmnew->lumap != NULL) { /* duplicate luminance mapping */
              len = tmnew->mbrmax-tmnew->mbrmin+1;
              tmnew->lumap = (unsigned short *)malloc(
                                          len*sizeof(unsigned short) );
              if (tmnew->lumap != NULL)
                     for (i = len; i--; )
                            tmnew->lumap[i] = tms->lumap[i];
       }
                                   /* clear package data */
       for (i = tmNumPkgs; i--; )
              tmnew->pd[i] = NULL;
                                   /* return copy */
       return(tmnew);
}

Here is the caller graph for this function:

int tmErrorReturn ( const char *  func,
TMstruct tms,
int  err 
)

Definition at line 697 of file tonemap.c.

{
       if (tms != NULL) {
              tms->lastFunc = func;
              tms->lastError = err;
              if (tms->flags & TM_F_NOSTDERR)
                     return(err);
       }
       fputs(func, stderr);
       fputs(": ", stderr);
       fputs(tmErrorMessage[err], stderr);
       fputs("!\n", stderr);
       return(err);
}
int tmFixedMapping ( TMstruct tms,
double  expmult,
double  gamval 
)

Definition at line 424 of file tonemap.c.

{
       static const char funcName[] = "tmFixedMapping";
       double        d;
       int    i;
       
       if (!tmNewMap(tms))
              returnErr(TM_E_NOMEM);
       if (expmult <= .0)
              expmult = 1.;
       if (gamval < MINGAM)
              gamval = tms->mongam;
       d = log(expmult/tms->inpsf);
       for (i = tms->mbrmax-tms->mbrmin+1; i--; ) {
              double val = 256. * exp(
                     ( d + (tms->mbrmin+i)*(1./TM_BRTSCALE) )
                     / gamval);
              tms->lumap[i] = val >= (double)0xffff ? 0xffff : (int)val;
       }
       returnOK;
}

Here is the call graph for this function:

TMstruct* tmInit ( int  flags,
RGBPRIMP  monpri,
double  gamval 
)

Definition at line 33 of file tonemap.c.

{
       COLORMAT      cmat;
       TMstruct      *tmnew;
       int    i;
                                          /* allocate structure */
       tmnew = (TMstruct *)malloc(sizeof(TMstruct));
       if (tmnew == NULL)
              return(NULL);

       tmnew->flags = flags & ~TM_F_UNIMPL;
       if (tmnew->flags & TM_F_BW)
              tmnew->flags &= ~TM_F_MESOPIC;
                                          /* set monitor transform */
       if (monpri == NULL || monpri == stdprims || tmnew->flags & TM_F_BW) {
              tmnew->monpri = stdprims;
              tmnew->clf[RED] = rgb2xyzmat[1][0];
              tmnew->clf[GRN] = rgb2xyzmat[1][1];
              tmnew->clf[BLU] = rgb2xyzmat[1][2];
       } else {
              comprgb2xyzmat(cmat, tmnew->monpri=monpri);
              tmnew->clf[RED] = cmat[1][0];
              tmnew->clf[GRN] = cmat[1][1];
              tmnew->clf[BLU] = cmat[1][2];
       }
                                          /* set gamma value */
       if (gamval < MINGAM)
              tmnew->mongam = DEFGAM;
       else
              tmnew->mongam = gamval;
                                          /* set color divisors */
       for (i = 0; i < 3; i++)
              tmnew->cdiv[i] = 256.*pow(tmnew->clf[i], 1./tmnew->mongam);

                                          /* set input transform */
       tmnew->inppri = tmnew->monpri;
       tmnew->cmat[0][0] = tmnew->cmat[1][1] = tmnew->cmat[2][2] =
                     tmnew->inpsf = WHTEFFICACY;
       tmnew->cmat[0][1] = tmnew->cmat[0][2] = tmnew->cmat[1][0] =
       tmnew->cmat[1][2] = tmnew->cmat[2][0] = tmnew->cmat[2][1] = 0.;
       tmnew->inpdat = NULL;
       tmnew->hbrmin = 10; tmnew->hbrmax = -10;
       tmnew->histo = NULL;
       tmnew->mbrmin = 10; tmnew->mbrmax = -10;
       tmnew->lumap = NULL;
                                          /* zero private data */
       for (i = TM_MAXPKG; i--; )
              tmnew->pd[i] = NULL;
       tmnew->lastError = TM_E_OK;
       tmnew->lastFunc = "NoErr";
                                          /* return new TMstruct */
       return(tmnew);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tmMapPixels ( TMstruct tms,
BYTE ps,
TMbright ls,
BYTE cs,
int  len 
)

Definition at line 560 of file tonemap.c.

{
       static const char funcName[] = "tmMapPixels";
       int32  li, pv;

       if (tms == NULL || tms->lumap == NULL)
              returnErr(TM_E_TMINVAL);
       if ((ps == NULL) | (ls == NULL) | (len < 0))
              returnErr(TM_E_ILLEGAL);
       while (len--) {
              if ((li = *ls++) < tms->mbrmin) {
                     li = 0;
              } else {
                     if (li > tms->mbrmax)
                            li = tms->mbrmax;
                     li = tms->lumap[li - tms->mbrmin];
              }
              if (cs == TM_NOCHROM)
                     *ps++ = li>255 ? 255 : li;
              else {
                     pv = *cs++ * li / tms->cdiv[RED];
                     *ps++ = pv>255 ? 255 : pv;
                     pv = *cs++ * li / tms->cdiv[GRN];
                     *ps++ = pv>255 ? 255 : pv;
                     pv = *cs++ * li / tms->cdiv[BLU];
                     *ps++ = pv>255 ? 255 : pv;
              }
       }
       returnOK;
}

Here is the caller graph for this function:

void tmMkMesofact ( void  )

Definition at line 661 of file tonemap.c.

{
       int    i;

       if (tmMesofact[BMESUPPER-BMESLOWER-1])
              return;

       for (i = BMESLOWER; i < BMESUPPER; i++)
              tmMesofact[i-BMESLOWER] = 256. *
                            (tmLuminance(i) - LMESLOWER) /
                            (LMESUPPER - LMESLOWER);
}

Here is the caller graph for this function:

int tmNewMap ( TMstruct tms)

Definition at line 676 of file tonemap.c.

{
       if (tms->lumap != NULL && (tms->mbrmax - tms->mbrmin) !=
                                   (tms->hbrmax - tms->hbrmin)) {
              free((MEM_PTR)tms->lumap);
              tms->lumap = NULL;
       }
       tms->mbrmin = tms->hbrmin;
       tms->mbrmax = tms->hbrmax;
       if (tms->mbrmin > tms->mbrmax)
              return 0;
       if (tms->lumap == NULL)
              tms->lumap = (unsigned short *)malloc(sizeof(unsigned short)*
                                   (tms->mbrmax-tms->mbrmin+1));
       return(tms->lumap != NULL);
}

Here is the caller graph for this function:

int tmSetSpace ( TMstruct tms,
RGBPRIMP  pri,
double  sf,
MEM_PTR  dat 
)

Definition at line 93 of file tonemap.c.

{
       static const char funcName[] = "tmSetSpace";
       int    i, j;
                                          /* error check */
       if (tms == NULL)
              returnErr(TM_E_TMINVAL);
       if (sf <= 1e-12)
              returnErr(TM_E_ILLEGAL);
                                          /* check if no change */
       if (pri == tms->inppri && FEQ(sf, tms->inpsf) && dat == tms->inpdat)
              returnOK;
       tms->inppri = pri;                 /* let's set it */
       tms->inpsf = sf;
       tms->inpdat = dat;

       if (tms->flags & TM_F_BW) {        /* color doesn't matter */
              tms->monpri = tms->inppri;         /* eliminate xform */
              if (tms->inppri == TM_XYZPRIM) {
                     tms->clf[CIEX] = tms->clf[CIEZ] = 0.;
                     tms->clf[CIEY] = 1.;
              } else {
                     comprgb2xyzmat(tms->cmat, tms->monpri);
                     tms->clf[RED] = tms->cmat[1][0];
                     tms->clf[GRN] = tms->cmat[1][1];
                     tms->clf[BLU] = tms->cmat[1][2];
              }
              tms->cmat[0][0] = tms->cmat[1][1] = tms->cmat[2][2] =
                            tms->inpsf;
              tms->cmat[0][1] = tms->cmat[0][2] = tms->cmat[1][0] =
              tms->cmat[1][2] = tms->cmat[2][0] = tms->cmat[2][1] = 0.;

       } else if (tms->inppri == TM_XYZPRIM)     /* input is XYZ */
              compxyz2rgbWBmat(tms->cmat, tms->monpri);

       else {                             /* input is RGB */
              if (tms->inppri != tms->monpri &&
                            PRIMEQ(tms->inppri, tms->monpri))
                     tms->inppri = tms->monpri;  /* no xform */
              comprgb2rgbWBmat(tms->cmat, tms->inppri, tms->monpri);
       }
       for (i = 0; i < 3; i++)
              for (j = 0; j < 3; j++)
                     tms->cmat[i][j] *= tms->inpsf;
                                          /* set color divisors */
       for (i = 0; i < 3; i++)
              if (tms->clf[i] > .001)
                     tms->cdiv[i] =
                            256.*pow(tms->clf[i], 1./tms->mongam);
              else
                     tms->cdiv[i] = 1;
                                          /* notify packages */
       for (i = tmNumPkgs; i--; )
              if (tms->pd[i] != NULL && tmPkg[i]->NewSpace != NULL)
                     (*tmPkg[i]->NewSpace)(tms);
       returnOK;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

const char RCSid[] = "$Id: tonemap.c,v 3.34 2009/02/09 20:48:08 greg Exp $" [static]

Definition at line 2 of file tonemap.c.

TMbright* tmFloat2BrtLUT = NULL [static]

Definition at line 27 of file tonemap.c.

Definition at line 658 of file tonemap.c.

int tmNumPkgs = 0

Definition at line 24 of file tonemap.c.

Definition at line 23 of file tonemap.c.