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
00027 #ifndef MLN_FUN_V2V_RGB_TO_HSL_HH
00028 # define MLN_FUN_V2V_RGB_TO_HSL_HH
00029
00030 # include <cmath>
00031
00032 # include <mln/math/round.hh>
00033 # include <mln/math/max.hh>
00034 # include <mln/math/min.hh>
00035
00036 # include <mln/trait/value_.hh>
00037
00038 # include <mln/value/rgb.hh>
00039
00040 namespace mln
00041 {
00042
00043
00044 namespace value
00045 {
00046 template <typename H, typename S, typename L> class hsl_;
00047 typedef hsl_<float, float, float> hsl_f;
00048 }
00049
00050 namespace fun
00051 {
00052
00053 namespace v2v
00054 {
00055
00056 template <typename T_hsl>
00057 struct f_rgb_to_hsl_ : public Function_v2v< f_rgb_to_hsl_<T_hsl> >
00058 {
00059 typedef T_hsl result;
00060
00061 f_rgb_to_hsl_();
00062
00063 template <typename T_rgb>
00064 T_hsl operator()(const T_rgb& rgb) const;
00065
00066 };
00067
00068 typedef f_rgb_to_hsl_<value::hsl_f> f_rgb_to_hsl_f_t;
00069
00070 extern f_rgb_to_hsl_f_t f_rgb_to_hsl_f;
00071
00072
00073 # ifndef MLN_INCLUDE_ONLY
00074
00075 # ifndef MLN_WO_GLOBAL_VARS
00076
00079 f_rgb_to_hsl_f_t f_rgb_to_hsl_f;
00081
00082 # endif // ! MLN_WO_GLOBAL_VARS
00083
00084 template <typename T_hsl>
00085 f_rgb_to_hsl_<T_hsl>::f_rgb_to_hsl_()
00086 {
00087 }
00088
00089 template <typename T_hsl>
00090 template <typename T_rgb>
00091 inline
00092 T_hsl
00093 f_rgb_to_hsl_<T_hsl>::operator()(const T_rgb& rgb) const
00094 {
00095
00096 T_hsl hsl;
00097
00098 typename T_rgb::red_t rmax = math::max(rgb.red(), math::max(rgb.green(), rgb.blue()));
00099 typename T_rgb::red_t rmin = math::min(rgb.red(), math::min(rgb.green(), rgb.blue()));
00100
00101 if (rmin == rmax)
00102 hsl.hue() = 0;
00103 else
00104 if (rmax == rgb.red())
00105 {
00106 hsl.hue() = (60. * (rgb.green() - rgb.blue()) / (rmax - rmin));
00107 if (hsl.hue() < 0)
00108 hsl.hue() += 360.;
00109 }
00110 else
00111 if (rmax == rgb.green())
00112 hsl.hue() = (60. * (rgb.blue() - rgb.red()) / (rmax - rmin)) + 120.;
00113 else
00114 hsl.hue() = (60. * (rgb.red() - rgb.green()) / (rmax - rmin)) + 240;
00115
00116
00117 rmax -= mln_min(typename T_rgb::red_t);
00118 rmin -= mln_min(typename T_rgb::red_t);
00119 double nmax = (double) rmax / (mln_max(typename T_rgb::red_t) - mln_min(typename T_rgb::red_t));
00120 double nmin = (double) rmin / (mln_max(typename T_rgb::red_t) - mln_min(typename T_rgb::red_t));
00121
00122 hsl.lum() = ((double) nmax + (double) nmin) / 2;
00123
00124 if (rmin == rmax)
00125 hsl.sat() = 0;
00126 else
00127 if (hsl.lum() <= 0.5)
00128 hsl.sat() = (nmax - nmin) / (nmax + nmin);
00129 else
00130 hsl.sat() = (nmax - nmin) / (2 - nmax - nmin);
00131
00132 return hsl;
00133 }
00134
00135
00136 # endif // !MLN_INCLUDE_ONLY
00137
00138 }
00139
00140 }
00141
00142 }
00143
00144 #endif // ! MLN_FUN_V2V_RGB_TO_HSL_HH