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