1 #ifndef color_hsl_convert_rgb 2 #define color_hsl_convert_rgb 3 4 #include "../category.hpp" 5 #include "../place/place.hpp" 6 7 #include "../../_internal/convert.hpp" 8 9 #include "../../rgb/trait/container.hpp" 10 #include "../../rgb/trait/component.hpp" 11 #include "../../rgb/trait/index.hpp" 12 #include "../../rgb/trait/bound.hpp" 13 #include "../../rgb/category.hpp" 14 15 16 #include "../../_internal/normalize.hpp" 17 #include "../../_internal/diverse.hpp" 18 19 20 namespace color 21 { 22 namespace _internal 23 { 24 25 template 26 < 27 typename hsl_tag_name 28 ,typename rgb_tag_name 29 > 30 struct convert 31 < 32 ::color::category::hsl< hsl_tag_name > 33 ,::color::category::rgb< rgb_tag_name > 34 > 35 { 36 public: 37 typedef ::color::category::hsl< hsl_tag_name > category_left_type; 38 typedef ::color::category::rgb< rgb_tag_name > category_right_type; 39 40 typedef typename ::color::trait::scalar<category_left_type>::instance_type scalar_type; 41 42 typedef ::color::trait::scalar<category_left_type> scalar_trait_type; 43 44 typedef ::color::trait::container<category_left_type> container_left_trait_type; 45 typedef ::color::trait::container<category_right_type> container_right_trait_type; 46 47 typedef typename container_left_trait_type::input_type container_left_input_type; 48 typedef typename container_right_trait_type::model_type container_right_const_input_type; 49 50 typedef ::color::_internal::diverse< category_left_type > diverse_type; 51 typedef ::color::_internal::normalize< category_right_type > normalize_type; 52 53 enum 54 { 55 hue_p = ::color::place::_internal::hue<category_left_type>::position_enum 56 ,saturation_p = ::color::place::_internal::saturation<category_left_type>::position_enum 57 , lightness_p = ::color::place::_internal::lightness<category_left_type>::position_enum 58 }; 59 60 enum 61 { 62 red_p = ::color::place::_internal::red<category_right_type>::position_enum 63 ,green_p = ::color::place::_internal::green<category_right_type>::position_enum 64 ,blue_p = ::color::place::_internal::blue<category_right_type>::position_enum 65 }; 66 processcolor::_internal::convert67 static void process 68 ( 69 container_left_input_type left 70 ,container_right_const_input_type right 71 ) 72 { 73 scalar_type r = normalize_type::template process<red_p >( container_right_trait_type::template get<red_p >( right ) ); 74 scalar_type g = normalize_type::template process<green_p>( container_right_trait_type::template get<green_p>( right ) ); 75 scalar_type b = normalize_type::template process<blue_p >( container_right_trait_type::template get<blue_p >( right ) ); 76 77 const scalar_type hi = std::max<scalar_type>( { r, g, b } ); 78 const scalar_type lo = std::min<scalar_type>( { r, g, b } ); 79 scalar_type delta = hi - lo; 80 81 scalar_type h = 0; 82 scalar_type s = 0; 83 scalar_type l = (hi + lo) / scalar_type(2); 84 85 if( false == scalar_trait_type::is_small( delta ) ) 86 { 87 s = delta / ( 1 - fabs( 2*l - 1 ) ); 88 if( hi == r ) 89 { 90 h = (scalar_type(60)/scalar_type(360)) * (g - b) / delta + (g < b ? scalar_type(1) : scalar_type(0)); 91 } 92 if( hi == g ) 93 { 94 h = (scalar_type(60)/scalar_type(360)) * (b - r) / delta + (scalar_type(120)/scalar_type(360)); 95 } 96 if( hi == b ) 97 { 98 h = (scalar_type(60)/scalar_type(360)) * (r - g) / delta + (scalar_type(240)/scalar_type(360)); 99 } 100 } 101 102 container_left_trait_type::template set< hue_p>( left, diverse_type::template process< hue_p>( h ) ); 103 container_left_trait_type::template set<saturation_p>( left, diverse_type::template process<saturation_p>( s ) ); 104 container_left_trait_type::template set< lightness_p>( left, diverse_type::template process< lightness_p>( l ) ); 105 } 106 }; 107 108 } 109 } 110 111 #endif 112