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

Comparing ray/src/common/spec_rgb.c (file contents):
Revision 2.11 by greg, Sat Feb 22 02:07:22 2003 UTC vs.
Revision 2.23 by greg, Fri May 20 02:06:38 2011 UTC

# Line 8 | Line 8 | static const char      RCSid[] = "$Id$";
8   * Externals declared in color.h
9   */
10  
11 < /* ====================================================================
12 < * The Radiance Software License, Version 1.0
13 < *
14 < * Copyright (c) 1990 - 2002 The Regents of the University of California,
15 < * through Lawrence Berkeley National Laboratory.   All rights reserved.
16 < *
17 < * Redistribution and use in source and binary forms, with or without
18 < * modification, are permitted provided that the following conditions
19 < * are met:
20 < *
21 < * 1. Redistributions of source code must retain the above copyright
22 < *         notice, this list of conditions and the following disclaimer.
23 < *
24 < * 2. Redistributions in binary form must reproduce the above copyright
25 < *       notice, this list of conditions and the following disclaimer in
26 < *       the documentation and/or other materials provided with the
27 < *       distribution.
28 < *
29 < * 3. The end-user documentation included with the redistribution,
30 < *           if any, must include the following acknowledgment:
31 < *             "This product includes Radiance software
32 < *                 (http://radsite.lbl.gov/)
33 < *                 developed by the Lawrence Berkeley National Laboratory
34 < *               (http://www.lbl.gov/)."
35 < *       Alternately, this acknowledgment may appear in the software itself,
36 < *       if and wherever such third-party acknowledgments normally appear.
37 < *
38 < * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
39 < *       and "The Regents of the University of California" must
40 < *       not be used to endorse or promote products derived from this
41 < *       software without prior written permission. For written
42 < *       permission, please contact [email protected].
43 < *
44 < * 5. Products derived from this software may not be called "Radiance",
45 < *       nor may "Radiance" appear in their name, without prior written
46 < *       permission of Lawrence Berkeley National Laboratory.
47 < *
48 < * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
49 < * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
50 < * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51 < * DISCLAIMED.   IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
52 < * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
53 < * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
54 < * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
55 < * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
56 < * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
57 < * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
58 < * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 < * SUCH DAMAGE.
60 < * ====================================================================
61 < *
62 < * This software consists of voluntary contributions made by many
63 < * individuals on behalf of Lawrence Berkeley National Laboratory.   For more
64 < * information on Lawrence Berkeley National Laboratory, please see
65 < * <http://www.lbl.gov/>.
66 < */
11 > #include "copyright.h"
12  
13 < #include "color.h"
13 > #include <stdio.h>
14   #include <string.h>
15 + #include "color.h"
16  
17   #define CEPS    1e-4                    /* color epsilon */
18  
# Line 92 | Line 38 | float  xyneu[2] = {1./3., 1./3.};      /* neutral xy chroma
38   #define  INCWL          10              /* wavelength increment */
39   #define  NINC           40              /* # of values */
40  
41 < static BYTE  chroma[3][NINC] = {
41 > static uby8  chroma[3][NINC] = {
42          {                                                       /* X */
43                  0,   0,   0,   2,   6,   13,  22,  30,  36,  41,
44                  42,  43,  43,  44,  46,  52,  60,  71,  87,  106,
# Line 145 | Line 91 | COLORMAT  ivkmat = {           /* inverse Sharp primary matrix
91  
92  
93   void
94 < spec_rgb(col, s, e)             /* compute RGB color from spectral range */
95 < COLOR  col;
96 < int  s, e;
94 > spec_rgb(                       /* compute RGB color from spectral range */
95 > COLOR  col,
96 > int  s,
97 > int  e
98 > )
99   {
100          COLOR  ciecolor;
101  
# Line 157 | Line 105 | int  s, e;
105  
106  
107   void
108 < spec_cie(col, s, e)             /* compute a color from a spectral range */
109 < COLOR  col;             /* returned color */
110 < int  s, e;              /* starting and ending wavelengths */
108 > spec_cie(                       /* compute a color from a spectral range */
109 > COLOR  col,             /* returned color */
110 > int  s,                 /* starting and ending wavelengths */
111 > int  e
112 > )
113   {
114          register int  i, d, r;
115          
# Line 192 | Line 142 | int  s, e;             /* starting and ending wavelengths */
142  
143  
144   void
145 < cie_rgb(rgb, xyz)               /* convert CIE color to standard RGB */
146 < COLOR   rgb;
147 < COLOR  xyz;
145 > cie_rgb(                        /* convert CIE color to standard RGB */
146 > COLOR   rgb,
147 > COLOR  xyz
148 > )
149   {
150          colortrans(rgb, xyz2rgbmat, xyz);
151          clipgamut(rgb, xyz[CIEY], CGAMUT_LOWER, cblack, cwhite);
# Line 202 | Line 153 | COLOR  xyz;
153  
154  
155   int
156 < clipgamut(col, brt, gamut, lower, upper)        /* clip to gamut cube */
157 < COLOR  col;
158 < double  brt;
159 < int  gamut;
160 < COLOR  lower, upper;
156 > clipgamut(                      /* clip to gamut cube */
157 > COLOR  col,
158 > double  brt,
159 > int  gamut,
160 > COLOR  lower,
161 > COLOR  upper
162 > )
163   {
164          int  rflags = 0;
165          double  brtmin, brtmax, v, vv;
# Line 232 | Line 185 | COLOR  lower, upper;
185          vv = 1.;                        /* check each limit */
186          for (i = 0; i < 3; i++)
187                  if (gamut & CGAMUT_LOWER && col[i] < lower[i]) {
188 <                        v = (lower[i]+CEPS - cgry[i])/(col[i] - cgry[i]);
188 >                        v = (lower[i] - cgry[i])/(col[i] - cgry[i]);
189                          if (v < vv) vv = v;
190                          rflags |= CGAMUT_LOWER;
191                  } else if (gamut & CGAMUT_UPPER && col[i] > upper[i]) {
192 <                        v = (upper[i]-CEPS - cgry[i])/(col[i] - cgry[i]);
192 >                        v = (upper[i] - cgry[i])/(col[i] - cgry[i]);
193                          if (v < vv) vv = v;
194                          rflags |= CGAMUT_UPPER;
195                  }
# Line 248 | Line 201 | COLOR  lower, upper;
201  
202  
203   void
204 < colortrans(c2, mat, c1)         /* convert c1 by mat and put into c2 */
205 < register COLOR  c2;
206 < register COLORMAT  mat;
207 < register COLOR  c1;
204 > colortrans(                     /* convert c1 by mat and put into c2 */
205 > register COLOR  c2,
206 > register COLORMAT  mat,
207 > register COLOR  c1
208 > )
209   {
210          COLOR   cout;
211  
# Line 264 | Line 218 | register COLOR  c1;
218  
219  
220   void
221 < multcolormat(m3, m2, m1)        /* multiply m1 by m2 and put into m3 */
222 < COLORMAT  m3;                   /* m3 can be either m1 or m2 w/o harm */
223 < COLORMAT  m2, m1;
221 > multcolormat(                   /* multiply m1 by m2 and put into m3 */
222 > COLORMAT  m3,                   /* m3 can be either m1 or m2 w/o harm */
223 > COLORMAT  m2,
224 > COLORMAT  m1
225 > )
226   {
227          COLORMAT  mt;
228          register int  i, j;
# Line 280 | Line 236 | COLORMAT  m2, m1;
236   }
237  
238  
239 < void
240 < compxyz2rgbmat(mat, pr)         /* compute conversion from CIE to RGB space */
241 < COLORMAT  mat;
242 < register RGBPRIMS  pr;
239 > int
240 > colorprimsOK(                   /* are color primaries reasonable? */
241 > RGBPRIMS  pr
242 > )
243   {
244 +        int     i, j;
245 +        
246 +        for (i = 0; i < 3; i++) {
247 +                if ((pr[i][CIEX] <= -1.) | (pr[i][CIEY] <= -1.))
248 +                        return(0);
249 +                if ((pr[i][CIEX] >= 2.) | (pr[i][CIEY] >= 2.))
250 +                        return(0);
251 +                if (pr[i][CIEX] + pr[i][CIEY] <= -1.)
252 +                        return(0);
253 +                if (pr[i][CIEX] + pr[i][CIEY] >= 2.)
254 +                        return(0);
255 +        }
256 +        if ((pr[3][CIEX] <= 0.) | (pr[3][CIEX] >= 1.) |
257 +                        (pr[3][CIEY] <= 0.) | (pr[3][CIEY] >= 1.))
258 +                return(0);
259 +        for (i = 0; i < 4; i++)
260 +                for (j = i+1; j < 4; j++)
261 +                        if (CEQ(pr[i][CIEX],pr[j][CIEX]) &&
262 +                                        CEQ(pr[i][CIEY],pr[j][CIEY]))
263 +                                return(0);
264 +        return(1);
265 + }
266 +
267 +
268 +
269 + int
270 + compxyz2rgbmat(                 /* compute conversion from CIE to RGB space */
271 + COLORMAT  mat,
272 + register RGBPRIMS  pr
273 + )
274 + {
275          double  C_rD, C_gD, C_bD;
276  
277          if (pr == stdprims) {   /* can use xyz2rgbmat */
278                  cpcolormat(mat, xyz2rgbmat);
279 <                return;
279 >                return(1);
280          }
281 +        if (CEQ(pr[WHT][CIEX],0.) | CEQ(pr[WHT][CIEY],0.))
282 +                return(0);
283          C_rD = (1./pr[WHT][CIEY]) *
284                          ( pr[WHT][CIEX]*(pr[GRN][CIEY] - pr[BLU][CIEY]) -
285                            pr[WHT][CIEY]*(pr[GRN][CIEX] - pr[BLU][CIEX]) +
286                    pr[GRN][CIEX]*pr[BLU][CIEY] - pr[BLU][CIEX]*pr[GRN][CIEY] ) ;
287 +        if (CEQ(C_rD,0.))
288 +                return(0);
289          C_gD = (1./pr[WHT][CIEY]) *
290                          ( pr[WHT][CIEX]*(pr[BLU][CIEY] - pr[RED][CIEY]) -
291                            pr[WHT][CIEY]*(pr[BLU][CIEX] - pr[RED][CIEX]) -
292                    pr[RED][CIEX]*pr[BLU][CIEY] + pr[BLU][CIEX]*pr[RED][CIEY] ) ;
293 +        if (CEQ(C_gD,0.))
294 +                return(0);
295          C_bD = (1./pr[WHT][CIEY]) *
296                          ( pr[WHT][CIEX]*(pr[RED][CIEY] - pr[GRN][CIEY]) -
297                            pr[WHT][CIEY]*(pr[RED][CIEX] - pr[GRN][CIEX]) +
298                    pr[RED][CIEX]*pr[GRN][CIEY] - pr[GRN][CIEX]*pr[RED][CIEY] ) ;
299 <
299 >        if (CEQ(C_bD,0.))
300 >                return(0);
301          mat[0][0] = (pr[GRN][CIEY] - pr[BLU][CIEY] -
302                          pr[BLU][CIEX]*pr[GRN][CIEY] +
303                          pr[BLU][CIEY]*pr[GRN][CIEX])/C_rD ;
# Line 328 | Line 322 | register RGBPRIMS  pr;
322                          pr[RED][CIEX]*pr[GRN][CIEY])/C_bD ;
323          mat[2][2] = (pr[RED][CIEX]*pr[GRN][CIEY] -
324                          pr[GRN][CIEX]*pr[RED][CIEY])/C_bD ;
325 +        return(1);
326   }
327  
328  
329 < void
330 < comprgb2xyzmat(mat, pr)         /* compute conversion from RGB to CIE space */
331 < COLORMAT  mat;
332 < register RGBPRIMS  pr;
329 > int
330 > comprgb2xyzmat(                 /* compute conversion from RGB to CIE space */
331 > COLORMAT  mat,
332 > register RGBPRIMS  pr
333 > )
334   {
335          double  C_rD, C_gD, C_bD, D;
336  
337          if (pr == stdprims) {   /* can use rgb2xyzmat */
338                  cpcolormat(mat, rgb2xyzmat);
339 <                return;
339 >                return(1);
340          }
341 +        if (CEQ(pr[WHT][CIEX],0.) | CEQ(pr[WHT][CIEY],0.))
342 +                return(0);
343          C_rD = (1./pr[WHT][CIEY]) *
344                          ( pr[WHT][CIEX]*(pr[GRN][CIEY] - pr[BLU][CIEY]) -
345                            pr[WHT][CIEY]*(pr[GRN][CIEX] - pr[BLU][CIEX]) +
# Line 357 | Line 355 | register RGBPRIMS  pr;
355          D = pr[RED][CIEX]*(pr[GRN][CIEY] - pr[BLU][CIEY]) +
356                          pr[GRN][CIEX]*(pr[BLU][CIEY] - pr[RED][CIEY]) +
357                          pr[BLU][CIEX]*(pr[RED][CIEY] - pr[GRN][CIEY]) ;
358 +        if (CEQ(D,0.))
359 +                return(0);
360          mat[0][0] = pr[RED][CIEX]*C_rD/D;
361          mat[0][1] = pr[GRN][CIEX]*C_gD/D;
362          mat[0][2] = pr[BLU][CIEX]*C_bD/D;
# Line 366 | Line 366 | register RGBPRIMS  pr;
366          mat[2][0] = (1.-pr[RED][CIEX]-pr[RED][CIEY])*C_rD/D;
367          mat[2][1] = (1.-pr[GRN][CIEX]-pr[GRN][CIEY])*C_gD/D;
368          mat[2][2] = (1.-pr[BLU][CIEX]-pr[BLU][CIEY])*C_bD/D;
369 +        return(1);
370   }
371  
372  
373 < void
374 < comprgb2rgbmat(mat, pr1, pr2)   /* compute conversion from RGB1 to RGB2 */
375 < COLORMAT  mat;
376 < RGBPRIMS  pr1, pr2;
373 > int
374 > comprgb2rgbmat(                 /* compute conversion from RGB1 to RGB2 */
375 > COLORMAT  mat,
376 > RGBPRIMS  pr1,
377 > RGBPRIMS  pr2
378 > )
379   {
380          COLORMAT  pr1toxyz, xyztopr2;
381  
# Line 380 | Line 383 | RGBPRIMS  pr1, pr2;
383                  mat[0][0] = mat[1][1] = mat[2][2] = 1.0;
384                  mat[0][1] = mat[0][2] = mat[1][0] =
385                  mat[1][2] = mat[2][0] = mat[2][1] = 0.0;
386 <                return;
386 >                return(1);
387          }
388 <        comprgb2xyzmat(pr1toxyz, pr1);
389 <        compxyz2rgbmat(xyztopr2, pr2);
388 >        if (!comprgb2xyzmat(pr1toxyz, pr1))
389 >                return(0);
390 >        if (!compxyz2rgbmat(xyztopr2, pr2))
391 >                return(0);
392                                  /* combine transforms */
393          multcolormat(mat, pr1toxyz, xyztopr2);
394 +        return(1);
395   }
396  
397  
398 < void
399 < compxyzWBmat(mat, wht1, wht2)   /* CIE von Kries transform from wht1 to wht2 */
400 < COLORMAT  mat;
401 < float  wht1[2], wht2[2];
398 > int
399 > compxyzWBmat(                   /* CIE von Kries transform from wht1 to wht2 */
400 > COLORMAT  mat,
401 > float  wht1[2],
402 > float  wht2[2]
403 > )
404   {
405          COLOR   cw1, cw2;
406          if (XYEQ(wht1,wht2)) {
407                  mat[0][0] = mat[1][1] = mat[2][2] = 1.0;
408                  mat[0][1] = mat[0][2] = mat[1][0] =
409                  mat[1][2] = mat[2][0] = mat[2][1] = 0.0;
410 <                return;
410 >                return(1);
411          }
412 +        if (CEQ(wht1[CIEX],0.) | CEQ(wht1[CIEY],0.))
413 +                return(0);
414          cw1[RED] = wht1[CIEX]/wht1[CIEY];
415          cw1[GRN] = 1.;
416          cw1[BLU] = (1. - wht1[CIEX] - wht1[CIEY])/wht1[CIEY];
417          colortrans(cw1, vkmat, cw1);
418 +        if (CEQ(wht2[CIEX],0.) | CEQ(wht2[CIEY],0.))
419 +                return(0);
420          cw2[RED] = wht2[CIEX]/wht2[CIEY];
421          cw2[GRN] = 1.;
422          cw2[BLU] = (1. - wht2[CIEX] - wht2[CIEY])/wht2[CIEY];
423          colortrans(cw2, vkmat, cw2);
424 +        if (CEQ(cw1[RED],0.) | CEQ(cw1[GRN],0.) | CEQ(cw1[BLU],0.))
425 +                return(0);
426          mat[0][0] = cw2[RED]/cw1[RED];
427          mat[1][1] = cw2[GRN]/cw1[GRN];
428          mat[2][2] = cw2[BLU]/cw1[BLU];
# Line 416 | Line 430 | float  wht1[2], wht2[2];
430          mat[1][2] = mat[2][0] = mat[2][1] = 0.0;
431          multcolormat(mat, vkmat, mat);
432          multcolormat(mat, mat, ivkmat);
433 +        return(1);
434   }
435  
436  
437 < void
438 < compxyz2rgbWBmat(mat, pr)       /* von Kries conversion from CIE to RGB space */
439 < COLORMAT  mat;
440 < RGBPRIMS  pr;
437 > int
438 > compxyz2rgbWBmat(               /* von Kries conversion from CIE to RGB space */
439 > COLORMAT  mat,
440 > RGBPRIMS  pr
441 > )
442   {
443          COLORMAT        wbmat;
444  
445 <        compxyz2rgbmat(mat, pr);
445 >        if (!compxyz2rgbmat(mat, pr))
446 >                return(0);
447          if (XYEQ(pr[WHT],xyneu))
448 <                return;
449 <        compxyzWBmat(wbmat, xyneu, pr[WHT]);
448 >                return(1);
449 >        if (!compxyzWBmat(wbmat, xyneu, pr[WHT]))
450 >                return(0);
451          multcolormat(mat, wbmat, mat);
452 +        return(1);
453   }
454  
455 < void
456 < comprgb2xyzWBmat(mat, pr)       /* von Kries conversion from RGB to CIE space */
457 < COLORMAT  mat;
458 < RGBPRIMS  pr;
455 > int
456 > comprgb2xyzWBmat(               /* von Kries conversion from RGB to CIE space */
457 > COLORMAT  mat,
458 > RGBPRIMS  pr
459 > )
460   {
461          COLORMAT        wbmat;
462          
463 <        comprgb2xyzmat(mat, pr);
463 >        if (!comprgb2xyzmat(mat, pr))
464 >                return(0);
465          if (XYEQ(pr[WHT],xyneu))
466 <                return;
467 <        compxyzWBmat(wbmat, pr[WHT], xyneu);
466 >                return(1);
467 >        if (!compxyzWBmat(wbmat, pr[WHT], xyneu))
468 >                return(0);
469          multcolormat(mat, mat, wbmat);
470 +        return(1);
471   }
472  
473 < void
474 < comprgb2rgbWBmat(mat, pr1, pr2) /* von Kries conversion from RGB1 to RGB2 */
475 < COLORMAT  mat;
476 < RGBPRIMS  pr1, pr2;
473 > int
474 > comprgb2rgbWBmat(               /* von Kries conversion from RGB1 to RGB2 */
475 > COLORMAT  mat,
476 > RGBPRIMS  pr1,
477 > RGBPRIMS  pr2
478 > )
479   {
480          COLORMAT  pr1toxyz, xyztopr2, wbmat;
481  
# Line 458 | Line 483 | RGBPRIMS  pr1, pr2;
483                  mat[0][0] = mat[1][1] = mat[2][2] = 1.0;
484                  mat[0][1] = mat[0][2] = mat[1][0] =
485                  mat[1][2] = mat[2][0] = mat[2][1] = 0.0;
486 <                return;
486 >                return(1);
487          }
488 <        comprgb2xyzmat(pr1toxyz, pr1);
489 <        compxyzWBmat(wbmat, pr1[WHT], pr2[WHT]);
490 <        compxyz2rgbmat(xyztopr2, pr2);
488 >        if (!comprgb2xyzmat(pr1toxyz, pr1))
489 >                return(0);
490 >        if (!compxyzWBmat(wbmat, pr1[WHT], pr2[WHT]))
491 >                return(0);
492 >        if (!compxyz2rgbmat(xyztopr2, pr2))
493 >                return(0);
494                                  /* combine transforms */
495          multcolormat(mat, pr1toxyz, wbmat);
496          multcolormat(mat, mat, xyztopr2);
497 +        return(1);
498   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines