#ifndef STIM_ENVI_H #define STIM_ENVI_H #include "../envi/envi_header.h" #include "../envi/bsq.h" #include "../envi/bip.h" #include "../envi/bil.h" #include //#include "../image/image.h" namespace stim{ /** This class implements reading of ENVI hyperspectral files. These files can be stored in multiple orientations (including BSQ, BIP, and BIL) in order to optimize streaming speed depending on applications. Basic ENVI files are stored on disk as a large binary file with a corresponding header. Code for reading and processing ENVI header files is in the envi_header class. */ class envi{ void* file; //void pointer to the relevant file reader (bip, bsq, or bil - with appropriate data type) public: envi_header header; /// Returns the progress of the current processing operation as a percentage void reset_progress(){ if(header.interleave == envi_header::BSQ){ //if the infile is bsq file if(header.data_type ==envi_header::float32) ((bsq*)file)->reset_thread_data(); else if(header.data_type == envi_header::float64) ((bsq*)file)->reset_thread_data(); else std::cout<<"ERROR: unidentified data type"<*)file)->reset_thread_data(); else if(header.data_type == envi_header::float64) ((bil*)file)->reset_thread_data(); else std::cout<<"ERROR: unidentified data type"<*)file)->reset_thread_data(); else if(header.data_type == envi_header::float64) ((bip*)file)->reset_thread_data(); else std::cout<<"ERROR: unidentified data type"<*)file)->get_thread_data(); else if(header.data_type == envi_header::float64) return ((bsq*)file)->get_thread_data(); else std::cout<<"ERROR: unidentified data type"<*)file)->get_thread_data(); else if(header.data_type == envi_header::float64) return ((bil*)file)->get_thread_data(); else std::cout<<"ERROR: unidentified data type"<*)file)->get_thread_data(); else if(header.data_type == envi_header::float64) return ((bip*)file)->get_thread_data(); else std::cout<<"ERROR: unidentified data type"<()); 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 } /// Open an existing ENVI file given the file and header names. /// @param filename is the name of the ENVI binary file /// @param headername is the name of the ENVI header file bool open(std::string filename, std::string headername){ //allocate memory allocate(); //load the header header.load(headername); //load the file 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; } 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 "< threshold (preventing division by small numbers) bool normalize(std::string outfile, double band, double threshold = 0.0){ if(header.interleave == envi_header::BSQ){ //if the infile is bsq file if(header.data_type ==envi_header::float32) return ((bsq*)file)->normalize(outfile, band, threshold); else if(header.data_type == envi_header::float64) return ((bsq*)file)->normalize(outfile,band, threshold); 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)->build_mask(mask_band, threshold, p); else if(header.data_type == envi_header::float64) return ((bsq*)file)->build_mask(mask_band, threshold, p); else std::cout<<"ERROR: unidentified data type"<*)file)->build_mask(mask_band, threshold, p); else if(header.data_type == envi_header::float64) return ((bil*)file)->build_mask(mask_band, threshold, p); else std::cout<<"ERROR: unidentified data type"<*)file)->build_mask(mask_band, threshold, p); else if(header.data_type == envi_header::float64) return ((bip*)file)->build_mask(mask_band, threshold, p); else std::cout<<"ERROR: unidentified data type"<*)file)->apply_mask(outfile, p); else if (header.data_type == envi_header::float64) return ((bsq*)file)->apply_mask(outfile, p); else std::cout << "ERROR: unidentified data type" << std::endl; } else if (header.interleave == envi_header::BIL){ //if the infile is bil file if (header.data_type == envi_header::float32) return ((bil*)file)->apply_mask(outfile, p); else if (header.data_type == envi_header::float64) return ((bil*)file)->apply_mask(outfile, p); else std::cout << "ERROR: unidentified data type" << std::endl; } else if (header.interleave == envi_header::BIP){ //if the infile is bip file if (header.data_type == envi_header::float32) return ((bip*)file)->apply_mask(outfile, p); else if (header.data_type == envi_header::float64) return ((bip*)file)->apply_mask(outfile, p); else std::cout << "ERROR: unidentified data type" << std::endl; } else{ std::cout << "ERROR: unidentified file type" << std::endl; exit(1); } return false; } /// sift-mask saves in an array only those spectra corresponding to nonzero values of the mask. bool sift(std::string outfile, unsigned char* p) { //calculate the number of non-zero values in the mask unsigned int nnz = 0; unsigned int npixels = header.lines * header.samples; for(unsigned int i = 0; i < npixels; i++) if( p[i] > 0 ) nnz++; //create a new header envi_header new_header = header; //if a BIL file is sifted, it's saved as a BIP if(header.interleave == envi_header::BIL) new_header.interleave = envi_header::BIP; //set the number of lines to 1 (this is a matrix with 1 line and N samples) new_header.lines = 1; new_header.samples = nnz; new_header.save(outfile + ".hdr"); std::cout<<"Saved: "<*)file)->sift(outfile, p); else if (header.data_type == envi_header::float64) return ((bsq*)file)->sift(outfile, p); else std::cout << "ERROR: unidentified data type" << std::endl; } else if (header.interleave == envi_header::BIL){ //if the infile is bil file if (header.data_type == envi_header::float32) return ((bil*)file)->sift(outfile, p); else if (header.data_type == envi_header::float64) return ((bil*)file)->sift(outfile, p); else std::cout << "ERROR: unidentified data type" << std::endl; } else if (header.interleave == envi_header::BIP){ //if the infile is bip file if (header.data_type == envi_header::float32) return ((bip*)file)->sift(outfile, p); else if (header.data_type == envi_header::float64) return ((bip*)file)->sift(outfile, p); else std::cout << "ERROR: unidentified data type" << std::endl; } else{ std::cout << "ERROR: unidentified file type" << std::endl; exit(1); } return false; } bool unsift(std::string outfile, unsigned char* mask, unsigned int samples, unsigned int lines){ //create a new header envi_header new_header = header; //set the number of lines and samples in the output file (that's all that changes) new_header.lines = lines; new_header.samples = samples; new_header.save(outfile + ".hdr"); if (header.interleave == envi_header::BSQ){ //if the infile is bsq file if (header.data_type == envi_header::float32) return ((bsq*)file)->unsift(outfile, mask, samples, lines); else if (header.data_type == envi_header::float64) return ((bsq*)file)->unsift(outfile, mask, samples, lines); else std::cout << "ERROR: unidentified data type" << std::endl; } else if (header.interleave == envi_header::BIL){ //if the infile is bil file std::cout << "ERROR in stim::envi::unsift - BIL files aren't supported yet" << std::endl; } else if (header.interleave == envi_header::BIP){ //if the infile is bip file if (header.data_type == envi_header::float32) return ((bip*)file)->unsift(outfile, mask, samples, lines); else if (header.data_type == envi_header::float64) return ((bip*)file)->unsift(outfile, mask, samples, lines); else std::cout << "ERROR: unidentified data type" << std::endl; } else{ std::cout << "ERROR: unidentified file type" << std::endl; } return 0; } /// Compute the ratio of two baseline-corrected peaks. The result is stored in a pre-allocated array. /// @param lb1 is the label value for the left baseline point for the first peak (numerator) /// @param rb1 is the label value for the right baseline point for the first peak (numerator) /// @param pos1 is the label value for the first peak (numerator) position /// @param lb2 is the label value for the left baseline point for the second peak (denominator) /// @param rb2 is the label value for the right baseline point for the second peak (denominator) /// @param pos2 is the label value for the second peak (denominator) position /// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size bool ph_to_ph(double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, void * result){ if(header.interleave == envi_header::BSQ){ //if the infile is bsq file if(header.data_type ==envi_header::float32) return ((bsq*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (float*)result); else if(header.data_type == envi_header::float64) return ((bsq*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (double*)result); else std::cout<<"ERROR: unidentified data type"<*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (float*)result); else if(header.data_type == envi_header::float64) return ((bil*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (double*)result); else std::cout<<"ERROR: unidentified data type"<*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (float*)result); else if(header.data_type == envi_header::float64) return ((bip*)file)->ph_to_ph(lb1, rb1, pos1, lb2, rb2, pos2, (double*)result); else std::cout<<"ERROR: unidentified data type"<*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (float*)result); else if(header.data_type == envi_header::float64) return ((bsq*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (double*)result); else std::cout<<"ERROR: unidentified data type"<*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (float*)result); else if(header.data_type == envi_header::float64) return ((bil*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (double*)result); else std::cout<<"ERROR: unidentified data type"<*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (float*)result); else if(header.data_type == envi_header::float64) return ((bip*)file)->pa_to_ph(lb1, rb1, lab1, rab1, lb2, rb2, pos, (double*)result); else std::cout<<"ERROR: unidentified data type"<*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (float*)result); else if(header.data_type == envi_header::float64) return ((bsq*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (double*)result); else std::cout<<"ERROR: unidentified data type"<*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (float*)result); else if(header.data_type == envi_header::float64) return ((bil*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (double*)result); else std::cout<<"ERROR: unidentified data type"<*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (float*)result); else if(header.data_type == envi_header::float64) return ((bip*)file)->pa_to_pa(lb1, rb1, lab1, rab1, lb2, rb2, lab2, rab2, (double*)result); else std::cout<<"ERROR: unidentified data type"<*)file)->cpoint(lb1, rb1, lab1, rab1, (float*)result); else if(header.data_type == envi_header::float64) return ((bsq*)file)->cpoint(lb1, rb1, lab1, rab1, (double*)result); else std::cout<<"ERROR: unidentified data type"<*)file)->cpoint(lb1, rb1, lab1, rab1, (float*)result); else if(header.data_type == envi_header::float64) return ((bil*)file)->cpoint(lb1, rb1, lab1, rab1, (double*)result); else std::cout<<"ERROR: unidentified data type"<*)file)->cpoint(lb1, rb1, lab1, rab1,(float*)result); else if(header.data_type == envi_header::float64) return ((bip*)file)->cpoint(lb1, rb1, lab1, rab1, (double*)result); 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"<*)file)->pixel((float*)p, n); else if(header.data_type == envi_header::float64) return ((bsq*)file)->pixel((double*)p, n); else{ std::cout<<"ERROR: unidentified data type"<*)file)->pixel((float*)p, n); else if(header.data_type == envi_header::float64) return ((bil*)file)->pixel((double*)p, n); else{ std::cout<<"ERROR: unidentified data type"<*)file)->pixel((float*)p, n); else if(header.data_type == envi_header::float64) return ((bip*)file)->pixel((double*)p, n); else{ std::cout<<"ERROR: unidentified data type"<*)file)->band((float*)ptr, wavelength); else if (header.data_type == envi_header::float64) return ((bsq*)file)->band((double*)ptr, wavelength); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } else if (header.interleave == envi_header::BIL){ if (header.data_type == envi_header::float32) return ((bil*)file)->band((float*)ptr, wavelength); else if (header.data_type == envi_header::float64) return ((bil*)file)->band((double*)ptr, wavelength); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } else if (header.interleave == envi_header::BIP){ if (header.data_type == envi_header::float32) return ((bip*)file)->band((float*)ptr, wavelength); else if (header.data_type == envi_header::float64) return ((bip*)file)->band((double*)ptr, wavelength); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } return false; } /// Retrieve a spectrum from the specified location /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T) /// @param x is the x-coordinate of the spectrum /// @param y is the y-coordinate of the spectrum bool spectrum(void* ptr, unsigned int x, unsigned int y){ if(header.interleave == envi_header::BSQ){ //if the infile is bsq file if(header.data_type ==envi_header::float32) return ((bsq*)file)->spectrum((float*)ptr, x, y); else if (header.data_type == envi_header::float64) return ((bsq*)file)->spectrum((double*)ptr, x, y); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } else if (header.interleave == envi_header::BIL){ if (header.data_type == envi_header::float32) return ((bil*)file)->spectrum((float*)ptr, x, y); else if (header.data_type == envi_header::float64) return ((bil*)file)->spectrum((double*)ptr, x, y); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } else if (header.interleave == envi_header::BIP){ if (header.data_type == envi_header::float32) return ((bip*)file)->spectrum((float*)ptr, x, y); else if (header.data_type == envi_header::float64) return ((bip*)file)->spectrum((double*)ptr, x, y); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } return false; } /// Retrieve a single band (based on index) and stores it in pre-allocated memory. /// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size. /// @param page <= B is the integer number of the band to be copied. bool band_index(void* ptr, unsigned int b){ if (header.interleave == envi_header::BSQ){ //if the infile is bsq file if (header.data_type == envi_header::float32) return ((bsq*)file)->band_index((float*)ptr, b); else if (header.data_type == envi_header::float64) return ((bsq*)file)->band_index((double*)ptr, b); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } else if (header.interleave == envi_header::BIL){ if (header.data_type == envi_header::float32) return ((bil*)file)->band_index((float*)ptr, b); else if (header.data_type == envi_header::float64) return ((bil*)file)->band_index((double*)ptr, b); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } else if (header.interleave == envi_header::BIP){ if (header.data_type == envi_header::float32) return ((bip*)file)->band_index((float*)ptr, b); else if (header.data_type == envi_header::float64) return ((bip*)file)->band_index((double*)ptr, b); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } return false; } /// Helper function that loads a mask into memory given a filename. /// @param mask is a pointer to pre-allocated memory of size X*Y /// @param maskname is the file name for the image that will serve as the mask /*bool load_mask(unsigned char * mask, std::string maskname){ //open the mask file stim::image mask_image(maskname); mask_image.data_noninterleaved(mask); //save mask file into memory //memcpy(mask, mask_image.data_noninterleaved(), mask_image.size()); //mask_image.clear(); return true; }*/ /// Calculate the mean value for all masked (or valid) pixels in a band and returns the average spectrum /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location bool avg_band(void * p, unsigned char* mask){ if (header.interleave == envi_header::BSQ){ if (header.data_type == envi_header::float32) return ((bsq*)file)->avg_band((float*)p, mask); else if (header.data_type == envi_header::float64) return ((bsq*)file)->avg_band((double*)p, mask); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } else if (header.interleave == envi_header::BIL){ if (header.data_type == envi_header::float32) return ((bil*)file)->avg_band((float*)p, mask); else if (header.data_type == envi_header::float64) return ((bil*)file)->avg_band((double*)p, mask); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } else if (header.interleave == envi_header::BIP){ if (header.data_type == envi_header::float32) return ((bip*)file)->avg_band((float*)p, mask); else if (header.data_type == envi_header::float64) return ((bip*)file)->avg_band((double*)p, mask); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } return false; } /// Calculate the covariance matrix for all masked pixels in the image. /// @param co is a pointer to pre-allocated memory of size [B * B] that stores the resulting covariance matrix /// @param avg is a pointer to memory of size B that stores the average spectrum /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location bool co_matrix(void* co, void* avg, unsigned char* mask){ if (header.interleave == envi_header::BSQ){ if (header.data_type == envi_header::float32) return ((bsq*)file)->co_matrix((float*)co, (float*)avg, mask); else if (header.data_type == envi_header::float64) return ((bsq*)file)->co_matrix((double*)co, (double*)avg, mask); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } else if (header.interleave == envi_header::BIL){ if (header.data_type == envi_header::float32) return ((bil*)file)->co_matrix((float*)co, (float*)avg, mask); else if (header.data_type == envi_header::float64) return ((bil*)file)->co_matrix((double*)co, (double*)avg, mask); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } else if (header.interleave == envi_header::BIP){ if (header.data_type == envi_header::float32) return ((bip*)file)->co_matrix((float*)co, (float*)avg, mask); else if (header.data_type == envi_header::float64) return ((bip*)file)->co_matrix((double*)co, (double*)avg, mask); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } return false; } /// Crop a region of the image and save it to a new file. /// @param outfile is the file name for the new cropped image /// @param x0 is the lower-left x pixel coordinate to be included in the cropped image /// @param y0 is the lower-left y pixel coordinate to be included in the cropped image /// @param x1 is the upper-right x pixel coordinate to be included in the cropped image /// @param y1 is the upper-right y pixel coordinate to be included in the cropped image bool crop(std::string outfile,unsigned x0, unsigned y0, unsigned x1, unsigned y1, unsigned b0, unsigned b1){ //save the header for the cropped file stim::envi_header new_header = header; new_header.samples = x1 - x0; new_header.lines = y1 - y0; new_header.bands = b1 - b0; std::vector::const_iterator first = new_header.wavelength.begin() + b0; std::vector::const_iterator last = new_header.wavelength.begin() + b1; new_header.wavelength = std::vector(first, last); new_header.save(outfile + ".hdr"); if (header.interleave == envi_header::BSQ){ if (header.data_type == envi_header::float32) return ((bsq*)file)->crop(outfile, x0, y0, x1, y1, b0, b1); else if (header.data_type == envi_header::float64) return ((bsq*)file)->crop(outfile, x0, y0, x1, y1, b0, b1); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } else if (header.interleave == envi_header::BIL){ if (header.data_type == envi_header::float32) return ((bil*)file)->crop(outfile, x0, y0, x1, y1, b0, b1); else if (header.data_type == envi_header::float64) return ((bil*)file)->crop(outfile, x0, y0, x1, y1, b0, b1); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } else if (header.interleave == envi_header::BIP){ if (header.data_type == envi_header::float32) return ((bip*)file)->crop(outfile, x0, y0, x1, y1, b0, b1); else if (header.data_type == envi_header::float64) return ((bip*)file)->crop(outfile, x0, y0, x1, y1, b0, b1); else{ std::cout << "ERROR: unidentified data type" << std::endl; exit(1); } } return false; } }; } //end namespace rts #endif