rgbhsv.hh

Go to the documentation of this file.
00001 // Copyright (C) 2001, 2002, 2003, 2004  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
00016 // MA 02111-1307, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library 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
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
00027 
00028 
00029 #ifndef OLENA_CONVERT_RGBHSV_HH
00030 # define OLENA_CONVERT_RGBHSV_HH
00031 
00032 # include <oln/basics.hh>
00033 # include <oln/convert/abstract/colorconv.hh>
00034 
00035 # include <ntg/basics.hh>
00036 # include <ntg/color/rgb.hh>
00037 # include <ntg/color/hsv.hh>
00038 
00039 # include <mlc/contract.hh>
00040 
00041 # include <sstream>
00042 
00047 namespace oln {
00048 
00049   using namespace ntg;
00050 
00051   namespace convert {
00052 
00057     template<unsigned inbits, unsigned outbits>
00058     struct f_rgb_to_hsv
00059       : public abstract::color_conversion<3, inbits, rgb_traits,
00060                                           3, outbits, hsv_traits, f_rgb_to_hsv<inbits, outbits> >
00061     {
00062       color<3, outbits, hsv_traits>
00063       doit(const color<3, inbits, rgb_traits>& v) const
00064       {
00065         vec<3, float> in = v.to_float();
00066         vec<3, float> out;
00067         float max_in = std::max(in[rgb_R], std::max(in[rgb_B], in[rgb_G]));
00068         float min_in = std::min(in[rgb_R], std::min(in[rgb_B], in[rgb_G]));
00069         float delta = max_in - min_in;
00070 
00071 
00072         out[hsv_V] = max_in;
00073 
00074         if (max_in != 0)
00075           out[hsv_S] = delta / max_in;
00076         else
00077           out[hsv_S] = 0;
00078 
00079         if (out[hsv_S] == 0)
00080           out[hsv_H] = -1;   // undefined
00081         else {
00082           if (in[rgb_R] == max_in)
00083             out[hsv_H] = (in[rgb_G] - in[rgb_B]) / delta;
00084           else if (in[rgb_G] == max_in)
00085             out[hsv_H] = 2 + (in[rgb_B] - in[rgb_R]) / delta;
00086           else
00087             out[hsv_H] = 4 + (in[rgb_R] - in[rgb_G]) / delta;
00088           out[hsv_H] *= 60;
00089           if (out[hsv_H] < 0)
00090             out[hsv_H] += 360;
00091         }
00092 
00093         return out;
00094       }
00095 
00096       static std::string
00097       name()
00098       {
00099         std::ostringstream s;
00100         s << "f_rgb_to_hsv<" << inbits << ", " << outbits << '>';
00101         s.str();
00102       }
00103     };
00104 
00109     template <unsigned inbits, unsigned outbits>
00110     color<3, outbits, hsv_traits>
00111     rgb_to_hsv(const color<3, inbits, rgb_traits>& v)
00112     {
00113       f_rgb_to_hsv<inbits, outbits> f;
00114       return f(v);
00115     }
00116 
00121     template<unsigned inbits, unsigned outbits>
00122     struct f_hsv_to_rgb
00123       : public abstract::color_conversion<3, inbits, hsv_traits,
00124                                 3, outbits, rgb_traits, f_hsv_to_rgb<inbits, outbits> >
00125     {
00126       color<3, outbits, rgb_traits>
00127       doit(const color<3, inbits, hsv_traits>& v) const
00128       {
00129         vec<3, float> in = v.to_float();
00130         vec<3, float> out;
00131 
00132         if(in[hsv_S] == 0)
00133           out[rgb_G] = out[rgb_B] = out[rgb_R] = in[hsv_V];
00134         else
00135           {
00136             in[hsv_H] /= 60;
00137             int i = (int)floor (in[hsv_H]);
00138             float f = in[hsv_H] - i;
00139             float p = in[hsv_V] * (1 - in[hsv_S]);
00140             float q = in[hsv_V] * (1 - in[hsv_S] * f);
00141             float t = in[hsv_V] * (1 - in[hsv_S] * (1 - f));
00142 
00143             switch (i){
00144             case 0:
00145             case 6:
00146               out[rgb_R] = in[hsv_V];
00147               out[rgb_G] = t;
00148               out[rgb_B] = p;
00149               break;
00150             case 1:
00151               out[rgb_R] = q;
00152               out[rgb_G] = in[hsv_V];
00153               out[rgb_B] = p;
00154               break;
00155             case 2:
00156               out[rgb_R] = p;
00157               out[rgb_G] = in[hsv_V];
00158               out[rgb_B] = t;
00159               break;
00160             case 3:
00161               out[rgb_R] = p;
00162               out[rgb_G] = q;
00163               out[rgb_B] = in[hsv_V];
00164               break;
00165             case 4:
00166               out[rgb_R] = t;
00167               out[rgb_G] = p;
00168               out[rgb_B] = in[hsv_V];
00169               break;
00170             default:
00171               out[rgb_R] = in[hsv_V];
00172               out[rgb_G] = p;
00173               out[rgb_B] = q;
00174               break;
00175             }
00176           }
00177         return out;
00178       }
00179 
00180       static std::string
00181       name()
00182       {
00183         std::ostringstream s;
00184         s << "f_hsv_to_rgb<" << inbits << ", " << outbits << '>';
00185         s.str();
00186       }
00187     };
00188 
00193     template <unsigned inbits, unsigned outbits>
00194     color<3, outbits, rgb_traits>
00195     hsv_to_rgb(const color<3, inbits, hsv_traits>& v)
00196     {
00197       f_hsv_to_rgb<inbits, outbits> f;
00198       return f(v);
00199     }
00200 
00201   } // convert
00202 } // oln
00203 
00204 #endif // OLENA_CONVERT_RGBHSV_HH

Generated on Thu Apr 15 20:13:14 2004 for Olena by doxygen 1.3.6-20040222