00001
00002 #ifndef mbl_mask_h_
00003 #define mbl_mask_h_
00004
00005
00006
00007
00008
00009 #include <vcl_algorithm.h>
00010 #include <vcl_vector.h>
00011 #include <vcl_stdexcept.h>
00012 #include <vcl_iterator.h>
00013 #include <vcl_string.h>
00014 #include <vcl_iosfwd.h>
00015 #include <vcl_cstddef.h>
00016 #include <vcl_iostream.h>
00017 #include <vul/vul_sprintf.h>
00018
00019
00020
00021
00022 class mbl_mask : public vcl_vector<bool>
00023 {
00024 public:
00025 mbl_mask() : vcl_vector<bool>() {}
00026 mbl_mask(unsigned n, bool val = false) : vcl_vector<bool>(n, val) {}
00027 };
00028
00029
00030
00031
00032
00033
00034 void mbl_masks_from_index_set(const vcl_vector<unsigned> & indices,
00035 vcl_vector<mbl_mask> & masks);
00036
00037
00038
00039 void mbl_mask_on_mask(const mbl_mask & A, mbl_mask & B);
00040
00041
00042
00043 template <typename ForwardIterator>
00044 void mbl_mask_merge_values(const mbl_mask & mask,
00045 ForwardIterator first1, ForwardIterator last1,
00046 ForwardIterator first2, ForwardIterator last2,
00047 ForwardIterator result)
00048 {
00049 if (vcl_distance(first1, last1) != (int)mask.size() || vcl_distance(first2, last2) != (int)mask.size())
00050 throw vcl_out_of_range("Values and mask lengths differ");
00051
00052 for (unsigned n = 0 ; first1 != last1 ; ++first1, ++first2, ++n)
00053 *result++ = mask[n] ? *first2 : *first1;
00054 }
00055
00056
00057 void mbl_mask_logic(const mbl_mask & A, mbl_mask & B, const vcl_string & operation);
00058
00059
00060 void mbl_mask_logic_and(const mbl_mask & A, mbl_mask & B);
00061
00062
00063 void mbl_mask_logic_or(const mbl_mask & A, mbl_mask & B);
00064
00065
00066 void mbl_mask_logic_xor(const mbl_mask & A, mbl_mask & B);
00067
00068
00069 void mbl_mask_logic_nor(const mbl_mask & A, mbl_mask & B);
00070
00071
00072 void mbl_mask_logic_xnor(const mbl_mask & A, mbl_mask & B);
00073
00074
00075 void mbl_mask_logic_nand(const mbl_mask & A, mbl_mask & B);
00076
00077
00078 template <typename ForwardIterator, typename OutputIterator>
00079 void mbl_apply_mask(const mbl_mask & mask, ForwardIterator first, ForwardIterator last, OutputIterator target)
00080 {
00081 if (vcl_distance(first, last) != (int)mask.size())
00082 throw vcl_out_of_range("Values and mask lengths differ");
00083
00084 for (unsigned n = 0; first != last ; ++first, ++n)
00085 if (mask[n]) *target++ = *first;
00086 }
00087
00088
00089
00090 template <typename T>
00091 vcl_vector<T> mbl_apply_mask(const mbl_mask & mask, const vcl_vector<T> & values)
00092 {
00093 vcl_vector<T> retval(values);
00094 mbl_apply_mask(mask, retval);
00095 return retval;
00096 }
00097
00098
00099
00100
00101
00102 template <typename T>
00103 void mbl_apply_mask(const mbl_mask & mask, const vcl_vector<T> & src, vcl_vector<T> & dst)
00104 {
00105 const unsigned n_in = src.size();
00106 if (mask.size() != n_in)
00107 {
00108 throw vcl_out_of_range(vul_sprintf("src and mask lengths differ: src %d mask %d",n_in,mask.size()));
00109 }
00110
00111 dst.clear();
00112 dst.reserve(n_in);
00113 for (unsigned i=0; i<n_in; ++i)
00114 {
00115 if (mask[i])
00116 {
00117 dst.push_back(src[i]);
00118 }
00119 }
00120 }
00121
00122
00123
00124
00125
00126
00127 template <typename T>
00128 void mbl_replace_using_mask(const mbl_mask & mask, const vcl_vector<T> & src1, const vcl_vector<T> & src2, vcl_vector<T> & dst)
00129 {
00130 const unsigned n_in = src1.size();
00131 if (mask.size() != n_in)
00132 throw vcl_out_of_range("src1 and mask lengths differ");
00133
00134 vcl_size_t n_true = vcl_count( mask.begin(), mask.end(), true );
00135 if ( n_true != src2.size() )
00136 throw vcl_out_of_range("src2 and mask are not compatible");
00137
00138 vcl_vector<T> dst_tmp;
00139 dst_tmp.clear();
00140 dst_tmp.reserve(n_in);
00141 unsigned j = 0;
00142 for (unsigned i=0; i<n_in; ++i)
00143 {
00144 if (mask[i])
00145 {
00146 dst_tmp.push_back(src2[j]);
00147 ++j;
00148 }
00149 else
00150 dst_tmp.push_back(src1[i]);
00151 }
00152 dst = dst_tmp;
00153 }
00154
00155
00156 template <typename T>
00157 void mbl_apply_mask(const mbl_mask & mask, vcl_vector<T> & values)
00158 {
00159 const unsigned n_in = values.size();
00160 if (mask.size() != n_in)
00161 throw vcl_out_of_range("Values and mask lengths differ");
00162
00163 unsigned n_out = 0;
00164 for (unsigned i = 0 ; i < n_in ; ++i)
00165 {
00166 if (mask[i])
00167 {
00168 values[n_out] = values[i];
00169 ++n_out;
00170 }
00171 }
00172 values.resize(n_out);
00173 }
00174
00175
00176 void mbl_save_mask(const mbl_mask & mask, vcl_ostream & stream);
00177
00178
00179 void mbl_save_mask(const mbl_mask & mask, const char * filename);
00180
00181
00182 void mbl_save_mask(const mbl_mask & mask, const vcl_string &filename);
00183
00184
00185 void mbl_load_mask(mbl_mask & mask, vcl_istream & stream);
00186
00187
00188 void mbl_load_mask(mbl_mask & mask, const char * filename);
00189
00190
00191 void mbl_load_mask(mbl_mask & mask, const vcl_string &filename);
00192
00193
00194
00195
00196 void mbl_mask_to_indices(const mbl_mask& mask, vcl_vector<unsigned>& inds);
00197
00198
00199
00200
00201
00202 void mbl_indices_to_mask(const vcl_vector<unsigned>& inds,
00203 const unsigned n,
00204 mbl_mask& mask);
00205
00206
00207
00208
00209 #endif // mbl_mask_h_