1 /*******************************************************************************
2  * colutils.cpp
3  *
4  * This module implements the utility functions for colors.
5  *
6  * ---------------------------------------------------------------------------
7  * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
8  * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
9  *
10  * POV-Ray is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Affero General Public License as
12  * published by the Free Software Foundation, either version 3 of the
13  * License, or (at your option) any later version.
14  *
15  * POV-Ray is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Affero General Public License for more details.
19  *
20  * You should have received a copy of the GNU Affero General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  * ---------------------------------------------------------------------------
23  * POV-Ray is based on the popular DKB raytracer version 2.12.
24  * DKBTrace was originally written by David K. Buck.
25  * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
26  * ---------------------------------------------------------------------------
27  * $File: //depot/public/povray/3.x/source/backend/colour/colutils.cpp $
28  * $Revision: #1 $
29  * $Change: 6069 $
30  * $DateTime: 2013/11/06 11:59:40 $
31  * $Author: chrisc $
32  *******************************************************************************/
33 
34 // frame.h must always be the first POV file included (pulls in platform config)
35 #include "backend/frame.h"
36 #include "backend/colour/colutils.h"
37 #include "backend/colour/colour.h"
38 #include "backend/math/vector.h"
39 
40 // this must be the last file included
41 #include "base/povdebug.h"
42 
43 namespace pov
44 {
45 
46 /*****************************************************************************
47 *
48 * FUNCTION
49 *
50 *   colour2photonRgbe
51 *
52 * INPUT
53 *
54 *
55 * OUTPUT
56 *
57 *
58 * RETURNS
59 *
60 * AUTHOR
61 *
62   originally float2rgb
63 
64   Bruce Walter - http://www.graphics.cornell.edu/online/formats/rgbe/
65 
66  This file contains code to read and write four byte rgbe file format
67  developed by Greg Ward.  It handles the conversions between rgbe and
68  pixels consisting of floats.  The data is assumed to be an array of floats.
69  By default there are three floats per pixel in the order red, green, blue.
70  (RGBE_DATA_??? values control this.)  Only the mimimal header reading and
71  writing is implemented.  Each routine does error checking and will return
72  a status value as defined below.  This code is intended as a skeleton so
73  feel free to modify it to suit your needs.
74 
75  (Place notice here if you modified the code.)
76  posted to http://www.graphics.cornell.edu/~bjw/
77  written by Bruce Walter  (bjw@graphics.cornell.edu)  5/26/95
78  based on code written by Greg Ward
79 *
80 * DESCRIPTION
81 *
82 *   standard conversion from float pixels to rgbe pixels.
83 *
84 * CHANGES
85 *
86 *  May 25, 20020 - incorporated into POV-Ray - Nathan Kopp
87 *                  For photons, our exponent will almost always be
88 *                  negative, so we use e+250 to get a larger range of negative
89 *                  exponents.
90 *
91 ******************************************************************************/
colour2photonRgbe(SMALL_COLOUR rgbe,const RGBColour & c)92 void colour2photonRgbe(SMALL_COLOUR rgbe, const RGBColour& c)
93 {
94 	float v;
95 	int e;
96 
97 	v = c[pRED];
98 	if (c[pGREEN] > v) v = c[pGREEN];
99 	if (c[pBLUE] > v) v = c[pBLUE];
100 	if (v < 1e-32) {
101 		rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
102 	}
103 	else {
104 		v = frexp(v,&e) * 256.0/v;
105 		rgbe[0] = (unsigned char) (c[pRED] * v);
106 		rgbe[1] = (unsigned char) (c[pGREEN] * v);
107 		rgbe[2] = (unsigned char) (c[pBLUE] * v);
108 		//rgbe[3] = (unsigned char) (e + 128);
109 		rgbe[3] = (unsigned char) (e + 250);
110 	}
111 }
112 
113 /*****************************************************************************
114 *
115 * FUNCTION
116 *
117 *   photonRgbe2colour
118 *
119 * INPUT
120 *
121 *
122 * OUTPUT
123 *
124 *
125 * RETURNS
126 *
127 * AUTHOR
128 *
129   originally float2rgb
130 
131   Bruce Walter - http://www.graphics.cornell.edu/online/formats/rgbe/
132 
133  This file contains code to read and write four byte rgbe file format
134  developed by Greg Ward.  It handles the conversions between rgbe and
135  pixels consisting of floats.  The data is assumed to be an array of floats.
136  By default there are three floats per pixel in the order red, green, blue.
137  (RGBE_DATA_??? values control this.)  Only the mimimal header reading and
138  writing is implemented.  Each routine does error checking and will return
139  a status value as defined below.  This code is intended as a skeleton so
140  feel free to modify it to suit your needs.
141 
142  (Place notice here if you modified the code.)
143  posted to http://www.graphics.cornell.edu/~bjw/
144  written by Bruce Walter  (bjw@graphics.cornell.edu)  5/26/95
145  based on code written by Greg Ward
146 *
147 * DESCRIPTION
148 *
149 *   standard conversion from rgbe to float pixels
150 *   note: Ward uses ldexp(col+0.5,exp-(128+8)).  However we wanted pixels
151 *         in the range [0,1] to map back into the range [0,1].
152 *
153 * CHANGES
154 *
155 *  May 25, 20020 - incorporated into POV-Ray - Nathan Kopp
156 *                  For photons, our exponent will almost always be
157 *                  negative, so we use e+250 to get a larger range of negative
158 *                  exponents.
159 *
160 ******************************************************************************/
photonRgbe2colour(RGBColour & c,const SMALL_COLOUR rgbe)161 void photonRgbe2colour(RGBColour& c, const SMALL_COLOUR rgbe)
162 {
163 	float f;
164 
165 	if (rgbe[3]) {   /*nonzero pixel*/
166 		f = ldexp(1.0,rgbe[3]-(int)(250+8));
167 		c[pRED] = rgbe[0] * f;
168 		c[pGREEN] = rgbe[1] * f;
169 		c[pBLUE] = rgbe[2] * f;
170 	}
171 	else
172 		c.clear();
173 }
174 
175 }
176