1 #ifndef color_hsi_convert_rgb 2 #define color_hsi_convert_rgb 3 4 #include "../../_internal/convert.hpp" 5 #include "../../rgb/rgb.hpp" 6 7 #include "../../_internal/normalize.hpp" 8 #include "../../_internal/diverse.hpp" 9 #include "../../generic/constant.hpp" 10 11 namespace color 12 { 13 namespace _internal 14 { 15 16 template< typename hsi_tag_name, typename rgb_tag_name > 17 struct convert 18 < 19 ::color::category::hsi< hsi_tag_name > 20 ,::color::category::rgb< rgb_tag_name > 21 > 22 { 23 public: 24 typedef ::color::category::hsi< hsi_tag_name > category_left_type; 25 typedef ::color::category::rgb< rgb_tag_name > category_right_type; 26 27 typedef typename ::color::trait::scalar< category_left_type >::instance_type scalar_type; 28 29 typedef ::color::trait::scalar<category_left_type> scalar_trait_type; 30 31 typedef ::color::trait::container<category_left_type> container_left_trait_type; 32 typedef ::color::trait::container<category_right_type> container_right_trait_type; 33 34 typedef typename container_left_trait_type::input_type container_left_input_type; 35 typedef typename container_right_trait_type::model_type container_right_const_input_type; 36 37 typedef ::color::_internal::diverse< category_left_type > diverse_type; 38 typedef ::color::_internal::normalize< category_right_type > normalize_type; 39 40 typedef ::color::constant::generic< category_left_type > constant_type; 41 42 43 enum 44 { 45 hue_p = ::color::place::_internal::hue<category_left_type>::position_enum 46 ,saturation_p = ::color::place::_internal::saturation<category_left_type>::position_enum 47 , intensity_p = ::color::place::_internal::intensity<category_left_type>::position_enum 48 }; 49 50 enum 51 { 52 red_p = ::color::place::_internal::red<category_right_type>::position_enum 53 ,green_p = ::color::place::_internal::green<category_right_type>::position_enum 54 , blue_p = ::color::place::_internal::blue<category_right_type>::position_enum 55 }; 56 processcolor::_internal::convert57 static void process 58 ( 59 container_left_input_type left 60 ,container_right_const_input_type right 61 ) 62 { 63 scalar_type r = normalize_type::template process<red_p >( container_right_trait_type::template get<red_p >( right ) ); 64 scalar_type g = normalize_type::template process<green_p>( container_right_trait_type::template get<green_p>( right ) ); 65 scalar_type b = normalize_type::template process<blue_p >( container_right_trait_type::template get<blue_p >( right ) ); 66 67 scalar_type lo = std::min<scalar_type>( {r,g,b} ); 68 69 scalar_type h = 0; 70 scalar_type i = ( r + g + b ) / scalar_type(3); 71 scalar_type s = scalar_type(1); 72 if( false == scalar_trait_type::is_small( i ) ) 73 { 74 s = scalar_type(1) - lo / i; 75 } 76 77 scalar_type c1 = r - g* scalar_type( 0.5 ) - b * scalar_type( 0.5 ); 78 scalar_type c2 = ( g - b ) * constant_type::sqrt_3() * scalar_type( 0.5 ); 79 scalar_type thetaX = atan2( c2, c1 ); 80 if( thetaX < 0 ){ thetaX += constant_type::two_pi(); } 81 h = thetaX; 82 83 //scalar_type alpha = ( (r-g) + ( r- b) ) * scalar_type( 0.5 ); 84 //scalar_type beta = (r-g)*(r-g) + (r-b)*(g-b) ; 85 // beta = sqrt( beta ); 86 //scalar_type thetaA = acos( alpha / beta ); 87 //if( b > g ) { thetaA = constant_type::two_pi() - thetaA; } 88 //h = thetaA; 89 90 h /= constant_type::two_pi(); 91 92 {// TODO 93 // typedef ::color::category::rgb< scalar_type > rgb_scalar_type; 94 //typedef ::color::get::_internal::rgb::hue::usher< rgb_scalar_type, ::color::get::constant::rgb::hue::polar_atan2_entity > hue_type; 95 //h = hue_type::process( r, g, b ) / ( 2 * pi ); 96 } 97 98 container_left_trait_type::template set< hue_p>( left, diverse_type::template process< hue_p>( h ) ); 99 container_left_trait_type::template set<saturation_p>( left, diverse_type::template process<saturation_p>( s ) ); 100 container_left_trait_type::template set< intensity_p>( left, diverse_type::template process< intensity_p>( i ) ); 101 } 102 }; 103 104 } 105 } 106 107 #endif 108