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

Comparing ray/src/common/tmap16bit.c (file contents):
Revision 1.1 by greg, Mon Jul 14 18:21:07 2003 UTC vs.
Revision 1.8 by greg, Thu May 15 22:15:16 2008 UTC

# Line 15 | Line 15 | static const char RCSid[] = "$Id$";
15  
16   #define LOGTABBITS      11      /* log table is 1<<LOGTABBITS long */
17   #define GAMTABBITS      9       /* gamma table is 1<<GAMTABBITS long */
18 + #define MONGAMTSZ       1024    /* monitor gamma table length */
19  
20   static float    logtab[1<<LOGTABBITS];
21   static float    gamtab[1<<GAMTABBITS];
22   static float    gammul[16];
23   static double   cur_gam = 0.;
24 + static BYTE     mongamtab[MONGAMTSZ];
25 + static double   cur_mongam = 0.;
26  
27   #define imultpow2(i,s)  ((s)>=0 ? (i)<<(s) : (i)>>-(s))
28  
# Line 38 | Line 41 | mkLogTable()
41   }
42  
43  
44 < /* Fill our gamma table */
44 > /* Fill our input gamma table */
45   static void
46   mkGamTable(double gv)
47   {
# Line 54 | Line 57 | mkGamTable(double gv)
57   }
58  
59  
60 + /* Fill our monitor gamma table */
61 + static void
62 + mkMonGamTable(TMstruct *tms)
63 + {
64 +        int     i;
65 +        
66 +        if (tms->mongam == cur_mongam)
67 +                return;
68 +        for (i = MONGAMTSZ; i--; )
69 +                mongamtab[i] = 256.*pow((i+.5)*(1./MONGAMTSZ), 1./tms->mongam);
70 +        cur_mongam = tms->mongam;
71 + }
72 +
73 +
74   /* Find normalizing shift value for a 2-byte unsigned integer */
75   static int
76   normShift16(int i)
77   {
78          int     s = 0;
79          
80 +        if (!i)
81 +                return(-1);
82          while (!(i & 0x8000)) {
83                  i <<= 1;
84                  ++s;
# Line 81 | Line 100 | normShift48(uint16 clr48[3])
100  
101   /* convert at 48-bit tristimulus value to a COLOR */
102   static void
103 < rgb48_color(COLOR col, uint16 clr48[3])
103 > rgb48_color(COLOR col, uint16 clr48[3], double gv)
104   {
105          int     nshft;
106  
107 <        if (cur_gam == 1.) {                    /* linear case */
107 >        if (gv == 1.) {                         /* linear case */
108                  col[0] = clr48[0]*(1./(1L<<16));
109                  col[1] = clr48[1]*(1./(1L<<16));
110                  col[2] = clr48[2]*(1./(1L<<16));
111                  return;
112          }
113                                                  /* non-linear case */
114 +        /* XXX Uncomment if this routine is made public
115 +        if (gv != cur_gam)
116 +                mkGamTable(gv);
117 +        */
118          nshft = normShift48(clr48);
119 +        if (nshft < 0) {
120 +                col[0] = col[1] = col[2] = .0f;
121 +                return;
122 +        }
123          col[0] = gamtab[imultpow2(clr48[0],GAMTABBITS-16+nshft)] *
124                          gammul[nshft];
125          col[1] = gamtab[imultpow2(clr48[1],GAMTABBITS-16+nshft)] *
# Line 104 | Line 131 | rgb48_color(COLOR col, uint16 clr48[3])
131  
132   /* Convert 16-bit gray scanline to encoded luminance */
133   int
134 < tmCvGray16(TMbright *ls, uint16 *scan, int len, double gv)
134 > tmCvGray16(TMstruct *tms, TMbright *ls, uint16 *scan, int len, double gv)
135   {
136 <        static char     funcName[] = "tmCvGray16";
136 >        static const char       funcName[] = "tmCvGray16";
137          static double   cur_inpsf = 1.;
138          static double   log_inpsf = 0.;
139          int             nshft;
140          double          d;
141  
142 <        if (tmTop == NULL)
142 >        if (tms == NULL)
143                  returnErr(TM_E_TMINVAL);
144 <        if (ls == NULL | scan == NULL | len < 0 | gv <= MINGAM)
144 >        if ((ls == NULL) | (scan == NULL) | (len < 0))
145                  returnErr(TM_E_ILLEGAL);
146 +        if (gv <= 0.)
147 +                gv = DEFGAM;
148                                                  /* initialize log table */
149          if (logtab[0] == 0.f)
150                  mkLogTable();
151 <        if (cur_inpsf != tmTop->inpsf)
152 <                log_inpsf = log(cur_inpsf = tmTop->inpsf);
151 >        if (cur_inpsf != tms->inpsf)
152 >                log_inpsf = log(cur_inpsf = tms->inpsf);
153                                                  /* convert 16-bit grays */
154          while (len--) {
155                  nshft = normShift16(*scan);
156 +                if (nshft < 0) {                /* bogus value */
157 +                        *ls++ = TM_NOBRT;
158 +                        scan++;
159 +                        continue;
160 +                }
161                  d = logtab[ imultpow2(*scan,LOGTABBITS-15+nshft) &
162 <                                        ((1L<<LOGTABBITS)-1) ]
163 <                                - M_LN2*nshft;
162 >                                        ((1L<<LOGTABBITS)-1) ];
163 >                d -= M_LN2*nshft;
164                  d = (double)TM_BRTSCALE * (gv*d + log_inpsf);
165                  *ls++ = (d>0. ? d+.5 : d-.5);
166                  scan++;
# Line 136 | Line 170 | tmCvGray16(TMbright *ls, uint16 *scan, int len, double
170  
171   /* Convert a 48-bit RGB scanline to encoded luminance/chrominance */
172   int
173 < tmCvRGB48(TMbright *ls, BYTE *cs, uint16 (*scan)[3], int len, double gv)
173 > tmCvRGB48(TMstruct *tms, TMbright *ls, BYTE *cs,
174 >                uint16 (*scan)[3], int len, double gv)
175   {
176 <        static char     funcName[] = "tmCvRGB48";
176 >        static const char       funcName[] = "tmCvRGB48";
177          static double   cur_inpsf = 1.;
178          static double   log_inpsf = 0.;
179          int             i;
180  
181 <        if (tmTop == NULL)
181 >        if (tms == NULL)
182                  returnErr(TM_E_TMINVAL);
183 <        if (ls == NULL | scan == NULL | len < 0 | gv <= MINGAM)
183 >        if ((ls == NULL) | (scan == NULL) | (len < 0))
184                  returnErr(TM_E_ILLEGAL);
185 <                                                /* update gamma table */
186 <        if (gv != 1. & gv != cur_gam)
185 >        if (gv <= 0.)
186 >                gv = DEFGAM;
187 >                                                /* sync input gamma table */
188 >        if (gv != cur_gam)
189                  mkGamTable(gv);
190 < #if 0
154 <        if (tmNeedMatrix(tmTop)) {              /* need floating point */
155 < #else
156 <        {
157 < #endif
190 >        if (tmNeedMatrix(tms)) {                /* need floating point */
191                  COLOR   *newscan;
192                  newscan = (COLOR *)tempbuffer(len*sizeof(COLOR));
193                  if (newscan == NULL)
194                          returnErr(TM_E_NOMEM);
195                  for (i = len; i--; )
196 <                        rgb48_color(newscan[i], scan[i]);
197 <                return(tmCvColors(ls, cs, newscan, len));
196 >                        rgb48_color(newscan[i], scan[i], gv);
197 >                return(tmCvColors(tms, ls, cs, newscan, len));
198          }
199 < #if 0
199 >                                                /* sync monitor gamma table */
200 >        if (cs != TM_NOCHROM && tms->mongam != cur_mongam)
201 >                mkMonGamTable(tms);
202                                                  /* initialize log table */
203          if (logtab[0] == 0.f)
204                  mkLogTable();
205 <        if (cur_inpsf != tmTop->inpsf)
206 <                log_inpsf = log(cur_inpsf = tmTop->inpsf);
205 >        if (cur_inpsf != tms->inpsf)
206 >                log_inpsf = log(cur_inpsf = tms->inpsf);
207 >        if (tms->flags & TM_F_MESOPIC)
208 >                tmMkMesofact();
209                                                  /* convert scanline */
210          for (i = len; i--; ) {
211 <                copycolr(cmon, scan[i]);
212 <                                                        /* world luminance */
213 <                li =  ( cd->clfb[RED]*cmon[RED] +
214 <                        cd->clfb[GRN]*cmon[GRN] +
215 <                        cd->clfb[BLU]*cmon[BLU] ) >> 8;
216 <                bi = BRT2SCALE(cmon[EXP]-COLXS) +
180 <                                logi[li] + cd->inpsfb;
181 <                if (li <= 0) {
211 >                int     nshft = normShift48(scan[i]);
212 >                COLOR   cmon;
213 >                double  lum;
214 >                int     bi;
215 >                
216 >                if (nshft < 0) {
217                          bi = TM_NOBRT;                  /* bogus value */
218 <                        li = 1;                         /* avoid li==0 */
218 >                        lum = 1.;
219 >                        setcolor(cmon, 1., 1., 1.);
220 >                } else {
221 >                        int     j = GAMTABBITS-16+nshft;
222 >                        int     nshft2;
223 >                        double  d;
224 >                                                        /* normalized linear */
225 >                        setcolor(cmon,  gamtab[imultpow2(scan[i][0],j)],
226 >                                        gamtab[imultpow2(scan[i][1],j)],
227 >                                        gamtab[imultpow2(scan[i][2],j)] );
228 >                        lum =   tms->clf[RED]*cmon[RED];
229 >                        lum +=  tms->clf[GRN]*cmon[GRN];
230 >                        lum +=  tms->clf[BLU]*cmon[BLU];
231 >                                                        /* convert to log Y */
232 >                        j = lum * (double)(1L<<16);
233 >                        nshft2 = normShift16(j);
234 >                        d = logtab[ imultpow2(j,LOGTABBITS-15+nshft2) &
235 >                                                ((1L<<LOGTABBITS)-1) ];
236 >                        d -= M_LN2*(gv*nshft + nshft2);
237 >                        d = (double)TM_BRTSCALE*(d + log_inpsf);
238 >                        bi = (int)(d>0. ? d+.5 : d-.5);
239                  }
240 +                                                        /* world luminance */
241                  ls[i] = bi;
242                  if (cs == TM_NOCHROM)                   /* no color? */
243                          continue;
244                                                          /* mesopic adj. */
245 <                if (tmTop->flags & TM_F_MESOPIC && bi < BMESUPPER) {
246 <                        int     pf, sli = normscot(cmon);
245 >                if (tms->flags & TM_F_MESOPIC && bi < BMESUPPER) {
246 >                        double  slum = scotlum(cmon);
247                          if (bi < BMESLOWER)
248 <                                cmon[RED] = cmon[GRN] = cmon[BLU] = sli;
248 >                                setcolor(cmon, slum, slum, slum);
249                          else {
250 <                                if (tmTop->flags & TM_F_BW)
251 <                                        cmon[RED] = cmon[GRN] = cmon[BLU] = li;
252 <                                pf = tmMesofact[bi-BMESLOWER];
253 <                                sli *= 256 - pf;
254 <                                cmon[RED] = ( sli + pf*cmon[RED] ) >> 8;
255 <                                cmon[GRN] = ( sli + pf*cmon[GRN] ) >> 8;
256 <                                cmon[BLU] = ( sli + pf*cmon[BLU] ) >> 8;
250 >                                double  pf;
251 >                                pf = (1./256.)*tmMesofact[bi-BMESLOWER];
252 >                                if (tms->flags & TM_F_BW)
253 >                                        cmon[RED] = cmon[GRN] = cmon[BLU] = lum;
254 >                                slum *= 1. - pf;
255 >                                cmon[RED] = slum + pf*cmon[RED];
256 >                                cmon[GRN] = slum + pf*cmon[GRN];
257 >                                cmon[BLU] = slum + pf*cmon[BLU];
258                          }
259 <                } else if (tmTop->flags & TM_F_BW) {
260 <                        cmon[RED] = cmon[GRN] = cmon[BLU] = li;
259 >                } else if (tms->flags & TM_F_BW) {
260 >                        cmon[RED] = cmon[GRN] = cmon[BLU] = lum;
261                  }
262 <                bi = ( (int32)GAMTSZ*cd->clfb[RED]*cmon[RED]/li ) >> 8;
263 <                cs[3*i  ] = bi>=GAMTSZ ? 255 : cd->gamb[bi];
264 <                bi = ( (int32)GAMTSZ*cd->clfb[GRN]*cmon[GRN]/li ) >> 8;
265 <                cs[3*i+1] = bi>=GAMTSZ ? 255 : cd->gamb[bi];
266 <                bi = ( (int32)GAMTSZ*cd->clfb[BLU]*cmon[BLU]/li ) >> 8;
267 <                cs[3*i+2] = bi>=GAMTSZ ? 255 : cd->gamb[bi];
262 >                bi = (double)MONGAMTSZ*tms->clf[RED]*cmon[RED]/lum;
263 >                cs[3*i  ] = bi>=MONGAMTSZ ? 255 : mongamtab[bi];
264 >                bi = (double)MONGAMTSZ*tms->clf[GRN]*cmon[GRN]/lum;
265 >                cs[3*i+1] = bi>=MONGAMTSZ ? 255 : mongamtab[bi];
266 >                bi = (double)MONGAMTSZ*tms->clf[BLU]*cmon[BLU]/lum;
267 >                cs[3*i+2] = bi>=MONGAMTSZ ? 255 : mongamtab[bi];
268          }
269          returnOK;
213 #endif
270   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines