1 #ifndef color_yiq_convert_rgb
2 #define color_yiq_convert_rgb
3 
4 #include "../../_internal/convert.hpp"
5 #include "../../rgb/trait/container.hpp"
6 #include "../../rgb/category.hpp"
7 #include "../../rgb/place/place.hpp"
8 
9 #include "../place/place.hpp"
10 #include "../category.hpp"
11 #include "../constant.hpp"
12 
13 #include "../../_internal/normalize.hpp"
14 #include "../../_internal/diverse.hpp"
15 
16 namespace color
17  {
18   namespace _internal
19    {
20 
21     template< typename yiq_tag_name, typename rgb_tag_name >
22      struct convert
23       <
24         ::color::category::yiq<  yiq_tag_name >
25        ,::color::category::rgb<  rgb_tag_name >
26       >
27       {
28        public:
29          typedef ::color::category::yiq<  yiq_tag_name > category_left_type;
30          typedef ::color::category::rgb<  rgb_tag_name > category_right_type;
31          typedef typename ::color::trait::scalar<category_left_type>::instance_type  scalar_type;
32 
33          typedef ::color::trait::container<category_left_type>     container_left_trait_type;
34          typedef ::color::trait::container<category_right_type>    container_right_trait_type;
35 
36          typedef ::color::constant::yiq< category_left_type > yiq_const_type;
37 
38          typedef typename container_left_trait_type::input_type         container_left_input_type;
39          typedef typename container_right_trait_type::model_type  container_right_const_input_type;
40 
41          typedef ::color::_internal::diverse< category_left_type >    diverse_type;
42          typedef ::color::_internal::normalize< category_right_type > normalize_type;
43 
44          enum
45           {
46                   luma_p  = ::color::place::_internal::luma<category_left_type>::position_enum
47            ,   inphase_p  = ::color::place::_internal::inphase<category_left_type>::position_enum
48            ,quadrature_p  = ::color::place::_internal::quadrature<category_left_type>::position_enum
49           };
50 
51          enum
52           {
53             red_p   = ::color::place::_internal::red<category_right_type>::position_enum
54            ,green_p = ::color::place::_internal::green<category_right_type>::position_enum
55            ,blue_p  = ::color::place::_internal::blue<category_right_type>::position_enum
56           };
57 
processcolor::_internal::convert58          static void process
59           (
60             container_left_input_type         left
61            ,container_right_const_input_type  right
62           )
63           {
64 
65            static scalar_type b11 = yiq_const_type::b11(), b12 = yiq_const_type::b12(), b13 = yiq_const_type::b13();
66            static scalar_type b21 = yiq_const_type::b21(), b22 = yiq_const_type::b22(), b23 = yiq_const_type::b23();
67            static scalar_type b31 = yiq_const_type::b31(), b32 = yiq_const_type::b32(), b33 = yiq_const_type::b33();
68            static scalar_type const                              b32n = -b32;
69 
70            scalar_type r = normalize_type::template process<red_p  >( container_right_trait_type::template get<red_p  >( right ) );
71            scalar_type g = normalize_type::template process<green_p>( container_right_trait_type::template get<green_p>( right ) );
72            scalar_type b = normalize_type::template process<blue_p >( container_right_trait_type::template get<blue_p >( right ) );
73 
74            scalar_type y = b11 * r + b12 * g + b13 * b;
75            scalar_type i = b21 * r + b22 * g + b23 * b;
76            scalar_type q = b31 * r + b32 * g + b33 * b;
77 
78            i = ( i / b21  + scalar_type(1) ) / scalar_type(2);
79            q = ( q / b32n + scalar_type(1) ) / scalar_type(2);
80 
81            container_left_trait_type::template set<      luma_p>( left, diverse_type::template process<      luma_p>( y ) );
82            container_left_trait_type::template set<   inphase_p>( left, diverse_type::template process<   inphase_p>( i ) );
83            container_left_trait_type::template set<quadrature_p>( left, diverse_type::template process<quadrature_p>( q ) );
84           }
85       };
86 
87    }
88  }
89 
90 #endif
91