00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 #ifndef MLN_FUN_V2V_HSI_TO_RGB_HH
00027 # define MLN_FUN_V2V_HSI_TO_RGB_HH
00028 
00032 
00033 #include <cmath>
00034 
00035 #include <mln/value/rgb8.hh>
00036 #include <mln/math/round.hh>
00037 
00038 #include <mln/value/hsi.hh>
00039 
00040 
00041 namespace mln
00042 {
00043 
00044 
00045   namespace fun
00046   {
00047 
00048     namespace v2v
00049     {
00050 
00054       
00055       template <typename T_rgb>
00056       struct f_hsi_to_rgb_ : public Function_v2v< f_hsi_to_rgb_<T_rgb> >
00057       {
00058         typedef T_rgb result;
00059 
00060         template <typename T_hsi>
00061         T_rgb operator()(const T_hsi& hsi) const;
00062 
00063       };
00064 
00065       typedef f_hsi_to_rgb_<value::rgb8> f_hsi_to_rgb_3x8_t;
00066 
00067       extern f_hsi_to_rgb_3x8_t f_hsi_to_rgb_3x8;
00068 
00069 
00070 # ifndef MLN_INCLUDE_ONLY
00071 
00074       f_hsi_to_rgb_3x8_t f_hsi_to_rgb_3x8;
00076 
00077       template <typename T_rgb>
00078       template <typename T_hsi>
00079       inline
00080       T_rgb
00081       f_hsi_to_rgb_<T_rgb>::operator()(const T_hsi& hsi) const
00082       {
00083         typedef typename T_rgb::red_t   red_t;
00084         typedef typename T_rgb::green_t green_t;
00085         typedef typename T_rgb::blue_t  blue_t;
00086 
00087         static math::round<red_t>   to_r;
00088         static math::round<green_t> to_g;
00089         static math::round<blue_t>  to_b;
00090 
00091         static const float
00092           sqrt3_3   = std::sqrt(3) / 3,
00093           inv_sqrt6 = 1 / std::sqrt(6),
00094           inv_sqrt2 = 1 / std::sqrt(2);
00095 
00096         float
00097           h     = hsi.hue() / 180.0 * 3.1415,
00098           alpha = hsi.sat() * std::cos(h),
00099           beta  = hsi.sat() * std::sin(h);
00100 
00101 
00102         red_t   r = to_r(sqrt3_3 * hsi.inty() + 2 * inv_sqrt6 * beta);
00103         green_t g =
00104           to_g(sqrt3_3 * hsi.inty() + inv_sqrt2 * alpha - inv_sqrt6 * beta);
00105         blue_t  b =
00106           to_b(sqrt3_3 * hsi.inty() - inv_sqrt2 * alpha - inv_sqrt6 * beta);
00107 
00108         T_rgb rgb(r, g, b);
00109 
00110         return rgb;
00111       }
00112 
00113 # endif // !MLN_INCLUDE_ONLY
00114 
00115     } 
00116 
00117   } 
00118 
00119 } 
00120 
00121 #endif // ! MLN_FUN_V2V_HSI_TO_RGB_HH