00001
00002
00003
00004
00005
00006
00007
00008 #include "mbl_mask.h"
00009 #include <vcl_set.h>
00010 #include <vcl_map.h>
00011 #include <vcl_fstream.h>
00012 #include <vcl_string.h>
00013 #include <vul/vul_string.h>
00014 #include <mbl/mbl_exception.h>
00015
00016
00017
00018
00019
00020
00021
00022
00023 void mbl_masks_from_index_set(const vcl_vector<unsigned> & indices,
00024 vcl_vector<mbl_mask> & masks)
00025 {
00026 masks.clear();
00027 unsigned n = indices.size(), n_masks = 0;
00028 vcl_set<unsigned> used_indices;
00029 vcl_map<unsigned, unsigned> ordering;
00030
00031 for (unsigned i = 0 ; i < n ; ++i)
00032 used_indices.insert(indices[i]);
00033
00034 for (vcl_set<unsigned>::const_iterator it = used_indices.begin(),
00035 end = used_indices.end();
00036 it != end; ++it)
00037 {
00038 ordering[*it] = n_masks++;
00039 masks.push_back(mbl_mask(n));
00040 }
00041
00042 for (unsigned i = 0 ; i < n ; ++i)
00043 masks[ordering[indices[i]]][i] = true;
00044 }
00045
00046
00047
00048 void mbl_mask_on_mask(const mbl_mask & A, mbl_mask & B)
00049 {
00050 unsigned nA = A.size();
00051 unsigned nB = 0;
00052 for (unsigned i = 0 ; i < B.size() ; ++i) nB += B[i];
00053 if (nA != nB)
00054 throw vcl_out_of_range("mbl_mask: Length of A mismatch with number of true elements of B");
00055
00056 for (unsigned i = 0, j = 0 ; i < B.size() ; ++i)
00057 if (B[i]) B[i] = A[j++];
00058 }
00059
00060
00061
00062 void mbl_mask_logic_and(const mbl_mask & A, mbl_mask & B)
00063 {
00064 mbl_mask_logic(A, B, "0001");
00065 }
00066
00067
00068 void mbl_mask_logic_or(const mbl_mask & A, mbl_mask & B)
00069 {
00070 mbl_mask_logic(A, B, "0111");
00071 }
00072
00073
00074 void mbl_mask_logic_xor(const mbl_mask & A, mbl_mask & B)
00075 {
00076 mbl_mask_logic(A, B, "0110");
00077 }
00078
00079
00080 void mbl_mask_logic_nor(const mbl_mask & A, mbl_mask & B)
00081 {
00082 mbl_mask_logic(A, B, "1000");
00083 }
00084
00085
00086 void mbl_mask_logic_xnor(const mbl_mask & A, mbl_mask & B)
00087 {
00088 mbl_mask_logic(A, B, "1001");
00089 }
00090
00091
00092 void mbl_mask_logic_nand(const mbl_mask & A, mbl_mask & B)
00093 {
00094 mbl_mask_logic(A, B, "1110");
00095 }
00096
00097
00098
00099 void mbl_mask_logic(const mbl_mask & A, mbl_mask & B, const vcl_string & operation)
00100 {
00101 if (A.size() != B.size())
00102 throw vcl_out_of_range("mbl_mask_logic: Mask lengths differ");
00103
00104
00105
00106 if (operation.length() != 4)
00107 throw vcl_length_error("mbl_mask_logic: Operation must be of length 4");
00108 vcl_vector<bool> op_rule(4);
00109 for (unsigned i = 0 ; i < 4 ; ++i)
00110 {
00111 if (operation[i] == '0') op_rule[i] = false;
00112 else if (operation[i] == '1') op_rule[i] = true;
00113 else throw vcl_invalid_argument("mbl_mask_logic: Invalid character in operation string - must contain only '0' or '1'");
00114 }
00115
00116
00117 for (unsigned i = 0 ; i < A.size() ; ++i)
00118 B[i] = op_rule[2*A[i] + B[i]];
00119 }
00120
00121
00122
00123 void mbl_save_mask(const mbl_mask & mask, vcl_ostream & stream)
00124 {
00125 vcl_vector<bool>::const_iterator it = mask.begin();
00126 const vcl_vector<bool>::const_iterator & end = mask.end();
00127 for (; it != end; ++it)
00128 stream << *it << vcl_endl;
00129 }
00130
00131
00132 void mbl_save_mask(const mbl_mask & mask, const char * filename)
00133 {
00134 vcl_ofstream stream(filename);
00135 if (!stream)
00136 mbl_exception_throw_os_error(filename);
00137 mbl_save_mask(mask, stream);
00138 }
00139
00140
00141 void mbl_save_mask(const mbl_mask & mask, const vcl_string &filename)
00142 {
00143 vcl_ofstream stream(filename.c_str());
00144 if (!stream)
00145 mbl_exception_throw_os_error(filename);
00146 mbl_save_mask(mask, stream);
00147 }
00148
00149
00150 void mbl_load_mask(mbl_mask & mask, vcl_istream & stream)
00151 {
00152 mask.clear();
00153 vcl_string line;
00154 while (stream.good())
00155 {
00156 char c='X';
00157 stream >> vcl_ws >> c;
00158 if (stream.eof()) break;
00159 if (c == '0') mask.push_back(false);
00160 else if (c == '1') mask.push_back(true);
00161 else
00162 {
00163 mask.clear();
00164 throw mbl_exception_parse_file_error(vcl_string("Unable to parse mask value " +
00165 vul_string_escape_ctrl_chars(vcl_string(1,c)) ), "" );
00166 }
00167 }
00168 }
00169
00170
00171 void mbl_load_mask(mbl_mask & mask, const char * filename)
00172 {
00173 vcl_ifstream stream(filename);
00174 if (!stream)
00175 mbl_exception_throw_os_error(filename);
00176 try
00177 {
00178 mbl_load_mask(mask, stream);
00179 }
00180 catch (mbl_exception_parse_file_error & e)
00181 {
00182 throw mbl_exception_parse_file_error(e.what(), filename);
00183 }
00184 }
00185
00186
00187 void mbl_load_mask(mbl_mask & mask, const vcl_string &filename)
00188 {
00189 mbl_load_mask( mask, filename.c_str() );
00190 }
00191
00192
00193
00194 void mbl_mask_to_indices(const mbl_mask& mask, vcl_vector<unsigned>& inds)
00195 {
00196 inds.clear();
00197 for (unsigned i=0,n=mask.size(); i<n; ++i)
00198 {
00199 if (mask[i]) inds.push_back(i);
00200 }
00201 }
00202
00203
00204
00205 void mbl_indices_to_mask(const vcl_vector<unsigned>& inds,
00206 const unsigned n,
00207 mbl_mask& mask)
00208 {
00209 mask.resize(n, false);
00210 for (unsigned i=0, m=inds.size(); i<m; ++i)
00211 {
00212 mask[inds[i]]=true;
00213 }
00214 }
00215
00216
00217
00218