Back to index

radiance  4R0+20100331
Classes | Defines | Typedefs | Functions | Variables
tonemap.h File Reference
#include "tiff.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  TMstruct
struct  tmPackage

Defines

#define TM_F_HCONTR   01 /* human contrast sensitivity */
#define TM_F_MESOPIC   02 /* mesopic color sensitivity */
#define TM_F_LINEAR   04 /* linear brightness mapping */
#define TM_F_ACUITY   010 /* acuity adjustment */
#define TM_F_VEIL   020 /* veiling glare */
#define TM_F_CWEIGHT   040 /* center weighting */
#define TM_F_FOVEAL   0100 /* use foveal sample size */
#define TM_F_BW   0200 /* luminance only */
#define TM_F_NOSTDERR   0400 /* don't report errors to stderr */
#define TM_F_CAMERA   0
#define TM_F_HUMAN
#define TM_F_UNIMPL   (TM_F_CWEIGHT|TM_F_VEIL|TM_F_ACUITY|TM_F_FOVEAL)
#define TM_XYZPRIM   (RGBPRIMP)NULL /* indicate XYZ primaries (Note 1) */
#define TM_NOCHROM   (BYTE *)NULL /* indicate no chrominance */
#define TM_NOCHROMP   (BYTE **)NULL /* indicate no chrominances */
#define TM_GETFILE   (FILE *)NULL /* indicate file must be opened */
#define TM_E_OK   0 /* normal return status */
#define TM_E_NOMEM   1 /* out of memory */
#define TM_E_ILLEGAL   2 /* illegal argument value */
#define TM_E_TMINVAL   3 /* no valid tone mapping */
#define TM_E_TMFAIL   4 /* cannot compute tone mapping */
#define TM_E_BADFILE   5 /* cannot open or understand file */
#define TM_E_CODERR1   6 /* code consistency error 1 */
#define TM_E_CODERR2   7 /* code consistency error 2 */
#define TM_BRTSCALE   128 /* brightness scale factor (integer) */
#define TM_NOBRT   (-1<<15) /* bogus brightness value */
#define TM_NOLUM   (1e-17) /* ridiculously small luminance */
#define TM_MAXPKG   8 /* maximum number of color formats */
#define MEM_PTR   void *
#define tmLuminance(li)   exp((li)*(1./TM_BRTSCALE))
#define tmNeedMatrix(t)   ((t)->monpri != (t)->inppri)
#define tmRegPkg(pf)
#define tmPkgData(t, i)   ((t)->pd[i]!=NULL ? (t)->pd[i] : (*tmPkg[i]->Init)(t))

Typedefs

typedef short TMbright

Functions

TMbright tmCvLuminance (double lum)
int tmCvLums (TMbright *ls, float *scan, int len)
TMstructtmInit (int flags, RGBPRIMP monpri, double gamval)
int tmSetSpace (TMstruct *tms, RGBPRIMP pri, double sf, MEM_PTR dat)
void tmClearHisto (TMstruct *tms)
int tmAddHisto (TMstruct *tms, TMbright *ls, int len, int wt)
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 *orig)
void tmDone (TMstruct *tms)
int tmCvGrays (TMstruct *tms, TMbright *ls, float *scan, int len)
int tmCvColors (TMstruct *tms, TMbright *ls, BYTE *cs, COLOR *scan, int len)
int tmCvColrs (TMstruct *tms, TMbright *ls, BYTE *cs, COLR *scan, int len)
int tmLoadPicture (TMstruct *tms, TMbright **lpp, BYTE **cpp, int *xp, int *yp, char *fname, FILE *fp)
int tmMapPicture (BYTE **psp, int *xp, int *yp, int flags, RGBPRIMP monpri, double gamval, double Lddyn, double Ldmax, char *fname, FILE *fp)
int tmCvRGB48 (TMstruct *tms, TMbright *ls, BYTE *cs, uint16(*scan)[3], int len, double gv)
int tmCvGray16 (TMstruct *tms, TMbright *ls, uint16 *scan, int len, double gv)

Variables

char * tmErrorMessage []
struct tmPackagetmPkg [TM_MAXPKG]
int tmNumPkgs

Class Documentation

struct TMstruct

Definition at line 73 of file tonemap.h.

Class Members
int cdiv
COLOR clf
COLORMAT cmat
int flags
TMbright hbrmax
TMbright hbrmin
int * histo
MEM_PTR inpdat
RGBPRIMP inppri
double inpsf
int lastError
const char * lastFunc
unsigned short * lumap
TMbright mbrmax
TMbright mbrmin
double mongam
RGBPRIMP monpri
MEM_PTR pd

Define Documentation

#define MEM_PTR   void *

Definition at line 65 of file tonemap.h.

#define TM_BRTSCALE   128 /* brightness scale factor (integer) */

Definition at line 54 of file tonemap.h.

#define TM_E_BADFILE   5 /* cannot open or understand file */

Definition at line 47 of file tonemap.h.

#define TM_E_CODERR1   6 /* code consistency error 1 */

Definition at line 48 of file tonemap.h.

#define TM_E_CODERR2   7 /* code consistency error 2 */

Definition at line 49 of file tonemap.h.

#define TM_E_ILLEGAL   2 /* illegal argument value */

Definition at line 44 of file tonemap.h.

#define TM_E_NOMEM   1 /* out of memory */

Definition at line 43 of file tonemap.h.

#define TM_E_OK   0 /* normal return status */

Definition at line 42 of file tonemap.h.

#define TM_E_TMFAIL   4 /* cannot compute tone mapping */

Definition at line 46 of file tonemap.h.

#define TM_E_TMINVAL   3 /* no valid tone mapping */

Definition at line 45 of file tonemap.h.

#define TM_F_ACUITY   010 /* acuity adjustment */

Definition at line 21 of file tonemap.h.

#define TM_F_BW   0200 /* luminance only */

Definition at line 25 of file tonemap.h.

#define TM_F_CAMERA   0

Definition at line 28 of file tonemap.h.

#define TM_F_CWEIGHT   040 /* center weighting */

Definition at line 23 of file tonemap.h.

#define TM_F_FOVEAL   0100 /* use foveal sample size */

Definition at line 24 of file tonemap.h.

#define TM_F_HCONTR   01 /* human contrast sensitivity */

Definition at line 18 of file tonemap.h.

#define TM_F_HUMAN
Value:

Definition at line 29 of file tonemap.h.

#define TM_F_LINEAR   04 /* linear brightness mapping */

Definition at line 20 of file tonemap.h.

#define TM_F_MESOPIC   02 /* mesopic color sensitivity */

Definition at line 19 of file tonemap.h.

#define TM_F_NOSTDERR   0400 /* don't report errors to stderr */

Definition at line 26 of file tonemap.h.

Definition at line 31 of file tonemap.h.

#define TM_F_VEIL   020 /* veiling glare */

Definition at line 22 of file tonemap.h.

#define TM_GETFILE   (FILE *)NULL /* indicate file must be opened */

Definition at line 37 of file tonemap.h.

#define TM_MAXPKG   8 /* maximum number of color formats */

Definition at line 59 of file tonemap.h.

#define TM_NOBRT   (-1<<15) /* bogus brightness value */

Definition at line 56 of file tonemap.h.

#define TM_NOCHROM   (BYTE *)NULL /* indicate no chrominance */

Definition at line 35 of file tonemap.h.

#define TM_NOCHROMP   (BYTE **)NULL /* indicate no chrominances */

Definition at line 36 of file tonemap.h.

#define TM_NOLUM   (1e-17) /* ridiculously small luminance */

Definition at line 57 of file tonemap.h.

#define TM_XYZPRIM   (RGBPRIMP)NULL /* indicate XYZ primaries (Note 1) */

Definition at line 34 of file tonemap.h.

#define tmLuminance (   li)    exp((li)*(1./TM_BRTSCALE))

Definition at line 106 of file tonemap.h.

#define tmNeedMatrix (   t)    ((t)->monpri != (t)->inppri)

Definition at line 109 of file tonemap.h.

#define tmPkgData (   t,
  i 
)    ((t)->pd[i]!=NULL ? (t)->pd[i] : (*tmPkg[i]->Init)(t))

Definition at line 116 of file tonemap.h.

#define tmRegPkg (   pf)
Value:
( tmNumPkgs >= TM_MAXPKG ? -1 : \
                            (tmPkg[tmNumPkgs] = (pf), tmNumPkgs++) )

Definition at line 112 of file tonemap.h.


Typedef Documentation

typedef short TMbright

Definition at line 70 of file tonemap.h.


Function Documentation

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 tmCvColrs ( TMstruct tms,
TMbright ls,
BYTE cs,
COLR scan,
int  len 
)

Definition at line 47 of file tmapcolrs.c.

{
       static const char    funcName[] = "tmCvColrs";
       int    cmon[4];
       register COLRDATA    *cd;
       register int  i, j, li, bi;
       int32  vl;

       if (tms == NULL)
              returnErr(TM_E_TMINVAL);
       if ((ls == NULL) | (scan == NULL) | (len < 0))
              returnErr(TM_E_ILLEGAL);
       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++)
                     logi[i] = 0;
              tmMkMesofact();
       }
       if ((cd = (COLRDATA *)tmPkgData(tms,colrReg)) == NULL)
              returnErr(TM_E_NOMEM);
       for (i = len; 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] +
                     cd->clfb[GRN]*cmon[GRN] +
                     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 (tms->flags & TM_F_MESOPIC && bi < BMESUPPER) {
                     int    pf, sli = normscot(cmon);
                     if (bi < BMESLOWER) {
                            cmon[RED] = cmon[GRN] = cmon[BLU] = sli;
                     } else {
                            if (tms->flags & TM_F_BW)
                                   cmon[RED] = cmon[GRN] = cmon[BLU] = li;
                            pf = tmMesofact[bi-BMESLOWER];
                            sli *= 256 - pf;
                            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 = ( (int32)GAMTSZ*cd->clfb[RED]*cmon[RED]/li ) >> 12;
              cs[3*i  ] = bi>=GAMTSZ ? 255 : cd->gamb[bi];
              bi = ( (int32)GAMTSZ*cd->clfb[GRN]*cmon[GRN]/li ) >> 12;
              cs[3*i+1] = bi>=GAMTSZ ? 255 : cd->gamb[bi];
              bi = ( (int32)GAMTSZ*cd->clfb[BLU]*cmon[BLU]/li ) >> 12;
              cs[3*i+2] = bi>=GAMTSZ ? 255 : cd->gamb[bi];
       }
       returnOK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tmCvGray16 ( TMstruct tms,
TMbright ls,
uint16 *  scan,
int  len,
double  gv 
)

Definition at line 134 of file tmap16bit.c.

{
       static const char    funcName[] = "tmCvGray16";
       static double cur_inpsf = 1.;
       static double log_inpsf = 0.;
       int           nshft;
       double        d;

       if (tms == NULL)
              returnErr(TM_E_TMINVAL);
       if ((ls == NULL) | (scan == NULL) | (len < 0))
              returnErr(TM_E_ILLEGAL);
       if (gv <= 0.)
              gv = DEFGAM;
                                          /* initialize log table */
       if (logtab[0] == 0.f)
              mkLogTable();
       if (cur_inpsf != tms->inpsf)
              log_inpsf = log(cur_inpsf = tms->inpsf);
                                          /* convert 16-bit grays */
       while (len--) {
              nshft = normShift16(*scan);
              if (nshft < 0) {            /* bogus value */
                     *ls++ = TM_NOBRT;
                     scan++;
                     continue;
              }
              d = logtab[ imultpow2(*scan,LOGTABBITS-15+nshft) &
                                   ((1L<<LOGTABBITS)-1) ];
              d -= M_LN2*nshft;
              d = (double)TM_BRTSCALE * (gv*d + log_inpsf);
              *ls++ = (d>0. ? d+.5 : d-.5);
              scan++;
       }
       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:

int tmCvRGB48 ( TMstruct tms,
TMbright ls,
BYTE cs,
uint16(*)  scan[3],
int  len,
double  gv 
)

Definition at line 173 of file tmap16bit.c.

{
       static const char    funcName[] = "tmCvRGB48";
       static double cur_inpsf = 1.;
       static double log_inpsf = 0.;
       int           i;

       if (tms == NULL)
              returnErr(TM_E_TMINVAL);
       if ((ls == NULL) | (scan == NULL) | (len < 0))
              returnErr(TM_E_ILLEGAL);
       if (gv <= 0.)
              gv = DEFGAM;
                                          /* sync input gamma table */
       if (gv != cur_gam)
              mkGamTable(gv);
       if (tmNeedMatrix(tms)) {           /* need floating point */
              COLOR  *newscan;
              newscan = (COLOR *)tempbuffer(len*sizeof(COLOR));
              if (newscan == NULL)
                     returnErr(TM_E_NOMEM);
              for (i = len; i--; )
                     rgb48_color(newscan[i], scan[i], gv);
              return(tmCvColors(tms, ls, cs, newscan, len));
       }
                                          /* sync monitor gamma table */
       if (cs != TM_NOCHROM && tms->mongam != cur_mongam)
              mkMonGamTable(tms);
                                          /* initialize log table */
       if (logtab[0] == 0.f)
              mkLogTable();
       if (cur_inpsf != tms->inpsf)
              log_inpsf = log(cur_inpsf = tms->inpsf);
       if (tms->flags & TM_F_MESOPIC)
              tmMkMesofact();
                                          /* convert scanline */
       for (i = len; i--; ) {
              int    nshft = normShift48(scan[i]);
              COLOR  cmon;
              double lum;
              int    bi;
              
              if (nshft < 0) {
                     bi = TM_NOBRT;                     /* bogus value */
                     lum = 1.;
                     setcolor(cmon, 1., 1., 1.);
              } else {
                     int    j = GAMTABBITS-16+nshft;
                     int    nshft2;
                     double d;
                                                 /* normalized linear */
                     setcolor(cmon,       gamtab[imultpow2(scan[i][0],j)],
                                   gamtab[imultpow2(scan[i][1],j)],
                                   gamtab[imultpow2(scan[i][2],j)] );
                     lum =  tms->clf[RED]*cmon[RED];
                     lum += tms->clf[GRN]*cmon[GRN];
                     lum += tms->clf[BLU]*cmon[BLU];
                                                 /* convert to log Y */
                     j = lum * (double)(1L<<16);
                     nshft2 = normShift16(j);
                     d = logtab[ imultpow2(j,LOGTABBITS-15+nshft2) &
                                          ((1L<<LOGTABBITS)-1) ];
                     d -= M_LN2*(gv*nshft + nshft2);
                     d = (double)TM_BRTSCALE*(d + log_inpsf);
                     bi = (int)(d>0. ? d+.5 : d-.5);
              }
                                                 /* world luminance */
              ls[i] = bi;
              if (cs == TM_NOCHROM)                     /* no color? */
                     continue;
                                                 /* mesopic adj. */
              if (tms->flags & TM_F_MESOPIC && bi < BMESUPPER) {
                     double slum = scotlum(cmon);
                     if (bi < BMESLOWER)
                            setcolor(cmon, slum, slum, slum);
                     else {
                            double pf;
                            pf = (1./256.)*tmMesofact[bi-BMESLOWER];
                            if (tms->flags & TM_F_BW)
                                   cmon[RED] = cmon[GRN] = cmon[BLU] = lum;
                            slum *= 1. - pf;
                            cmon[RED] = slum + pf*cmon[RED];
                            cmon[GRN] = slum + pf*cmon[GRN];
                            cmon[BLU] = slum + pf*cmon[BLU];
                     }
              } else if (tms->flags & TM_F_BW) {
                     cmon[RED] = cmon[GRN] = cmon[BLU] = lum;
              }
              bi = (double)MONGAMTSZ*tms->clf[RED]*cmon[RED]/lum;
              cs[3*i  ] = bi>=MONGAMTSZ ? 255 : mongamtab[bi];
              bi = (double)MONGAMTSZ*tms->clf[GRN]*cmon[GRN]/lum;
              cs[3*i+1] = bi>=MONGAMTSZ ? 255 : mongamtab[bi];
              bi = (double)MONGAMTSZ*tms->clf[BLU]*cmon[BLU]/lum;
              cs[3*i+2] = bi>=MONGAMTSZ ? 255 : mongamtab[bi];
       }
       returnOK;
}

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 orig)

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 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 tmLoadPicture ( TMstruct tms,
TMbright **  lpp,
BYTE **  cpp,
int *  xp,
int *  yp,
char *  fname,
FILE *  fp 
)

Definition at line 183 of file tmapcolrs.c.

{
       char   *funcName = fname==NULL ? "tmLoadPicture" : fname;
       FILE   *inpf;
       struct radhead       info;
       int    err;
       COLR   *scanin = NULL;
       int    i;
                                          /* check arguments */
       if (tms == NULL)
              returnErr(TM_E_TMINVAL);
       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, "rb")) == NULL)
              returnErr(TM_E_BADFILE);
       *lpp = NULL;
       if (cpp != TM_NOCHROMP) *cpp = NULL;
       info = rhdefault;                  /* get our header */
       getheader(inpf, headline, &info);
       if ((info.format == FMTBAD) | (info.expos <= 0.) ||
                     fgetresolu(xp, yp, inpf) < 0) {
              err = TM_E_BADFILE; goto done;
       }
       if (info.format == FMTUNK)         /* assume RGBE format */
              info.format = FMTRGB;
       if (info.format == FMTRGB)
              info.expos /= WHTEFFICACY;
       else if (info.format == FMTCIE)
              info.primp = TM_XYZPRIM;
                                          /* prepare library */
       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);
       if (*lpp == NULL)
              goto done;
       if (cpp != TM_NOCHROMP) {
              *cpp = (BYTE *)malloc(3*sizeof(BYTE) * *xp * *yp);
              if (*cpp == NULL)
                     goto done;
       }
       scanin = (COLR *)malloc(sizeof(COLR) * *xp);
       if (scanin == NULL)
              goto done;
       err = TM_E_BADFILE;                /* read & convert scanlines */
       for (i = 0; i < *yp; i++) {
              if (freadcolrs(scanin, *xp, inpf) < 0) {
                     err = TM_E_BADFILE; break;
              }
              err = tmCvColrs(tms, *lpp + (i * *xp),
                     cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp + (i * 3 * *xp),
                            scanin, *xp);
              if (err != TM_E_OK)
                     break;
       }
done:                                     /* clean up */
       if (fp == NULL)
              fclose(inpf);
       if (scanin != NULL)
              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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tmMapPicture ( BYTE **  psp,
int *  xp,
int *  yp,
int  flags,
RGBPRIMP  monpri,
double  gamval,
double  Lddyn,
double  Ldmax,
char *  fname,
FILE *  fp 
)

Definition at line 353 of file tmapcolrs.c.

{
       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)))
              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 ((tms = tmInit(flags, monpri, gamval)) == NULL)
              returnErr(TM_E_NOMEM);
                                          /* load & convert picture */
       err = tmLoadPicture(tms, &lp, (flags&TM_F_BW) ? TM_NOCHROMP : &cp,
                     xp, yp, fname, fp);
       if (err != TM_E_OK) {
              tmDone(tms);
              return(err);
       }
                                          /* allocate space for result */
       if (flags & TM_F_BW) {
              *psp = (BYTE *)malloc(sizeof(BYTE) * *xp * *yp);
              if (*psp == NULL) {
                     free((MEM_PTR)lp);
                     tmDone(tms);
                     returnErr(TM_E_NOMEM);
              }
              cp = TM_NOCHROM;
       } else
              *psp = cp;
                                          /* compute color mapping */
       err = tmAddHisto(tms, lp, *xp * *yp, 1);
       if (err != TM_E_OK)
              goto done;
       err = tmComputeMapping(tms, gamval, Lddyn, Ldmax);
       if (err != TM_E_OK)
              goto done;
                                          /* map colors */
       err = tmMapPixels(tms, *psp, lp, cp, *xp * *yp);

done:                                     /* clean up */
       free((MEM_PTR)lp);
       tmDone(tms);
       if (err != TM_E_OK) {                     /* free memory on error */
              free((MEM_PTR)*psp);
              *psp = NULL;
              returnErr(err);
       }
       returnOK;
}

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:

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

char* tmErrorMessage[]

Definition at line 13 of file tmerrmsg.h.

int tmNumPkgs

Definition at line 24 of file tonemap.c.

Definition at line 23 of file tonemap.c.