Commit 735a2a247ec4aeb7655e683a35e8465062e9d16b

Authored by David Mayerich
1 parent c5da6290

started testing out template casting support for stim::envi, added a stim::table…

… class for reading csv files
stim/envi/bil.h
... ... @@ -200,6 +200,11 @@ public:
200 200 /// @param p is a pointer to pre-allocated memory at least B * sizeof(T) in size.
201 201 /// @param x is the x-coordinate (dimension 1) of the spectrum.
202 202 /// @param y is the y-coordinate (dimension 2) of the spectrum.
  203 + bool spectrum(T* p, size_t n, bool PROGRESS = false){
  204 + size_t y = n / X();
  205 + size_t x = n - y * X();
  206 + return binary<T>::read_line_1(p, x, y, PROGRESS);
  207 + }
203 208 bool spectrum(T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){
204 209 return binary<T>::read_line_1(p, x, y, PROGRESS);
205 210 }
... ...
stim/envi/binary.h
... ... @@ -200,11 +200,30 @@ public:
200 200 /// @param p is a pointer to pre-allocated memory equal to the line size R[2]
201 201 /// @param x is the x coordinate
202 202 /// @param y is the y coordinate
203   - bool read_line_2( T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){
  203 + void read_line_2( T* p, size_t n, bool PROGRESS = false){
204 204 unsigned long long i;
205 205  
206 206 if(PROGRESS) progress = 0;
207 207  
  208 + if ( n > R[0] * R[1]){ //make sure the sample and line number is right
  209 + std::cout<<"ERROR: sample or line out of range in "<<__FILE__<<" (line "<<__LINE__<<")"<<std::endl;
  210 + exit(1);
  211 + }
  212 +
  213 + file.seekg(n * sizeof(T), std::ios::beg); //point to the certain sample and line
  214 + for (i = 0; i < R[2]; i++){ //for each band
  215 + file.read((char *)(p + i), sizeof(T));
  216 + file.seekg((R[1] * R[0] - 1) * sizeof(T), std::ios::cur); //go to the next band
  217 + if(PROGRESS) progress = (double)i / (double)R[2] * 100;
  218 + }
  219 + if(PROGRESS) progress = 100;
  220 + }
  221 + void read_line_2( T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){
  222 + read_line_2(p, y * R[0] + x, PROGRESS);
  223 + /*unsigned long long i;
  224 +
  225 + if(PROGRESS) progress = 0;
  226 +
208 227 if ( x >= R[0] || y >= R[1]){ //make sure the sample and line number is right
209 228 std::cout<<"ERROR: sample or line out of range"<<std::endl;
210 229 return false;
... ... @@ -219,7 +238,7 @@ public:
219 238 }
220 239 if(PROGRESS) progress = 100;
221 240  
222   - return true;
  241 + return true;*/
223 242 }
224 243  
225 244 ///Reads a line X (fastest dimension) for a given YZ value
... ... @@ -230,7 +249,7 @@ public:
230 249 bool read_line_0(T * p, unsigned long long y, unsigned long long z, bool PROGRESS = false){
231 250 //test to make sure the specified value is within range
232 251 if( y >= R[1] || z >= R[2] ){
233   - std::cout<<"ERROR: sample or line out of range"<<std::endl;
  252 + std::cout<<"ERROR: sample ("<<y<<", "<<z<<") out of range in "<<__FILE__<<" (line "<<__LINE__<<")"<<std::endl;
234 253 return false;
235 254 }
236 255  
... ... @@ -249,7 +268,7 @@ public:
249 268 if(PROGRESS) progress = 0;
250 269 //test to make sure the specified value is within range
251 270 if( x >= R[0] || z >= R[2] ){
252   - std::cout<<"ERROR: sample or line out of range"<<std::endl;
  271 + std::cout<<"ERROR: sample or line out of range in "<<__FILE__<<" (line "<<__LINE__<<")"<<std::endl;
253 272 return false;
254 273 }
255 274  
... ... @@ -270,7 +289,7 @@ public:
270 289 bool read_plane_0(T* p, unsigned long long n, bool PROGRESS = false){
271 290 if(PROGRESS) progress = 0;
272 291 if (n >= R[0]){ //make sure the number is within the possible range
273   - std::cout<<"ERROR read_plane_0: page out of range"<<std::endl;
  292 + std::cout<<"ERROR: sample or line out of range in "<<__FILE__<<" (line "<<__LINE__<<")"<<std::endl;
274 293 return false;
275 294 }
276 295 unsigned long long jump = (R[0] - 1) * sizeof(T); //number of bytes to skip between samples
... ...
stim/envi/bip.h
... ... @@ -143,6 +143,11 @@ public:
143 143 bool spectrum(T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){
144 144 return read_line_0(p, x, y, PROGRESS); //read a line in the binary YZ plane (dimension order for BIP is ZXY)
145 145 }
  146 + bool spectrum(T* p, size_t n, bool PROGRESS = false){
  147 + size_t y = n / X();
  148 + size_t x = n - y * X();
  149 + return read_line_0(p, x, y, PROGRESS); //read a line in the binary YZ plane (dimension order for BIP is ZXY)
  150 + }
146 151  
147 152 /// Retrieves a band of x values from a given xz plane.
148 153  
... ...
stim/envi/bsq.h
... ... @@ -146,9 +146,13 @@ public:
146 146 /// @param p is a pointer to pre-allocated memory at least B * sizeof(T) in size.
147 147 /// @param x is the x-coordinate (dimension 1) of the spectrum.
148 148 /// @param y is the y-coordinate (dimension 2) of the spectrum.
149   - bool spectrum(T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){
150   - return read_line_2(p, x, y, PROGRESS);
  149 + void spectrum(T* p, size_t n, bool PROGRESS){
  150 + read_line_2(p, n, PROGRESS);
151 151 }
  152 + void spectrum(T * p, unsigned long long x, unsigned long long y, bool PROGRESS = false){
  153 + read_line_2(p, x, y, PROGRESS);
  154 + }
  155 +
152 156  
153 157 /// Retrieve a single pixel and stores it in pre-allocated memory.
154 158  
... ...
stim/envi/envi.h
... ... @@ -21,10 +21,56 @@ class envi{
21 21 void* file; //void pointer to the relevant file reader (bip, bsq, or bil - with appropriate data type)
22 22 std::string fname; //file name used for repeated opening and closing
23 23  
  24 + //allocate sufficient space for a spectrum based on the data type and number of bands
  25 + void* alloc_array(size_t len){
  26 + switch(header.data_type){
  27 + case envi_header::int8:
  28 + return malloc(len);
  29 + case envi_header::int16:
  30 + case envi_header::uint16:
  31 + return malloc(2 * len);
  32 + case envi_header::int32:
  33 + case envi_header::uint32:
  34 + case envi_header::float32:
  35 + return malloc(4 * len);
  36 + case envi_header::int64:
  37 + case envi_header::uint64:
  38 + case envi_header::float64:
  39 + case envi_header::complex32:
  40 + return malloc(8 * len);
  41 + case envi_header::complex64:
  42 + return malloc(16 * len);
  43 + default:
  44 + std::cout<<"ERROR stim::envi data type not recognized for spectral allocation"<<std::endl;
  45 + exit(1);
  46 + }
  47 + }
  48 +
  49 + //cast a value to DEST type from SRC type
  50 + template<typename DST, typename SRC>
  51 + inline void cast(DST* dst, SRC* src){
  52 + (*dst) = (DST)(*src);
  53 + }
  54 +
  55 + //cast an array from type SRC to type DEST
  56 + template<typename DST, typename SRC>
  57 + inline void cast(DST* dst, SRC* src, size_t len){
  58 + for(size_t i = 0; i < len; i++)
  59 + cast(&dst[i], &src[i]);
  60 + }
  61 +
24 62 public:
25 63  
26 64 envi_header header;
27 65  
  66 + void* malloc_spectrum(){
  67 + return alloc_array(header.bands);
  68 + }
  69 +
  70 + void* malloc_band(){
  71 + return alloc_array(header.samples * header.lines);
  72 + }
  73 +
28 74 /// Returns the size of the data type in bytes
29 75 unsigned int type_size(){
30 76 if(header.data_type == envi_header::float32) return 4;
... ... @@ -1060,7 +1106,7 @@ public:
1060 1106 /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T)
1061 1107 /// @param x is the x-coordinate of the spectrum
1062 1108 /// @param y is the y-coordinate of the spectrum
1063   - bool spectrum(void* ptr, unsigned long long x, unsigned long long y, bool PROGRESS = false){
  1109 + /*bool spectrum(void* ptr, unsigned long long x, unsigned long long y, bool PROGRESS = false){
1064 1110  
1065 1111 if(header.interleave == envi_header::BSQ){ //if the infile is bsq file
1066 1112 if(header.data_type ==envi_header::float32)
... ... @@ -1093,6 +1139,114 @@ public:
1093 1139 }
1094 1140 }
1095 1141 return false;
  1142 + }*/
  1143 +
  1144 + // Retrieve a spectrum at the specified 1D location
  1145 +
  1146 + /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T)
  1147 + /// @param x is the 1D coordinate of the spectrum
  1148 + template<typename T>
  1149 + void spectrum(T* ptr, size_t n, bool PROGRESS = false){
  1150 +
  1151 + void* temp = alloc_array(header.bands); //allocate space for the output array
  1152 +
  1153 + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file
  1154 + if(header.data_type ==envi_header::float32){
  1155 + ((bsq<float>*)file)->spectrum((float*)temp, n, PROGRESS);
  1156 + cast<T, float>(ptr, (float*)temp, header.bands);
  1157 + }
  1158 + else if (header.data_type == envi_header::float64){
  1159 + ((bsq<double>*)file)->spectrum((double*)temp, n, PROGRESS);
  1160 + cast<T, double>(ptr, (double*)temp, header.bands);
  1161 + }
  1162 + else{
  1163 + std::cout << "ERROR: unidentified data type" << std::endl;
  1164 + exit(1);
  1165 + }
  1166 + }
  1167 + else if (header.interleave == envi_header::BIL){
  1168 + if (header.data_type == envi_header::float32){
  1169 + ((bil<float>*)file)->spectrum((float*)temp, n, PROGRESS);
  1170 + cast<T, float>(ptr, (float*)temp, header.bands);
  1171 + }
  1172 + else if (header.data_type == envi_header::float64){
  1173 + ((bil<double>*)file)->spectrum((double*)temp, n, PROGRESS);
  1174 + cast<T, double>(ptr, (double*)temp, header.bands);
  1175 + }
  1176 + else{
  1177 + std::cout << "ERROR: unidentified data type" << std::endl;
  1178 + exit(1);
  1179 + }
  1180 + }
  1181 + else if (header.interleave == envi_header::BIP){
  1182 + if (header.data_type == envi_header::float32){
  1183 + ((bip<float>*)file)->spectrum((float*)temp, n, PROGRESS);
  1184 + cast<T, float>(ptr, (float*)temp, header.bands);
  1185 + }
  1186 + else if (header.data_type == envi_header::float64){
  1187 + ((bip<double>*)file)->spectrum((double*)temp, n, PROGRESS);
  1188 + cast<T, double>(ptr, (double*)temp, header.bands);
  1189 + }
  1190 + else{
  1191 + std::cout << "ERROR: unidentified data type" << std::endl;
  1192 + exit(1);
  1193 + }
  1194 + }
  1195 + }
  1196 +
  1197 + /// Retrieve a spectrum from the specified (x, y) location
  1198 +
  1199 + /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T)
  1200 + /// @param x is the x-coordinate of the spectrum
  1201 + /// @param y is the y-coordinate of the spectrum
  1202 + template<typename T>
  1203 + void spectrum(T* ptr, unsigned long long x, unsigned long long y, bool PROGRESS = false){
  1204 +
  1205 + spectrum<T>(ptr, y * header.samples + x, PROGRESS = false);
  1206 + /*void* temp = alloc_array<T>(header.bands); //allocate space for the output array
  1207 +
  1208 + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file
  1209 + if(header.data_type ==envi_header::float32){
  1210 + ((bsq<float>*)file)->spectrum((float*)temp, x, y, PROGRESS);
  1211 + cast<T, float>(ptr, temp, header.bands);
  1212 + }
  1213 + else if (header.data_type == envi_header::float64){
  1214 + ((bsq<double>*)file)->spectrum((double*)temp, x, y, PROGRESS);
  1215 + cast<T, double>(ptr, temp, header.bands);
  1216 + }
  1217 + else{
  1218 + std::cout << "ERROR: unidentified data type" << std::endl;
  1219 + exit(1);
  1220 + }
  1221 + }
  1222 + else if (header.interleave == envi_header::BIL){
  1223 + if (header.data_type == envi_header::float32){
  1224 + ((bil<float>*)file)->spectrum((float*)temp, x, y, PROGRESS);
  1225 + cast<T, float>(ptr, temp, header.bands);
  1226 + }
  1227 + else if (header.data_type == envi_header::float64){
  1228 + ((bil<double>*)file)->spectrum((double*)temp, x, y, PROGRESS);
  1229 + cast<T, double>(ptr, temp, header.bands);
  1230 + }
  1231 + else{
  1232 + std::cout << "ERROR: unidentified data type" << std::endl;
  1233 + exit(1);
  1234 + }
  1235 + }
  1236 + else if (header.interleave == envi_header::BIP){
  1237 + if (header.data_type == envi_header::float32){
  1238 + ((bip<float>*)file)->spectrum((float*)temp, x, y, PROGRESS);
  1239 + cast<T, float>(ptr, temp, header.bands);
  1240 + }
  1241 + else if (header.data_type == envi_header::float64){
  1242 + ((bip<double>*)file)->spectrum((double*)temp, x, y, PROGRESS);
  1243 + cast<T, double>(ptr, temp, header.bands);
  1244 + }
  1245 + else{
  1246 + std::cout << "ERROR: unidentified data type" << std::endl;
  1247 + exit(1);
  1248 + }
  1249 + }*/
1096 1250 }
1097 1251  
1098 1252 /// Retrieve a single band (based on index) and stores it in pre-allocated memory.
... ...
stim/image/image.h
... ... @@ -33,8 +33,7 @@ class image{
33 33  
34 34 void unalloc(){ //frees any resources associated with the image
35 35 if(img) free(img); //if memory has been allocated, free it
36   - img=NULL;
37   -
  36 + img=NULL;
38 37 }
39 38  
40 39  
... ... @@ -92,7 +91,9 @@ class image{
92 91 public:
93 92  
94 93 /// Default constructor - creates an empty image object
95   - image(){ init(); } //initialize all variables to zero, don't allocate any memory
  94 + image(){
  95 + init(); //initialize all variables to zero, don't allocate any memory
  96 + }
96 97  
97 98 /// Constructor with a filename - loads the specified file
98 99 image(std::string filename){ //constructor initialize the image with an image file
... ... @@ -114,7 +115,7 @@ public:
114 115 }
115 116  
116 117 /// Copy constructor - duplicates an image object
117   - image(const stim::image<T>& I){
  118 + image(const stim::image<T> &I){
118 119 init();
119 120 allocate(I.X(), I.Y(), I.C());
120 121 memcpy(img, I.img, bytes());
... ... @@ -125,7 +126,7 @@ public:
125 126 free(img);
126 127 }
127 128  
128   - stim::image<T> operator=(const stim::image<T>& I){
  129 + stim::image<T>& operator=(const stim::image<T>& I){
129 130 if(&I == this) //handle self-assignment
130 131 return *this;
131 132 allocate(I.X(), I.Y(), I.C());
... ... @@ -138,7 +139,7 @@ public:
138 139  
139 140 cv::Mat cvImage = cv::imread(filename, CV_LOAD_IMAGE_UNCHANGED); //use OpenCV to open the image file
140 141 if(!cvImage.data){
141   - std::cout<<"ERROR stim::image::load() - unable to find image "<<filename<<std::endl;
  142 + std::cout<<"ERROR stim::image::load() - unable to find image "<<filename<<" ["<<__FILE__<<" (line "<<__LINE__<<")]"<<std::endl;
142 143 exit(1);
143 144 }
144 145 allocate(cvImage.cols, cvImage.rows, cvImage.channels()); //allocate space for the image
... ...
stim/parser/table.h 0 → 100644
  1 +#ifndef STIM_CSV_H
  2 +#define STIM_CSV_H
  3 +
  4 +#include <vector>
  5 +#include <sstream>
  6 +#include <fstream>
  7 +
  8 +namespace stim{
  9 +
  10 + class table{
  11 +
  12 + std::vector< std::vector< std::string > > TABLE;
  13 +
  14 + size_t x; //current x and y positions for adding elements to the table
  15 + size_t y;
  16 +
  17 + void init(){
  18 + x = y = 0;
  19 + TABLE.resize(1); //create a single row
  20 + TABLE[0].clear(); //make sure that the row is empty
  21 + }
  22 + public:
  23 +
  24 + table(){
  25 + init();
  26 + }
  27 +
  28 + void new_column(){
  29 + x = 0; //reset to the first position of the column
  30 + y++; //increment the current row position
  31 + TABLE.push_back( std::vector<std::string>() ); //push an empty row
  32 + }
  33 +
  34 + template<typename T>
  35 + T operator<<(T i){
  36 + std::stringstream ss;
  37 + ss<<i;
  38 + TABLE[y].push_back(ss.str());
  39 + x++;
  40 + return i;
  41 + }
  42 +
  43 + std::string str(){
  44 + std::stringstream ss;
  45 + for(size_t yi = 0; yi < TABLE.size(); yi++){
  46 + for(size_t xi = 0; xi < TABLE[yi].size(); xi++){
  47 + if(xi != 0) ss<<", ";
  48 + ss<<TABLE[yi][xi];
  49 + }
  50 + ss<<std::endl;
  51 + }
  52 + return ss.str();
  53 + }
  54 +
  55 + void save_ascii(std::string filename, char col_delim = ',', char row_delim = '\n'){
  56 + ofstream outfile(filename);
  57 + for(size_t yi = 0; yi < TABLE.size(); yi++){
  58 + if(yi != 0 && TABLE[yi].size() > 0) outfile<<row_delim;
  59 + for(size_t xi = 0; xi < TABLE[yi].size(); xi++){
  60 + if(xi != 0) outfile<<col_delim;
  61 + outfile<<TABLE[yi][xi];
  62 + }
  63 + }
  64 + }
  65 +
  66 + void read_ascii(std::string filename, char col_delim = ',', char row_delim = '\n'){
  67 + ifstream infile(filename); //open an ascii file for reading
  68 + TABLE.clear(); //empty out the table
  69 +
  70 + std::string line;
  71 + while(!infile.eof()){
  72 + std::getline(infile, line, row_delim); //read a line from the file using the row delimiter
  73 + size_t pos = 0;
  74 + std::string token;
  75 + std::vector< std::string > row;
  76 + while ((pos = line.find(col_delim)) != std::string::npos) {
  77 + token = line.substr(0, pos);
  78 + row.push_back(token);
  79 + line.erase(0, pos + 1);
  80 + }
  81 + token = line.substr(0, std::string::npos); //read the last column
  82 + row.push_back(token); //push it into the table
  83 + TABLE.push_back(row); //add an empty vector to the table
  84 + }
  85 + }
  86 +
  87 + /// Returns a vector representation of the table by casting to the specified template
  88 + template<typename T>
  89 + std::vector< std::vector<T> > get_vector(){
  90 + std::vector< std::vector<T> > result;
  91 + result.resize(TABLE.size()); //initialize the first dimension of the returned table
  92 + for(size_t i = 0; i < TABLE.size(); i++){ //for each row
  93 + result[i].resize(TABLE[i].size()); //initialize the number of columns in this row
  94 + for(size_t j = 0; j < TABLE[i].size(); j++){ //for each column
  95 + std::stringstream ss(TABLE[i][j]);
  96 + ss >> result[i][j];
  97 + }
  98 + }
  99 + return result; //return the casted table
  100 + }
  101 +
  102 + };
  103 +};
  104 +
  105 +
  106 +#endif
0 107 \ No newline at end of file
... ...