color.hh

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 #ifndef NTG_COLOR_COLOR_HH
00029 # define NTG_COLOR_COLOR_HH
00030 
00031 /*
00032   Header for generic color type, from which real color types are defined.
00033 */
00034 
00035 # include <ntg/basics.hh>
00036 # include <ntg/int.hh>
00037 # include <ntg/vect/vec.hh>
00038 # include <ntg/core/pred_succ.hh>
00039 
00040 # include <mlc/cmp.hh>
00041 
00042 # include <iostream>
00043 # include <sstream>
00044 # include <string>
00045 
00046 namespace ntg {
00047 
00048   namespace internal {
00049 
00050     /*------------------.
00051     | typetraits<color> |
00052     `------------------*/
00053 
00054     template <unsigned ncomps,
00055               unsigned qbits,
00056               template <unsigned> class color_system>
00057     struct typetraits<color<ncomps, qbits, color_system> >
00058     {
00059       enum { nb_comp = ncomps };
00060 
00061       typedef color<ncomps, qbits, color_system>        self;
00062       typedef self                                      ntg_type;
00063       typedef vectorial                                 abstract_type;
00064       typedef int_u<qbits>                              comp_type;
00065       typedef self                                      base_type;
00066       typedef vec<ncomps, int_u<qbits> >                storage_type;
00067     };
00068 
00069     /*-------------------------.
00070     | Helper structs for float |
00071     `-------------------------*/
00072 
00077     template <unsigned n,
00078               unsigned ncomps,
00079               unsigned qbits,
00080               template <unsigned> class color_system>
00081     struct _to_float
00082     {
00083       typedef int_u<qbits>              T;
00084       typedef vec<ncomps, T>            in_type;
00085       typedef vec<ncomps, float>        out_type;
00086 
00087       static void
00088       doit (const in_type& in, out_type& out)
00089       {
00090         float in_range = float(ntg_max_val(T)) - float(ntg_min_val(T));
00091         float out_range = float(color_system<n>::upper_bound())
00092           - float(color_system<n>::lower_bound());
00093         out[n] = ((float(in[n]) - float(ntg_min_val(T)))
00094                   * out_range / in_range
00095                   + float(color_system<n>::lower_bound()));
00096 
00097         // process next componant recursively:
00098         _to_float<n + 1, ncomps, qbits, color_system>::doit(in, out);
00099       }
00100     };
00101 
00102     // Stop recursion when n == ncomps.
00103     template <unsigned ncomps,
00104               unsigned qbits,
00105               template <unsigned> class color_system>
00106     struct _to_float<ncomps, ncomps, qbits, color_system>
00107     {
00108       typedef vec<ncomps, int_u<qbits> >        in_type;
00109       typedef vec<ncomps, float>                out_type;
00110 
00111       static void
00112       doit (const in_type&, out_type&)
00113       {}
00114     };
00115 
00120     template <unsigned n,
00121               unsigned ncomps,
00122               unsigned qbits,
00123               template <unsigned> class color_system>
00124     struct _from_float
00125     {
00126       typedef int_u<qbits>              T;
00127       typedef vec<ncomps, float>        in_type;
00128       typedef vec<ncomps, T>            out_type;
00129 
00130       static void
00131       doit (const in_type& in, out_type& out)
00132       {
00133         float out_range = float(optraits<T>::max())
00134           - float(optraits<T>::min());
00135         float in_range = float(color_system<n>::upper_bound())
00136           - float(color_system<n>::lower_bound());
00137 
00138         out[n] = cast::rbound<int_u<qbits> >
00139           ((in[n] - float(color_system<n>::lower_bound()))
00140            * out_range / in_range
00141            + float(color_system<n>::lower_bound()));
00142 
00143         // process next componant recursively:
00144         _from_float<n + 1, ncomps, qbits, color_system>::doit(in, out);
00145       }
00146     };
00147 
00148     // stop recursion when n == ncomps.
00149     template <unsigned ncomps,
00150               unsigned qbits,
00151               template <unsigned> class color_system>
00152     struct _from_float<ncomps, ncomps, qbits, color_system>
00153     {
00154       typedef vec<ncomps, float>                in_type;
00155       typedef vec<ncomps, int_u<qbits> >        out_type;
00156 
00157       static void
00158       doit (const in_type&, out_type&)
00159       {}
00160     };
00161 
00162   } // end of internal.
00163 
00164   /*-----------------------------------.
00165   | color<ncomps, qbits, color_system> |
00166   `-----------------------------------*/
00167 
00169 
00179   template <unsigned ncomps,
00180             unsigned qbits,
00181             template <unsigned> class color_system>
00182   struct color : public vect_value<color<ncomps, qbits, color_system> >
00183   {
00184     typedef int_u<qbits>                comp_type;
00185     typedef vec<ncomps, comp_type>      vec_type;
00186     typedef vec<ncomps, float>          float_vec_type;
00187 
00188     color() {};
00189     color(const vec_type& vec) { this->val_ = vec; };
00190     color(const float_vec_type& vec)
00191     {
00192       internal::_from_float<0,ncomps,qbits,color_system>::doit(vec,this->val_);
00193     }
00194 
00195     color(const comp_type& c1, const comp_type& c2, const comp_type& c3)
00196     {
00197       mlc::is_true<ncomps == 3>::ensure();
00198       this->val_[0] = c1;
00199       this->val_[1] = c2;
00200       this->val_[2] = c3;
00201     }
00202 
00203     vec_type&           as_vec()       { return this->val_; }
00204     const vec_type&     as_vec() const { return this->val_; }
00205 
00206     float_vec_type
00207     to_float() const
00208     {
00209       float_vec_type tmp;
00210       internal::_to_float<0,ncomps,qbits,color_system>::doit(this->val_, tmp);
00211       return tmp;
00212     }
00213 
00214     bool
00215     operator==(const color& r) const
00216     { return this->val_ == r.val_; }
00217   };
00218 
00222   template<int lval, int uval>
00223   struct interval
00224   {
00225     static int lower_bound() { return lval; }
00226     static int upper_bound() { return uval; }
00227   };
00228 
00229   template <unsigned ncomps,
00230             unsigned qbits,
00231             template <unsigned> class color_system>
00232   inline std::ostream&
00233   operator<<(std::ostream& o,
00234              const color<ncomps, qbits, color_system>& r)
00235   {
00236     o << r.as_vec();
00237     return o;
00238   }
00239 
00240   namespace internal
00241   {
00242 
00243     /*----------------.
00244     | optraits<color> |
00245     `----------------*/
00246 
00247     template <unsigned ncomps,
00248               unsigned qbits,
00249               template <unsigned> class color_system>
00250     struct optraits<color<ncomps, qbits, color_system> >
00251     {
00252     private:
00253       typedef color<ncomps, qbits, color_system> self;
00254       typedef typename typetraits<self>::storage_type storage_type;
00255 
00256     public:
00257       static unsigned max_print_width ()
00258       {
00259         return ntg_max_print_width(storage_type);
00260       }
00261 
00262       static std::string
00263       name()
00264       {
00265         std::ostringstream out;
00266         // FIXME: Output color_system somehow.
00267         out << "color<" << ncomps << "," << qbits <<  ",...>" << std::ends;
00268         return out.str();
00269       }
00270     };
00271 
00272 
00273     template <typename T> struct default_less;
00274 
00287     template <unsigned ncomps,
00288               unsigned qbits,
00289               template <unsigned> class color_system>
00290     struct default_less< ntg::color<ncomps, qbits, color_system> >
00291     {
00292       typedef ntg::color<ncomps, qbits, color_system> arg_type;
00293       bool operator()(const arg_type& l,
00294                       const arg_type& r) const
00295       {
00296         for (unsigned i = 0; i < ntg_nb_comp(arg_type); ++i)
00297           if (l[i] < r[i])
00298             return true;
00299           else if (l[i] > r[i])
00300             return false;
00301         return false;
00302       }
00303     };
00304   } // end of internal.
00305 
00306 } // end of ntg.
00307 
00308 #endif // !NTG_COLOR_COLOR_HH

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