diff --git a/stim/envi/binary.h b/stim/envi/binary.h index 3385d00..48810ab 100644 --- a/stim/envi/binary.h +++ b/stim/envi/binary.h @@ -30,6 +30,8 @@ protected: double progress; //stores the progress on the current operation (accessible using a thread) + static const size_t bufferSize = 1000000000; + /// Private initialization function used to set default parameters in the data structure. void init(){ diff --git a/stim/envi/bsq.h b/stim/envi/bsq.h index 4ea407a..69a3f6e 100644 --- a/stim/envi/bsq.h +++ b/stim/envi/bsq.h @@ -377,18 +377,63 @@ public: } /// Convert the current BSQ file to a BIL file with the specified file name. + bool bil(std::string outname, bool PROGRESS = false){ + size_t XY = X() * Y(); //number of elements in a band + size_t XYbytes = XY * sizeof(T); //number of bytes in a band + size_t batchB = binary::bufferSize / (XYbytes); //calculate the number of slices that can fit in memory + size_t batchXB = X() * batchB; //number of elements in a batch + T* ptrBatch = (T*) malloc(batchB * XYbytes); //allocate a large buffer storing the read data + T* ptrSlice = (T*) malloc(sizeof(T) * batchB * X()); //allocate space for storing an output buffer + + size_t jump = (Z() - batchB) * X() * sizeof(T); //jump between writes in the output file + + std::ofstream target(outname.c_str(), std::ios::binary); + std::string headername = outname + ".hdr"; + + size_t batches = ceil((double)(Z()) / (double)batchB); //calculate the number of batches + T* ptrDst; + T* ptrSrc; + for(size_t c = 0; c < batches; c++){ + target.seekp(c * batchB * sizeof(T) * X(), std::ios::beg); //seek to the start of the current batch in the output file + file.read((char*)ptrBatch, sizeof(T) * X() * Y() * batchB); //read a batch + if(c == (batches - 1)){ + batchB = Z() - (batches - 1) * batchB; //if this is the last batch, calculate the remaining # of bands + jump = (Z() - batchB) * X() * sizeof(T); + } + for(size_t y = 0; y < Y(); y++){ //for each line, store an XB slice in ptrDest + ptrDst = ptrSlice; //initialize ptrDst to the start of the XB output slice + ptrSrc = ptrBatch + (y * X()); + for(size_t b = 0; b < batchB; b++){ //for each band in the current line + memcpy(ptrDst, ptrSrc, X() * sizeof(T)); //copy the band line from the source to the destination + ptrDst += X(); + ptrSrc += X() * Y(); + } + target.write((char*)ptrSlice, sizeof(T) * X() * batchB); //write the XB slice to disk + target.seekp(jump, std::ios::cur); //seek to the beginning of the next XB slice in the batch + } + if(PROGRESS) progress = (double)(c+1)/(double)(batches) * 100; + } + + //if(PROGRESS) progress = 100; + + free(ptrBatch); + free(ptrSlice); + target.close(); + + return true; + } /// @param outname is the name of the output BIL file to be saved to disk. - bool bil(std::string outname, bool PROGRESS = false) - { + /*bool bil(std::string outname, bool PROGRESS = false){ + //simplify image resolution unsigned long long jump = (Y() - 1) * X() * sizeof(T); std::ofstream target(outname.c_str(), std::ios::binary); std::string headername = outname + ".hdr"; - unsigned long long L = X(); - T* line = (T*)malloc(sizeof(T) * L); + unsigned long long L = X(); //calculate the number of pixels in a line + T* line = (T*)malloc(sizeof(T) * L); //allocate space for a line for ( unsigned long long y = 0; y < Y(); y++) //for each y position { @@ -406,7 +451,7 @@ public: target.close(); return true; - } + }*/ /// Return a baseline corrected band given two adjacent baseline points and their bands. The result is stored in a pre-allocated array. -- libgit2 0.21.4