color.hh

00001 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 EPITA Research and
00002 // Development Laboratory
00003 //
00004 // This file is part of the Olena Library.  This library is free
00005 // software; you can redistribute it and/or modify it under the terms
00006 // of the GNU General Public License version 2 as published by the
00007 // Free Software Foundation.
00008 //
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this library; see the file COPYING.  If not, write to
00016 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017 // Boston, MA 02110-1301, USA.
00018 //
00019 // As a special exception, you may use this file as part of a free
00020 // software library without restriction.  Specifically, if other files
00021 // instantiate templates or use macros or inline functions from this
00022 // file, or you compile this file and link it with other files to
00023 // produce an executable, this file does not by itself cause the
00024 // resulting executable to be covered by the GNU General Public
00025 // License.  This exception does not however invalidate any other
00026 // reasons why the executable file might be covered by the GNU General
00027 // Public License.
00028 
00029 #ifndef NTG_COLOR_COLOR_HH
00030 # define NTG_COLOR_COLOR_HH
00031 
00032 /*
00033   Header for generic color type, from which real color types are defined.
00034 */
00035 
00036 # include <ntg/basics.hh>
00037 # include <ntg/int.hh>
00038 # include <ntg/vect/vec.hh>
00039 # include <ntg/core/pred_succ.hh>
00040 
00041 # include <mlc/cmp.hh>
00042 
00043 # include <iostream>
00044 # include <sstream>
00045 # include <string>
00046 
00047 namespace ntg {
00048 
00049   namespace internal {
00050 
00051     /*------------------.
00052     | typetraits<color> |
00053     `------------------*/
00054 
00055     template <unsigned ncomps,
00056               unsigned qbits,
00057               template <unsigned> class color_system>
00058     struct typetraits<color<ncomps, qbits, color_system> >
00059     {
00060       static const unsigned nb_comp = ncomps;
00061 
00062       typedef color<ncomps, qbits, color_system>        self;
00063       typedef self                                      ntg_type;
00064       typedef vectorial                                 abstract_type;
00065       typedef int_u<qbits>                              comp_type;
00066       typedef self                                      base_type;
00067       typedef vec<ncomps, int_u<qbits> >                storage_type;
00068     };
00069 
00070     /*-------------------------.
00071     | Helper structs for float |
00072     `-------------------------*/
00073 
00078     template <unsigned n,
00079               unsigned ncomps,
00080               unsigned qbits,
00081               template <unsigned> class color_system>
00082     struct _to_float
00083     {
00084       typedef int_u<qbits>              T;
00085       typedef vec<ncomps, T>            in_type;
00086       typedef vec<ncomps, float>        out_type;
00087 
00088       static void
00089       doit (const in_type& in, out_type& out)
00090       {
00091         float in_range = float(ntg_max_val(T)) - float(ntg_min_val(T));
00092         float out_range = float(color_system<n>::upper_bound())
00093           - float(color_system<n>::lower_bound());
00094         out[n] = ((float(in[n]) - float(ntg_min_val(T)))
00095                   * out_range / in_range
00096                   + float(color_system<n>::lower_bound()));
00097 
00098         // Process next component recursively.
00099         _to_float<n + 1, ncomps, qbits, color_system>::doit(in, out);
00100       }
00101     };
00102 
00103     // Stop recursion when n == ncomps.
00104     template <unsigned ncomps,
00105               unsigned qbits,
00106               template <unsigned> class color_system>
00107     struct _to_float<ncomps, ncomps, qbits, color_system>
00108     {
00109       typedef vec<ncomps, int_u<qbits> >        in_type;
00110       typedef vec<ncomps, float>                out_type;
00111 
00112       static void
00113       doit (const in_type&, out_type&)
00114       {}
00115     };
00116 
00121     template <unsigned n,
00122               unsigned ncomps,
00123               unsigned qbits,
00124               template <unsigned> class color_system>
00125     struct _from_float
00126     {
00127       typedef int_u<qbits>              T;
00128       typedef vec<ncomps, float>        in_type;
00129       typedef vec<ncomps, T>            out_type;
00130 
00131       static void
00132       doit (const in_type& in, out_type& out)
00133       {
00134         float out_range = float(optraits<T>::max())
00135           - float(optraits<T>::min());
00136         float in_range = float(color_system<n>::upper_bound())
00137           - float(color_system<n>::lower_bound());
00138 
00139         out[n] = cast::rbound<int_u<qbits> >
00140           ((in[n] - float(color_system<n>::lower_bound()))
00141            * out_range / in_range
00142            + float(optraits<T>::min()));
00143 
00144         // Process next component recursively.
00145         _from_float<n + 1, ncomps, qbits, color_system>::doit(in, out);
00146       }
00147     };
00148 
00149     // Stop recursion when n == ncomps.
00150     template <unsigned ncomps,
00151               unsigned qbits,
00152               template <unsigned> class color_system>
00153     struct _from_float<ncomps, ncomps, qbits, color_system>
00154     {
00155       typedef vec<ncomps, float>                in_type;
00156       typedef vec<ncomps, int_u<qbits> >        out_type;
00157 
00158       static void
00159       doit (const in_type&, out_type&)
00160       {}
00161     };
00162 
00163   } // end of internal.
00164 
00165   /*-----------------------------------.
00166   | color<ncomps, qbits, color_system> |
00167   `-----------------------------------*/
00168 
00170 
00180   template <unsigned ncomps,
00181             unsigned qbits,
00182             template <unsigned> class color_system>
00183   struct color : public vect_value<color<ncomps, qbits, color_system> >
00184   {
00185     typedef int_u<qbits>                comp_type;
00186     typedef vec<ncomps, comp_type>      vec_type;
00187     typedef vec<ncomps, float>          float_vec_type;
00188 
00189     color() {};
00190     color(const vec_type& vec) { this->val_ = vec; };
00191     color(const float_vec_type& vec)
00192     {
00193       internal::_from_float<0,ncomps,qbits,color_system>::doit(vec,this->val_);
00194     }
00195 
00196     color(const comp_type& c1, const comp_type& c2, const comp_type& c3)
00197     {
00198       mlc::is_true<ncomps == 3>::ensure();
00199       this->val_[0] = c1;
00200       this->val_[1] = c2;
00201       this->val_[2] = c3;
00202     }
00203 
00204     vec_type&           as_vec()       { return this->val_; }
00205     const vec_type&     as_vec() const { return this->val_; }
00206 
00207     float_vec_type
00208     to_float() const
00209     {
00210       float_vec_type tmp;
00211       internal::_to_float<0,ncomps,qbits,color_system>::doit(this->val_, tmp);
00212       return tmp;
00213     }
00214 
00215     bool
00216     operator==(const color& r) const
00217     { return this->val_ == r.val_; }
00218   };
00219 
00223   template<int lval, int uval>
00224   struct interval
00225   {
00226     static int lower_bound() { return lval; }
00227     static int upper_bound() { return uval; }
00228   };
00229 
00230   template <unsigned ncomps,
00231             unsigned qbits,
00232             template <unsigned> class color_system>
00233   inline std::ostream&
00234   operator<<(std::ostream& o,
00235              const color<ncomps, qbits, color_system>& r)
00236   {
00237     o << r.as_vec();
00238     return o;
00239   }
00240 
00241   namespace internal
00242   {
00243 
00244     /*----------------.
00245     | optraits<color> |
00246     `----------------*/
00247 
00248     template <unsigned ncomps,
00249               unsigned qbits,
00250               template <unsigned> class color_system>
00251     struct optraits<color<ncomps, qbits, color_system> >
00252     {
00253     private:
00254       typedef color<ncomps, qbits, color_system> self;
00255       typedef typename typetraits<self>::storage_type storage_type;
00256 
00257     public:
00258       static unsigned max_print_width ()
00259       {
00260         return ntg_max_print_width(storage_type);
00261       }
00262 
00263       static std::string
00264       name()
00265       {
00266         std::ostringstream out;
00267         // FIXME: Output color_system somehow.
00268         out << "color<" << ncomps << "," << qbits <<  ",...>" << std::ends;
00269         return out.str();
00270       }
00271     };
00272 
00273 
00274     template <typename T> struct default_less;
00275 
00288     template <unsigned ncomps,
00289               unsigned qbits,
00290               template <unsigned> class color_system>
00291     struct default_less< ntg::color<ncomps, qbits, color_system> >
00292     {
00293       typedef ntg::color<ncomps, qbits, color_system> arg_type;
00294       bool operator()(const arg_type& l,
00295                       const arg_type& r) const
00296       {
00297         for (unsigned i = 0; i < ntg_nb_comp(arg_type); ++i)
00298           if (l[i] < r[i])
00299             return true;
00300           else if (l[i] > r[i])
00301             return false;
00302         return false;
00303       }
00304     };
00305   } // end of internal.
00306 
00307 } // end of ntg.
00308 
00309 #endif // !NTG_COLOR_COLOR_HH

Generated on Tue Feb 20 20:18:45 2007 for Olena by  doxygen 1.5.1