PBRT
/home/felix/UBC/projects/AdaptiveLightfieldSampling/pbrt_v2/src/3rdparty/ilmbase-1.0.2/ImathColorAlgo.h
00001 
00002 //
00003 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
00004 // Digital Ltd. LLC
00005 // 
00006 // All rights reserved.
00007 // 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions are
00010 // met:
00011 // *       Redistributions of source code must retain the above copyright
00012 // notice, this list of conditions and the following disclaimer.
00013 // *       Redistributions in binary form must reproduce the above
00014 // copyright notice, this list of conditions and the following disclaimer
00015 // in the documentation and/or other materials provided with the
00016 // distribution.
00017 // *       Neither the name of Industrial Light & Magic nor the names of
00018 // its contributors may be used to endorse or promote products derived
00019 // from this software without specific prior written permission. 
00020 // 
00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 //
00034 
00035 
00036 
00037 #ifndef INCLUDED_IMATHCOLORALGO_H
00038 #define INCLUDED_IMATHCOLORALGO_H
00039 
00040 
00041 #include "ImathColor.h"
00042 #include "ImathMath.h"
00043 #include "ImathLimits.h"
00044 
00045 namespace Imath {
00046 
00047 
00048 //
00049 //      Non-templated helper routines for color conversion.
00050 //      These routines eliminate type warnings under g++.
00051 //
00052 
00053 Vec3<double>    hsv2rgb_d(const Vec3<double> &hsv);
00054 
00055 Color4<double>  hsv2rgb_d(const Color4<double> &hsv);
00056 
00057 
00058 Vec3<double>    rgb2hsv_d(const Vec3<double> &rgb);
00059 
00060 Color4<double>  rgb2hsv_d(const Color4<double> &rgb);
00061 
00062 
00063 //
00064 //      Color conversion functions and general color algorithms
00065 //
00066 //      hsv2rgb(), rgb2hsv(), rgb2packed(), packed2rgb()
00067 //      see each funtion definition for details.
00068 //
00069 
00070 template<class T> 
00071 Vec3<T>  
00072 hsv2rgb(const Vec3<T> &hsv)
00073 {
00074     if ( limits<T>::isIntegral() )
00075     {
00076         Vec3<double> v = Vec3<double>(hsv.x / double(limits<T>::max()),
00077                                       hsv.y / double(limits<T>::max()),
00078                                       hsv.z / double(limits<T>::max()));
00079         Vec3<double> c = hsv2rgb_d(v);
00080         return Vec3<T>((T) (c.x * limits<T>::max()),
00081                        (T) (c.y * limits<T>::max()),
00082                        (T) (c.z * limits<T>::max()));
00083     }
00084     else
00085     {
00086         Vec3<double> v = Vec3<double>(hsv.x, hsv.y, hsv.z);
00087         Vec3<double> c = hsv2rgb_d(v);
00088         return Vec3<T>((T) c.x, (T) c.y, (T) c.z);
00089     }
00090 }
00091 
00092 
00093 template<class T> 
00094 Color4<T>  
00095 hsv2rgb(const Color4<T> &hsv)
00096 {
00097     if ( limits<T>::isIntegral() )
00098     {
00099         Color4<double> v = Color4<double>(hsv.r / float(limits<T>::max()),
00100                                           hsv.g / float(limits<T>::max()),
00101                                           hsv.b / float(limits<T>::max()),
00102                                           hsv.a / float(limits<T>::max()));
00103         Color4<double> c = hsv2rgb_d(v);
00104         return Color4<T>((T) (c.r * limits<T>::max()),
00105                          (T) (c.g * limits<T>::max()),
00106                          (T) (c.b * limits<T>::max()),
00107                          (T) (c.a * limits<T>::max()));
00108     }
00109     else
00110     {
00111         Color4<double> v = Color4<double>(hsv.r, hsv.g, hsv.b, hsv.a);
00112         Color4<double> c = hsv2rgb_d(v);
00113         return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);
00114     }
00115 }
00116 
00117 
00118 template<class T> 
00119 Vec3<T>  
00120 rgb2hsv(const Vec3<T> &rgb)
00121 {
00122     if ( limits<T>::isIntegral() )
00123     {
00124         Vec3<double> v = Vec3<double>(rgb.x / double(limits<T>::max()),
00125                                       rgb.y / double(limits<T>::max()),
00126                                       rgb.z / double(limits<T>::max()));
00127         Vec3<double> c = rgb2hsv_d(v);
00128         return Vec3<T>((T) (c.x * limits<T>::max()),
00129                        (T) (c.y * limits<T>::max()),
00130                        (T) (c.z * limits<T>::max()));
00131     }
00132     else
00133     {
00134         Vec3<double> v = Vec3<double>(rgb.x, rgb.y, rgb.z);
00135         Vec3<double> c = rgb2hsv_d(v);
00136         return Vec3<T>((T) c.x, (T) c.y, (T) c.z);
00137     }
00138 }
00139 
00140 
00141 template<class T> 
00142 Color4<T>  
00143 rgb2hsv(const Color4<T> &rgb)
00144 {
00145     if ( limits<T>::isIntegral() )
00146     {
00147         Color4<double> v = Color4<double>(rgb.r / float(limits<T>::max()),
00148                                           rgb.g / float(limits<T>::max()),
00149                                           rgb.b / float(limits<T>::max()),
00150                                           rgb.a / float(limits<T>::max()));
00151         Color4<double> c = rgb2hsv_d(v);
00152         return Color4<T>((T) (c.r * limits<T>::max()),
00153                          (T) (c.g * limits<T>::max()),
00154                          (T) (c.b * limits<T>::max()),
00155                          (T) (c.a * limits<T>::max()));
00156     }
00157     else
00158     {
00159         Color4<double> v = Color4<double>(rgb.r, rgb.g, rgb.b, rgb.a);
00160         Color4<double> c = rgb2hsv_d(v);
00161         return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);
00162     }
00163 }
00164 
00165 template <class T>
00166 PackedColor
00167 rgb2packed(const Vec3<T> &c)
00168 {
00169     if ( limits<T>::isIntegral() )
00170     {
00171         float x = c.x / float(limits<T>::max());
00172         float y = c.y / float(limits<T>::max());
00173         float z = c.z / float(limits<T>::max());
00174         return rgb2packed( V3f(x,y,z) );
00175     }
00176     else
00177     {
00178         return (  (PackedColor) (c.x * 255)             |
00179                 (((PackedColor) (c.y * 255)) << 8)      |
00180                 (((PackedColor) (c.z * 255)) << 16)     | 0xFF000000 );
00181     }
00182 }
00183 
00184 template <class T>
00185 PackedColor
00186 rgb2packed(const Color4<T> &c)
00187 {
00188     if ( limits<T>::isIntegral() )
00189     {
00190         float r = c.r / float(limits<T>::max());
00191         float g = c.g / float(limits<T>::max());
00192         float b = c.b / float(limits<T>::max());
00193         float a = c.a / float(limits<T>::max());
00194         return rgb2packed( C4f(r,g,b,a) );
00195     }
00196     else
00197     {
00198         return (  (PackedColor) (c.r * 255)             |
00199                 (((PackedColor) (c.g * 255)) << 8)      |
00200                 (((PackedColor) (c.b * 255)) << 16)     |
00201                 (((PackedColor) (c.a * 255)) << 24));
00202     }
00203 }
00204 
00205 //
00206 //      This guy can't return the result because the template
00207 //      parameter would not be in the function signiture. So instead,
00208 //      its passed in as an argument.
00209 //
00210 
00211 template <class T>
00212 void
00213 packed2rgb(PackedColor packed, Vec3<T> &out)
00214 {
00215     if ( limits<T>::isIntegral() )
00216     {
00217         T f = limits<T>::max() / ((PackedColor)0xFF);
00218         out.x =  (packed &     0xFF) * f;
00219         out.y = ((packed &   0xFF00) >>  8) * f;
00220         out.z = ((packed & 0xFF0000) >> 16) * f;
00221     }
00222     else
00223     {
00224         T f = T(1) / T(255);
00225         out.x =  (packed &     0xFF) * f;
00226         out.y = ((packed &   0xFF00) >>  8) * f;
00227         out.z = ((packed & 0xFF0000) >> 16) * f;
00228     }
00229 }
00230 
00231 template <class T>
00232 void
00233 packed2rgb(PackedColor packed, Color4<T> &out)
00234 {
00235     if ( limits<T>::isIntegral() )
00236     {
00237         T f = limits<T>::max() / ((PackedColor)0xFF);
00238         out.r =  (packed &       0xFF) * f;
00239         out.g = ((packed &     0xFF00) >>  8) * f;
00240         out.b = ((packed &   0xFF0000) >> 16) * f;
00241         out.a = ((packed & 0xFF000000) >> 24) * f;
00242     }
00243     else
00244     {
00245         T f = T(1) / T(255);
00246         out.r =  (packed &       0xFF) * f;
00247         out.g = ((packed &     0xFF00) >>  8) * f;
00248         out.b = ((packed &   0xFF0000) >> 16) * f;
00249         out.a = ((packed & 0xFF000000) >> 24) * f;
00250     }
00251 }
00252 
00253 
00254 } // namespace Imath
00255 
00256 #endif