envi.h 12.3 KB
#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"

namespace rts{

//container class for an ENVI binary file reader
class envi{	

	void* file;		//void pointer to the relevant file reader (bip, bsq, or bil - with appropriate data type)

public:

	envi_header header;

	bool allocate(){

		file = NULL;	//set file to a NULL pointer

		if(header.interleave == envi_header::BSQ){
			if(header.data_type ==envi_header::float32)
				return(file = new bsq<float>());
			else if(header.data_type == envi_header::float64)
				return(file = new bsq<double>());
		}
		else if(header.interleave == envi_header::BIP){
			if(header.data_type ==envi_header::float32)
				return(file = new bip<float>());
			else if(header.data_type == envi_header::float64)
				return(file = new bip<double>());
		}
		else if(header.interleave == envi_header::BIL){
			if(header.data_type ==envi_header::float32)
				return(file = new bil<float>());
			else if(header.data_type == envi_header::float64)
				return(file = new bil<double>());
		}

		exit(1);	//if the function hasn't already returned, we don't handle this state

	}

	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<float>*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength);
			}
			else if(header.data_type == envi_header::float64) {
				return ((bsq<double>*)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<float>*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength);
			}
			else if(header.data_type == envi_header::float64) {
				return ((bil<double>*)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<float>*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength);
			}
			else if(header.data_type == envi_header::float64) {
				return ((bip<double>*)file)->open(filename, header.samples, header.lines, header.bands, header.header_offset, header.wavelength);
			}
			else
				return false;		
		}
		
		else{
		std::cout<<"ERROR: unidentified type file       "<<headername<<std::cout;
		exit(1);
		}

	}

	//perform normalization
	bool normalize(std::string outfile, double band){
	
		if(header.interleave == envi_header::BSQ){		//if the infile is bsq file
			if(header.data_type ==envi_header::float32)
				return ((bsq<float>*)file)->normalize(outfile, band);
			else if(header.data_type == envi_header::float64)
				return ((bsq<double>*)file)->normalize(outfile,band);
			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<float>*)file)->normalize(outfile, band);
			else if(header.data_type == envi_header::float64)
				return ((bil<double>*)file)->normalize(outfile,band);
			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<float>*)file)->normalize(outfile, band);
			else if(header.data_type == envi_header::float64)
				return ((bip<double>*)file)->normalize(outfile,band);
			else
				std::cout<<"ERROR: unidentified data type"<<std::endl;
		}

		else{
			std::cout<<"ERROR: unidentified file type"<<std::endl;
			exit(1);
		}
		return false;
	}

	//perform baseline correction
	bool baseline(std::string outfile, std::vector<double> w){

		if(header.interleave == envi_header::BSQ){		//if the infile is bsq file
			if(header.data_type ==envi_header::float32)
				return ((bsq<float>*)file)->baseline(outfile, w);
			else if(header.data_type == envi_header::float64)
				return ((bsq<double>*)file)->baseline(outfile,w);
			else{
				std::cout<<"ERROR: unidentified data type"<<std::endl;
				exit(1);
			}
		}

		else if(header.interleave == envi_header::BIL){		//if the infile is bil file
			if(header.data_type ==envi_header::float32)
				return ((bil<float>*)file)->baseline(outfile, w);
			else if(header.data_type == envi_header::float64)
				return ((bil<double>*)file)->baseline(outfile, w);
			else{
				std::cout<<"ERROR: unidentified data type"<<std::endl;
				exit(1);
			}
		}

		else if(header.interleave == envi_header::BIP){		//if the infile is bip file 
			if(header.data_type ==envi_header::float32)
				return ((bip<float>*)file)->baseline(outfile, w);
			else if(header.data_type == envi_header::float64)
				return ((bip<double>*)file)->baseline(outfile, w);
			else{
				std::cout<<"ERROR: unidentified data type"<<std::endl;
				exit(1);
			}
		}

		else{
			std::cout<<"ERROR: unidentified file type"<<std::endl;
			exit(1);
		}
	}

	//perform conversion
	bool convert(std::string outfile, rts::envi_header::interleaveType interleave){

		if(header.interleave == envi_header::BSQ){			//if the infile is bsq file

			if(header.data_type ==envi_header::float32){		//if the data type of infile is float
				if(interleave == envi_header::BSQ){
					std::cout<<"ERROR:  is already BSQ file"<<std::endl;
					exit(1);
				}
				else if(interleave == envi_header::BIL)			//if the target file is bil file
					return ((bsq<float>*)file)->bil(outfile);
				else if(interleave == envi_header::BIP)			//if the target file is bip file
					return ((bsq<float>*)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"<<std::endl;
					exit(1);
				}
				else if(interleave == envi_header::BIL)
					return ((bsq<double>*)file)->bil(outfile);
				else if(interleave == envi_header::BIP)
					return ((bsq<double>*)file)->bip(outfile);
			}
			
			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){		//if the data type of infile is float
				if(interleave == envi_header::BIL){
					std::cout<<"ERROR:  is already BIL file"<<std::endl;
					exit(1);
				}
				else if(interleave == envi_header::BSQ)			//if the target file is bsq file
					return ((bil<float>*)file)->bsq(outfile);
				else if(interleave == envi_header::BIP)			//if the target file is bip file
					return ((bil<float>*)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"<<std::endl;
					exit(1);
				}
				else if(interleave == envi_header::BSQ)
					return ((bil<double>*)file)->bsq(outfile);
				else if(interleave == envi_header::BIP)
					return ((bil<double>*)file)->bip(outfile);
			}
			
			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){		//if the data type of infile is float
				if(interleave == envi_header::BIP){
					std::cout<<"ERROR:  is already BIP file"<<std::endl;
					exit(1);
				}
				else if(interleave == envi_header::BIL)			//if the target file is bil file
					return ((bip<float>*)file)->bil(outfile);
				else if(interleave == envi_header::BSQ)			//if the target file is bsq file
					return ((bip<float>*)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"<<std::endl;
					exit(1);
				}
				else if(interleave == envi_header::BIL)			//if the target file is bil file
					return ((bip<double>*)file)->bil(outfile);
				else if(interleave == envi_header::BSQ)			//if the target file is bsq file
					return ((bip<double>*)file)->bsq(outfile);
			}
			
			else{
				std::cout<<"ERROR: unidentified data type"<<std::endl;
				exit(1);				
			}
		}
		
		else{
			std::cout<<"ERROR: unidentified interleave type"<<std::endl;
			exit(1);
		}
		return false;
	
	}

	//get the mask
	bool mask(unsigned char* p, double mask_band, double threshold)	{

		if(header.interleave == envi_header::BSQ){		//if the infile is bsq file
			if(header.data_type ==envi_header::float32)
				return ((bsq<float>*)file)->mask(p, mask_band, threshold);
			else if(header.data_type == envi_header::float64)
				return ((bsq<double>*)file)->mask(p, mask_band, threshold);
			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<float>*)file)->mask(p, mask_band, threshold);
			else if(header.data_type == envi_header::float64)
				return ((bil<double>*)file)->mask(p, mask_band, threshold);
			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<float>*)file)->mask(p, mask_band, threshold);
			else if(header.data_type == envi_header::float64)
				return ((bip<double>*)file)->mask(p, mask_band, threshold);
			else
				std::cout<<"ERROR: unidentified data type"<<std::endl;
		}

		else{
			std::cout<<"ERROR: unidentified file type"<<std::endl;
			exit(1);
		}
		return false;
	}

	//do baseline correction and caculate the area between two bounds
	bool area(double lb, double rb){
		if(header.interleave == envi_header::BSQ){		//if the infile is bsq file
			if(header.data_type ==envi_header::float32)
				return ((bsq<float>*)file)->area(lb, rb);
			else if(header.data_type == envi_header::float64)
				return ((bsq<double>*)file)->area(lb, rb);
			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<float>*)file)->area(lb, rb);
			else if(header.data_type == envi_header::float64)
				return ((bil<double>*)file)->area(lb, rb);
			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<float>*)file)->area(lb, rb);
			else if(header.data_type == envi_header::float64)
				return ((bip<double>*)file)->area(lb, rb);
			else
				std::cout<<"ERROR: unidentified data type"<<std::endl;
		}

		else{
			std::cout<<"ERROR: unidentified file type"<<std::endl;
			exit(1);
		}
		return false;
	}

	bool close(){
		if(header.interleave == envi_header::BSQ){
			if(header.data_type ==envi_header::float32)
				return ((bsq<float>*)file)->close();
			else if(header.data_type == envi_header::float64)
				return ((bsq<double>*)file)->close();
			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<float>*)file)->close();
			else if(header.data_type == envi_header::float64)
				return ((bil<double>*)file)->close();
			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<float>*)file)->close();
			else if(header.data_type == envi_header::float64)
				return ((bip<double>*)file)->close();
			else{
				std::cout<<"ERROR: unidentified data type"<<std::endl;
				exit(1);
			}
		}
		return false;
	}

	bool save_header(std::string filename){

		//save the header file here
		header.save(filename);

		return true;
	}





};

}	//end namespace rts

#endif