• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

hsl_to_rgb.hh

00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
00002 // (LRDE)
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
00026 
00027 #ifndef MLN_FUN_V2V_HSL_TO_RGB_HH
00028 # define MLN_FUN_V2V_HSL_TO_RGB_HH
00029 
00035 
00036 # include <cmath>
00037 
00038 # include <mln/math/round.hh>
00039 # include <mln/math/max.hh>
00040 # include <mln/math/min.hh>
00041 
00042 # include <mln/trait/value_.hh>
00043 
00044 # include <mln/value/rgb.hh>
00045 
00046 
00047 
00048 namespace mln
00049 {
00050 
00051   // Forward declarations
00052   namespace value
00053   {
00054     template <typename H, typename S, typename L> class hsl_;
00055     typedef hsl_<float, float, float> hsl_f;
00056     template <unsigned n> struct rgb;
00057   }
00058 
00059   namespace fun
00060   {
00061 
00062     namespace v2v
00063     {
00064 
00068       //
00069       template <typename T_rgb>
00070       struct f_hsl_to_rgb_ : public Function_v2v< f_hsl_to_rgb_<T_rgb> >
00071       {
00072         typedef T_rgb result;
00073 
00074         template <typename T_hsl>
00075         T_rgb operator()(const T_hsl& hsl) const;
00076 
00077       };
00078 
00079       typedef f_hsl_to_rgb_< value::rgb<8> > f_hsl_to_rgb_3x8_t;
00080       typedef f_hsl_to_rgb_< value::rgb<16> > f_hsl_to_rgb_3x16_t;
00081 
00082       extern f_hsl_to_rgb_3x8_t f_hsl_to_rgb_3x8;
00083       extern f_hsl_to_rgb_3x16_t f_hsl_to_rgb_3x16;
00084 
00085 
00086 # ifndef MLN_INCLUDE_ONLY
00087 
00088 #  ifndef MLN_WO_GLOBAL_VARS
00089 
00092       f_hsl_to_rgb_3x8_t f_hsl_to_rgb_3x8;
00093       f_hsl_to_rgb_3x16_t f_hsl_to_rgb_3x16;
00095 #  endif // !MLN_WO_GLOBAL_VARS
00096 
00097 
00101       template <typename T_rgb>
00102       template <typename T_hsl>
00103       inline
00104       T_rgb
00105       f_hsl_to_rgb_<T_rgb>::operator()(const T_hsl& hsl) const
00106       {
00107         typedef typename T_rgb::red_t   red_t;
00108         typedef typename T_rgb::green_t green_t;
00109         typedef typename T_rgb::blue_t  blue_t;
00110 
00111         static math::round<red_t>   to_r;
00112         static math::round<green_t> to_g;
00113         static math::round<blue_t>  to_b;
00114 
00115         const float q = (hsl.lum() < 0.5) ? hsl.lum() * (1.0 + hsl.sat()) :
00116                                             hsl.lum() + hsl.sat() - (hsl.lum() * hsl.sat());
00117         const float p = 2.0 * hsl.lum() - q;
00118         const float hk = hsl.hue() / 360.0; // hk = normalized hue
00119         float tr = hk + (1.0 / 3.0);
00120         float tg = hk;
00121         float tb = hk - (1.0 / 3.0);
00122 
00123         if (tr < 0.0)
00124           tr += 1.0;
00125         if (tr > 1.0)
00126           tr -= 1.0;
00127 
00128         if (tg < 0.0)
00129           tg += 1.0;
00130         if (tg > 1.0)
00131           tg -= 1.0;
00132 
00133         if (tb < 0.0)
00134           tb += 1.0;
00135         if (tb > 1.0)
00136           tb -= 1.0;
00137 
00138         // Red.
00139         float red;
00140         if (tr < (1.0 / 6.0))
00141           red = p + ((q - p) * 6 * tr);
00142         else if (tr < (1.0 / 2.0))
00143           red = q;
00144         else if (tr < (2.0 / 3.0))
00145           red = p + ((q - p) * 6 * ((2.0 / 3.0) - tr));
00146         else
00147           red = p;
00148 
00149         // Green.
00150         float green;
00151         if (tg < (1.0 / 6.0))
00152           green = p + ((q - p) * 6 * tg);
00153         else if (tg < (1.0 / 2.0))
00154           green = q;
00155         else if (tg < (2.0 / 3.0))
00156           green = p + ((q - p) * 6 * ((2.0 / 3.0) - tg));
00157         else
00158           green = p;
00159 
00160         // Blue.
00161         float blue;
00162         if (tb < (1.0 / 6.0))
00163           blue = p + ((q - p) * 6 * tb);
00164         else if (tb < (1.0 / 2.0))
00165           blue = q;
00166         else if (tb < (2.0 / 3.0))
00167           blue = p + ((q - p) * 6 * ((2.0 / 3.0) - tb));
00168         else
00169           blue = p;
00170 
00171         // Each component is in [0, 1].
00172         red_t   r = to_r(red * 255);
00173         green_t g = to_g(green * 255);
00174         blue_t  b = to_b(blue * 255);
00175 
00176         T_rgb rgb_result(r, g, b);
00177 
00178         return rgb_result;
00179       }
00180 
00181 # endif // !MLN_INCLUDE_ONLY
00182 
00183     } // end of namespace fun::v2v
00184 
00185   } // end of namespace fun
00186 
00187 } // end of namespace mln
00188 
00189 
00190 #endif // ! MLN_FUN_V2V_HSL_TO_RGB_HH

Generated on Tue Oct 4 2011 15:23:56 for Milena (Olena) by  doxygen 1.7.1