TuttleOFX
1
|
00001 #ifndef _BOOST_GIL_COLOR_GRADATION_HPP_ 00002 #define _BOOST_GIL_COLOR_GRADATION_HPP_ 00003 00004 #include <boost/gil/algorithm.hpp> 00005 #include <terry/typedefs.hpp> 00006 #include <terry/channel.hpp> 00007 00008 #include <cmath> 00009 00010 namespace terry 00011 { 00012 using namespace boost::gil; 00013 00014 namespace color 00015 { 00016 00017 /** 00018 * @brief All supported gradations 00019 */ 00020 namespace gradation 00021 { 00022 struct Linear 00023 { 00024 }; 00025 struct sRGB 00026 { 00027 }; 00028 struct Rec709 00029 { 00030 }; 00031 struct Cineon 00032 { 00033 Cineon() : 00034 _blackPoint(95.0), _whitePoint(685.0), _gammaSensito(0.6) 00035 { 00036 } 00037 Cineon(const double blackPoint, const double whitePoint, 00038 const double gammaSensito) : 00039 _blackPoint(blackPoint), _whitePoint(whitePoint), _gammaSensito( 00040 gammaSensito) 00041 { 00042 } 00043 double _blackPoint; 00044 double _whitePoint; 00045 double _gammaSensito; 00046 }; 00047 struct Gamma 00048 { 00049 Gamma() : 00050 _gamma(1.0) 00051 { 00052 } 00053 Gamma(const double gamma) : 00054 _gamma(gamma) 00055 { 00056 } 00057 double _gamma; 00058 }; 00059 struct Panalog 00060 { 00061 }; 00062 struct REDLog 00063 { 00064 }; 00065 struct ViperLog 00066 { 00067 }; 00068 struct REDSpace 00069 { 00070 }; 00071 struct AlexaV3LogC 00072 { 00073 }; 00074 00075 } 00076 00077 /// @brief change the color gradation 00078 template<typename Channel, class TIN, class TOUT> 00079 struct channel_color_gradation_t : public std::binary_function<Channel, 00080 Channel, Channel> 00081 { 00082 typedef typename floating_channel_type_t<Channel>::type T; 00083 typedef typename channel_base_type<Channel>::type TBase; 00084 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00085 typedef typename channel_traits<Channel>::reference ChannelRef; 00086 00087 // This class implementation must be used only: 00088 // * with TIN != TOUT 00089 BOOST_STATIC_ASSERT(( ! boost::is_same<TIN, TOUT>::value )); // Must use channel_color_gradation_t<Channel, INOUT> ! 00090 // * TIN and TOUT must be other gradation mode than Linear 00091 // For each gradation mode, you have to specialize: GradationMode -> Linear and Linear -> GradationMode 00092 BOOST_STATIC_ASSERT(( ! boost::is_same<TIN, gradation::Linear>::value )); // The conversion IN to Linear is not implemented ! 00093 BOOST_STATIC_ASSERT(( ! boost::is_same<TOUT, gradation::Linear>::value )); // The conversion Linear to OUT is not implemented ! 00094 00095 const TIN& _in; 00096 const TOUT& _out; 00097 00098 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00099 _in(in), _out(out) 00100 { 00101 } 00102 00103 ChannelRef 00104 operator()(ChannelConstRef src, ChannelRef dst) const 00105 { 00106 Channel inter; 00107 // IN -> Linear 00108 channel_color_gradation_t<Channel, TIN, gradation::Linear>(_in, 00109 gradation::Linear())(src, inter); 00110 // Linear -> OUT 00111 return channel_color_gradation_t<Channel, gradation::Linear, TOUT>( 00112 gradation::Linear(), _out)(inter, dst); 00113 } 00114 }; 00115 00116 template<typename Channel, class INOUT> 00117 struct channel_color_gradation_t<Channel, INOUT, INOUT> : public std::binary_function< 00118 Channel, Channel, Channel> 00119 { 00120 typedef typename floating_channel_type_t<Channel>::type T; 00121 typedef typename channel_base_type<Channel>::type TBase; 00122 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00123 typedef typename channel_traits<Channel>::reference ChannelRef; 00124 00125 const INOUT& _in; 00126 const INOUT& _out; 00127 00128 channel_color_gradation_t(const INOUT& in, const INOUT& out) : 00129 _in(in), _out(out) 00130 { 00131 } 00132 00133 ChannelRef 00134 operator()(ChannelConstRef src, ChannelRef dst) const 00135 { 00136 return dst = Channel(src); 00137 } 00138 }; 00139 00140 //////////////////////////////////////////////////////////////////////////////// 00141 // sRGB // 00142 00143 /** 00144 * @brief sRGB to Lin 00145 * 00146 */ 00147 template<typename Channel> 00148 struct channel_color_gradation_t<Channel, gradation::sRGB, 00149 gradation::Linear> : public std::binary_function<Channel, Channel, 00150 Channel> 00151 { 00152 typedef typename floating_channel_type_t<Channel>::type T; 00153 typedef typename channel_base_type<Channel>::type TBase; 00154 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00155 typedef typename channel_traits<Channel>::reference ChannelRef; 00156 typedef typename gradation::sRGB TIN; 00157 typedef typename gradation::Linear TOUT; 00158 00159 const TIN& _in; 00160 const TOUT& _out; 00161 00162 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00163 _in(in), _out(out) 00164 { 00165 } 00166 00167 ChannelRef 00168 operator()(ChannelConstRef src, ChannelRef dst) const 00169 { 00170 const T fSrc = channel_convert<T>(src); 00171 T fDst; 00172 00173 if (src > 0.04045) 00174 { 00175 fDst = std::pow((fSrc + 0.055) / 1.055, 2.4); 00176 } 00177 else 00178 { 00179 fDst = fSrc / 12.92; 00180 } 00181 /* 00182 // Old sRGB standard, taken from Computational color technology by Kang. 00183 if( fSrc > 0.03928 ) 00184 { 00185 fDst = exp( log( ( fSrc + 0.055 ) / 1.055 ) * 2.4 ); 00186 } 00187 else 00188 { 00189 fDst = fSrc / 12.92; 00190 } 00191 */ 00192 return dst = channel_convert<Channel>(fDst); 00193 } 00194 00195 }; 00196 00197 /** 00198 * @brief Lin to sRGB 00199 */ 00200 template<typename Channel> 00201 struct channel_color_gradation_t<Channel, gradation::Linear, 00202 gradation::sRGB> : public std::binary_function<Channel, Channel, 00203 Channel> 00204 { 00205 typedef typename floating_channel_type_t<Channel>::type T; 00206 typedef typename channel_base_type<Channel>::type TBase; 00207 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00208 typedef typename channel_traits<Channel>::reference ChannelRef; 00209 typedef typename gradation::Linear TIN; 00210 typedef typename gradation::sRGB TOUT; 00211 00212 const TIN& _in; 00213 const TOUT& _out; 00214 00215 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00216 _in(in), _out(out) 00217 { 00218 } 00219 00220 ChannelRef 00221 operator()(ChannelConstRef src, ChannelRef dst) const 00222 { 00223 const T fSrc = channel_convert<T>(src); 00224 T fDst; 00225 00226 if (src > 0.0031308) 00227 { 00228 fDst = 1.055 * std::pow(T(fSrc), T(1.0 / 2.4)) - 0.055; 00229 } 00230 else 00231 { 00232 fDst = 12.92 * fSrc; 00233 } 00234 /* 00235 // Old sRGB standard, taken from Computational color technology by Kang. 00236 static const double inv_2_4 = 1.0 / 2.4; 00237 if( fSrc > 0.00304 ) 00238 { 00239 fDst = 1.055 * exp( log( fSrc ) * inv_2_4 ) - 0.055; 00240 } 00241 else 00242 { 00243 fDst = 12.92 * fSrc; 00244 } 00245 */ 00246 return dst = channel_convert<Channel>(fDst); 00247 } 00248 00249 }; 00250 //////////////////////////////////////////////////////////////////////////////// 00251 // Rec709 // 00252 00253 /** 00254 * @brief Rec709 to Lin 00255 * 00256 */ 00257 template<typename Channel> 00258 struct channel_color_gradation_t<Channel, gradation::Rec709, 00259 gradation::Linear> : public std::binary_function<Channel, Channel, 00260 Channel> 00261 { 00262 typedef typename floating_channel_type_t<Channel>::type T; 00263 typedef typename channel_base_type<Channel>::type TBase; 00264 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00265 typedef typename channel_traits<Channel>::reference ChannelRef; 00266 typedef typename gradation::Rec709 TIN; 00267 typedef typename gradation::Linear TOUT; 00268 00269 const TIN& _in; 00270 const TOUT& _out; 00271 00272 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00273 _in(in), _out(out) 00274 { 00275 } 00276 00277 ChannelRef 00278 operator()(ChannelConstRef src, ChannelRef dst) const 00279 { 00280 const T fSrc = channel_convert<T>(src); 00281 T fDst; 00282 if (fSrc < 0.081) 00283 fDst = fSrc * (1.0/4.5); 00284 else 00285 fDst = std::pow ((fSrc + 0.099) * (1.0/1.099), (1.0/0.45)); 00286 return dst = channel_convert<Channel>(fDst); 00287 } 00288 00289 }; 00290 00291 /** 00292 * @brief Lin to Rec709 00293 */ 00294 template<typename Channel> 00295 struct channel_color_gradation_t<Channel, gradation::Linear, 00296 gradation::Rec709> : public std::binary_function<Channel, Channel, 00297 Channel> 00298 { 00299 typedef typename floating_channel_type_t<Channel>::type T; 00300 typedef typename channel_base_type<Channel>::type TBase; 00301 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00302 typedef typename channel_traits<Channel>::reference ChannelRef; 00303 typedef typename gradation::Linear TIN; 00304 typedef typename gradation::Rec709 TOUT; 00305 00306 const TIN& _in; 00307 const TOUT& _out; 00308 00309 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00310 _in(in), _out(out) 00311 { 00312 } 00313 00314 ChannelRef 00315 operator()(ChannelConstRef src, ChannelRef dst) const 00316 { 00317 const T fSrc = channel_convert<T>(src); 00318 T fDst; 00319 if (fSrc < 0.018) 00320 fDst = fSrc * 4.5; 00321 else 00322 fDst = 1.099 * std::pow(T(fSrc), T(0.45)) - 0.099; 00323 return dst = channel_convert<Channel>(fDst); 00324 } 00325 00326 }; 00327 00328 //////////////////////////////////////////////////////////////////////////////// 00329 // Cineon 00330 00331 /** 00332 * @brief Cineon to Lin 00333 */ 00334 template<typename Channel> 00335 struct channel_color_gradation_t<Channel, gradation::Cineon, 00336 gradation::Linear> : public std::binary_function<Channel, Channel, 00337 Channel> 00338 { 00339 typedef typename floating_channel_type_t<Channel>::type T; 00340 typedef typename channel_base_type<Channel>::type TBase; 00341 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00342 typedef typename channel_traits<Channel>::reference ChannelRef; 00343 typedef typename gradation::Cineon TIN; 00344 typedef typename gradation::Linear TOUT; 00345 00346 const TIN& _in; 00347 const TOUT& _out; 00348 00349 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00350 _in(in), _out(out) 00351 { 00352 } 00353 00354 ChannelRef 00355 operator()(ChannelConstRef src, ChannelRef dst) const 00356 { 00357 const T fSrc = channel_convert<T>(src); 00358 00359 double offset = std::pow(10, 00360 (_in._blackPoint - _in._whitePoint) * 0.002 / _in._gammaSensito); 00361 double gain = 1.0 / (1 - offset); 00362 T fDst = gain 00363 * (std::pow(10.0, 00364 (1023 * fSrc - _in._whitePoint) * 0.002 / _in._gammaSensito) 00365 - offset); 00366 return dst = channel_convert<Channel>(fDst); 00367 } 00368 }; 00369 00370 /** 00371 * @brief Lin to Cineon 00372 */ 00373 template<typename Channel> 00374 struct channel_color_gradation_t<Channel, gradation::Linear, 00375 gradation::Cineon> : public std::binary_function<Channel, Channel, 00376 Channel> 00377 { 00378 typedef typename floating_channel_type_t<Channel>::type T; 00379 typedef typename channel_base_type<Channel>::type TBase; 00380 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00381 typedef typename channel_traits<Channel>::reference ChannelRef; 00382 typedef typename gradation::Linear TIN; 00383 typedef typename gradation::Cineon TOUT; 00384 00385 const TIN& _in; 00386 const TOUT& _out; 00387 00388 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00389 _in(in), _out(out) 00390 { 00391 } 00392 00393 ChannelRef 00394 operator()(ChannelConstRef src, ChannelRef dst) const 00395 { 00396 const T fSrc = channel_convert<T>(src); 00397 double offset = std::pow(10, 00398 (_out._blackPoint - _out._whitePoint) * 0.002 00399 / _out._gammaSensito); 00400 double gain = 1.0 / (1 - offset); 00401 T fDst = (std::log10((fSrc + offset) / gain) 00402 / (0.002 / _out._gammaSensito) + _out._whitePoint)/1023.0; 00403 00404 return dst = channel_convert<Channel>(fDst); 00405 } 00406 }; 00407 00408 //////////////////////////////////////////////////////////////////////////////// 00409 // Gamma 00410 00411 /** 00412 * @brief Gamma to Lin 00413 */ 00414 template<typename Channel> 00415 struct channel_color_gradation_t<Channel, gradation::Gamma, 00416 gradation::Linear> : public std::binary_function<Channel, Channel, 00417 Channel> 00418 { 00419 typedef typename floating_channel_type_t<Channel>::type T; 00420 typedef typename channel_base_type<Channel>::type TBase; 00421 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00422 typedef typename channel_traits<Channel>::reference ChannelRef; 00423 typedef typename gradation::Gamma TIN; 00424 typedef typename gradation::Linear TOUT; 00425 00426 const TIN& _in; 00427 const TOUT& _out; 00428 00429 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00430 _in(in), _out(out) 00431 { 00432 } 00433 00434 ChannelRef 00435 operator()(ChannelConstRef src, ChannelRef dst) const 00436 { 00437 const T fSrc = channel_convert<T>(src); 00438 T fDst; 00439 00440 if (src == 0) 00441 { 00442 fDst = 0.0; 00443 } 00444 else if (src > 0.0) 00445 { 00446 // compute gamma value 00447 // fDst = DstChannel( std::pow( 10.0, _value * std::log10( fSrc ) ) ); 00448 fDst = std::pow(static_cast<double>(fSrc), _in._gamma); 00449 } 00450 else 00451 { 00452 // for negative values, we return a linear conversion 00453 fDst = fSrc; 00454 } 00455 return dst = channel_convert<Channel>(fDst); 00456 } 00457 }; 00458 00459 /** 00460 * @brief Lin to Gamma 00461 */ 00462 template<typename Channel> 00463 struct channel_color_gradation_t<Channel, gradation::Linear, 00464 gradation::Gamma> : public std::binary_function<Channel, Channel, 00465 Channel> 00466 { 00467 typedef typename floating_channel_type_t<Channel>::type T; 00468 typedef typename channel_base_type<Channel>::type TBase; 00469 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00470 typedef typename channel_traits<Channel>::reference ChannelRef; 00471 typedef typename gradation::Linear TIN; 00472 typedef typename gradation::Gamma TOUT; 00473 00474 const TIN& _in; 00475 const TOUT& _out; 00476 00477 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00478 _in(in), _out(out) 00479 { 00480 } 00481 00482 ChannelRef 00483 operator()(ChannelConstRef src, ChannelRef dst) const 00484 { 00485 const T fSrc = channel_convert<T>(src); 00486 T fDst; 00487 00488 if (src == 0) 00489 { 00490 fDst = 0.0; 00491 } 00492 else if (src > 0.0) 00493 { 00494 // compute gamma value 00495 fDst = std::pow(static_cast<double>(fSrc), 1.0 / _out._gamma); 00496 } 00497 else 00498 { 00499 // for negative values, we return a linear conversion 00500 fDst = fSrc; 00501 } 00502 return dst = channel_convert<Channel>(fDst); 00503 } 00504 }; 00505 00506 //////////////////////////////////////////////////////////////////////////////// 00507 // Panalog 00508 00509 /** 00510 * @brief Panalog to Lin 00511 */ 00512 template<typename Channel> 00513 struct channel_color_gradation_t<Channel, gradation::Panalog, 00514 gradation::Linear> : public std::binary_function<Channel, Channel, 00515 Channel> 00516 { 00517 typedef typename floating_channel_type_t<Channel>::type T; 00518 typedef typename channel_base_type<Channel>::type TBase; 00519 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00520 typedef typename channel_traits<Channel>::reference ChannelRef; 00521 typedef typename gradation::Panalog TIN; 00522 typedef typename gradation::Linear TOUT; 00523 00524 const TIN& _in; 00525 const TOUT& _out; 00526 00527 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00528 _in(in), _out(out) 00529 { 00530 } 00531 00532 ChannelRef 00533 operator()(ChannelConstRef src, ChannelRef dst) const 00534 { 00535 const T fSrc = channel_convert<T>(src); 00536 T fDst = (std::pow(10.0, (1023.0 * fSrc - 681.0) / 444.0) - 0.0408) 00537 / (1.0 - 0.0408); 00538 return dst = channel_convert<Channel>(fDst); 00539 } 00540 }; 00541 00542 /** 00543 * @brief Lin to Panalog 00544 */ 00545 template<typename Channel> 00546 struct channel_color_gradation_t<Channel, gradation::Linear, 00547 gradation::Panalog> : public std::binary_function<Channel, Channel, 00548 Channel> 00549 { 00550 typedef typename floating_channel_type_t<Channel>::type T; 00551 typedef typename channel_base_type<Channel>::type TBase; 00552 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00553 typedef typename channel_traits<Channel>::reference ChannelRef; 00554 typedef typename gradation::Linear TIN; 00555 typedef typename gradation::Panalog TOUT; 00556 00557 const TIN& _in; 00558 const TOUT& _out; 00559 00560 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00561 _in(in), _out(out) 00562 { 00563 } 00564 00565 ChannelRef 00566 operator()(ChannelConstRef src, ChannelRef dst) const 00567 { 00568 const T fSrc = channel_convert<T>(src); 00569 T fDst = (444.0 * std::log10(0.0408 + (1.0 - 0.0408) * fSrc) + 681.0) 00570 / 1023.0; 00571 return dst = channel_convert<Channel>(fDst); 00572 } 00573 }; 00574 00575 //////////////////////////////////////////////////////////////////////////////// 00576 // REDLog 00577 00578 /** 00579 * @brief REDLog to Lin 00580 */ 00581 template<typename Channel> 00582 struct channel_color_gradation_t<Channel, gradation::REDLog, 00583 gradation::Linear> : public std::binary_function<Channel, Channel, 00584 Channel> 00585 { 00586 typedef typename floating_channel_type_t<Channel>::type T; 00587 typedef typename channel_base_type<Channel>::type TBase; 00588 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00589 typedef typename channel_traits<Channel>::reference ChannelRef; 00590 typedef typename gradation::REDLog TIN; 00591 typedef typename gradation::Linear TOUT; 00592 00593 const TIN& _in; 00594 const TOUT& _out; 00595 00596 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00597 _in(in), _out(out) 00598 { 00599 } 00600 00601 ChannelRef 00602 operator()(ChannelConstRef src, ChannelRef dst) const 00603 { 00604 const T fSrc = channel_convert<T>(src); 00605 T fDst = (std::pow(10.0, (1023.0 * fSrc - 1023.0) / 511.0) - 0.01) 00606 / (1.0 - 0.01); 00607 return dst = channel_convert<Channel>(fDst); 00608 } 00609 }; 00610 00611 /** 00612 * @brief Lin to REDLog 00613 */ 00614 template<typename Channel> 00615 struct channel_color_gradation_t<Channel, gradation::Linear, 00616 gradation::REDLog> : public std::binary_function<Channel, Channel, 00617 Channel> 00618 { 00619 typedef typename floating_channel_type_t<Channel>::type T; 00620 typedef typename channel_base_type<Channel>::type TBase; 00621 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00622 typedef typename channel_traits<Channel>::reference ChannelRef; 00623 typedef typename gradation::Linear TIN; 00624 typedef typename gradation::REDLog TOUT; 00625 00626 const TIN& _in; 00627 const TOUT& _out; 00628 00629 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00630 _in(in), _out(out) 00631 { 00632 } 00633 00634 ChannelRef 00635 operator()(ChannelConstRef src, ChannelRef dst) const 00636 { 00637 const T fSrc = channel_convert<T>(src); 00638 T fDst = (511.0 * std::log10(0.01 + (1.0 - 0.01) * fSrc) + 1023.0) 00639 / 1023.0; 00640 return dst = channel_convert<Channel>(fDst); 00641 } 00642 }; 00643 00644 //////////////////////////////////////////////////////////////////////////////// 00645 // ViperLog 00646 00647 /** 00648 * @brief ViperLog to Lin 00649 */ 00650 template<typename Channel> 00651 struct channel_color_gradation_t<Channel, gradation::ViperLog, 00652 gradation::Linear> : public std::binary_function<Channel, Channel, 00653 Channel> 00654 { 00655 typedef typename floating_channel_type_t<Channel>::type T; 00656 typedef typename channel_base_type<Channel>::type TBase; 00657 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00658 typedef typename channel_traits<Channel>::reference ChannelRef; 00659 typedef typename gradation::ViperLog TIN; 00660 typedef typename gradation::Linear TOUT; 00661 00662 const TIN& _in; 00663 const TOUT& _out; 00664 00665 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00666 _in(in), _out(out) 00667 { 00668 } 00669 00670 ChannelRef 00671 operator()(ChannelConstRef src, ChannelRef dst) const 00672 { 00673 const T fSrc = channel_convert<T>(src); 00674 T fDst = std::pow(10.0, (1023.0 * fSrc - 1023.0) / 500.0); 00675 return dst = channel_convert<Channel>(fDst); 00676 } 00677 }; 00678 00679 /** 00680 * @brief Lin to ViperLog 00681 */ 00682 template<typename Channel> 00683 struct channel_color_gradation_t<Channel, gradation::Linear, 00684 gradation::ViperLog> : public std::binary_function<Channel, Channel, 00685 Channel> 00686 { 00687 typedef typename floating_channel_type_t<Channel>::type T; 00688 typedef typename channel_base_type<Channel>::type TBase; 00689 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00690 typedef typename channel_traits<Channel>::reference ChannelRef; 00691 typedef typename gradation::Linear TIN; 00692 typedef typename gradation::ViperLog TOUT; 00693 00694 const TIN& _in; 00695 const TOUT& _out; 00696 00697 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00698 _in(in), _out(out) 00699 { 00700 } 00701 00702 ChannelRef 00703 operator()(ChannelConstRef src, ChannelRef dst) const 00704 { 00705 const T fSrc = channel_convert<T>(src); 00706 T fDst = (500.0 * std::log10(fSrc) + 1023.0) / 1023.0; 00707 return dst = channel_convert<Channel>(fDst); 00708 } 00709 }; 00710 00711 //////////////////////////////////////////////////////////////////////////////// 00712 // REDSpace 00713 00714 /** 00715 * @brief REDSpace to Lin 00716 */ 00717 template<typename Channel> 00718 struct channel_color_gradation_t<Channel, gradation::REDSpace, 00719 gradation::Linear> : public std::binary_function<Channel, Channel, 00720 Channel> 00721 { 00722 typedef typename floating_channel_type_t<Channel>::type T; 00723 typedef typename channel_base_type<Channel>::type TBase; 00724 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00725 typedef typename channel_traits<Channel>::reference ChannelRef; 00726 typedef typename gradation::REDSpace TIN; 00727 typedef typename gradation::Linear TOUT; 00728 00729 const TIN& _in; 00730 const TOUT& _out; 00731 00732 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00733 _in(in), _out(out) 00734 { 00735 } 00736 00737 ChannelRef 00738 operator()(ChannelConstRef src, ChannelRef dst) const 00739 { 00740 return dst = Channel(src); // the equation wasn't found actually 00741 } 00742 }; 00743 00744 /** 00745 * @brief Lin to REDSpace 00746 */ 00747 template<typename Channel> 00748 struct channel_color_gradation_t<Channel, gradation::Linear, 00749 gradation::REDSpace> : public std::binary_function<Channel, Channel, 00750 Channel> 00751 { 00752 typedef typename floating_channel_type_t<Channel>::type T; 00753 typedef typename channel_base_type<Channel>::type TBase; 00754 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00755 typedef typename channel_traits<Channel>::reference ChannelRef; 00756 typedef typename gradation::Linear TIN; 00757 typedef typename gradation::REDSpace TOUT; 00758 00759 const TIN& _in; 00760 const TOUT& _out; 00761 00762 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00763 _in(in), _out(out) 00764 { 00765 } 00766 00767 ChannelRef 00768 operator()(ChannelConstRef src, ChannelRef dst) const 00769 { 00770 return dst = Channel(src); // the equation wasn't found actually 00771 } 00772 }; 00773 00774 //////////////////////////////////////////////////////////////////////////////// 00775 // AlexaV3LogC 00776 00777 /** 00778 * @brief AlexaV3LogC to Lin 00779 */ 00780 template<typename Channel> 00781 struct channel_color_gradation_t<Channel, gradation::AlexaV3LogC, 00782 gradation::Linear> : public std::binary_function<Channel, Channel, 00783 Channel> 00784 { 00785 typedef typename floating_channel_type_t<Channel>::type T; 00786 typedef typename channel_base_type<Channel>::type TBase; 00787 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00788 typedef typename channel_traits<Channel>::reference ChannelRef; 00789 typedef typename gradation::AlexaV3LogC TIN; 00790 typedef typename gradation::Linear TOUT; 00791 00792 const TIN& _in; 00793 const TOUT& _out; 00794 00795 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00796 _in(in), _out(out) 00797 { 00798 } 00799 00800 ChannelRef 00801 operator()(ChannelConstRef src, ChannelRef dst) const 00802 { 00803 const T fSrc = channel_convert<T>(src); 00804 T fDst; 00805 00806 if (fSrc > 0.1496582) 00807 { 00808 fDst = std::pow(10.0,(fSrc - 0.385537)/0.2471896) * 0.18 - 0.00937677; 00809 } 00810 else 00811 { 00812 fDst = (fSrc/ 0.9661776 - 0.04378604)* 0.18 - 0.00937677; 00813 } 00814 00815 return dst = channel_convert<Channel>(fDst); 00816 } 00817 }; 00818 00819 /** 00820 * @brief Lin to AlexaV3LogC 00821 */ 00822 template<typename Channel> 00823 struct channel_color_gradation_t<Channel, gradation::Linear, 00824 gradation::AlexaV3LogC> : public std::binary_function<Channel, Channel, 00825 Channel> 00826 { 00827 typedef typename floating_channel_type_t<Channel>::type T; 00828 typedef typename channel_base_type<Channel>::type TBase; 00829 typedef typename channel_traits<Channel>::const_reference ChannelConstRef; 00830 typedef typename channel_traits<Channel>::reference ChannelRef; 00831 typedef typename gradation::Linear TIN; 00832 typedef typename gradation::AlexaV3LogC TOUT; 00833 00834 const TIN& _in; 00835 const TOUT& _out; 00836 00837 channel_color_gradation_t(const TIN& in, const TOUT& out) : 00838 _in(in), _out(out) 00839 { 00840 } 00841 00842 ChannelRef 00843 operator()(ChannelConstRef src, ChannelRef dst) const 00844 { 00845 const T fSrc = channel_convert<T>(src); 00846 T fDst; 00847 00848 if (fSrc > 0.010591) 00849 { 00850 fDst = 0.247190 * std::log10(5.555556 * fSrc + 0.052272) + 0.385537; 00851 } 00852 else 00853 { 00854 fDst = fSrc* 5.367655 + 0.092809; 00855 } 00856 00857 return dst = channel_convert<Channel>(fDst); 00858 } 00859 }; 00860 00861 //////////////////////////////////////////////////////////////////////////////// 00862 //////////////////////////////////////////////////////////////////////////////// 00863 00864 template<typename Pixel, class TIN, class TOUT> 00865 struct pixel_color_gradation_t 00866 { 00867 typedef typename channel_type<Pixel>::type Channel; 00868 const TIN& _in; 00869 const TOUT& _out; 00870 00871 pixel_color_gradation_t(const TIN& in, const TOUT& out) : 00872 _in(in), _out(out) 00873 { 00874 } 00875 00876 Pixel& 00877 operator()(const Pixel& p1, Pixel& p2) const 00878 { 00879 static_for_each(p1, p2, 00880 channel_color_gradation_t<Channel, TIN, TOUT>(_in, _out)); 00881 return p2; 00882 } 00883 }; 00884 00885 template<class TIN, class TOUT> 00886 struct transform_pixel_color_gradation_t 00887 { 00888 const TIN& _in; 00889 const TOUT& _out; 00890 00891 transform_pixel_color_gradation_t(const TIN& in, const TOUT& out) : 00892 _in(in), _out(out) 00893 { 00894 } 00895 00896 template<typename Pixel> 00897 Pixel 00898 operator()(const Pixel& p1) const 00899 { 00900 Pixel p2; 00901 pixel_color_gradation_t<Pixel, TIN, TOUT>(_in, _out)(p1, p2); 00902 return p2; 00903 } 00904 }; 00905 00906 /** 00907 * @example gradation_convert_view( srcView, dstView, gradation::sRGB(), gradation::Gamma(5.0) ); 00908 */ 00909 template<class GradationIN, class GradationOUT, class View> 00910 void 00911 gradation_convert_view(const View& src, View& dst, 00912 const GradationIN& gradationIn = GradationIN(), 00913 const GradationOUT& gradationOut = GradationOUT()) 00914 { 00915 boost::gil::transform_pixels(src, dst, 00916 transform_pixel_color_gradation_t<GradationIN, GradationOUT>( 00917 gradationIn, gradationOut)); 00918 } 00919 00920 /** 00921 * @example gradation_convert_pixel( srcPix, dstPix, gradation::sRGB(), gradation::Gamma(5.0) ); 00922 */ 00923 template<class GradationIN, class GradationOUT, class Pixel> 00924 void 00925 gradation_convert_pixel(const Pixel& src, Pixel& dst, 00926 const GradationIN& gradationIn = GradationIN(), 00927 const GradationOUT& gradationOut = GradationOUT()) 00928 { 00929 pixel_color_gradation_t<Pixel, GradationIN, GradationOUT>(gradationIn, 00930 gradationOut)(src, dst); 00931 } 00932 00933 } 00934 } 00935 00936 #endif 00937