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
00028 #ifndef NTG_COLOR_COLOR_HH
00029 # define NTG_COLOR_COLOR_HH
00030
00031
00032
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
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
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
00098 _to_float<n + 1, ncomps, qbits, color_system>::doit(in, out);
00099 }
00100 };
00101
00102
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
00144 _from_float<n + 1, ncomps, qbits, color_system>::doit(in, out);
00145 }
00146 };
00147
00148
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 }
00163
00164
00165
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
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
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 }
00305
00306 }
00307
00308 #endif // !NTG_COLOR_COLOR_HH