ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/tonemap.c
(Generate patch)

Comparing ray/src/common/tonemap.c (file contents):
Revision 3.2 by greg, Tue Apr 15 20:04:43 1997 UTC vs.
Revision 3.5 by gregl, Wed Nov 12 13:25:48 1997 UTC

# Line 18 | Line 18 | static char SCCSid[] = "$SunId$ LBL";
18  
19   struct tmStruct *tmTop = NULL;          /* current tone mapping stack */
20  
21 +                                        /* our list of conversion packages */
22 + struct tmPackage        *tmPkg[TM_MAXPKG];
23 + int     tmNumPkgs = 0;                  /* number of registered packages */
24  
25 + int     tmLastError;                    /* last error incurred by library */
26 + char    *tmLastFunction;                /* error-generating function name */
27 +
28 +
29   int
30   tmErrorReturn(func, err)                /* error return (with message) */
31   char    *func;
32   int     err;
33   {
34 +        tmLastFunction = func;
35 +        tmLastError = err;
36          if (tmTop != NULL && tmTop->flags & TM_F_NOSTDERR)
37                  return(err);
38          fputs(func, stderr);
# Line 62 | Line 71 | double gamval;
71                  tmnew->clf[GRN] = cmat[1][1];
72                  tmnew->clf[BLU] = cmat[1][2];
73          }
65        tmnew->clfb[RED] = 256.*tmnew->clf[RED] + .5;
66        tmnew->clfb[GRN] = 256.*tmnew->clf[GRN] + .5;
67        tmnew->clfb[BLU] = 256.*tmnew->clf[BLU] + .5;
68        tmnew->clfb[EXP] = COLXS;
74                                                  /* set gamma value */
75          if (gamval < MINGAM)
76                  tmnew->mongam = DEFGAM;
77          else
78                  tmnew->mongam = gamval;
79 <        for (i = TM_GAMTSZ; i--; )
80 <                tmnew->gamb[i] = 256.*pow((i+.5)/TM_GAMTSZ, 1./tmnew->mongam);
79 >                                                /* set color divisors */
80 >        for (i = 0; i < 3; i++)
81 >                tmnew->cdiv[i] = 256.*pow(tmnew->clf[i], 1./tmnew->mongam);
82 >
83                                                  /* set input transform */
84          tmnew->inppri = tmnew->monpri;
85          tmnew->cmat[0][0] = tmnew->cmat[1][1] = tmnew->cmat[2][2] =
86                          tmnew->inpsf = WHTEFFICACY;
80        tmnew->inpsfb = TM_BRTSCALE*log(tmnew->inpsf) + .5;
87          tmnew->cmat[0][1] = tmnew->cmat[0][2] = tmnew->cmat[1][0] =
88          tmnew->cmat[1][2] = tmnew->cmat[2][0] = tmnew->cmat[2][1] = 0.;
83        tmnew->flags &= ~TM_F_NEEDMAT;
89          tmnew->brmin = tmnew->brmax = 0;
90          tmnew->histo = NULL;
91          tmnew->lumap = NULL;
92 <        tmnew->tmprev = NULL;
93 <
94 <        tmnew->flags |= TM_F_INITED;
95 <                                                /* make it current */
92 >                                                /* zero private data */
93 >        for (i = TM_MAXPKG; i--; )
94 >                tmnew->pd[i] = NULL;
95 >                                                /* make tmnew current */
96          tmnew->tmprev = tmTop;
97          return(tmTop = tmnew);
98   }
# Line 110 | Line 115 | double sf;
115                  returnOK;
116          tmTop->inppri = pri;                    /* let's set it */
117          tmTop->inpsf = sf;
113        tmTop->inpsfb = TM_BRTSCALE*log(sf) + (sf>=1. ? .5 : -.5);
118  
119          if (tmTop->flags & TM_F_BW) {           /* color doesn't matter */
120                  tmTop->monpri = tmTop->inppri;          /* eliminate xform */
121                  if (tmTop->inppri == TM_XYZPRIM) {
122                          tmTop->clf[CIEX] = tmTop->clf[CIEZ] = 0.;
123                          tmTop->clf[CIEY] = 1.;
120                        tmTop->clfb[CIEX] = tmTop->clfb[CIEZ] = 0;
121                        tmTop->clfb[CIEY] = 255;
124                  } else {
125                          comprgb2xyzmat(tmTop->cmat, tmTop->monpri);
126                          tmTop->clf[RED] = tmTop->cmat[1][0];
# Line 142 | Line 144 | double sf;
144          for (i = 0; i < 3; i++)
145                  for (j = 0; j < 3; j++)
146                          tmTop->cmat[i][j] *= tmTop->inpsf;
147 <        if (tmTop->inppri != tmTop->monpri)
148 <                tmTop->flags |= TM_F_NEEDMAT;
149 <        else
150 <                tmTop->flags &= ~TM_F_NEEDMAT;
147 >                                                /* set color divisors */
148 >        for (i = 0; i < 3; i++)
149 >                if (tmTop->clf[i] > .001)
150 >                        tmTop->cdiv[i] =
151 >                                256.*pow(tmTop->clf[i], 1./tmTop->mongam);
152 >                else
153 >                        tmTop->cdiv[i] = 1;
154 >                                                /* notify packages */
155 >        for (i = tmNumPkgs; i--; )
156 >                if (tmTop->pd[i] != NULL && tmPkg[i]->NewSpace != NULL)
157 >                        (*tmPkg[i]->NewSpace)(tmTop);
158          returnOK;
159   }
160  
# Line 155 | Line 164 | tmClearHisto()                 /* clear current histogram */
164   {
165          if (tmTop == NULL || tmTop->histo == NULL)
166                  return;
167 <        free((char *)tmTop->histo);
167 >        free((MEM_PTR)tmTop->histo);
168          tmTop->histo = NULL;
169   }
170  
# Line 168 | Line 177 | COLOR  *scan;
177   int     len;
178   {
179          static char     funcName[] = "tmCvColors";
180 +        static COLOR    csmall = {1e-6, 1e-6, 1e-6};
181          COLOR   cmon;
182          double  lum, slum;
183          register double d;
# Line 178 | Line 188 | int    len;
188          if (ls == NULL | scan == NULL | len <= 0)
189                  returnErr(TM_E_ILLEGAL);
190          for (i = len; i--; ) {
191 <                if (tmTop->flags & TM_F_NEEDMAT)        /* get monitor RGB */
191 >                if (tmNeedMatrix(tmTop))                /* get monitor RGB */
192                          colortrans(cmon, tmTop->cmat, scan[i]);
193                  else {
194                          cmon[RED] = tmTop->inpsf*scan[i][RED];
# Line 190 | Line 200 | int    len;
200                          tmTop->clf[GRN]*cmon[GRN] +
201                          tmTop->clf[BLU]*cmon[BLU] ;
202                                                          /* check range */
203 <                if (clipgamut(cmon, lum, CGAMUT_LOWER, cblack, cwhite))
203 >                if (clipgamut(cmon, lum, CGAMUT_LOWER, csmall, cwhite))
204                          lum =   tmTop->clf[RED]*cmon[RED] +
205                                  tmTop->clf[GRN]*cmon[GRN] +
206                                  tmTop->clf[BLU]*cmon[BLU] ;
# Line 223 | Line 233 | int    len;
233                          cmon[RED] = cmon[GRN] = cmon[BLU] = lum;
234                  }
235                  d = tmTop->clf[RED]*cmon[RED]/lum;
236 <                /* cs[3*i  ] = d>.999 ? 255 : 256.*pow(d, 1./tmTop->mongam); */
237 <                cs[3*i  ] = d>.999 ? 255 : tmTop->gamb[(int)(d*TM_GAMTSZ)];
236 >                cs[3*i  ] = d>=.999 ? 255 :
237 >                                (int)(256.*pow(d, 1./tmTop->mongam));
238                  d = tmTop->clf[GRN]*cmon[GRN]/lum;
239 <                /* cs[3*i+1] = d>.999 ? 255 : 256.*pow(d, 1./tmTop->mongam); */
240 <                cs[3*i+1] = d>.999 ? 255 : tmTop->gamb[(int)(d*TM_GAMTSZ)];
239 >                cs[3*i+1] = d>=.999 ? 255 :
240 >                                (int)(256.*pow(d, 1./tmTop->mongam));
241                  d = tmTop->clf[BLU]*cmon[BLU]/lum;
242 <                /* cs[3*i+2] = d>.999 ? 255 : 256.*pow(d, 1./tmTop->mongam); */
243 <                cs[3*i+2] = d>.999 ? 255 : tmTop->gamb[(int)(d*TM_GAMTSZ)];
242 >                cs[3*i+2] = d>=.999 ? 255 :
243 >                                (int)(256.*pow(d, 1./tmTop->mongam));
244          }
245          returnOK;
246   }
# Line 279 | Line 289 | int    wt;
289                  if (oldlen) {                   /* copy and free old */
290                          for (i = oldlen, j = i+oldorig-horig; i; )
291                                  newhist[--j] = tmTop->histo[--i];
292 <                        free((char *)tmTop->histo);
292 >                        free((MEM_PTR)tmTop->histo);
293                  }
294                  tmTop->histo = newhist;
295                  if (tmTop->lumap != NULL) {     /* invalid tone map */
296 <                        free((char *)tmTop->lumap);
296 >                        free((MEM_PTR)tmTop->lumap);
297                          tmTop->lumap = NULL;
298                  }
299          }
# Line 420 | Line 430 | double Ldmax;
430                  }
431          }
432          if (!(tmTop->flags & TM_F_LINEAR)) {
433 <                free((char *)histo);
434 <                free((char *)cumf);
433 >                free((MEM_PTR)histo);
434 >                free((MEM_PTR)cumf);
435          }
436          returnOK;
437   }
# Line 435 | Line 445 | register BYTE  *cs;
445   int     len;
446   {
447          static char     funcName[] = "tmMapPixels";
448 <        int     rdiv, gdiv, bdiv;
439 <        register int    li, pv;
448 >        register int4   li, pv;
449  
450          if (tmTop == NULL || tmTop->lumap == NULL)
451                  returnErr(TM_E_TMINVAL);
452          if (ps == NULL | ls == NULL | len <= 0)
453                  returnErr(TM_E_ILLEGAL);
445        rdiv = tmTop->gamb[((int4)TM_GAMTSZ*tmTop->clfb[RED])>>8];
446        gdiv = tmTop->gamb[((int4)TM_GAMTSZ*tmTop->clfb[GRN])>>8];
447        bdiv = tmTop->gamb[((int4)TM_GAMTSZ*tmTop->clfb[BLU])>>8];
454          while (len--) {
455                  if ((li = *ls++) < tmTop->brmin)
456                          li = tmTop->brmin;
# Line 454 | Line 460 | int    len;
460                  if (cs == TM_NOCHROM)
461                          *ps++ = li>255 ? 255 : li;
462                  else {
463 <                        pv = *cs++ * li / rdiv;
463 >                        pv = *cs++ * li / tmTop->cdiv[RED];
464                          *ps++ = pv>255 ? 255 : pv;
465 <                        pv = *cs++ * li / gdiv;
465 >                        pv = *cs++ * li / tmTop->cdiv[GRN];
466                          *ps++ = pv>255 ? 255 : pv;
467 <                        pv = *cs++ * li / bdiv;
467 >                        pv = *cs++ * li / tmTop->cdiv[BLU];
468                          *ps++ = pv>255 ? 255 : pv;
469                  }
470          }
# Line 500 | Line 506 | register struct tmStruct       *tms;
506   }
507  
508  
509 + struct tmStruct *
510 + tmDup()                         /* duplicate top tone mapping */
511 + {
512 +        int     len;
513 +        register int    i;
514 +        register struct tmStruct        *tmnew;
515 +
516 +        if (tmTop == NULL)              /* anything to duplicate? */
517 +                return(NULL);
518 +        tmnew = (struct tmStruct *)malloc(sizeof(struct tmStruct));
519 +        if (tmnew == NULL)
520 +                return(NULL);
521 +        *tmnew = *tmTop;                /* copy everything */
522 +        if (tmnew->histo != NULL) {     /* duplicate histogram */
523 +                len = (tmnew->brmax-MINBRT)/HISTEP + 1 -
524 +                                (tmnew->brmin-MINBRT)/HISTEP;
525 +                tmnew->histo = (int *)malloc(len*sizeof(int));
526 +                if (tmnew->histo != NULL)
527 +                        for (i = len; i--; )
528 +                                tmnew->histo[i] = tmTop->histo[i];
529 +        }
530 +        if (tmnew->lumap != NULL) {     /* duplicate luminance mapping */
531 +                len = tmnew->brmax-tmnew->brmin+1;
532 +                tmnew->lumap = (unsigned short *)malloc(
533 +                                                len*sizeof(unsigned short) );
534 +                if (tmnew->lumap != NULL)
535 +                        for (i = len; i--; )
536 +                                tmnew->lumap[i] = tmTop->lumap[i];
537 +        }
538 +                                        /* clear package data */
539 +        for (i = tmNumPkgs; i--; )
540 +                tmnew->pd[i] = NULL;
541 +        tmnew->tmprev = tmTop;          /* make copy current */
542 +        return(tmTop = tmnew);
543 + }
544 +
545 +
546   int
547   tmPush(tms)                     /* push tone mapping on top of stack */
548   register struct tmStruct        *tms;
549   {
550          static char     funcName[] = "tmPush";
551                                          /* check validity */
552 <        if (tms == NULL || !(tms->flags & TM_F_INITED))
552 >        if (tms == NULL)
553                  returnErr(TM_E_ILLEGAL);
554          if (tms == tmTop)               /* check necessity */
555                  returnOK;
# Line 523 | Line 566 | void
566   tmDone(tms)                     /* done with tone mapping -- destroy it */
567   register struct tmStruct        *tms;
568   {
569 +        register int    i;
570                                          /* NULL arg. is equiv. to tmTop */
571          if (tms == NULL && (tms = tmTop) == NULL)
572                  return;
# Line 530 | Line 574 | register struct tmStruct       *tms;
574          (void)tmPull(tms);
575                                          /* free tables */
576          if (tms->histo != NULL)
577 <                free((char *)tms->histo);
577 >                free((MEM_PTR)tms->histo);
578          if (tms->lumap != NULL)
579 <                free((char *)tms->lumap);
580 <        tms->flags = 0;
581 <        free((char *)tms);              /* free basic structure */
579 >                free((MEM_PTR)tms->lumap);
580 >                                        /* free private data */
581 >        for (i = tmNumPkgs; i--; )
582 >                if (tms->pd[i] != NULL)
583 >                        (*tmPkg[i]->Free)(tms->pd[i]);
584 >        free((MEM_PTR)tms);             /* free basic structure */
585   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines