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 template <typename T_rgb>
00062 T_hsl operator()(const T_rgb& rgb) const;
00063
00064 };
00065
00066 typedef f_rgb_to_hsl_<value::hsl_f> f_rgb_to_hsl_f_t;
00067
00068 extern f_rgb_to_hsl_f_t f_rgb_to_hsl_f;
00069
00070
00071 # ifndef MLN_INCLUDE_ONLY
00072
00075 f_rgb_to_hsl_f_t f_rgb_to_hsl_f;
00077
00078
00079 template <typename T_hsl>
00080 template <typename T_rgb>
00081 inline
00082 T_hsl
00083 f_rgb_to_hsl_<T_hsl>::operator()(const T_rgb& rgb) const
00084 {
00085
00086 T_hsl hsl;
00087
00088 typename T_rgb::red_t rmax = math::max(rgb.red(), math::max(rgb.green(), rgb.blue()));
00089 typename T_rgb::red_t rmin = math::min(rgb.red(), math::min(rgb.green(), rgb.blue()));
00090
00091 if (rmin == rmax)
00092 hsl.hue() = 0;
00093 else
00094 if (rmax == rgb.red())
00095 {
00096 hsl.hue() = (60. * (rgb.green() - rgb.blue()) / (rmax - rmin));
00097 if (hsl.hue() < 0)
00098 hsl.hue() += 360.;
00099 }
00100 else
00101 if (rmax == rgb.green())
00102 hsl.hue() = (60. * (rgb.blue() - rgb.red()) / (rmax - rmin)) + 120.;
00103 else
00104 hsl.hue() = (60. * (rgb.red() - rgb.green()) / (rmax - rmin)) + 240;
00105
00106 hsl.lum() = ((double) rmax + (double) rmin) / 2;
00107
00108
00109 rmax -= mln_min(typename T_rgb::red_t);
00110 rmin -= mln_min(typename T_rgb::red_t);
00111 double nmax = (double) rmax / (mln_max(typename T_rgb::red_t) - mln_min(typename T_rgb::red_t));
00112 double nmin = (double) rmin / (mln_max(typename T_rgb::red_t) - mln_min(typename T_rgb::red_t));
00113
00114 if (rmin == rmax)
00115 hsl.sat() = 0;
00116 else
00117 if (hsl.lum() <= 0.5)
00118 hsl.sat() = (nmax - nmin) / (nmax + nmin);
00119 else
00120 hsl.sat() = (nmax - nmin) / (2 - nmax - nmin);
00121
00122 return hsl;
00123 }
00124
00125
00126 # endif // !MLN_INCLUDE_ONLY
00127
00128 }
00129
00130 }
00131
00132 }
00133
00134 #endif // ! MLN_FUN_V2V_RGB_TO_HSL_HH