bsq.h 3.77 KB
#include "../envi/envi.h"
#include "../envi/binary.h"

namespace rts{

template <typename T>

class bsq: public binary<T> {

protected:
	
	envi header;

public:

	//open a file, given the file and its header's names
	bool open(std::string filename, std::string headername){

		if (header.load(headername)==false){
			std::cout<<"ERROR: unable to load head file"<<std::endl;
			return false;
		}

		binary::open(filename, vec<unsigned int>(header.samples, header.lines, header.bands), header.header_offset);
		return true;
		
	}

	//save one band of the file into the memory, and return the pointer
	bool getBand( T * p, unsigned int page){

		if (page >= header.bands){										//make sure the bank number is right
			std::cout<<"ERROR: page out of range"<<std::endl;
			return false;
		}

		getSlice(p, 2, page);
		return true;
	}

	//save one pixel of the file into the memory, and return the pointer
	bool getSpectrum(T * p, unsigned x, unsigned y){

		unsigned int i;

		if ( x >= header.samples || y >= header.lines){							//make sure the sample and line number is right
			std::cout<<"ERROR: sample or line out of range"<<std::endl;
			return false;
		}

		file.seekg((x + y * header.samples) * sizeof(T), std::ios::beg);           //point to the certain sample and line
		for (i = 0; i < header.bands; i++)
		{
			file.read((char *)(p + i), sizeof(T));
			file.seekg((header.lines * header.samples - 1) * sizeof(T), std::ios::cur);    //go to the next band
		}

		return true;	
	}

	//baseline correction and save it into file
	bool baseline(std::string outname, std::vector<unsigned> bands )
	{
		unsigned N = bands.size();							 //to get points number;

		ofstream bitext(outname.c_str(), std::ios::binary);                  //target binary file

		unsigned i, j, k;
		unsigned lownum, highnum;
		unsigned control=0;

		T * low;
		T * high;
		T * current;
		T * temp;

		low=(T *)malloc(header.lines * header.samples * sizeof(T));     //memory allocation
		high=(T *)malloc(header.lines * header.samples * sizeof(T)); 
		current=(T *)malloc(header.lines * header.samples * sizeof(T)); 

		if (low == NULL || high == NULL || current == NULL){
			cout<<"memory allocation failure";	
			return false;
			}

		//perform baseline correction

		//initialize lownum, highnum, low, high		
		lownum=0;
		if(bands[0] != 0){
			highnum = bands[control];			
			memset(low, 0.0, sizeof(T) * header.lines * header.samples);
		}
		else{
			control += 1;
			getBand(low, lownum);
			highnum = bands[control];
		}
		getBand(high, highnum);

		//correct every band 
		for(k = 0; k < header.bands; k++)		
		{		
			cout<<k<<endl;			//progress bar, delete it afterwards
			if( k == highnum && k != header.bands-1) {
				//if the high band is now on the last BL point?
				if (control != N-1) {

					control += 1;

					temp=low;
					low = high;
					high=temp;

					lownum=highnum;
					highnum = bands[control];
					getBand(high, highnum);

				}
				//if the last BL point on the last band of the file?
				else if ( bands[control] != header.bands-1) {

					temp = low;
					low = high;
					high = temp;

					memset(high, 0.0, sizeof(T) * header.lines * header.samples);

					lownum = highnum;
					highnum = header.bands-1;
				}
			}
			getBand(current, k);

		for(j=0; j<header.lines; j++)
			{
				for(i=0; i<header.samples; i++)
				{
					//straight line correction
					current[j * header.samples + i] = current[j * header.samples + i] - (
						( high[j * header.samples + i] - low[j * header.samples + i] ) * (T)(k - lownum) / (T)(highnum - lownum)
						) - low[j * header.samples + i];
				}				
			}
			
		bitext.write(reinterpret_cast<const char*>(current), sizeof(T) * header.lines * header.samples);   //write the corrected data into destination
		
		}	
		
		free(low);
		free(high);
		free(current);
		bitext.close();
		return true;
	}


	};
}