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