Move the sources to trunk
[opencv] / otherlibs / _graphics / include / OpenEXR / ImathColorAlgo.h
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
4 // Digital Ltd. LLC
5 // 
6 // All rights reserved.
7 // 
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met:
11 // *       Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // *       Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // *       Neither the name of Industrial Light & Magic nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission. 
20 // 
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 ///////////////////////////////////////////////////////////////////////////
34
35
36
37 #ifndef INCLUDED_IMATHCOLORALGO_H
38 #define INCLUDED_IMATHCOLORALGO_H
39
40
41 #include "ImathColor.h"
42 #include "ImathMath.h"
43 #include "ImathLimits.h"
44
45 namespace Imath {
46
47
48 //
49 //      Non-templated helper routines for color conversion.
50 //      These routines eliminate type warnings under g++.
51 //
52
53 Vec3<double>    hsv2rgb_d(const Vec3<double> &hsv);
54
55 Color4<double>  hsv2rgb_d(const Color4<double> &hsv);
56
57
58 Vec3<double>    rgb2hsv_d(const Vec3<double> &rgb);
59
60 Color4<double>  rgb2hsv_d(const Color4<double> &rgb);
61
62
63 //
64 //      Color conversion functions and general color algorithms
65 //
66 //      hsv2rgb(), rgb2hsv(), rgb2packed(), packed2rgb()
67 //      see each funtion definition for details.
68 //
69
70 template<class T> 
71 Vec3<T>  
72 hsv2rgb(const Vec3<T> &hsv)
73 {
74     if ( limits<T>::isIntegral() )
75     {
76         Vec3<double> v = Vec3<double>(hsv.x / double(limits<T>::max()),
77                                       hsv.y / double(limits<T>::max()),
78                                       hsv.z / double(limits<T>::max()));
79         Vec3<double> c = hsv2rgb_d(v);
80         return Vec3<T>((T) (c.x * limits<T>::max()),
81                        (T) (c.y * limits<T>::max()),
82                        (T) (c.z * limits<T>::max()));
83     }
84     else
85     {
86         Vec3<double> v = Vec3<double>(hsv.x, hsv.y, hsv.z);
87         Vec3<double> c = hsv2rgb_d(v);
88         return Vec3<T>((T) c.x, (T) c.y, (T) c.z);
89     }
90 }
91
92
93 template<class T> 
94 Color4<T>  
95 hsv2rgb(const Color4<T> &hsv)
96 {
97     if ( limits<T>::isIntegral() )
98     {
99         Color4<double> v = Color4<double>(hsv.r / float(limits<T>::max()),
100                                           hsv.g / float(limits<T>::max()),
101                                           hsv.b / float(limits<T>::max()),
102                                           hsv.a / float(limits<T>::max()));
103         Color4<double> c = hsv2rgb_d(v);
104         return Color4<T>((T) (c.r * limits<T>::max()),
105                          (T) (c.g * limits<T>::max()),
106                          (T) (c.b * limits<T>::max()),
107                          (T) (c.a * limits<T>::max()));
108     }
109     else
110     {
111         Color4<double> v = Color4<double>(hsv.r, hsv.g, hsv.g, hsv.a);
112         Color4<double> c = hsv2rgb_d(v);
113         return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);
114     }
115 }
116
117
118 template<class T> 
119 Vec3<T>  
120 rgb2hsv(const Vec3<T> &rgb)
121 {
122     if ( limits<T>::isIntegral() )
123     {
124         Vec3<double> v = Vec3<double>(rgb.x / double(limits<T>::max()),
125                                       rgb.y / double(limits<T>::max()),
126                                       rgb.z / double(limits<T>::max()));
127         Vec3<double> c = rgb2hsv_d(v);
128         return Vec3<T>((T) (c.x * limits<T>::max()),
129                        (T) (c.y * limits<T>::max()),
130                        (T) (c.z * limits<T>::max()));
131     }
132     else
133     {
134         Vec3<double> v = Vec3<double>(rgb.x, rgb.y, rgb.z);
135         Vec3<double> c = rgb2hsv_d(v);
136         return Vec3<T>((T) c.x, (T) c.y, (T) c.z);
137     }
138 }
139
140
141 template<class T> 
142 Color4<T>  
143 rgb2hsv(const Color4<T> &rgb)
144 {
145     if ( limits<T>::isIntegral() )
146     {
147         Color4<double> v = Color4<double>(rgb.r / float(limits<T>::max()),
148                                           rgb.g / float(limits<T>::max()),
149                                           rgb.b / float(limits<T>::max()),
150                                           rgb.a / float(limits<T>::max()));
151         Color4<double> c = rgb2hsv_d(v);
152         return Color4<T>((T) (c.r * limits<T>::max()),
153                          (T) (c.g * limits<T>::max()),
154                          (T) (c.b * limits<T>::max()),
155                          (T) (c.a * limits<T>::max()));
156     }
157     else
158     {
159         Color4<double> v = Color4<double>(rgb.r, rgb.g, rgb.g, rgb.a);
160         Color4<double> c = rgb2hsv_d(v);
161         return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);
162     }
163 }
164
165 template <class T>
166 PackedColor
167 rgb2packed(const Vec3<T> &c)
168 {
169     if ( limits<T>::isIntegral() )
170     {
171         float x = c.x / float(limits<T>::max());
172         float y = c.y / float(limits<T>::max());
173         float z = c.z / float(limits<T>::max());
174         return rgb2packed( V3f(x,y,z) );
175     }
176     else
177     {
178         return (  (PackedColor) (c.x * 255)             |
179                 (((PackedColor) (c.y * 255)) << 8)      |
180                 (((PackedColor) (c.z * 255)) << 16)     | 0xFF000000 );
181     }
182 }
183
184 template <class T>
185 PackedColor
186 rgb2packed(const Color4<T> &c)
187 {
188     if ( limits<T>::isIntegral() )
189     {
190         float r = c.r / float(limits<T>::max());
191         float g = c.g / float(limits<T>::max());
192         float b = c.b / float(limits<T>::max());
193         float a = c.a / float(limits<T>::max());
194         return rgb2packed( C4f(r,g,b,a) );
195     }
196     else
197     {
198         return (  (PackedColor) (c.r * 255)             |
199                 (((PackedColor) (c.g * 255)) << 8)      |
200                 (((PackedColor) (c.b * 255)) << 16)     |
201                 (((PackedColor) (c.a * 255)) << 24));
202     }
203 }
204
205 //
206 //      This guy can't return the result because the template
207 //      parameter would not be in the function signiture. So instead,
208 //      its passed in as an argument.
209 //
210
211 template <class T>
212 void
213 packed2rgb(PackedColor packed, Vec3<T> &out)
214 {
215     if ( limits<T>::isIntegral() )
216     {
217         T f = limits<T>::max() / ((PackedColor)0xFF);
218         out.x =  (packed &     0xFF) * f;
219         out.y = ((packed &   0xFF00) >>  8) * f;
220         out.z = ((packed & 0xFF0000) >> 16) * f;
221     }
222     else
223     {
224         T f = T(1) / T(255);
225         out.x =  (packed &     0xFF) * f;
226         out.y = ((packed &   0xFF00) >>  8) * f;
227         out.z = ((packed & 0xFF0000) >> 16) * f;
228     }
229 }
230
231 template <class T>
232 void
233 packed2rgb(PackedColor packed, Color4<T> &out)
234 {
235     if ( limits<T>::isIntegral() )
236     {
237         T f = limits<T>::max() / ((PackedColor)0xFF);
238         out.r =  (packed &       0xFF) * f;
239         out.g = ((packed &     0xFF00) >>  8) * f;
240         out.b = ((packed &   0xFF0000) >> 16) * f;
241         out.a = ((packed & 0xFF000000) >> 24) * f;
242     }
243     else
244     {
245         T f = T(1) / T(255);
246         out.r =  (packed &       0xFF) * f;
247         out.g = ((packed &     0xFF00) >>  8) * f;
248         out.b = ((packed &   0xFF0000) >> 16) * f;
249         out.a = ((packed & 0xFF000000) >> 24) * f;
250     }
251 }
252
253
254 } // namespace Imath
255
256 #endif