00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_MASKED_DILATION_TABLES_INCLUDE
00013 #define MTL_MASKED_DILATION_TABLES_INCLUDE
00014
00015 #include <iostream>
00016 #include <iomanip>
00017
00018 namespace mtl { namespace dilated {
00019
00020 template <class T, T Mask>
00021 struct masked_dilation_tables
00022 {
00023 typedef masked_dilation_tables self;
00024 typedef T value_type;
00025 const static T mask= Mask;
00026
00027 static const T n_bytes= sizeof(T);
00028 typedef T lookup_type[n_bytes][256];
00029 typedef T mp_type[n_bytes];
00030 typedef T it_type[n_bytes];
00031
00032 protected:
00033 static lookup_type* my_mask_lut;
00034 static lookup_type* my_unmask_lut;
00035 static mp_type* my_mask_piece;
00036 static it_type* my_mask_size;
00037 static it_type* my_mask_shift_table;
00038 static it_type* my_unmask_shift_table;
00039 static T n_valid_table;
00040
00041 public:
00042 lookup_type& mask_lut()
00043 {
00044
00045 return *my_mask_lut;
00046 }
00047
00048 lookup_type& unmask_lut()
00049 {
00050
00051 return *my_unmask_lut;
00052 }
00053
00054 mp_type& mask_piece()
00055 {
00056
00057 return *my_mask_piece;
00058 }
00059
00060 it_type& mask_size()
00061 {
00062
00063 return *my_mask_size;
00064 }
00065
00066 it_type& mask_shift_table()
00067 {
00068
00069 return *my_mask_shift_table;
00070 }
00071
00072 it_type& unmask_shift_table()
00073 {
00074
00075 return *my_unmask_shift_table;
00076 }
00077
00078 private:
00079
00080
00081 static T get_f_mask(int n_bits)
00082 {
00083 return (1 << n_bits) - 1;
00084 }
00085
00086 T inc(T i, T mask)
00087 {
00088 return ((i - mask) & mask);
00089 }
00090
00091 void compute_tables()
00092 {
00093
00094 init();
00095
00096
00097 for (T j = 0; j < n_valid_table; ++j) {
00098 T f_mask = get_f_mask(mask_size()[j]), i, ii;
00099 for (i = 0, ii = 0; i < 256; ++i, ii = inc(ii, mask_piece()[j])) {
00100 mask_lut()[j][i] = (ii & f_mask) << mask_shift_table()[j];
00101 }
00102 }
00103
00104
00105 T f_mask = get_f_mask(8);
00106 for (T j = 0; j < sizeof(T); ++j) {
00107
00108 T t_mask = (Mask >> (8*j)) & f_mask, i, ii;
00109 for(i = 0, ii = 0; ii < t_mask; ii = inc(ii, t_mask), ++i) {
00110 unmask_lut()[j][ii] = i << unmask_shift_table()[j];
00111 }
00112
00113 unmask_lut()[j][t_mask] = i << unmask_shift_table()[j];
00114 }
00115 }
00116
00117
00118 void allocate()
00119 {
00120 my_mask_lut= new lookup_type[1];
00121 my_unmask_lut= new lookup_type[1];
00122 my_mask_piece= new mp_type[1];
00123 my_mask_size= new it_type[1];
00124 my_mask_shift_table= new it_type[1];
00125 my_unmask_shift_table= new it_type[1];
00126 }
00127
00128
00129
00130 void init()
00131 {
00132 allocate();
00133
00134
00135 int n = count_n_ones(Mask);
00136 if (n <= 8)
00137 n_valid_table = 1;
00138 else n_valid_table = (n%8 == 0 ? n/8 : n/8 + 1);
00139
00140
00141 set_mask();
00142 }
00143
00144
00145
00146 int count_n_ones(T t)
00147 {
00148 int n_ones = 0;
00149 while(t) {
00150 if((t & 0x01) == 1) ++n_ones;
00151 t = t >>1;
00152 }
00153 return n_ones;
00154 };
00155
00156
00157
00158 int count_bits(T t)
00159 {
00160 int bits = 0;
00161 while(t) {
00162 ++bits;
00163 t = t >>1;
00164 }
00165 return bits;
00166 };
00167
00168
00169
00170 void set_mask()
00171 {
00172
00173 unmask_shift_table()[0] = 0;
00174 T t_mask = Mask, tmp, count;
00175 for (T i = 1; i < n_bytes; ++i) {
00176 tmp = t_mask & get_f_mask(8);
00177 count = count_n_ones(tmp);
00178 unmask_shift_table()[i] = count + unmask_shift_table()[i - 1];
00179 t_mask >>= 8;
00180 }
00181
00182 mask_shift_table()[0] = 0;
00183
00184
00185 if (n_valid_table == 1) {
00186 mask_piece()[0] = Mask;
00187 mask_size()[0] = count_bits(Mask);
00188 return;
00189 }
00190
00191 t_mask = Mask;
00192 for (T i = 0; i < n_valid_table - 1; ++i) {
00193 T n_bits = 0, tmp = t_mask;
00194 for (T n_ones= 0; n_ones < 8; ++n_bits) {
00195 if ((t_mask & 0x01) == 1) ++n_ones;
00196 t_mask = t_mask >>1;
00197 }
00198
00199 mask_piece()[i] = get_f_mask(n_bits) & tmp;
00200
00201
00202 mask_size()[i] = n_bits;
00203
00204
00205 mask_shift_table()[i + 1] = n_bits + mask_shift_table()[i];
00206 }
00207
00208
00209
00210 mask_piece()[n_valid_table - 1 ] = t_mask;
00211 mask_size()[n_valid_table - 1] = count_bits(t_mask);
00212 };
00213
00214 public:
00215
00216 void check()
00217 {
00218 if (n_valid_table == 0)
00219 compute_tables();
00220 }
00221
00222
00223 T to_masked(T x)
00224 {
00225 check();
00226 T result = 0;
00227 for (T i = 0; i < n_valid_table; ++i)
00228 result += mask_lut()[i][0xff & (x >> (8*i)) ];
00229 return result;
00230 }
00231
00232
00233
00234 T to_unmasked(T x)
00235 {
00236 check();
00237 T result = 0;
00238 x &= Mask;
00239 for (T i = 0; i < n_bytes; ++i) {
00240
00241
00242 result += unmask_lut()[i][0xff & (x >> (8*i)) ];
00243 }
00244 return result;
00245 }
00246 };
00247
00248 template <class T, T Mask>
00249 typename masked_dilation_tables<T, Mask>::lookup_type* masked_dilation_tables<T, Mask>::my_mask_lut= 0;
00250
00251 template <class T, T Mask>
00252 typename masked_dilation_tables<T, Mask>::lookup_type* masked_dilation_tables<T, Mask>::my_unmask_lut= 0;
00253
00254 template <class T, T Mask>
00255 typename masked_dilation_tables<T, Mask>::mp_type* masked_dilation_tables<T, Mask>::my_mask_piece= 0;
00256
00257 template <class T, T Mask>
00258 typename masked_dilation_tables<T, Mask>::it_type* masked_dilation_tables<T, Mask>::my_mask_size= 0;
00259
00260 template <class T, T Mask>
00261 typename masked_dilation_tables<T, Mask>::it_type* masked_dilation_tables<T, Mask>::my_mask_shift_table= 0;
00262
00263 template <class T, T Mask>
00264 typename masked_dilation_tables<T, Mask>::it_type* masked_dilation_tables<T, Mask>::my_unmask_shift_table= 0;
00265
00266 template <class T, T Mask>
00267 T masked_dilation_tables<T, Mask>::n_valid_table= 0;
00268
00269
00270
00271
00272 template <long unsigned Mask, typename T>
00273 inline T mask(T const& value)
00274 {
00275 masked_dilation_tables<T, T(Mask)> tables;
00276 return tables.to_masked(value);
00277 }
00278
00279
00280
00281 template <typename T, T Mask>
00282 inline T mask(T const& value, masked_dilation_tables<T, Mask> tables)
00283 {
00284 return tables.to_masked(value);
00285 }
00286
00287
00288
00289
00290 template <long unsigned Mask, typename T>
00291 inline T unmask(T const& value)
00292 {
00293 masked_dilation_tables<T, T(Mask)> tables;
00294 return tables.to_unmasked(value);
00295 }
00296
00297
00298
00299 template <typename T, T Mask>
00300 inline T unmask(T const& value, masked_dilation_tables<T, Mask> tables)
00301 {
00302 return tables.to_unmasked(value);
00303 }
00304
00305
00306
00307
00308
00309 template <long unsigned Mask1, long unsigned Mask2, typename T>
00310 inline T convert(T const& value)
00311 {
00312 return mask<Mask2>(unmask<Mask1>(value));
00313 }
00314
00315
00316 template <long unsigned Mask1, long unsigned Mask2, typename T>
00317 inline T convert(T const& value, masked_dilation_tables<T, Mask1> const& tables1,
00318 masked_dilation_tables<T, Mask2> const& tables2)
00319 {
00320 return tables2.to_masked(tables1.to_unmasked(value));
00321 }
00322
00323
00324
00325 }
00326
00327
00328
00329 }
00330
00331 #endif // MTL_MASKED_DILATION_TABLES_INCLUDE