Commit 6708cc2537b1f0c00b17fdf198c52ba281624486

Authored by heziqi
1 parent e8eb202f

Ziqi added envi class

envi/bil.h
... ... @@ -14,41 +14,40 @@ class bil: public binary<T> {
14 14  
15 15 protected:
16 16  
17   - envi_header header;
  17 + std::vector<double> w; //band wavelength
18 18  
19 19 public:
20 20  
21 21 using binary<T>::open;
22 22 using binary<T>::file;
  23 + using binary<T>::R;
23 24  
24 25 //open a file, given the file and its header's names
25   - bool open(std::string filename, std::string headername){
  26 + bool open(std::string filename, unsigned int X, unsigned int Y, unsigned int B, unsigned int header_offset, std::vector<double> wavelengths){
26 27  
27   - if (header.load(headername)==false){
28   - std::cout<<"ERROR: unable to load header file: "<<headername<<std::endl;
29   - return false;
30   - }
  28 + w = wavelengths;
31 29  
32   - open(filename, vec<unsigned int>(header.samples, header.lines, header.bands), header.header_offset);
33   - return true;
  30 + return open(filename, vec<unsigned int>(X, Y, B), header_offset);
  31 +
  32 + return false;
34 33  
35 34 }
36 35  
37 36 //save one band of the file into the memory, and return the pointer
38 37 bool band_index( T * p, unsigned int page){
39 38  
40   - unsigned int L = header.samples * sizeof(T); //caculate the number of bytes in a sample line
41   - unsigned int jump = header.samples * (header.bands - 1) * sizeof(T);
  39 + unsigned int L = R[0] * sizeof(T); //caculate the number of bytes in a sample line
  40 + unsigned int jump = R[0] * (R[2] - 1) * sizeof(T);
42 41  
43   - if (page >= header.bands){ //make sure the bank number is right
  42 + if (page >= R[2]){ //make sure the bank number is right
44 43 std::cout<<"ERROR: page out of range"<<std::endl;
45 44 return false;
46 45 }
47 46  
48   - file.seekg(header.samples * page * sizeof(T), std::ios::beg);
49   - for (unsigned i = 0; i < header.lines; i++)
  47 + file.seekg(R[0] * page * sizeof(T), std::ios::beg);
  48 + for (unsigned i = 0; i < R[1]; i++)
50 49 {
51   - file.read((char *)(p + i * header.samples), L);
  50 + file.read((char *)(p + i * R[0]), L);
52 51 file.seekg( jump, std::ios::cur);
53 52 }
54 53  
... ... @@ -57,7 +56,7 @@ public:
57 56  
58 57 bool getBand( T * p, double wavelength){
59 58  
60   - unsigned int XY = header.samples * header.lines; //calculate the number of pixels in a band
  59 + unsigned int XY = R[0] * R[1]; //calculate the number of pixels in a band
61 60 unsigned int S = XY * sizeof(T); //calculate the number of bytes of a band
62 61  
63 62 unsigned page=0; //bands around the wavelength
... ... @@ -67,28 +66,28 @@ public:
67 66 //get the bands numbers around the wavelength
68 67  
69 68 //if wavelength is smaller than the first one in header file
70   - if ( header.wavelength[page] > wavelength ){
  69 + if ( w[page] > wavelength ){
71 70 band_index(p, page);
72 71 return true;
73 72 }
74 73  
75   - while( header.wavelength[page] < wavelength )
  74 + while( w[page] < wavelength )
76 75 {
77 76 page++;
78 77 //if wavelength is larger than the last wavelength in header file
79   - if (page == header.bands) {
80   - band_index(p, header.bands-1);
  78 + if (page == R[2]) {
  79 + band_index(p, R[2]-1);
81 80 return true;
82 81 }
83 82 }
84   - if ( wavelength < header.wavelength[page] )
  83 + if ( wavelength < w[page] )
85 84 {
86 85 p1=(T*)malloc(S); //memory allocation
87 86 p2=(T*)malloc(S);
88 87 band_index(p1, page - 1);
89 88 band_index(p2, page );
90 89 for(unsigned i=0; i < XY; i++){
91   - double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]);
  90 + double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]);
92 91 p[i] = (p2[i] - p1[i]) * r + p1[i];
93 92 }
94 93 }
... ... @@ -103,8 +102,8 @@ public:
103 102 //get YZ line from the a Y slice, Y slice data should be already IN the MEMORY
104 103 bool getYZ(T* p, T* c, double wavelength)
105 104 {
106   - unsigned int X = header.samples; //calculate the number of pixels in a sample
107   - unsigned int B = header.bands;
  105 + unsigned int X = R[0]; //calculate the number of pixels in a sample
  106 + unsigned int B = R[2];
108 107 unsigned int L = X * sizeof(T);
109 108  
110 109 unsigned page=0; //samples around the wavelength
... ... @@ -114,12 +113,12 @@ public:
114 113 //get the bands numbers around the wavelength
115 114  
116 115 //if wavelength is smaller than the first one in header file
117   - if ( header.wavelength[page] > wavelength ){
  116 + if ( w[page] > wavelength ){
118 117 memcpy(p, c, L);
119 118 return true;
120 119 }
121 120  
122   - while( header.wavelength[page] < wavelength )
  121 + while( w[page] < wavelength )
123 122 {
124 123 page++;
125 124 //if wavelength is larger than the last wavelength in header file
... ... @@ -128,7 +127,7 @@ public:
128 127 return true;
129 128 }
130 129 }
131   - if ( wavelength < header.wavelength[page] )
  130 + if ( wavelength < w[page] )
132 131 {
133 132 p1=(T*)malloc( L ); //memory allocation
134 133 p2=(T*)malloc( L );
... ... @@ -137,7 +136,7 @@ public:
137 136 memcpy(p2, c + page * X, L);
138 137  
139 138 for(unsigned i=0; i < X; i++){
140   - double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]);
  139 + double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]);
141 140 p[i] = (p2[i] - p1[i]) * r + p1[i];
142 141 }
143 142 }
... ... @@ -150,16 +149,16 @@ public:
150 149 //save one pixel of the BIP file into the memory, and return the pointer
151 150 bool getSpectrum(T * p, unsigned x, unsigned y){
152 151  
153   - if ( x >= header.samples || y >= header.lines){ //make sure the sample and line number is right
  152 + if ( x >= R[0] || y >= R[1]){ //make sure the sample and line number is right
154 153 std::cout<<"ERROR: sample or line out of range"<<std::endl;
155 154 exit(1);
156 155 }
157 156  
158   - unsigned jump = (header.samples - 1) * sizeof(T);
  157 + unsigned jump = (R[0] - 1) * sizeof(T);
159 158  
160   - file.seekg((y * header.samples * header.bands + x) * sizeof(T), std::ios::beg);
  159 + file.seekg((y * R[0] * R[2] + x) * sizeof(T), std::ios::beg);
161 160  
162   - for(unsigned i = 0; i < header.bands; i++)
  161 + for(unsigned i = 0; i < R[2]; i++)
163 162 { //point to the certain sample and line
164 163 file.read((char *)(p + i), sizeof(T));
165 164 file.seekg(jump, std::ios::cur);
... ... @@ -171,13 +170,13 @@ public:
171 170 //given a Y ,return a XZ slice
172 171 bool getY(T * p, unsigned y)
173 172 {
174   - if ( y >= header.lines){ //make sure the line number is right
  173 + if ( y >= R[1]){ //make sure the line number is right
175 174 std::cout<<"ERROR: line out of range"<<std::endl;
176 175 exit(1);
177 176 }
178 177  
179   - file.seekg(y * header.bands * header.samples * sizeof(T), std::ios::beg);
180   - file.read((char *)p, sizeof(T) * header.bands * header.samples);
  178 + file.seekg(y * R[2] * R[0] * sizeof(T), std::ios::beg);
  179 + file.read((char *)p, sizeof(T) * R[2] * R[0]);
181 180  
182 181 return true;
183 182  
... ... @@ -192,10 +191,10 @@ public:
192 191 std::string headername = outname + ".hdr"; //the header file name
193 192  
194 193 //simplify image resolution
195   - unsigned int ZX = header.bands * header.samples; //calculate the number of points in a Y slice
  194 + unsigned int ZX = R[2] * R[0]; //calculate the number of points in a Y slice
196 195 unsigned int L = ZX * sizeof(T); //calculate the number of bytes of a Y slice
197   - unsigned int B = header.bands;
198   - unsigned int X = header.samples;
  196 + unsigned int B = R[2];
  197 + unsigned int X = R[0];
199 198  
200 199 T* c; //pointer to the current Y slice
201 200 c = (T*)malloc(L); //memory allocation
... ... @@ -217,17 +216,17 @@ public:
217 216 }
218 217 // loop start correct every y slice
219 218  
220   - for (unsigned k =0; k < header.lines; k++)
  219 + for (unsigned k =0; k < R[1]; k++)
221 220 {
222 221 //get the current y slice
223 222 getY(c, k);
224 223  
225 224 //initialize lownum, highnum, low, high
226   - ai = header.wavelength[0];
  225 + ai = w[0];
227 226 control=0;
228 227 //if no baseline point is specified at band 0,
229 228 //set the baseline point at band 0 to 0
230   - if(wls[0] != header.wavelength[0]){
  229 + if(wls[0] != w[0]){
231 230 bi = wls[control];
232 231 memset(a, (char)0, X * sizeof(T) );
233 232 }
... ... @@ -245,7 +244,7 @@ public:
245 244 for(unsigned cii = 0; cii < B; cii++){
246 245  
247 246 //update baseline points, if necessary
248   - if( header.wavelength[cii] >= bi && cii != B - 1) {
  247 + if( w[cii] >= bi && cii != B - 1) {
249 248 //if the high band is now on the last BL point
250 249 if (control != N-1) {
251 250  
... ... @@ -259,18 +258,18 @@ public:
259 258  
260 259 }
261 260 //if the last BL point on the last band of the file?
262   - else if ( wls[control] < header.wavelength[B - 1]) {
  261 + else if ( wls[control] < w[B - 1]) {
263 262  
264 263 std::swap(a, b); //swap the baseline band pointers
265 264  
266 265 memset(b, (char)0, X * sizeof(T) ); //clear the high band
267 266  
268 267 ai = bi;
269   - bi = header.wavelength[B - 1];
  268 + bi = w[B - 1];
270 269 }
271 270 }
272 271  
273   - ci = header.wavelength[cii];
  272 + ci = w[cii];
274 273  
275 274 unsigned jump = cii * X;
276 275 //perform the baseline correction
... ... @@ -282,9 +281,7 @@ public:
282 281  
283 282 }//loop for YZ line end
284 283 target.write(reinterpret_cast<const char*>(c), L); //write the corrected data into destination
285   - }//loop for Y slice end
286   -
287   - header.save(headername); //save the new header file
  284 + }//loop for Y slice end
288 285  
289 286 free(a);
290 287 free(b);
... ... @@ -297,11 +294,11 @@ public:
297 294 // normalize the BIL file
298 295 bool normalize(std::string outname, double band)
299 296 {
300   - unsigned int B = header.bands; //calculate the number of bands
301   - unsigned int Y = header.lines;
302   - unsigned int X = header.samples;
303   - unsigned int ZX = header.bands * header.samples;
304   - unsigned int XY = header.samples * header.lines; //calculate the number of pixels in a band
  297 + unsigned int B = R[2]; //calculate the number of bands
  298 + unsigned int Y = R[1];
  299 + unsigned int X = R[0];
  300 + unsigned int ZX = R[2] * R[0];
  301 + unsigned int XY = R[0] * R[1]; //calculate the number of pixels in a band
305 302 unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band
306 303 unsigned int L = ZX * sizeof(T);
307 304  
... ... @@ -328,7 +325,6 @@ public:
328 325 }
329 326 target.write(reinterpret_cast<const char*>(c), L); //write normalized data into destination
330 327 }
331   - header.save(headername); //save the new header file
332 328  
333 329 free(b);
334 330 free(c);
... ... @@ -339,7 +335,7 @@ public:
339 335 //convert BIL file to BSQ file and save it
340 336 bool bsq(std::string outname)
341 337 {
342   - unsigned int S = header.samples * header.lines * sizeof(T); //calculate the number of bytes in a band
  338 + unsigned int S = R[0] * R[1] * sizeof(T); //calculate the number of bytes in a band
343 339  
344 340 std::ofstream target(outname.c_str(), std::ios::binary);
345 341 std::string headername = outname + ".hdr";
... ... @@ -347,15 +343,12 @@ public:
347 343 T * p; //pointer to the current band
348 344 p = (T*)malloc(S);
349 345  
350   - for ( unsigned i = 0; i < header.bands; i++)
  346 + for ( unsigned i = 0; i < R[2]; i++)
351 347 {
352 348 band_index(p, i);
353 349 target.write(reinterpret_cast<const char*>(p), S); //write a band data into target file
354 350 }
355   -
356   - header.interleave = rts::envi_header::BSQ; //change the type of file in header file
357   - header.save(headername);
358   -
  351 +
359 352 free(p);
360 353 target.close();
361 354 return true;
... ... @@ -364,7 +357,7 @@ public:
364 357 //convert bil file to bip file and save it
365 358 bool bip(std::string outname)
366 359 {
367   - unsigned int S = header.samples * header.bands * sizeof(T); //calculate the number of bytes in a ZX slice
  360 + unsigned int S = R[0] * R[2] * sizeof(T); //calculate the number of bytes in a ZX slice
368 361  
369 362 std::ofstream target(outname.c_str(), std::ios::binary);
370 363 std::string headername = outname + ".hdr";
... ... @@ -374,22 +367,20 @@ public:
374 367 T * q; //pointer to the current ZX slice for bip file
375 368 q = (T*)malloc(S);
376 369  
377   - for ( unsigned i = 0; i < header.lines; i++)
  370 + for ( unsigned i = 0; i < R[1]; i++)
378 371 {
379 372 getY(p, i);
380   - for ( unsigned k = 0; k < header.bands; k++)
  373 + for ( unsigned k = 0; k < R[2]; k++)
381 374 {
382   - unsigned ks = k * header.samples;
383   - for ( unsigned j = 0; j < header.samples; j++)
384   - q[k + j * header.bands] = p[ks + j];
  375 + unsigned ks = k * R[0];
  376 + for ( unsigned j = 0; j < R[0]; j++)
  377 + q[k + j * R[2]] = p[ks + j];
385 378 }
386 379  
387 380 target.write(reinterpret_cast<const char*>(q), S); //write a band data into target file
388 381 }
389 382  
390   - header.interleave = rts::envi_header::BIP; //change the type of file in header file
391   - header.save(headername);
392   -
  383 +
393 384 free(p);
394 385 free(q);
395 386 target.close();
... ...
envi/bip.h
... ... @@ -15,40 +15,44 @@ class bip: public binary&lt;T&gt; {
15 15  
16 16 protected:
17 17  
18   - envi_header header;
  18 +
  19 + std::vector<double> w; //band wavelength
  20 + unsigned int offset; //header offset
19 21  
20 22 public:
21 23  
22 24 using binary<T>::open;
23 25 using binary<T>::file;
  26 + using binary<T>::R;
24 27  
25 28 //open a file, given the file and its header's names
26   - bool open(std::string filename, std::string headername){
  29 + bool open(std::string filename, unsigned int X, unsigned int Y, unsigned int B, unsigned int header_offset, std::vector<double> wavelengths){
27 30  
28   - if (header.load(headername)==false){
29   - std::cout<<"ERROR: unable to load header file: "<<headername<<std::endl;
30   - return false;
31   - }
  31 + //copy the wavelengths to the BSQ file structure
  32 + w = wavelengths;
  33 + //copy the offset to the structure
  34 + offset = header_offset;
32 35  
33   - open(filename, vec<unsigned int>(header.samples, header.lines, header.bands), header.header_offset);
34   - return true;
  36 + return open(filename, vec<unsigned int>(X, Y, B), header_offset);
  37 +
  38 + return false;
35 39  
36 40 }
37 41  
38 42 //save one band of the file into the memory, and return the pointer
39 43 bool band_index( T * p, unsigned int page){
40 44  
41   - if (page >= header.bands){ //make sure the bank number is right
  45 + if (page >= R[2]){ //make sure the bank number is right
42 46 std::cout<<"ERROR: page out of range"<<std::endl;
43 47 return false;
44 48 }
45 49  
46 50 //binary::getSlice(p, 0, page); //I met some problems when I called this function?????
47 51 file.seekg(page * sizeof(T), std::ios::beg);
48   - for (unsigned i = 0; i < header.samples * header.lines; i++)
  52 + for (unsigned i = 0; i < R[0] * R[1]; i++)
49 53 {
50 54 file.read((char *)(p + i), sizeof(T));
51   - file.seekg( (header.bands - 1) * sizeof(T), std::ios::cur);
  55 + file.seekg( (R[2] - 1) * sizeof(T), std::ios::cur);
52 56 }
53 57  
54 58 return true;
... ... @@ -56,7 +60,7 @@ public:
56 60  
57 61 bool getBand( T * p, double wavelength){
58 62  
59   - unsigned int XY = header.samples * header.lines; //calculate the number of pixels in a band
  63 + unsigned int XY = R[0] * R[1]; //calculate the number of pixels in a band
60 64  
61 65 unsigned page=0; //bands around the wavelength
62 66 T * p1;
... ... @@ -65,28 +69,28 @@ public:
65 69 //get the bands numbers around the wavelength
66 70  
67 71 //if wavelength is smaller than the first one in header file
68   - if ( header.wavelength[page] > wavelength ){
  72 + if ( w[page] > wavelength ){
69 73 band_index(p, page);
70 74 return true;
71 75 }
72 76  
73   - while( header.wavelength[page] < wavelength )
  77 + while( w[page] < wavelength )
74 78 {
75 79 page++;
76 80 //if wavelength is larger than the last wavelength in header file
77   - if (page == header.bands) {
78   - band_index(p, header.bands-1);
  81 + if (page == R[2]) {
  82 + band_index(p, R[2]-1);
79 83 return true;
80 84 }
81 85 }
82   - if ( wavelength < header.wavelength[page] )
  86 + if ( wavelength < w[page] )
83 87 {
84 88 p1=(T*)malloc( XY * sizeof(T)); //memory allocation
85 89 p2=(T*)malloc( XY * sizeof(T));
86 90 band_index(p1, page - 1);
87 91 band_index(p2, page );
88 92 for(unsigned i=0; i < XY; i++){
89   - double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]);
  93 + double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]);
90 94 p[i] = (p2[i] - p1[i]) * r + p1[i];
91 95 }
92 96 }
... ... @@ -102,8 +106,8 @@ public:
102 106 //get YZ line from the a Y slice, Y slice data should be already IN the MEMORY
103 107 bool getYZ(T* p, T* c, double wavelength)
104 108 {
105   - unsigned int X = header.samples; //calculate the number of pixels in a sample
106   - unsigned int B = header.bands;
  109 + unsigned int X = R[0]; //calculate the number of pixels in a sample
  110 + unsigned int B = R[2];
107 111  
108 112 unsigned page=0; //samples around the wavelength
109 113 T * p1;
... ... @@ -112,27 +116,27 @@ public:
112 116 //get the bands numbers around the wavelength
113 117  
114 118 //if wavelength is smaller than the first one in header file
115   - if ( header.wavelength[page] > wavelength ){
116   - for(unsigned j = 0; j < header.samples; j++)
  119 + if ( w[page] > wavelength ){
  120 + for(unsigned j = 0; j < R[0]; j++)
117 121 {
118 122 p[j] = c[j * B];
119 123 }
120 124 return true;
121 125 }
122 126  
123   - while( header.wavelength[page] < wavelength )
  127 + while( w[page] < wavelength )
124 128 {
125 129 page++;
126 130 //if wavelength is larger than the last wavelength in header file
127 131 if (page == B) {
128   - for(unsigned j = 0; j < header.samples; j++)
  132 + for(unsigned j = 0; j < R[0]; j++)
129 133 {
130 134 p[j] = c[(j + 1) * B - 1];
131 135 }
132 136 return true;
133 137 }
134 138 }
135   - if ( wavelength < header.wavelength[page] )
  139 + if ( wavelength < w[page] )
136 140 {
137 141 p1=(T*)malloc( X * sizeof(T)); //memory allocation
138 142 p2=(T*)malloc( X * sizeof(T));
... ... @@ -148,7 +152,7 @@ public:
148 152 }
149 153  
150 154 for(unsigned i=0; i < X; i++){
151   - double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]);
  155 + double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]);
152 156 p[i] = (p2[i] - p1[i]) * r + p1[i];
153 157 }
154 158 }
... ... @@ -167,7 +171,7 @@ public:
167 171 //I do not use it right now, to accelerate the processing speed, I try to read a YZ whole slice into memory first, and then we can call "getYZ"
168 172 bool get_x_wavelength(T * p, unsigned y, double wavelength)
169 173 {
170   - unsigned int X = header.samples; //calculate the number of pixels in a sample
  174 + unsigned int X = R[0]; //calculate the number of pixels in a sample
171 175  
172 176 unsigned page=0; //samples around the wavelength
173 177 T * p1;
... ... @@ -176,62 +180,62 @@ public:
176 180 //get the bands numbers around the wavelength
177 181  
178 182 //if wavelength is smaller than the first one in header file
179   - if ( header.wavelength[page] > wavelength ){
180   - file.seekg( y * header.bands * header.samples * sizeof(T), std::ios::beg);
181   - for(unsigned j = 0; j < header.samples; j++)
  183 + if ( w[page] > wavelength ){
  184 + file.seekg( y * R[2] * R[0] * sizeof(T), std::ios::beg);
  185 + for(unsigned j = 0; j < R[0]; j++)
182 186 {
183 187 file.read((char *)(p + j), sizeof(T));
184   - file.seekg((header.bands - 1) * sizeof(T), std::ios::cur);
  188 + file.seekg((R[2] - 1) * sizeof(T), std::ios::cur);
185 189 }
186 190 return true;
187 191 }
188 192  
189   - while( header.wavelength[page] < wavelength )
  193 + while( w[page] < wavelength )
190 194 {
191 195 page++;
192 196 //if wavelength is larger than the last wavelength in header file
193   - if (page == header.bands) {
194   - file.seekg( (y * header.bands * header.samples + header.bands - 1)* sizeof(T), std::ios::beg);
195   - for(unsigned j = 0; j < header.samples; j++)
  197 + if (page == R[2]) {
  198 + file.seekg( (y * R[2] * R[0] + R[2] - 1)* sizeof(T), std::ios::beg);
  199 + for(unsigned j = 0; j < R[0]; j++)
196 200 {
197 201 file.read((char *)(p + j), sizeof(T));
198   - file.seekg((header.bands - 1) * sizeof(T), std::ios::cur);
  202 + file.seekg((R[2] - 1) * sizeof(T), std::ios::cur);
199 203 }
200 204 return true;
201 205 }
202 206 }
203   - if ( wavelength < header.wavelength[page] )
  207 + if ( wavelength < w[page] )
204 208 {
205 209 p1=(T*)malloc( X * sizeof(T)); //memory allocation
206 210 p2=(T*)malloc( X * sizeof(T));
207 211 //band_index(p1, page - 1);
208   - file.seekg( (y * header.bands * header.samples + page - 1)* sizeof(T), std::ios::beg);
209   - for(unsigned j = 0; j < header.samples; j++)
  212 + file.seekg( (y * R[2] * R[0] + page - 1)* sizeof(T), std::ios::beg);
  213 + for(unsigned j = 0; j < R[0]; j++)
210 214 {
211 215 file.read((char *)(p1 + j), sizeof(T));
212   - file.seekg((header.bands - 1) * sizeof(T), std::ios::cur);
  216 + file.seekg((R[2] - 1) * sizeof(T), std::ios::cur);
213 217 }
214 218 //band_index(p2, page );
215   - file.seekg( (y * header.bands * header.samples + page)* sizeof(T), std::ios::beg);
216   - for(unsigned j = 0; j < header.samples; j++)
  219 + file.seekg( (y * R[2] * R[0] + page)* sizeof(T), std::ios::beg);
  220 + for(unsigned j = 0; j < R[0]; j++)
217 221 {
218 222 file.read((char *)(p2 + j), sizeof(T));
219   - file.seekg((header.bands - 1) * sizeof(T), std::ios::cur);
  223 + file.seekg((R[2] - 1) * sizeof(T), std::ios::cur);
220 224 }
221 225  
222   - for(unsigned i=0; i < header.samples; i++){
223   - double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]);
  226 + for(unsigned i=0; i < R[0]; i++){
  227 + double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]);
224 228 p[i] = (p2[i] - p1[i]) * r + p1[i];
225 229 }
226 230 }
227 231 else //if the wavelength is equal to a wavelength in header file
228 232 {
229 233 //band_index(p, page);
230   - file.seekg( (y * header.bands * header.samples + page) * sizeof(T), std::ios::beg);
231   - for(unsigned j = 0; j < header.samples; j++)
  234 + file.seekg( (y * R[2] * R[0] + page) * sizeof(T), std::ios::beg);
  235 + for(unsigned j = 0; j < R[0]; j++)
232 236 {
233 237 file.read((char *)(p + j), sizeof(T));
234   - file.seekg((header.bands - 1) * sizeof(T), std::ios::cur);
  238 + file.seekg((R[2] - 1) * sizeof(T), std::ios::cur);
235 239 }
236 240 }
237 241 return true;
... ... @@ -240,14 +244,14 @@ public:
240 244 //save one pixel of the BIP file into the memory, and return the pointer
241 245 bool getSpectrum(T * p, unsigned x, unsigned y){
242 246  
243   - if ( x >= header.samples || y >= header.lines){ //make sure the sample and line number is right
  247 + if ( x >= R[0] || y >= R[1]){ //make sure the sample and line number is right
244 248 std::cout<<"ERROR: sample or line out of range"<<std::endl;
245 249 exit(1);
246 250 }
247 251  
248   - file.seekg((x + y * header.samples) * header.bands * sizeof(T), std::ios::beg); //point to the certain sample and line
  252 + file.seekg((x + y * R[0]) * R[2] * sizeof(T), std::ios::beg); //point to the certain sample and line
249 253  
250   - file.read((char *)p, sizeof(T) * header.bands);
  254 + file.read((char *)p, sizeof(T) * R[2]);
251 255  
252 256 return true;
253 257 }
... ... @@ -255,13 +259,13 @@ public:
255 259 //given a Y ,return a ZX slice
256 260 bool getY(T * p, unsigned y)
257 261 {
258   - if ( y >= header.lines){ //make sure the line number is right
  262 + if ( y >= R[1]){ //make sure the line number is right
259 263 std::cout<<"ERROR: line out of range"<<std::endl;
260 264 exit(1);
261 265 }
262 266  
263   - file.seekg(y * header.bands * header.samples * sizeof(T), std::ios::beg);
264   - file.read((char *)p, sizeof(T) * header.bands * header.samples);
  267 + file.seekg(y * R[2] * R[0] * sizeof(T), std::ios::beg);
  268 + file.read((char *)p, sizeof(T) * R[2] * R[0]);
265 269  
266 270 return true;
267 271  
... ... @@ -276,10 +280,10 @@ public:
276 280 std::string headername = outname + ".hdr"; //the header file name
277 281  
278 282 //simplify image resolution
279   - unsigned int ZX = header.bands * header.samples; //calculate the number of points in a Y slice
  283 + unsigned int ZX = R[2] * R[0]; //calculate the number of points in a Y slice
280 284 unsigned int L = ZX * sizeof(T); //calculate the number of bytes of a Y slice
281   - unsigned int B = header.bands;
282   - unsigned int X = header.samples;
  285 + unsigned int B = R[2];
  286 + unsigned int X = R[0];
283 287  
284 288 T* c; //pointer to the current Y slice
285 289 c = (T*)malloc(L); //memory allocation
... ... @@ -301,17 +305,17 @@ public:
301 305 }
302 306 // loop start correct every y slice
303 307  
304   - for (unsigned k =0; k < header.lines; k++)
  308 + for (unsigned k =0; k < R[1]; k++)
305 309 {
306 310 //get the current y slice
307 311 getY(c, k);
308 312  
309 313 //initialize lownum, highnum, low, high
310 314 control=0;
311   - ai = header.wavelength[0];
  315 + ai = w[0];
312 316 //if no baseline point is specified at band 0,
313 317 //set the baseline point at band 0 to 0
314   - if(wls[0] != header.wavelength[0]){
  318 + if(wls[0] != w[0]){
315 319 bi = wls[control];
316 320 memset(a, (char)0, X * sizeof(T) );
317 321 }
... ... @@ -328,7 +332,7 @@ public:
328 332  
329 333 for(unsigned cii = 0; cii < B; cii++){
330 334 //update baseline points, if necessary
331   - if( header.wavelength[cii] >= bi && cii != B - 1) {
  335 + if( w[cii] >= bi && cii != B - 1) {
332 336 //if the high band is now on the last BL point?
333 337 if (control != N-1) {
334 338  
... ... @@ -342,18 +346,18 @@ public:
342 346  
343 347 }
344 348 //if the last BL point on the last band of the file?
345   - else if ( wls[control] < header.wavelength[B - 1]) {
  349 + else if ( wls[control] < w[B - 1]) {
346 350  
347 351 std::swap(a, b); //swap the baseline band pointers
348 352  
349 353 memset(b, (char)0, X * sizeof(T) ); //clear the high band
350 354  
351 355 ai = bi;
352   - bi = header.wavelength[B - 1];
  356 + bi = w[B - 1];
353 357 }
354 358 }
355 359  
356   - ci = header.wavelength[cii];
  360 + ci = w[cii];
357 361  
358 362 //perform the baseline correction
359 363 for(unsigned i=0; i < X; i++)
... ... @@ -366,7 +370,7 @@ public:
366 370 target.write(reinterpret_cast<const char*>(c), L); //write the corrected data into destination
367 371 }//loop for Y slice end
368 372  
369   - header.save(headername); //save the new header file
  373 +
370 374  
371 375 free(a);
372 376 free(b);
... ... @@ -379,11 +383,11 @@ public:
379 383 // normalize the BIP file
380 384 bool normalize(std::string outname, double band)
381 385 {
382   - unsigned int B = header.bands; //calculate the number of bands
383   - unsigned int Y = header.lines;
384   - unsigned int X = header.samples;
385   - unsigned int ZX = header.bands * header.samples;
386   - unsigned int XY = header.samples * header.lines; //calculate the number of pixels in a band
  386 + unsigned int B = R[2]; //calculate the number of bands
  387 + unsigned int Y = R[1];
  388 + unsigned int X = R[0];
  389 + unsigned int ZX = R[2] * R[0];
  390 + unsigned int XY = R[0] * R[1]; //calculate the number of pixels in a band
387 391 unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band
388 392 unsigned int L = ZX * sizeof(T);
389 393  
... ... @@ -412,7 +416,7 @@ public:
412 416 }
413 417 target.write(reinterpret_cast<const char*>(c), L); //write normalized data into destination
414 418 }
415   - header.save(headername); //save the new header file
  419 +
416 420  
417 421 free(b);
418 422 free(c);
... ... @@ -429,7 +433,7 @@ public:
429 433 bil(temp);
430 434  
431 435 rts::bil<T> n;
432   - if(n.open(temp, headtemp)==false){ //open infile
  436 + if(n.bil::open(temp, R[0], R[1], R[2], offset, w)==false){ //open infile
433 437 std::cout<<"ERROR: unable to open input file"<<std::endl;
434 438 exit(1);
435 439 }
... ... @@ -444,7 +448,7 @@ public:
444 448 //convert bip file to bil file and save it
445 449 bool bil(std::string outname)
446 450 {
447   - unsigned int S = header.samples * header.bands * sizeof(T); //calculate the number of bytes in a ZX slice
  451 + unsigned int S = R[0] * R[2] * sizeof(T); //calculate the number of bytes in a ZX slice
448 452  
449 453 std::ofstream target(outname.c_str(), std::ios::binary);
450 454 std::string headername = outname + ".hdr";
... ... @@ -454,20 +458,18 @@ public:
454 458 T * q; //pointer to the current XZ slice for bil file
455 459 q = (T*)malloc(S);
456 460  
457   - for ( unsigned i = 0; i < header.lines; i++)
  461 + for ( unsigned i = 0; i < R[1]; i++)
458 462 {
459 463 getY(p, i);
460   - for ( unsigned k = 0; k < header.bands; k++)
  464 + for ( unsigned k = 0; k < R[2]; k++)
461 465 {
462   - unsigned ks = k * header.samples;
463   - for ( unsigned j = 0; j < header.samples; j++)
464   - q[ks + j] = p[k + j * header.bands];
  466 + unsigned ks = k * R[0];
  467 + for ( unsigned j = 0; j < R[0]; j++)
  468 + q[ks + j] = p[k + j * R[2]];
465 469 }
466 470 target.write(reinterpret_cast<const char*>(q), S); //write a band data into target file
467 471 }
468 472  
469   - header.interleave = rts::envi_header::BIL; //change the type of file in header file
470   - header.save(headername);
471 473  
472 474 free(p);
473 475 free(q);
... ...
envi/bsq.h
... ... @@ -19,6 +19,7 @@ protected:
19 19 //envi_header header;
20 20  
21 21 std::vector<double> w; //band wavelengths
  22 + unsigned int offset;
22 23  
23 24 public:
24 25  
... ... @@ -37,6 +38,8 @@ public:
37 38  
38 39 //copy the wavelengths to the BSQ file structure
39 40 w = wavelengths;
  41 + //copy the wavelengths to the structure
  42 + offset = header_offset;
40 43  
41 44 return open(filename, vec<unsigned int>(X, Y, B), header_offset);
42 45  
... ... @@ -226,7 +229,6 @@ public:
226 229 // normalize the BSQ file
227 230 bool normalize(std::string outname, double band)
228 231 {
229   - std::cout<<"NORMALIZE A BSQ FILE"<<std::endl;
230 232 unsigned int B = R[2]; //calculate the number of bands
231 233 unsigned int XY = R[0] * R[1]; //calculate the number of pixels in a band
232 234 unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band
... ... @@ -269,7 +271,7 @@ public:
269 271 bil(temp);
270 272  
271 273 rts::bil<T> n;
272   - if(n.open(temp, headtemp)==false){ //open infile
  274 + if(n.bil::open(temp, R[0], R[1], R[2], offset, w)==false){ //open infile
273 275 std::cout<<"ERROR: unable to open input file"<<std::endl;
274 276 exit(1);
275 277 }
... ... @@ -285,7 +287,7 @@ public:
285 287 bool bil(std::string outname)
286 288 {
287 289 //simplify image resolution
288   - unsigned int L = R[0] * R[1] * sizeof(T); //calculate the number of bytes of a ZX slice
  290 + unsigned int L = R[0] * R[2] * sizeof(T); //calculate the number of bytes of a ZX slice
289 291 unsigned int jump = (R[1] - 1) * R[0] * sizeof(T);
290 292  
291 293 std::ofstream target(outname.c_str(), std::ios::binary);
... ...
envi/envi.h
... ... @@ -21,9 +21,24 @@ public:
21 21  
22 22 file = NULL; //set file to a NULL pointer
23 23  
24   - if(header.interleave == envi_header::BSQ)
  24 + if(header.interleave == envi_header::BSQ){
25 25 if(header.data_type ==envi_header::float32)
26 26 return(file = new bsq<float>());
  27 + else if(header.data_type == envi_header::float64)
  28 + return(file = new bsq<double>());
  29 + }
  30 + else if(header.interleave == envi_header::BIP){
  31 + if(header.data_type ==envi_header::float32)
  32 + return(file = new bip<float>());
  33 + else if(header.data_type == envi_header::float64)
  34 + return(file = new bip<double>());
  35 + }
  36 + else if(header.interleave == envi_header::BIL){
  37 + if(header.data_type ==envi_header::float32)
  38 + return(file = new bil<float>());
  39 + else if(header.data_type == envi_header::float64)
  40 + return(file = new bil<double>());
  41 + }
27 42  
28 43 exit(1); //if the function hasn't already returned, we don't handle this state
29 44  
... ... @@ -38,22 +53,257 @@ public:
38 53 header.load(headername);
39 54  
40 55 //load the file
41   - if(header.interleave == envi_header::BSQ)
42   - if(header.data_type ==envi_header::float32)
  56 + if(header.interleave == envi_header::BSQ) { //if the infile is bsq file
  57 + if(header.data_type == envi_header::float32) {
43 58 return ((bsq<float>*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength);
  59 + }
  60 + else if(header.data_type == envi_header::float64) {
  61 + return ((bsq<double>*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength);
  62 + }
  63 + else
  64 + return false;
  65 + }
44 66  
45   - //handle other permutations.....
46   -
  67 + else if(header.interleave == envi_header::BIL) { //if the infile is bil file
  68 + if(header.data_type == envi_header::float32) {
  69 + return ((bil<float>*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength);
  70 + }
  71 + else if(header.data_type == envi_header::float64) {
  72 + return ((bil<double>*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength);
  73 + }
  74 + else
  75 + return false;
  76 + }
  77 +
  78 + else if(header.interleave == envi_header::BIP) { //if the infile is bip file
  79 + if(header.data_type == envi_header::float32) {
  80 + return ((bip<float>*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength);
  81 + }
  82 + else if(header.data_type == envi_header::float64) {
  83 + return ((bip<double>*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength);
  84 + }
  85 + else
  86 + return false;
  87 + }
  88 +
  89 + else{
  90 + std::cout<<"ERROR: unidentified type file "<<headername<<std::cout;
47 91 exit(1);
  92 + }
  93 +
48 94 }
49 95  
  96 + //perform normalization
50 97 bool normalize(std::string outfile, double band){
51   -
52   - if(header.interleave == envi_header::BSQ)
  98 +
  99 + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file
53 100 if(header.data_type ==envi_header::float32)
54 101 return ((bsq<float>*)file)->normalize(outfile, band);
  102 + else if(header.data_type == envi_header::float64)
  103 + return ((bsq<double>*)file)->normalize(outfile,band);
  104 + else
  105 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  106 + }
55 107  
56   - exit(1);
  108 + else if(header.interleave == envi_header::BIL){ //if the infile is bil file
  109 + if(header.data_type ==envi_header::float32)
  110 + return ((bil<float>*)file)->normalize(outfile, band);
  111 + else if(header.data_type == envi_header::float64)
  112 + return ((bil<double>*)file)->normalize(outfile,band);
  113 + else
  114 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  115 + }
  116 +
  117 + else if(header.interleave == envi_header::BIP){ //if the infile is bip file
  118 + if(header.data_type ==envi_header::float32)
  119 + return ((bip<float>*)file)->normalize(outfile, band);
  120 + else if(header.data_type == envi_header::float64)
  121 + return ((bip<double>*)file)->normalize(outfile,band);
  122 + else
  123 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  124 + }
  125 +
  126 + else{
  127 + std::cout<<"ERROR: unidentified file type"<<std::endl;
  128 + exit(1);
  129 + }
  130 + }
  131 +
  132 + //perform baseline correction
  133 + bool baseline(std::string outfile, std::vector<double> w){
  134 +
  135 + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file
  136 + if(header.data_type ==envi_header::float32)
  137 + return ((bsq<float>*)file)->baseline(outfile, w);
  138 + else if(header.data_type == envi_header::float64)
  139 + return ((bsq<double>*)file)->baseline(outfile,w);
  140 + else{
  141 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  142 + exit(1);
  143 + }
  144 + }
  145 +
  146 + else if(header.interleave == envi_header::BIL){ //if the infile is bil file
  147 + if(header.data_type ==envi_header::float32)
  148 + return ((bil<float>*)file)->baseline(outfile, w);
  149 + else if(header.data_type == envi_header::float64)
  150 + return ((bil<double>*)file)->baseline(outfile, w);
  151 + else{
  152 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  153 + exit(1);
  154 + }
  155 + }
  156 +
  157 + else if(header.interleave == envi_header::BIP){ //if the infile is bip file
  158 + if(header.data_type ==envi_header::float32)
  159 + return ((bip<float>*)file)->baseline(outfile, w);
  160 + else if(header.data_type == envi_header::float64)
  161 + return ((bip<double>*)file)->baseline(outfile, w);
  162 + else{
  163 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  164 + exit(1);
  165 + }
  166 + }
  167 +
  168 + else{
  169 + std::cout<<"ERROR: unidentified file type"<<std::endl;
  170 + exit(1);
  171 + }
  172 + }
  173 +
  174 + //perform conversion
  175 + bool convert(std::string outfile, rts::envi_header::interleaveType interleave){
  176 +
  177 + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file
  178 +
  179 + if(header.data_type ==envi_header::float32){ //if the data type of infile is float
  180 + if(interleave == envi_header::BSQ){
  181 + std::cout<<"ERROR: is already BSQ file"<<std::endl;
  182 + exit(1);
  183 + }
  184 + else if(interleave == envi_header::BIL) //if the target file is bil file
  185 + return ((bsq<float>*)file)->bil(outfile);
  186 + else if(interleave == envi_header::BIP) //if the target file is bip file
  187 + return ((bsq<float>*)file)->bip(outfile);
  188 + }
  189 +
  190 + else if(header.data_type == envi_header::float64){ //if the data type is float
  191 + if(interleave == envi_header::BSQ){
  192 + std::cout<<"ERROR: is already BSQ file"<<std::endl;
  193 + exit(1);
  194 + }
  195 + else if(interleave == envi_header::BIL)
  196 + return ((bsq<double>*)file)->bil(outfile);
  197 + else if(interleave == envi_header::BIP)
  198 + return ((bsq<double>*)file)->bip(outfile);
  199 + }
  200 +
  201 + else{
  202 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  203 + exit(1);
  204 + }
  205 + }
  206 +
  207 + else if(header.interleave == envi_header::BIL){
  208 +
  209 + if(header.data_type ==envi_header::float32){ //if the data type of infile is float
  210 + if(interleave == envi_header::BIL){
  211 + std::cout<<"ERROR: is already BIL file"<<std::endl;
  212 + exit(1);
  213 + }
  214 + else if(interleave == envi_header::BSQ) //if the target file is bsq file
  215 + return ((bil<float>*)file)->bsq(outfile);
  216 + else if(interleave == envi_header::BIP) //if the target file is bip file
  217 + return ((bil<float>*)file)->bip(outfile);
  218 + }
  219 +
  220 + else if(header.data_type == envi_header::float64){ //if the data type is float
  221 + if(interleave == envi_header::BIL){
  222 + std::cout<<"ERROR: is already BIL file"<<std::endl;
  223 + exit(1);
  224 + }
  225 + else if(interleave == envi_header::BSQ)
  226 + return ((bil<double>*)file)->bsq(outfile);
  227 + else if(interleave == envi_header::BIP)
  228 + return ((bil<double>*)file)->bip(outfile);
  229 + }
  230 +
  231 + else{
  232 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  233 + exit(1);
  234 + }
  235 + }
  236 +
  237 + else if(header.interleave == envi_header::BIP){
  238 +
  239 + if(header.data_type ==envi_header::float32){ //if the data type of infile is float
  240 + if(interleave == envi_header::BIP){
  241 + std::cout<<"ERROR: is already BIP file"<<std::endl;
  242 + exit(1);
  243 + }
  244 + else if(interleave == envi_header::BIL) //if the target file is bil file
  245 + return ((bip<float>*)file)->bil(outfile);
  246 + else if(interleave == envi_header::BSQ) //if the target file is bsq file
  247 + return ((bip<float>*)file)->bsq(outfile);
  248 + }
  249 +
  250 + else if(header.data_type == envi_header::float64){ //if the data type is float
  251 + if(interleave == envi_header::BIP){
  252 + std::cout<<"ERROR: is already BIP file"<<std::endl;
  253 + exit(1);
  254 + }
  255 + else if(interleave == envi_header::BIL) //if the target file is bil file
  256 + return ((bip<double>*)file)->bil(outfile);
  257 + else if(interleave == envi_header::BSQ) //if the target file is bsq file
  258 + return ((bip<double>*)file)->bsq(outfile);
  259 + }
  260 +
  261 + else{
  262 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  263 + exit(1);
  264 + }
  265 + }
  266 +
  267 + else{
  268 + std::cout<<"ERROR: unidentified interleave type"<<std::endl;
  269 + exit(1);
  270 + }
  271 +
  272 + }
  273 +
  274 + bool close(){
  275 + if(header.interleave == envi_header::BSQ){
  276 + if(header.data_type ==envi_header::float32)
  277 + return ((bsq<float>*)file)->close();
  278 + else if(header.data_type == envi_header::float64)
  279 + return ((bsq<double>*)file)->close();
  280 + else{
  281 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  282 + exit(1);
  283 + }
  284 + }
  285 +
  286 + else if(header.interleave == envi_header::BIL){
  287 + if(header.data_type ==envi_header::float32)
  288 + return ((bil<float>*)file)->close();
  289 + else if(header.data_type == envi_header::float64)
  290 + return ((bil<double>*)file)->close();
  291 + else{
  292 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  293 + exit(1);
  294 + }
  295 + }
  296 +
  297 + else if(header.interleave == envi_header::BIP){
  298 + if(header.data_type ==envi_header::float32)
  299 + return ((bip<float>*)file)->close();
  300 + else if(header.data_type == envi_header::float64)
  301 + return ((bip<double>*)file)->close();
  302 + else{
  303 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  304 + exit(1);
  305 + }
  306 + }
57 307 }
58 308  
59 309 bool save_header(std::string filename){
... ...
envi/envi_header.h
... ... @@ -213,6 +213,7 @@ struct envi_header
213 213  
214 214 if(!file)
215 215 {
  216 + std::cout<<"ERROR: unable to open header file: "<<filename<<std::endl;
216 217 return false;
217 218 }
218 219  
... ...