diff --git a/envi/bil.h b/envi/bil.h index b5c0715..c9cf38f 100644 --- a/envi/bil.h +++ b/envi/bil.h @@ -14,41 +14,40 @@ class bil: public binary { protected: - envi_header header; + std::vector w; //band wavelength public: using binary::open; using binary::file; + using binary::R; //open a file, given the file and its header's names - bool open(std::string filename, std::string headername){ + bool open(std::string filename, unsigned int X, unsigned int Y, unsigned int B, unsigned int header_offset, std::vector wavelengths){ - if (header.load(headername)==false){ - std::cout<<"ERROR: unable to load header file: "<(header.samples, header.lines, header.bands), header.header_offset); - return true; + return open(filename, vec(X, Y, B), header_offset); + + return false; } //save one band of the file into the memory, and return the pointer bool band_index( T * p, unsigned int page){ - unsigned int L = header.samples * sizeof(T); //caculate the number of bytes in a sample line - unsigned int jump = header.samples * (header.bands - 1) * sizeof(T); + unsigned int L = R[0] * sizeof(T); //caculate the number of bytes in a sample line + unsigned int jump = R[0] * (R[2] - 1) * sizeof(T); - if (page >= header.bands){ //make sure the bank number is right + if (page >= R[2]){ //make sure the bank number is right std::cout<<"ERROR: page out of range"< wavelength ){ + if ( w[page] > wavelength ){ band_index(p, page); return true; } - while( header.wavelength[page] < wavelength ) + while( w[page] < wavelength ) { page++; //if wavelength is larger than the last wavelength in header file - if (page == header.bands) { - band_index(p, header.bands-1); + if (page == R[2]) { + band_index(p, R[2]-1); return true; } } - if ( wavelength < header.wavelength[page] ) + if ( wavelength < w[page] ) { p1=(T*)malloc(S); //memory allocation p2=(T*)malloc(S); band_index(p1, page - 1); band_index(p2, page ); for(unsigned i=0; i < XY; i++){ - double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]); + double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]); p[i] = (p2[i] - p1[i]) * r + p1[i]; } } @@ -103,8 +102,8 @@ public: //get YZ line from the a Y slice, Y slice data should be already IN the MEMORY bool getYZ(T* p, T* c, double wavelength) { - unsigned int X = header.samples; //calculate the number of pixels in a sample - unsigned int B = header.bands; + unsigned int X = R[0]; //calculate the number of pixels in a sample + unsigned int B = R[2]; unsigned int L = X * sizeof(T); unsigned page=0; //samples around the wavelength @@ -114,12 +113,12 @@ public: //get the bands numbers around the wavelength //if wavelength is smaller than the first one in header file - if ( header.wavelength[page] > wavelength ){ + if ( w[page] > wavelength ){ memcpy(p, c, L); return true; } - while( header.wavelength[page] < wavelength ) + while( w[page] < wavelength ) { page++; //if wavelength is larger than the last wavelength in header file @@ -128,7 +127,7 @@ public: return true; } } - if ( wavelength < header.wavelength[page] ) + if ( wavelength < w[page] ) { p1=(T*)malloc( L ); //memory allocation p2=(T*)malloc( L ); @@ -137,7 +136,7 @@ public: memcpy(p2, c + page * X, L); for(unsigned i=0; i < X; i++){ - double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]); + double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]); p[i] = (p2[i] - p1[i]) * r + p1[i]; } } @@ -150,16 +149,16 @@ public: //save one pixel of the BIP file into the memory, and return the pointer bool getSpectrum(T * p, unsigned x, unsigned y){ - if ( x >= header.samples || y >= header.lines){ //make sure the sample and line number is right + if ( x >= R[0] || y >= R[1]){ //make sure the sample and line number is right std::cout<<"ERROR: sample or line out of range"<= header.lines){ //make sure the line number is right + if ( y >= R[1]){ //make sure the line number is right std::cout<<"ERROR: line out of range"<= bi && cii != B - 1) { + if( w[cii] >= bi && cii != B - 1) { //if the high band is now on the last BL point if (control != N-1) { @@ -259,18 +258,18 @@ public: } //if the last BL point on the last band of the file? - else if ( wls[control] < header.wavelength[B - 1]) { + else if ( wls[control] < w[B - 1]) { std::swap(a, b); //swap the baseline band pointers memset(b, (char)0, X * sizeof(T) ); //clear the high band ai = bi; - bi = header.wavelength[B - 1]; + bi = w[B - 1]; } } - ci = header.wavelength[cii]; + ci = w[cii]; unsigned jump = cii * X; //perform the baseline correction @@ -282,9 +281,7 @@ public: }//loop for YZ line end target.write(reinterpret_cast(c), L); //write the corrected data into destination - }//loop for Y slice end - - header.save(headername); //save the new header file + }//loop for Y slice end free(a); free(b); @@ -297,11 +294,11 @@ public: // normalize the BIL file bool normalize(std::string outname, double band) { - unsigned int B = header.bands; //calculate the number of bands - unsigned int Y = header.lines; - unsigned int X = header.samples; - unsigned int ZX = header.bands * header.samples; - unsigned int XY = header.samples * header.lines; //calculate the number of pixels in a band + unsigned int B = R[2]; //calculate the number of bands + unsigned int Y = R[1]; + unsigned int X = R[0]; + unsigned int ZX = R[2] * R[0]; + unsigned int XY = R[0] * R[1]; //calculate the number of pixels in a band unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band unsigned int L = ZX * sizeof(T); @@ -328,7 +325,6 @@ public: } target.write(reinterpret_cast(c), L); //write normalized data into destination } - header.save(headername); //save the new header file free(b); free(c); @@ -339,7 +335,7 @@ public: //convert BIL file to BSQ file and save it bool bsq(std::string outname) { - unsigned int S = header.samples * header.lines * sizeof(T); //calculate the number of bytes in a band + unsigned int S = R[0] * R[1] * sizeof(T); //calculate the number of bytes in a band std::ofstream target(outname.c_str(), std::ios::binary); std::string headername = outname + ".hdr"; @@ -347,15 +343,12 @@ public: T * p; //pointer to the current band p = (T*)malloc(S); - for ( unsigned i = 0; i < header.bands; i++) + for ( unsigned i = 0; i < R[2]; i++) { band_index(p, i); target.write(reinterpret_cast(p), S); //write a band data into target file } - - header.interleave = rts::envi_header::BSQ; //change the type of file in header file - header.save(headername); - + free(p); target.close(); return true; @@ -364,7 +357,7 @@ public: //convert bil file to bip file and save it bool bip(std::string outname) { - unsigned int S = header.samples * header.bands * sizeof(T); //calculate the number of bytes in a ZX slice + unsigned int S = R[0] * R[2] * sizeof(T); //calculate the number of bytes in a ZX slice std::ofstream target(outname.c_str(), std::ios::binary); std::string headername = outname + ".hdr"; @@ -374,22 +367,20 @@ public: T * q; //pointer to the current ZX slice for bip file q = (T*)malloc(S); - for ( unsigned i = 0; i < header.lines; i++) + for ( unsigned i = 0; i < R[1]; i++) { getY(p, i); - for ( unsigned k = 0; k < header.bands; k++) + for ( unsigned k = 0; k < R[2]; k++) { - unsigned ks = k * header.samples; - for ( unsigned j = 0; j < header.samples; j++) - q[k + j * header.bands] = p[ks + j]; + unsigned ks = k * R[0]; + for ( unsigned j = 0; j < R[0]; j++) + q[k + j * R[2]] = p[ks + j]; } target.write(reinterpret_cast(q), S); //write a band data into target file } - header.interleave = rts::envi_header::BIP; //change the type of file in header file - header.save(headername); - + free(p); free(q); target.close(); diff --git a/envi/bip.h b/envi/bip.h index b2541fb..96db6fa 100644 --- a/envi/bip.h +++ b/envi/bip.h @@ -15,40 +15,44 @@ class bip: public binary { protected: - envi_header header; + + std::vector w; //band wavelength + unsigned int offset; //header offset public: using binary::open; using binary::file; + using binary::R; //open a file, given the file and its header's names - bool open(std::string filename, std::string headername){ + bool open(std::string filename, unsigned int X, unsigned int Y, unsigned int B, unsigned int header_offset, std::vector wavelengths){ - if (header.load(headername)==false){ - std::cout<<"ERROR: unable to load header file: "<(header.samples, header.lines, header.bands), header.header_offset); - return true; + return open(filename, vec(X, Y, B), header_offset); + + return false; } //save one band of the file into the memory, and return the pointer bool band_index( T * p, unsigned int page){ - if (page >= header.bands){ //make sure the bank number is right + if (page >= R[2]){ //make sure the bank number is right std::cout<<"ERROR: page out of range"< wavelength ){ + if ( w[page] > wavelength ){ band_index(p, page); return true; } - while( header.wavelength[page] < wavelength ) + while( w[page] < wavelength ) { page++; //if wavelength is larger than the last wavelength in header file - if (page == header.bands) { - band_index(p, header.bands-1); + if (page == R[2]) { + band_index(p, R[2]-1); return true; } } - if ( wavelength < header.wavelength[page] ) + if ( wavelength < w[page] ) { p1=(T*)malloc( XY * sizeof(T)); //memory allocation p2=(T*)malloc( XY * sizeof(T)); band_index(p1, page - 1); band_index(p2, page ); for(unsigned i=0; i < XY; i++){ - double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]); + double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]); p[i] = (p2[i] - p1[i]) * r + p1[i]; } } @@ -102,8 +106,8 @@ public: //get YZ line from the a Y slice, Y slice data should be already IN the MEMORY bool getYZ(T* p, T* c, double wavelength) { - unsigned int X = header.samples; //calculate the number of pixels in a sample - unsigned int B = header.bands; + unsigned int X = R[0]; //calculate the number of pixels in a sample + unsigned int B = R[2]; unsigned page=0; //samples around the wavelength T * p1; @@ -112,27 +116,27 @@ public: //get the bands numbers around the wavelength //if wavelength is smaller than the first one in header file - if ( header.wavelength[page] > wavelength ){ - for(unsigned j = 0; j < header.samples; j++) + if ( w[page] > wavelength ){ + for(unsigned j = 0; j < R[0]; j++) { p[j] = c[j * B]; } return true; } - while( header.wavelength[page] < wavelength ) + while( w[page] < wavelength ) { page++; //if wavelength is larger than the last wavelength in header file if (page == B) { - for(unsigned j = 0; j < header.samples; j++) + for(unsigned j = 0; j < R[0]; j++) { p[j] = c[(j + 1) * B - 1]; } return true; } } - if ( wavelength < header.wavelength[page] ) + if ( wavelength < w[page] ) { p1=(T*)malloc( X * sizeof(T)); //memory allocation p2=(T*)malloc( X * sizeof(T)); @@ -148,7 +152,7 @@ public: } for(unsigned i=0; i < X; i++){ - double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]); + double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]); p[i] = (p2[i] - p1[i]) * r + p1[i]; } } @@ -167,7 +171,7 @@ public: //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" bool get_x_wavelength(T * p, unsigned y, double wavelength) { - unsigned int X = header.samples; //calculate the number of pixels in a sample + unsigned int X = R[0]; //calculate the number of pixels in a sample unsigned page=0; //samples around the wavelength T * p1; @@ -176,62 +180,62 @@ public: //get the bands numbers around the wavelength //if wavelength is smaller than the first one in header file - if ( header.wavelength[page] > wavelength ){ - file.seekg( y * header.bands * header.samples * sizeof(T), std::ios::beg); - for(unsigned j = 0; j < header.samples; j++) + if ( w[page] > wavelength ){ + file.seekg( y * R[2] * R[0] * sizeof(T), std::ios::beg); + for(unsigned j = 0; j < R[0]; j++) { file.read((char *)(p + j), sizeof(T)); - file.seekg((header.bands - 1) * sizeof(T), std::ios::cur); + file.seekg((R[2] - 1) * sizeof(T), std::ios::cur); } return true; } - while( header.wavelength[page] < wavelength ) + while( w[page] < wavelength ) { page++; //if wavelength is larger than the last wavelength in header file - if (page == header.bands) { - file.seekg( (y * header.bands * header.samples + header.bands - 1)* sizeof(T), std::ios::beg); - for(unsigned j = 0; j < header.samples; j++) + if (page == R[2]) { + file.seekg( (y * R[2] * R[0] + R[2] - 1)* sizeof(T), std::ios::beg); + for(unsigned j = 0; j < R[0]; j++) { file.read((char *)(p + j), sizeof(T)); - file.seekg((header.bands - 1) * sizeof(T), std::ios::cur); + file.seekg((R[2] - 1) * sizeof(T), std::ios::cur); } return true; } } - if ( wavelength < header.wavelength[page] ) + if ( wavelength < w[page] ) { p1=(T*)malloc( X * sizeof(T)); //memory allocation p2=(T*)malloc( X * sizeof(T)); //band_index(p1, page - 1); - file.seekg( (y * header.bands * header.samples + page - 1)* sizeof(T), std::ios::beg); - for(unsigned j = 0; j < header.samples; j++) + file.seekg( (y * R[2] * R[0] + page - 1)* sizeof(T), std::ios::beg); + for(unsigned j = 0; j < R[0]; j++) { file.read((char *)(p1 + j), sizeof(T)); - file.seekg((header.bands - 1) * sizeof(T), std::ios::cur); + file.seekg((R[2] - 1) * sizeof(T), std::ios::cur); } //band_index(p2, page ); - file.seekg( (y * header.bands * header.samples + page)* sizeof(T), std::ios::beg); - for(unsigned j = 0; j < header.samples; j++) + file.seekg( (y * R[2] * R[0] + page)* sizeof(T), std::ios::beg); + for(unsigned j = 0; j < R[0]; j++) { file.read((char *)(p2 + j), sizeof(T)); - file.seekg((header.bands - 1) * sizeof(T), std::ios::cur); + file.seekg((R[2] - 1) * sizeof(T), std::ios::cur); } - for(unsigned i=0; i < header.samples; i++){ - double r = (double) (wavelength - header.wavelength[page-1]) / (double) (header.wavelength[page] - header.wavelength[page-1]); + for(unsigned i=0; i < R[0]; i++){ + double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]); p[i] = (p2[i] - p1[i]) * r + p1[i]; } } else //if the wavelength is equal to a wavelength in header file { //band_index(p, page); - file.seekg( (y * header.bands * header.samples + page) * sizeof(T), std::ios::beg); - for(unsigned j = 0; j < header.samples; j++) + file.seekg( (y * R[2] * R[0] + page) * sizeof(T), std::ios::beg); + for(unsigned j = 0; j < R[0]; j++) { file.read((char *)(p + j), sizeof(T)); - file.seekg((header.bands - 1) * sizeof(T), std::ios::cur); + file.seekg((R[2] - 1) * sizeof(T), std::ios::cur); } } return true; @@ -240,14 +244,14 @@ public: //save one pixel of the BIP file into the memory, and return the pointer bool getSpectrum(T * p, unsigned x, unsigned y){ - if ( x >= header.samples || y >= header.lines){ //make sure the sample and line number is right + if ( x >= R[0] || y >= R[1]){ //make sure the sample and line number is right std::cout<<"ERROR: sample or line out of range"<= header.lines){ //make sure the line number is right + if ( y >= R[1]){ //make sure the line number is right std::cout<<"ERROR: line out of range"<= bi && cii != B - 1) { + if( w[cii] >= bi && cii != B - 1) { //if the high band is now on the last BL point? if (control != N-1) { @@ -342,18 +346,18 @@ public: } //if the last BL point on the last band of the file? - else if ( wls[control] < header.wavelength[B - 1]) { + else if ( wls[control] < w[B - 1]) { std::swap(a, b); //swap the baseline band pointers memset(b, (char)0, X * sizeof(T) ); //clear the high band ai = bi; - bi = header.wavelength[B - 1]; + bi = w[B - 1]; } } - ci = header.wavelength[cii]; + ci = w[cii]; //perform the baseline correction for(unsigned i=0; i < X; i++) @@ -366,7 +370,7 @@ public: target.write(reinterpret_cast(c), L); //write the corrected data into destination }//loop for Y slice end - header.save(headername); //save the new header file + free(a); free(b); @@ -379,11 +383,11 @@ public: // normalize the BIP file bool normalize(std::string outname, double band) { - unsigned int B = header.bands; //calculate the number of bands - unsigned int Y = header.lines; - unsigned int X = header.samples; - unsigned int ZX = header.bands * header.samples; - unsigned int XY = header.samples * header.lines; //calculate the number of pixels in a band + unsigned int B = R[2]; //calculate the number of bands + unsigned int Y = R[1]; + unsigned int X = R[0]; + unsigned int ZX = R[2] * R[0]; + unsigned int XY = R[0] * R[1]; //calculate the number of pixels in a band unsigned int S = XY * sizeof(T); //calculate the number of bytes in a band unsigned int L = ZX * sizeof(T); @@ -412,7 +416,7 @@ public: } target.write(reinterpret_cast(c), L); //write normalized data into destination } - header.save(headername); //save the new header file + free(b); free(c); @@ -429,7 +433,7 @@ public: bil(temp); rts::bil n; - if(n.open(temp, headtemp)==false){ //open infile + if(n.bil::open(temp, R[0], R[1], R[2], offset, w)==false){ //open infile std::cout<<"ERROR: unable to open input file"<(q), S); //write a band data into target file } - header.interleave = rts::envi_header::BIL; //change the type of file in header file - header.save(headername); free(p); free(q); diff --git a/envi/bsq.h b/envi/bsq.h index 4a9140b..5199e66 100644 --- a/envi/bsq.h +++ b/envi/bsq.h @@ -19,6 +19,7 @@ protected: //envi_header header; std::vector w; //band wavelengths + unsigned int offset; public: @@ -37,6 +38,8 @@ public: //copy the wavelengths to the BSQ file structure w = wavelengths; + //copy the wavelengths to the structure + offset = header_offset; return open(filename, vec(X, Y, B), header_offset); @@ -226,7 +229,6 @@ public: // normalize the BSQ file bool normalize(std::string outname, double band) { - std::cout<<"NORMALIZE A BSQ FILE"< n; - if(n.open(temp, headtemp)==false){ //open infile + if(n.bil::open(temp, R[0], R[1], R[2], offset, w)==false){ //open infile std::cout<<"ERROR: unable to open input file"<()); + else if(header.data_type == envi_header::float64) + return(file = new bsq()); + } + else if(header.interleave == envi_header::BIP){ + if(header.data_type ==envi_header::float32) + return(file = new bip()); + else if(header.data_type == envi_header::float64) + return(file = new bip()); + } + else if(header.interleave == envi_header::BIL){ + if(header.data_type ==envi_header::float32) + return(file = new bil()); + else if(header.data_type == envi_header::float64) + return(file = new bil()); + } exit(1); //if the function hasn't already returned, we don't handle this state @@ -38,22 +53,257 @@ public: header.load(headername); //load the file - if(header.interleave == envi_header::BSQ) - if(header.data_type ==envi_header::float32) + if(header.interleave == envi_header::BSQ) { //if the infile is bsq file + if(header.data_type == envi_header::float32) { return ((bsq*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength); + } + else if(header.data_type == envi_header::float64) { + return ((bsq*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength); + } + else + return false; + } - //handle other permutations..... - + else if(header.interleave == envi_header::BIL) { //if the infile is bil file + if(header.data_type == envi_header::float32) { + return ((bil*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength); + } + else if(header.data_type == envi_header::float64) { + return ((bil*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength); + } + else + return false; + } + + else if(header.interleave == envi_header::BIP) { //if the infile is bip file + if(header.data_type == envi_header::float32) { + return ((bip*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength); + } + else if(header.data_type == envi_header::float64) { + return ((bip*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength); + } + else + return false; + } + + else{ + std::cout<<"ERROR: unidentified type file "<*)file)->normalize(outfile, band); + else if(header.data_type == envi_header::float64) + return ((bsq*)file)->normalize(outfile,band); + else + std::cout<<"ERROR: unidentified data type"<*)file)->normalize(outfile, band); + else if(header.data_type == envi_header::float64) + return ((bil*)file)->normalize(outfile,band); + else + std::cout<<"ERROR: unidentified data type"<*)file)->normalize(outfile, band); + else if(header.data_type == envi_header::float64) + return ((bip*)file)->normalize(outfile,band); + else + std::cout<<"ERROR: unidentified data type"< w){ + + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file + if(header.data_type ==envi_header::float32) + return ((bsq*)file)->baseline(outfile, w); + else if(header.data_type == envi_header::float64) + return ((bsq*)file)->baseline(outfile,w); + else{ + std::cout<<"ERROR: unidentified data type"<*)file)->baseline(outfile, w); + else if(header.data_type == envi_header::float64) + return ((bil*)file)->baseline(outfile, w); + else{ + std::cout<<"ERROR: unidentified data type"<*)file)->baseline(outfile, w); + else if(header.data_type == envi_header::float64) + return ((bip*)file)->baseline(outfile, w); + else{ + std::cout<<"ERROR: unidentified data type"<*)file)->bil(outfile); + else if(interleave == envi_header::BIP) //if the target file is bip file + return ((bsq*)file)->bip(outfile); + } + + else if(header.data_type == envi_header::float64){ //if the data type is float + if(interleave == envi_header::BSQ){ + std::cout<<"ERROR: is already BSQ file"<*)file)->bil(outfile); + else if(interleave == envi_header::BIP) + return ((bsq*)file)->bip(outfile); + } + + else{ + std::cout<<"ERROR: unidentified data type"<*)file)->bsq(outfile); + else if(interleave == envi_header::BIP) //if the target file is bip file + return ((bil*)file)->bip(outfile); + } + + else if(header.data_type == envi_header::float64){ //if the data type is float + if(interleave == envi_header::BIL){ + std::cout<<"ERROR: is already BIL file"<*)file)->bsq(outfile); + else if(interleave == envi_header::BIP) + return ((bil*)file)->bip(outfile); + } + + else{ + std::cout<<"ERROR: unidentified data type"<*)file)->bil(outfile); + else if(interleave == envi_header::BSQ) //if the target file is bsq file + return ((bip*)file)->bsq(outfile); + } + + else if(header.data_type == envi_header::float64){ //if the data type is float + if(interleave == envi_header::BIP){ + std::cout<<"ERROR: is already BIP file"<*)file)->bil(outfile); + else if(interleave == envi_header::BSQ) //if the target file is bsq file + return ((bip*)file)->bsq(outfile); + } + + else{ + std::cout<<"ERROR: unidentified data type"<*)file)->close(); + else if(header.data_type == envi_header::float64) + return ((bsq*)file)->close(); + else{ + std::cout<<"ERROR: unidentified data type"<*)file)->close(); + else if(header.data_type == envi_header::float64) + return ((bil*)file)->close(); + else{ + std::cout<<"ERROR: unidentified data type"<*)file)->close(); + else if(header.data_type == envi_header::float64) + return ((bip*)file)->close(); + else{ + std::cout<<"ERROR: unidentified data type"<