Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009, 2011 EPITA Research and Development 00002 // Laboratory (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_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 // Forward declaration 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 // Locals. 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 // We want min and max between 0 and 1 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 } // end of namespace fun::v2v 00139 00140 } // end of namespace fun 00141 00142 } // end of namespace mln 00143 00144 #endif // ! MLN_FUN_V2V_RGB_TO_HSL_HH