TuttleOFX  1
temperature.hpp
Go to the documentation of this file.
00001 #ifndef _TERRY_COLOR_TEMPERATURE_HPP_
00002 #define _TERRY_COLOR_TEMPERATURE_HPP_
00003 
00004 #include <terry/copy.hpp>
00005 
00006 namespace terry {
00007 namespace color {
00008 
00009 /**
00010  * @bief All supported temperatures
00011  */
00012 namespace temperature {
00013 struct T_A {};
00014 struct T_B {};
00015 struct T_C {};
00016 struct T_D50 {};
00017 struct T_D55 {};
00018 struct T_D58 {};
00019 struct T_D65 {};
00020 struct T_D75 {};
00021 struct T_9300 {};
00022 struct T_E {};
00023 struct T_F2 {};
00024 struct T_F7 {};
00025 struct T_F11 {};
00026 struct T_DCIP3 {};
00027 
00028 // we use D65 as the intermediate temperature color
00029 typedef T_D65 T_INTER;
00030 }
00031 
00032 
00033 /// @brief change the color temperature
00034 template< typename Channel,
00035           class IN,
00036           class OUT >
00037 struct channel_color_temperature_t : public std::binary_function<Channel, Channel, Channel>
00038 {
00039         typedef typename floating_channel_type_t<Channel>::type T;
00040         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00041         typedef typename channel_traits<Channel>::reference ChannelRef;
00042 
00043         // This class implementation must be used only:
00044         // * with IN != OUT
00045         BOOST_STATIC_ASSERT(( ! boost::is_same<IN, OUT>::value )); // Must use channel_color_temperature_t<Channel, INOUT> !
00046         // * IN and OUT must be other temperature mode than T_INTER
00047         //   For each temperature mode, you have to specialize: TemperatureMode -> T_INTER and T_INTER -> TemperatureMode
00048         BOOST_STATIC_ASSERT(( ! boost::is_same<IN, temperature::T_INTER>::value )); // The conversion IN to T_INTER is not implemented !
00049         BOOST_STATIC_ASSERT(( ! boost::is_same<OUT, temperature::T_INTER>::value )); // The conversion T_INTER to OUT is not implemented !
00050 
00051         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00052         {
00053                 Channel inter;
00054                 // IN -> T_INTER
00055                 channel_color_temperature_t<Channel, IN, temperature::T_INTER>( _in, temperature::T_INTER() )( src, inter );
00056                 // T_INTER -> OUT
00057                 return channel_color_temperature_t<Channel, temperature::T_INTER, OUT>( temperature::T_INTER(), _out )( inter, dst );
00058         }
00059 };
00060 
00061 template< typename Channel,
00062           class INOUT >
00063 struct channel_color_temperature_t<Channel, INOUT, INOUT> : public std::binary_function<Channel, Channel, Channel>
00064 {
00065         typedef typename floating_channel_type_t<Channel>::type T;
00066         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00067         typedef typename channel_traits<Channel>::reference ChannelRef;
00068 
00069         const INOUT& _in;
00070         const INOUT& _out;
00071 
00072         channel_color_temperature_t( const INOUT& in, const INOUT& out )
00073         : _in(in)
00074         , _out(out)
00075         {}
00076 
00077         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00078         {
00079                 return dst = Channel(src);
00080         }
00081 };
00082 
00083 ////////////////////////////////////////////////////////////////////////////////
00084 // T_A //
00085 
00086 /**
00087  * @brief 
00088  */
00089 template< typename Channel >
00090 struct channel_color_temperature_t<Channel, temperature::T_A, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00091 {
00092         typedef typename floating_channel_type_t<Channel>::type T;
00093         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00094         typedef typename channel_traits<Channel>::reference ChannelRef;
00095 
00096         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00097         {
00098                 get_color( dst, red_t()   )     =  1.84520578f * get_color( src, red_t() ) + 0.00000009f * get_color( src, green_t() ) + 0.00000002 * get_color( src, blue_t() );
00099                 get_color( dst, green_t() )     = -0.00000005f * get_color( src, red_t() ) + 0.82607192f * get_color( src, green_t() ) + 0.00000000 * get_color( src, blue_t() );
00100                 get_color( dst, blue_t()  )     =  0.00000001f * get_color( src, red_t() ) - 0.00000001f * get_color( src, green_t() ) + 0.23326041 * get_color( src, blue_t() );
00101                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00102                 return dst;
00103         }
00104 };
00105 
00106 /**
00107  * @brief 
00108  */
00109 template< typename Channel >
00110 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_A> : public std::binary_function<Channel, Channel, Channel>
00111 {
00112         typedef typename floating_channel_type_t<Channel>::type T;
00113         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00114         typedef typename channel_traits<Channel>::reference ChannelRef;
00115 
00116         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00117         {
00118                 get_color( dst, red_t()   )     =  0.54194504f * get_color( src, red_t() ) + 0.00000004f * get_color( src, green_t() ) + 0.00000000 * get_color( src, blue_t() );
00119                 get_color( dst, green_t() )     = +0.00000008f * get_color( src, red_t() ) + 1.21054840f * get_color( src, green_t() ) + 0.00000001 * get_color( src, blue_t() );
00120                 get_color( dst, blue_t()  )     = -0.00000001f * get_color( src, red_t() ) - 0.00000006f * get_color( src, green_t() ) + 0.85470724 * get_color( src, blue_t() );
00121                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00122                 return dst;
00123         }
00124 
00125 };
00126 
00127 
00128 ////////////////////////////////////////////////////////////////////////////////
00129 // T_B //
00130 
00131 /**
00132  * @brief
00133  */
00134 template< typename Channel >
00135 struct channel_color_temperature_t<Channel, temperature::T_B, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00136 {
00137         typedef typename floating_channel_type_t<Channel>::type T;
00138         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00139         typedef typename channel_traits<Channel>::reference ChannelRef;
00140 
00141         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00142         {
00143                 get_color( dst, red_t()   )     =  1.24874067f * get_color( src, red_t() ) + 0.00000004f * get_color( src, green_t() ) + 0.00000003 * get_color( src, blue_t() );
00144                 get_color( dst, green_t() )     = -0.00000002f * get_color( src, red_t() ) + 0.95096886f * get_color( src, green_t() ) + 0.00000001 * get_color( src, blue_t() );
00145                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) - 0.00000001f * get_color( src, green_t() ) + 0.75399793 * get_color( src, blue_t() );
00146                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00147                 return dst;
00148         }
00149 };
00150 
00151 /**
00152  * @brief
00153  */
00154 template< typename Channel >
00155 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_B> : public std::binary_function<Channel, Channel, Channel>
00156 {
00157         typedef typename floating_channel_type_t<Channel>::type T;
00158         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00159         typedef typename channel_traits<Channel>::reference ChannelRef;
00160 
00161         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00162         {
00163                 get_color( dst, red_t()   )     =  0.80080682f * get_color( src, red_t() ) + 0.00000004f * get_color( src, green_t() ) - 0.00000006 * get_color( src, blue_t() );
00164                 get_color( dst, green_t() )     =  0.00000008f * get_color( src, red_t() ) + 1.05155921f * get_color( src, green_t() ) + 0.00000001 * get_color( src, blue_t() );
00165                 get_color( dst, blue_t()  )     =  0.00000001f * get_color( src, red_t() ) + 0.00000003f * get_color( src, green_t() ) + 1.32802486 * get_color( src, blue_t() );
00166                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00167                 return dst;
00168         }
00169 
00170 };
00171 
00172 
00173 ////////////////////////////////////////////////////////////////////////////////
00174 // T_C //
00175 
00176 /**
00177  * @brief
00178  */
00179 template< typename Channel >
00180 struct channel_color_temperature_t<Channel, temperature::T_C, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00181 {
00182         typedef typename floating_channel_type_t<Channel>::type T;
00183         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00184         typedef typename channel_traits<Channel>::reference ChannelRef;
00185 
00186         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00187         {
00188                 get_color( dst, red_t()   )     =  1.05152202f * get_color( src, red_t() ) + 0.00000017f * get_color( src, green_t() ) + 0.00000018 * get_color( src, blue_t() );
00189                 get_color( dst, green_t() )     = -0.00000002f * get_color( src, red_t() ) + 0.97455227f * get_color( src, green_t() ) - 0.00000001 * get_color( src, blue_t() );
00190                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) - 0.00000001f * get_color( src, green_t() ) + 1.10034835 * get_color( src, blue_t() );
00191                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00192                 return dst;
00193         }
00194 };
00195 
00196 /**
00197  * @brief
00198  */
00199 template< typename Channel >
00200 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_C> : public std::binary_function<Channel, Channel, Channel>
00201 {
00202         typedef typename floating_channel_type_t<Channel>::type T;
00203         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00204         typedef typename channel_traits<Channel>::reference ChannelRef;
00205 
00206         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00207         {
00208                 get_color( dst, red_t()   )     =  0.95100260f * get_color( src, red_t() ) + 0.00000006f * get_color( src, green_t() ) + 0.00000003 * get_color( src, blue_t() );
00209                 get_color( dst, green_t() )     = -0.00000002f * get_color( src, red_t() ) + 1.02611196f * get_color( src, green_t() ) + 0.00000000 * get_color( src, blue_t() );
00210                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) + 0.00000001f * get_color( src, green_t() ) + 0.90880305 * get_color( src, blue_t() );
00211                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00212                 return dst;
00213         }
00214 
00215 };
00216 
00217 
00218 
00219 ////////////////////////////////////////////////////////////////////////////////
00220 // T_D50 //
00221 
00222 /**
00223  * @brief
00224  */
00225 template< typename Channel >
00226 struct channel_color_temperature_t<Channel, temperature::T_D50, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00227 {
00228         typedef typename floating_channel_type_t<Channel>::type T;
00229         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00230         typedef typename channel_traits<Channel>::reference ChannelRef;
00231 
00232         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00233         {
00234                 get_color( dst, red_t()   )     =  1.17609382f * get_color( src, red_t() ) + 0.00000007f * get_color( src, green_t() ) + 0.00000003 * get_color( src, blue_t() );
00235                 get_color( dst, green_t() )     = -0.00000006f * get_color( src, red_t() ) + 0.97570127f * get_color( src, green_t() ) + 0.00000001 * get_color( src, blue_t() );
00236                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) + 0.00000000f * get_color( src, green_t() ) + 0.72197068 * get_color( src, blue_t() );
00237                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00238                 return dst;
00239         }
00240 };
00241 
00242 /**
00243  * @brief
00244  */
00245 template< typename Channel >
00246 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_D50> : public std::binary_function<Channel, Channel, Channel>
00247 {
00248         typedef typename floating_channel_type_t<Channel>::type T;
00249         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00250         typedef typename channel_traits<Channel>::reference ChannelRef;
00251 
00252         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00253         {
00254                 get_color( dst, red_t()   )     =  0.85027254f * get_color( src, red_t() ) + 0.00000001f * get_color( src, green_t() ) + 0.00000000 * get_color( src, blue_t() );
00255                 get_color( dst, green_t() )     = -0.00000001f * get_color( src, red_t() ) + 1.02490389f * get_color( src, green_t() ) - 0.00000004 * get_color( src, blue_t() );
00256                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) + 0.00000001f * get_color( src, green_t() ) + 1.38509774 * get_color( src, blue_t() );
00257                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00258                 return dst;
00259         }
00260 
00261 };
00262 
00263 
00264 ////////////////////////////////////////////////////////////////////////////////
00265 // T_D55 //
00266 
00267 /**
00268  * @brief
00269  */
00270 template< typename Channel >
00271 struct channel_color_temperature_t<Channel, temperature::T_D55, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00272 {
00273         typedef typename floating_channel_type_t<Channel>::type T;
00274         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00275         typedef typename channel_traits<Channel>::reference ChannelRef;
00276 
00277         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00278         {
00279                 get_color( dst, red_t()   )     =  1.10405362f * get_color( src, red_t() ) + 0.00000012f * get_color( src, green_t() ) + 0.00000006 * get_color( src, blue_t() );
00280                 get_color( dst, green_t() )     = -0.00000002f * get_color( src, red_t() ) + 0.98688960f * get_color( src, green_t() ) + 0.00000001 * get_color( src, blue_t() );
00281                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) - 0.00000001f * get_color( src, green_t() ) + 0.82335168 * get_color( src, blue_t() );
00282                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00283                 return dst;
00284         }
00285 };
00286 
00287 /**
00288  * @brief
00289  */
00290 template< typename Channel >
00291 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_D55> : public std::binary_function<Channel, Channel, Channel>
00292 {
00293         typedef typename floating_channel_type_t<Channel>::type T;
00294         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00295         typedef typename channel_traits<Channel>::reference ChannelRef;
00296 
00297         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00298         {
00299                 get_color( dst, red_t()   )     =  0.90575325f * get_color( src, red_t() ) + 0.00000000f * get_color( src, green_t() ) + 0.00000000 * get_color( src, blue_t() );
00300                 get_color( dst, green_t() )     = -0.00000002f * get_color( src, red_t() ) + 1.01328468f * get_color( src, green_t() ) - 0.00000004 * get_color( src, blue_t() );
00301                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) + 0.00000001f * get_color( src, green_t() ) + 1.21454775 * get_color( src, blue_t() );
00302                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00303                 return dst;
00304         }
00305 
00306 };
00307 
00308 
00309 ////////////////////////////////////////////////////////////////////////////////
00310 // T_D58 //
00311 
00312 /**
00313  * @brief
00314  */
00315 template< typename Channel >
00316 struct channel_color_temperature_t<Channel, temperature::T_D58, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00317 {
00318         typedef typename floating_channel_type_t<Channel>::type T;
00319         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00320         typedef typename channel_traits<Channel>::reference ChannelRef;
00321 
00322         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00323         {
00324                 get_color( dst, red_t()   )     =  1.06815648f * get_color( src, red_t() ) + 0.00000016f * get_color( src, green_t() ) + 0.00000003 * get_color( src, blue_t() );
00325                 get_color( dst, green_t() )     = -0.00000004f * get_color( src, red_t() ) + 0.99201381f * get_color( src, green_t() ) + 0.00000001 * get_color( src, blue_t() );
00326                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) + 0.00000000f * get_color( src, green_t() ) + 0.87833548 * get_color( src, blue_t() );
00327                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00328                 return dst;
00329         }
00330 };
00331 
00332 /**
00333  * @brief
00334  */
00335 template< typename Channel >
00336 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_D58> : public std::binary_function<Channel, Channel, Channel>
00337 {
00338         typedef typename floating_channel_type_t<Channel>::type T;
00339         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00340         typedef typename channel_traits<Channel>::reference ChannelRef;
00341 
00342         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00343         {
00344                 get_color( dst, red_t()   )     =  0.93619251f * get_color( src, red_t() ) + 0.00000009f * get_color( src, green_t() ) + 0.00000000 * get_color( src, blue_t() );
00345                 get_color( dst, green_t() )     =  0.00000001f * get_color( src, red_t() ) + 1.00805032f * get_color( src, green_t() ) - 0.00000001 * get_color( src, blue_t() );
00346                 get_color( dst, blue_t()  )     = -0.00000001f * get_color( src, red_t() ) - 0.00000001f * get_color( src, green_t() ) + 1.13851726 * get_color( src, blue_t() );
00347                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00348                 return dst;
00349         }
00350 
00351 };
00352 
00353 
00354 
00355 
00356 ////////////////////////////////////////////////////////////////////////////////
00357 // T_D65 //
00358 
00359 /**
00360  * @brief
00361  */
00362 template< typename Channel >
00363 struct channel_color_temperature_t<Channel, temperature::T_D65, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00364 {
00365         typedef typename floating_channel_type_t<Channel>::type T;
00366         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00367         typedef typename channel_traits<Channel>::reference ChannelRef;
00368 
00369         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00370         {
00371                 get_color( dst, red_t()   )     =  get_color( src, red_t  () );
00372                 get_color( dst, green_t() )     =  get_color( src, green_t() );
00373                 get_color( dst, blue_t()  )     =  get_color( src, blue_t () );
00374                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00375                 return dst;
00376         }
00377 };
00378 
00379 /**
00380  * @brief
00381  */
00382 template< typename Channel >
00383 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_D65> : public std::binary_function<Channel, Channel, Channel>
00384 {
00385         typedef typename floating_channel_type_t<Channel>::type T;
00386         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00387         typedef typename channel_traits<Channel>::reference ChannelRef;
00388 
00389         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00390         {
00391                 get_color( dst, red_t()   )     =  get_color( src, red_t  () );
00392                 get_color( dst, green_t() )     =  get_color( src, green_t() );
00393                 get_color( dst, blue_t()  )     =  get_color( src, blue_t () );
00394                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00395                 return dst;
00396         }
00397 
00398 };
00399 
00400 
00401 ////////////////////////////////////////////////////////////////////////////////
00402 // T_D75 //
00403 
00404 /**
00405  * @brief
00406  */
00407 template< typename Channel >
00408 struct channel_color_temperature_t<Channel, temperature::T_D75, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00409 {
00410         typedef typename floating_channel_type_t<Channel>::type T;
00411         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00412         typedef typename channel_traits<Channel>::reference ChannelRef;
00413 
00414         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00415         {
00416                 get_color( dst, red_t()   )     =  0.92909920f * get_color( src, red_t() ) + 0.00000008f * get_color( src, green_t() ) + 0.00000003 * get_color( src, blue_t() );
00417                 get_color( dst, green_t() )     = -0.00000002f * get_color( src, red_t() ) + 1.00641775f * get_color( src, green_t() ) + 0.00000001 * get_color( src, blue_t() );
00418                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) - 0.00000001f * get_color( src, green_t() ) + 1.14529049 * get_color( src, blue_t() );
00419                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00420                 return dst;
00421         }
00422 };
00423 
00424 /**
00425  * @brief
00426  */
00427 template< typename Channel >
00428 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_D75> : public std::binary_function<Channel, Channel, Channel>
00429 {
00430         typedef typename floating_channel_type_t<Channel>::type T;
00431         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00432         typedef typename channel_traits<Channel>::reference ChannelRef;
00433 
00434         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00435         {
00436                 get_color( dst, red_t()   )     =  1.07631159f * get_color( src, red_t() ) + 0.00000002f * get_color( src, green_t() ) + 0.00000006 * get_color( src, blue_t() );
00437                 get_color( dst, green_t() )     =  0.00000001f * get_color( src, red_t() ) + 0.99362320f * get_color( src, green_t() ) - 0.00000001 * get_color( src, blue_t() );
00438                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) - 0.00000001f * get_color( src, green_t() ) + 0.87314081 * get_color( src, blue_t() );
00439                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00440                 return dst;
00441         }
00442 
00443 };
00444 
00445 
00446 ////////////////////////////////////////////////////////////////////////////////
00447 // T_9300 //
00448 
00449 /**
00450  * @brief
00451  */
00452 template< typename Channel >
00453 struct channel_color_temperature_t<Channel, temperature::T_9300, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00454 {
00455         typedef typename floating_channel_type_t<Channel>::type T;
00456         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00457         typedef typename channel_traits<Channel>::reference ChannelRef;
00458 
00459         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00460         {
00461                 get_color( dst, red_t()   )     =  0.89304549f * get_color( src, red_t() ) + 0.00000012f * get_color( src, green_t() ) + 0.00000012 * get_color( src, blue_t() );
00462                 get_color( dst, green_t() )     = -0.00000002f * get_color( src, red_t() ) + 0.99430132f * get_color( src, green_t() ) + 0.00000000 * get_color( src, blue_t() );
00463                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) + 0.00000000f * get_color( src, green_t() ) + 1.37155378 * get_color( src, blue_t() );
00464                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00465                 return dst;
00466         }
00467 };
00468 
00469 /**
00470  * @brief
00471  */
00472 template< typename Channel >
00473 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_9300> : public std::binary_function<Channel, Channel, Channel>
00474 {
00475         typedef typename floating_channel_type_t<Channel>::type T;
00476         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00477         typedef typename channel_traits<Channel>::reference ChannelRef;
00478 
00479         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00480         {
00481                 get_color( dst, red_t()   )     =  1.11976373f * get_color( src, red_t() ) - 0.00000004f * get_color( src, green_t() ) - 0.00000006 * get_color( src, blue_t() );
00482                 get_color( dst, green_t() )     =  0.00000000f * get_color( src, red_t() ) + 1.00573123f * get_color( src, green_t() ) - 0.00000001 * get_color( src, blue_t() );
00483                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) - 0.00000001f * get_color( src, green_t() ) + 0.72909999 * get_color( src, blue_t() );
00484                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00485                 return dst;
00486         }
00487 
00488 };
00489 
00490 
00491 ////////////////////////////////////////////////////////////////////////////////
00492 // T_E //
00493 
00494 /**
00495  * @brief
00496  */
00497 template< typename Channel >
00498 struct channel_color_temperature_t<Channel, temperature::T_E, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00499 {
00500         typedef typename floating_channel_type_t<Channel>::type T;
00501         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00502         typedef typename channel_traits<Channel>::reference ChannelRef;
00503 
00504         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00505         {
00506                 get_color( dst, red_t()   )     =  1.20491767f * get_color( src, red_t() ) + 0.00000008f * get_color( src, green_t() ) + 0.00000012 * get_color( src, blue_t() );
00507                 get_color( dst, green_t() )     = -0.00000003f * get_color( src, red_t() ) + 0.94827831f * get_color( src, green_t() ) - 0.00000001 * get_color( src, blue_t() );
00508                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) - 0.00000001f * get_color( src, green_t() ) + 0.90876031 * get_color( src, blue_t() );
00509                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00510                 return dst;
00511         }
00512 };
00513 
00514 /**
00515  * @brief
00516  */
00517 template< typename Channel >
00518 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_E> : public std::binary_function<Channel, Channel, Channel>
00519 {
00520         typedef typename floating_channel_type_t<Channel>::type T;
00521         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00522         typedef typename channel_traits<Channel>::reference ChannelRef;
00523 
00524         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00525         {
00526                 get_color( dst, red_t()   )     =  0.82993227f * get_color( src, red_t() ) - 0.00000005f * get_color( src, green_t() ) - 0.00000009 * get_color( src, blue_t() );
00527                 get_color( dst, green_t() )     =  0.00000005f * get_color( src, red_t() ) + 1.05454266f * get_color( src, green_t() ) + 0.00000003 * get_color( src, blue_t() );
00528                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) - 0.00000001f * get_color( src, green_t() ) + 1.10040021 * get_color( src, blue_t() );
00529                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00530                 return dst;
00531         }
00532 
00533 };
00534 
00535 
00536 ////////////////////////////////////////////////////////////////////////////////
00537 // T_F2 //
00538 
00539 /**
00540  * @brief
00541  */
00542 template< typename Channel >
00543 struct channel_color_temperature_t<Channel, temperature::T_F2, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00544 {
00545         typedef typename floating_channel_type_t<Channel>::type T;
00546         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00547         typedef typename channel_traits<Channel>::reference ChannelRef;
00548 
00549         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00550         {
00551                 get_color( dst, red_t()   )     =  1.34113419f * get_color( src, red_t() ) + 0.00000007f * get_color( src, green_t() ) + 0.00000006 * get_color( src, blue_t() );
00552                 get_color( dst, green_t() )     = -0.00000004f * get_color( src, red_t() ) + 0.94260973f * get_color( src, green_t() ) - 0.00000000 * get_color( src, blue_t() );
00553                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) + 0.00000000f * get_color( src, green_t() ) + 0.56362498 * get_color( src, blue_t() );
00554                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00555                 return dst;
00556         }
00557 };
00558 
00559 /**
00560  * @brief
00561  */
00562 template< typename Channel >
00563 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_F2> : public std::binary_function<Channel, Channel, Channel>
00564 {
00565         typedef typename floating_channel_type_t<Channel>::type T;
00566         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00567         typedef typename channel_traits<Channel>::reference ChannelRef;
00568 
00569         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00570         {
00571                 get_color( dst, red_t()   )     =  0.74563771f * get_color( src, red_t() ) + 0.00000003f * get_color( src, green_t() ) + 0.00000000 * get_color( src, blue_t() );
00572                 get_color( dst, green_t() )     =  0.00000002f * get_color( src, red_t() ) + 1.06088448f * get_color( src, green_t() ) + 0.00000000 * get_color( src, blue_t() );
00573                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) + 0.00000003f * get_color( src, green_t() ) + 1.77422941 * get_color( src, blue_t() );
00574                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00575                 return dst;
00576         }
00577 
00578 };
00579 
00580 
00581 
00582 ////////////////////////////////////////////////////////////////////////////////
00583 // T_F7 //
00584 
00585 /**
00586  * @brief
00587  */
00588 template< typename Channel >
00589 struct channel_color_temperature_t<Channel, temperature::T_F7, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00590 {
00591         typedef typename floating_channel_type_t<Channel>::type T;
00592         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00593         typedef typename channel_traits<Channel>::reference ChannelRef;
00594 
00595         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00596         {
00597                 get_color( dst, red_t()   )     =  1.00054073f * get_color( src, red_t() ) + 0.00000006f * get_color( src, green_t() ) + 0.00000012 * get_color( src, blue_t() );
00598                 get_color( dst, green_t() )     = -0.00000003f * get_color( src, red_t() ) + 0.99999511f * get_color( src, green_t() ) - 0.00000001 * get_color( src, blue_t() );
00599                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) - 0.00000001f * get_color( src, green_t() ) + 0.99845666 * get_color( src, blue_t() );
00600                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00601                 return dst;
00602         }
00603 };
00604 
00605 /**
00606  * @brief
00607  */
00608 template< typename Channel >
00609 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_F7> : public std::binary_function<Channel, Channel, Channel>
00610 {
00611         typedef typename floating_channel_type_t<Channel>::type T;
00612         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00613         typedef typename channel_traits<Channel>::reference ChannelRef;
00614 
00615         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00616         {
00617                 get_color( dst, red_t()   )     =  0.99945968f * get_color( src, red_t() ) - 0.00000008f * get_color( src, green_t() ) - 0.00000003 * get_color( src, blue_t() );
00618                 get_color( dst, green_t() )     =  0.00000001f * get_color( src, red_t() ) + 1.00000501f * get_color( src, green_t() ) + 0.00000000 * get_color( src, blue_t() );
00619                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) + 0.00000000f * get_color( src, green_t() ) + 1.00154579 * get_color( src, blue_t() );
00620                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00621                 return dst;
00622         }
00623 
00624 };
00625 
00626 
00627 
00628 ////////////////////////////////////////////////////////////////////////////////
00629 // T_F11 //
00630 
00631 /**
00632  * @brief
00633  */
00634 template< typename Channel >
00635 struct channel_color_temperature_t<Channel, temperature::T_F11, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00636 {
00637         typedef typename floating_channel_type_t<Channel>::type T;
00638         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00639         typedef typename channel_traits<Channel>::reference ChannelRef;
00640 
00641         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00642         {
00643                 get_color( dst, red_t()   )     =  1.20491767f * get_color( src, red_t() ) + 0.00000008f * get_color( src, green_t() ) + 0.00000012 * get_color( src, blue_t() );
00644                 get_color( dst, green_t() )     = -0.00000003f * get_color( src, red_t() ) + 0.94827831f * get_color( src, green_t() ) - 0.00000001 * get_color( src, blue_t() );
00645                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) - 0.00000001f * get_color( src, green_t() ) + 0.90876031 * get_color( src, blue_t() );
00646                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00647                 return dst;
00648         }
00649 };
00650 
00651 /**
00652  * @brief
00653  */
00654 template< typename Channel >
00655 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_F11> : public std::binary_function<Channel, Channel, Channel>
00656 {
00657         typedef typename floating_channel_type_t<Channel>::type T;
00658         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00659         typedef typename channel_traits<Channel>::reference ChannelRef;
00660 
00661         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00662         {
00663                 get_color( dst, red_t()   )     =  0.70728123f * get_color( src, red_t() ) + 0.00000006f * get_color( src, green_t() ) + 0.00000006 * get_color( src, blue_t() );
00664                 get_color( dst, green_t() )     = -0.00000002f * get_color( src, red_t() ) + 1.08209848f * get_color( src, green_t() ) + 0.00000000 * get_color( src, blue_t() );
00665                 get_color( dst, blue_t()  )     = -0.00000001f * get_color( src, red_t() ) + 0.00000000f * get_color( src, green_t() ) + 1.87809896 * get_color( src, blue_t() );
00666                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00667                 return dst;
00668         }
00669 
00670 };
00671 
00672 
00673 
00674 ////////////////////////////////////////////////////////////////////////////////
00675 // T_DCPI3 //
00676 
00677 /**
00678  * @brief
00679  */
00680 template< typename Channel >
00681 struct channel_color_temperature_t<Channel, temperature::T_DCIP3, temperature::T_INTER> : public std::binary_function<Channel, Channel, Channel>
00682 {
00683         typedef typename floating_channel_type_t<Channel>::type T;
00684         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00685         typedef typename channel_traits<Channel>::reference ChannelRef;
00686 
00687         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00688         {
00689                 get_color( dst, red_t()   )     =  0.88602084f * get_color( src, red_t() ) + 0.00000013f * get_color( src, green_t() ) + 0.00000003 * get_color( src, blue_t() );
00690                 get_color( dst, green_t() )     = -0.00000003f * get_color( src, red_t() ) + 1.04855490f * get_color( src, green_t() ) + 0.00000000 * get_color( src, blue_t() );
00691                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) - 0.00000000f * get_color( src, green_t() ) + 0.85470724 * get_color( src, blue_t() );
00692                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00693                 return dst;
00694         }
00695 };
00696 
00697 /**
00698  * @brief
00699  */
00700 template< typename Channel >
00701 struct channel_color_temperature_t<Channel, temperature::T_INTER, temperature::T_DCIP3> : public std::binary_function<Channel, Channel, Channel>
00702 {
00703         typedef typename floating_channel_type_t<Channel>::type T;
00704         typedef typename channel_traits<Channel>::const_reference ChannelConstRef;
00705         typedef typename channel_traits<Channel>::reference ChannelRef;
00706 
00707         ChannelRef operator()( ChannelConstRef src, ChannelRef dst ) const
00708         {
00709                 get_color( dst, red_t()   )     =  1.12864172f * get_color( src, red_t() ) - 0.00000001f * get_color( src, green_t() ) + 0.00000000 * get_color( src, blue_t() );
00710                 get_color( dst, green_t() )     =  0.00000000f * get_color( src, red_t() ) + 0.95369333f * get_color( src, green_t() ) - 0.00000001 * get_color( src, blue_t() );
00711                 get_color( dst, blue_t()  )     =  0.00000000f * get_color( src, red_t() ) + 0.00000000f * get_color( src, green_t() ) + 1.16999125 * get_color( src, blue_t() );
00712                 copy_pixel_channel_if_exist<alpha_t>( src, dst );
00713                 return dst;
00714         }
00715 };
00716 
00717 
00718 ////////////////////////////////////////////////////////////////////////////////
00719 ////////////////////////////////////////////////////////////////////////////////
00720 
00721 
00722 
00723 template< typename Pixel,
00724           class IN,
00725           class OUT >
00726 struct pixel_color_temperature_t
00727 {
00728         typedef typename channel_type<Pixel>::type Channel;
00729         const IN&  _in;
00730         const OUT& _out;
00731 
00732         pixel_color_temperature_t( const IN& in, const OUT& out )
00733         : _in(in)
00734         , _out(out)
00735         {}
00736 
00737         Pixel& operator()( const Pixel& p1,
00738                            Pixel& p2 ) const
00739         {
00740                 static_for_each(
00741                                 p1, p2,
00742                                 channel_color_temperature_t< Channel, IN, OUT >( _in, _out )
00743                         );
00744                 return p2;
00745         }
00746 };
00747 
00748 template< class IN,
00749           class OUT >
00750 struct transform_pixel_color_temperature_t
00751 {
00752         const IN&  _in;
00753         const OUT& _out;
00754 
00755         transform_pixel_color_temperature_t( const IN& in, const OUT& out )
00756         : _in(in)
00757         , _out(out)
00758         {}
00759 
00760         template< typename Pixel>
00761         Pixel operator()( const Pixel& p1 ) const
00762         {
00763                 Pixel p2;
00764                 pixel_color_temperature_t<Pixel, IN, OUT>( _in, _out )( p1, p2 );
00765                 return p2;
00766         }
00767 };
00768 
00769 /**
00770  * @example temperature_convert_view( srcView, dstView, temperature::sRGB(), temperature::Gamma(5.0) );
00771  */
00772 template<class TemperatureIN, class TemperatureOUT, class View>
00773 void temperature_convert_view( const View& src, View& dst, const TemperatureIN& temperatureIn = TemperatureIN(), const TemperatureOUT& temperatureOut = TemperatureOUT() )
00774 {
00775         boost::gil::transform_pixels( src, dst, transform_pixel_color_temperature_t<TemperatureIN, TemperatureOUT>( temperatureIn, temperatureOut ), *this );
00776 }
00777 
00778 /**
00779  * @example temperature_convert_pixel( srcPix, dstPix, temperature::sRGB(), temperature::Gamma(5.0) );
00780  */
00781 template<class TemperatureIN, class TemperatureOUT, class Pixel>
00782 void temperature_convert_pixel( const Pixel& src, Pixel& dst, const TemperatureIN& temperatureIn = TemperatureIN(), const TemperatureOUT& temperatureOut = TemperatureOUT() )
00783 {
00784         pixel_color_temperature_t<TemperatureIN, TemperatureOUT>( temperatureIn, temperatureOut )( src, dst );
00785 }
00786 
00787 }
00788 }
00789 
00790 #endif
00791