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