1254 lines
35 KiB
C++
1254 lines
35 KiB
C++
|
#include "LineAccessor.h"
|
||
|
#include <exception>
|
||
|
#include <cmath>
|
||
|
#include <complex>
|
||
|
#include <sstream>
|
||
|
#include <iostream>
|
||
|
#include <string>
|
||
|
#include <vector>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
using namespace std;
|
||
|
// PUBLIC
|
||
|
|
||
|
void LineAccessor::changeBandScheme(string filein, string fileout, string type, int width, int numBands, BandSchemeType bandIn, BandSchemeType bandOut)
|
||
|
{
|
||
|
|
||
|
try
|
||
|
{
|
||
|
fstream fin(filein.c_str(), ios::in);
|
||
|
if(!fin)
|
||
|
{
|
||
|
cout << "Cannot open file " << filein << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
int sizeV = getTypeSize(type);
|
||
|
int length = ((int)getFileSize(fin))/(width*numBands*sizeV);
|
||
|
char * totFile = new char[sizeV*width*length*numBands];
|
||
|
char * line = new char[sizeV*width];
|
||
|
ofstream fout(fileout.c_str());
|
||
|
if(!fout)
|
||
|
{
|
||
|
cout << "Cannot open file " << fileout << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
fin.read(totFile,sizeV*width*length*numBands);
|
||
|
|
||
|
if((bandIn == BIP && bandOut == BIL) || (bandIn == BSQ && bandOut == BIL))
|
||
|
{
|
||
|
for(int i = 0; i < length; ++i)
|
||
|
{
|
||
|
for(int k = 0; k < numBands; ++k)
|
||
|
{
|
||
|
int cnt = 0;
|
||
|
for(int j = 0; j < width; ++j)
|
||
|
{
|
||
|
|
||
|
for(int p = 0; p < sizeV; ++p)
|
||
|
{
|
||
|
if((bandIn == BIP))
|
||
|
{
|
||
|
line[cnt] = totFile[p + k*sizeV + j*sizeV*numBands + i*sizeV*numBands*width];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
line[cnt] = totFile[p + j*sizeV + i*sizeV*width + k*sizeV*length*width];
|
||
|
|
||
|
}
|
||
|
++cnt;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
fout.write(line,cnt);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else if((bandIn == BIP && bandOut == BSQ) || (bandIn == BIL && bandOut == BSQ))
|
||
|
{
|
||
|
for(int k = 0; k < numBands; ++k)
|
||
|
{
|
||
|
for(int i = 0; i < length; ++i)
|
||
|
{
|
||
|
int cnt = 0;
|
||
|
for(int j = 0; j < width; ++j)
|
||
|
{
|
||
|
|
||
|
for(int p = 0; p < sizeV; ++p)
|
||
|
{
|
||
|
if((bandIn == BIP))
|
||
|
{
|
||
|
line[cnt] = totFile[p + k*sizeV + j*sizeV*numBands + i*sizeV*numBands*width];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
line[cnt] = totFile[p + j*sizeV + k*sizeV*width + i*sizeV*numBands*width];
|
||
|
|
||
|
}
|
||
|
++cnt;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
fout.write(line,cnt);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else if((bandIn == BSQ && bandOut == BIP) || (bandIn == BIL && bandOut == BIP))
|
||
|
{
|
||
|
for(int i = 0; i < length; ++i)
|
||
|
{
|
||
|
for(int j = 0; j < width; ++j)
|
||
|
{
|
||
|
int cnt = 0;
|
||
|
for(int k = 0; k < numBands; ++k)
|
||
|
{
|
||
|
|
||
|
for(int p = 0; p < sizeV; ++p)
|
||
|
{
|
||
|
if((bandIn == BSQ))
|
||
|
{
|
||
|
line[cnt] = totFile[p + j*sizeV + i*sizeV*width + k*sizeV*length*width];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
line[cnt] = totFile[p + j*sizeV + k*sizeV*width + i*sizeV*numBands*width];
|
||
|
|
||
|
}
|
||
|
++cnt;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
fout.write(line,cnt);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cout << "Error. Type of input and/or output interleaving band scheme must be BIL,BSQ or BIP." << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
delete [] totFile;
|
||
|
delete [] line;
|
||
|
fout.close();
|
||
|
fin.close();
|
||
|
}
|
||
|
catch(bad_alloc&)//cannot read the full size in memory, try something else
|
||
|
{
|
||
|
//for BIP <-> BIL can read one "line" (width and number bands) and rearrange the elements i.e. the
|
||
|
//file can be read one "line" at the time
|
||
|
|
||
|
fstream fin(filein.c_str(), ios::in);
|
||
|
if(!fin)
|
||
|
{
|
||
|
cout << "Cannot open file " << filein << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
int sizeV = getTypeSize(type);
|
||
|
int length = ((int)getFileSize(fin))/(width*numBands*sizeV);
|
||
|
int lineSize = sizeV*width*numBands;
|
||
|
char * lineIn = new char[lineSize];
|
||
|
char * line = new char[lineSize];
|
||
|
ofstream fout(fileout.c_str());
|
||
|
if(!fout)
|
||
|
{
|
||
|
cout << "Cannot open file " << fileout << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
if((bandOut == BSQ))
|
||
|
{
|
||
|
vector<char> lineL(lineSize,0);
|
||
|
for(int i = 0; i < length; ++i)
|
||
|
{
|
||
|
fout.write((char *) &lineL[0], lineSize);
|
||
|
}
|
||
|
}
|
||
|
for(int i = 0; i < length; ++i)
|
||
|
{
|
||
|
|
||
|
if(((bandIn == BIL) && (bandOut == BIP)) || ((bandOut == BIL) && (bandIn == BIP)) )
|
||
|
{
|
||
|
fin.read(lineIn,lineSize);
|
||
|
for(int k = 0; k < numBands; ++k)
|
||
|
{
|
||
|
for(int j = 0; j < width; ++j)
|
||
|
{
|
||
|
|
||
|
for(int p = 0; p < sizeV; ++p)
|
||
|
{
|
||
|
if((bandIn == BIL))
|
||
|
{
|
||
|
line[p + k*sizeV + j*sizeV*numBands] = lineIn[p + j*sizeV + k*sizeV*width];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
line[p + j*sizeV + k*sizeV*width] = lineIn[p + k*sizeV + j*sizeV*numBands];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fout.write(line,lineSize);
|
||
|
}
|
||
|
else if(((bandIn == BIL) && (bandOut == BSQ)) || ((bandIn == BIP) && (bandOut == BSQ)) )
|
||
|
{
|
||
|
fin.read(lineIn,lineSize);
|
||
|
for(int k = 0; k < numBands; ++k)
|
||
|
{
|
||
|
streampos pos = sizeV*((width*i) + (k*length*width));
|
||
|
fout.seekp(pos);
|
||
|
if(bandIn == BIL)
|
||
|
{
|
||
|
fout.write(&lineIn[sizeV*width*k],sizeV*width);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for(int j = 0; j < width; ++j)
|
||
|
{
|
||
|
for(int p = 0; p < sizeV; ++p)
|
||
|
{
|
||
|
line[p + sizeV*(j + k*width)] = lineIn[p + k*sizeV + j*sizeV*numBands];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fout.write(&line[sizeV*width*k],sizeV*width);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if(((bandIn == BSQ) && (bandOut == BIL)) || ((bandIn == BSQ) && (bandOut == BIP)))
|
||
|
{
|
||
|
for(int k = 0; k < numBands; ++k)
|
||
|
{
|
||
|
streampos pos = sizeV*((width*i) + (k*length*width));
|
||
|
fin.seekg(pos);
|
||
|
fin.read(&lineIn[sizeV*width*k],sizeV*width);
|
||
|
}
|
||
|
if(bandOut == BIL)
|
||
|
{
|
||
|
fout.write(lineIn,sizeV*width*numBands);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for(int k = 0; k < numBands; ++k)
|
||
|
{
|
||
|
for(int j = 0; j < width; ++j)
|
||
|
{
|
||
|
for(int p = 0; p < sizeV; ++p)
|
||
|
{
|
||
|
line[p + sizeV*(k + j*numBands)] = lineIn[p + j*sizeV + k*sizeV*width];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
fout.write(line,lineSize);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cout << "Error. Type of input and/or output interleaving band scheme must be BIL,BSQ or BIP." << endl;
|
||
|
ERR_MESSAGE;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
delete [] lineIn;
|
||
|
delete [] line;
|
||
|
fout.close();
|
||
|
fin.close();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void LineAccessor::convertFileEndianness(string fileIn, string fileOut, string type)
|
||
|
{
|
||
|
|
||
|
fstream fin(fileIn.c_str(), ios::in);
|
||
|
if(!fin)
|
||
|
{
|
||
|
cout << "Error. Cannot open file " << fileIn << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
ofstream fout(fileOut.c_str());
|
||
|
if(!fin)
|
||
|
{
|
||
|
cout << "Error. Cannot open file " << fileOut << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
bool memoryNotAllocated = true;
|
||
|
char * fileBuffer = NULL;
|
||
|
int divisor = 1;
|
||
|
int sizeV = getSizeForSwap(type);
|
||
|
if(sizeV == 1)
|
||
|
{
|
||
|
cout << "No need to convert endianness if the type size is one." << endl;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
streampos fileSize = 0;
|
||
|
streampos memorySize = 0;
|
||
|
while(memoryNotAllocated)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
fileSize = getFileSize(fin);
|
||
|
memorySize = (fileSize/(divisor*sizeV))*sizeV;//make sure that an integer number of sizeV is read
|
||
|
fileBuffer = new char[memorySize];
|
||
|
memoryNotAllocated = false;
|
||
|
|
||
|
}
|
||
|
catch(bad_alloc&)
|
||
|
{
|
||
|
divisor *= 2;
|
||
|
}
|
||
|
}
|
||
|
while(!fin.eof())
|
||
|
{
|
||
|
fin.read(fileBuffer,memorySize);
|
||
|
streampos bytesRead = fin.gcount();
|
||
|
streampos numElements = bytesRead/sizeV;
|
||
|
swapBytes(fileBuffer,numElements,sizeV);
|
||
|
fout.write(fileBuffer,bytesRead);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
delete [] fileBuffer;
|
||
|
}
|
||
|
fin.close();
|
||
|
fout.close();
|
||
|
|
||
|
}
|
||
|
void LineAccessor::createFile(int * fileLength)
|
||
|
{
|
||
|
//Checked other ways of doing it using "truncate" function, but it's not portable
|
||
|
vector<char> line(LineSize,0);
|
||
|
for(int i = 0; i < (*fileLength); ++i)
|
||
|
{
|
||
|
FileObject.write((char *) &line[0], LineSize);
|
||
|
}
|
||
|
FileLength = (*fileLength);
|
||
|
FileSize = LineSize*FileLength;
|
||
|
FileObject.seekp(0, ios_base::beg);
|
||
|
FileObject.clear();
|
||
|
|
||
|
}
|
||
|
|
||
|
void LineAccessor::rewindImage()
|
||
|
{
|
||
|
ColumnPosition = 1;
|
||
|
LineCounter = 1;
|
||
|
LinePosition = 1;
|
||
|
FileObject.seekp(0, ios_base::beg);
|
||
|
FileObject.seekg(0, ios_base::beg);
|
||
|
FileObject.clear();
|
||
|
}
|
||
|
char LineAccessor::getMachineEndianness()
|
||
|
{
|
||
|
unsigned short int intV = 49;//ascii code for 1
|
||
|
char * ptChar = (char *) &intV;
|
||
|
char retVal = 'b';
|
||
|
if(ptChar[0] == '1')
|
||
|
{
|
||
|
retVal = 'l';
|
||
|
}
|
||
|
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
char * LineAccessor::getTileArray()
|
||
|
{
|
||
|
return PtArray;
|
||
|
}
|
||
|
|
||
|
int LineAccessor::getSizeForSwap(string type)
|
||
|
{
|
||
|
int size = getTypeSize(type);
|
||
|
if(type == "CFLOAT" || type == "CDOUBLE" || type == "CLONGDOUBLE" || type == "cfloat" || type == "cdouble" || type == "clongdouble")
|
||
|
{
|
||
|
size /=2;
|
||
|
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
int LineAccessor::getTypeSize(string type)
|
||
|
{
|
||
|
int retVal = -1;
|
||
|
if(type == "byte" || type == "BYTE" || type == "char" || type == "CHAR")
|
||
|
{
|
||
|
retVal = sizeof(char);
|
||
|
}
|
||
|
else if(type == "short" || type == "SHORT")
|
||
|
{
|
||
|
retVal = sizeof(short);
|
||
|
}
|
||
|
else if(type == "int" || type == "INT")
|
||
|
{
|
||
|
retVal = sizeof(int);
|
||
|
}
|
||
|
else if(type == "long" || type == "LONG")
|
||
|
{
|
||
|
retVal = sizeof(long);
|
||
|
}
|
||
|
else if(type == "longlong" || type == "LONGLONG")
|
||
|
{
|
||
|
retVal = sizeof(long long);
|
||
|
}
|
||
|
else if(type == "float" || type == "FLOAT")
|
||
|
{
|
||
|
retVal = sizeof(float);
|
||
|
}
|
||
|
else if(type == "double" || type == "DOUBLE")
|
||
|
{
|
||
|
retVal = sizeof(double);
|
||
|
}
|
||
|
else if(type == "longdouble" || type == "LONGDOUBLE")
|
||
|
{
|
||
|
retVal = sizeof(long double);
|
||
|
}
|
||
|
else if(type == "cfloat" || type == "CFLOAT")
|
||
|
{
|
||
|
retVal = sizeof(complex<float>);
|
||
|
}
|
||
|
else if(type == "cdouble" || type == "CDOUBLE")
|
||
|
{
|
||
|
retVal = sizeof(complex<double>);
|
||
|
}
|
||
|
else if(type == "clongdouble" || type == "CLONGDOUBLE")
|
||
|
{
|
||
|
retVal = sizeof(complex<long double>);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
vector<string> data = getAvailableDataTypes();
|
||
|
cout << "Error. Unrecognized data type " << type << ". Available types are: "<< endl;
|
||
|
for(int i = 0; i < (int)data.size(); ++i)
|
||
|
{
|
||
|
cout << data[i] << endl;
|
||
|
}
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
vector<string> LineAccessor::getAvailableDataTypes()
|
||
|
{
|
||
|
vector<string> dataType;
|
||
|
dataType.push_back("BYTE");
|
||
|
dataType.push_back("CHAR");
|
||
|
dataType.push_back("SHORT");
|
||
|
dataType.push_back("INT");
|
||
|
dataType.push_back("LONG");
|
||
|
dataType.push_back("LONGLONG");
|
||
|
dataType.push_back("FLOAT");
|
||
|
dataType.push_back("DOUBLE");
|
||
|
dataType.push_back("LONGDOUBLE");
|
||
|
dataType.push_back("CFLOAT");
|
||
|
dataType.push_back("CDOUBLE");
|
||
|
dataType.push_back("CLONGDOUBLE");
|
||
|
return dataType;
|
||
|
}
|
||
|
void LineAccessor::printAvailableDataTypesAndSizes()
|
||
|
{
|
||
|
vector<string> dataType;
|
||
|
vector<int> size;
|
||
|
|
||
|
getAvailableDataTypesAndSizes(dataType, size);
|
||
|
for(int i = 0; i < (int)size.size(); ++i)
|
||
|
{
|
||
|
cout << dataType[i] << "\t" << size[i] << endl;
|
||
|
}
|
||
|
}
|
||
|
void LineAccessor::getAvailableDataTypesAndSizes(vector<string> & dataType, vector<int> & size)
|
||
|
{
|
||
|
dataType.clear();
|
||
|
size.clear();
|
||
|
dataType.push_back("BYTE");
|
||
|
size.push_back(getTypeSize("BYTE"));
|
||
|
dataType.push_back("CHAR");
|
||
|
size.push_back(getTypeSize("CHAR"));
|
||
|
dataType.push_back("SHORT");
|
||
|
size.push_back(getTypeSize("SHORT"));
|
||
|
dataType.push_back("INT");
|
||
|
size.push_back(getTypeSize("INT"));
|
||
|
dataType.push_back("LONG");
|
||
|
size.push_back(getTypeSize("LONG"));
|
||
|
dataType.push_back("LONGLONG");
|
||
|
size.push_back(getTypeSize("LONGLONG"));
|
||
|
dataType.push_back("FLOAT");
|
||
|
size.push_back(getTypeSize("FLOAT"));
|
||
|
dataType.push_back("DOUBLE");
|
||
|
size.push_back(getTypeSize("DOUBLE"));
|
||
|
dataType.push_back("LONGDOUBLE");
|
||
|
size.push_back(getTypeSize("LONGDOUBLE"));
|
||
|
dataType.push_back("CFLOAT");
|
||
|
size.push_back(getTypeSize("CFLOAT"));
|
||
|
dataType.push_back("CDOUBLE");
|
||
|
size.push_back(getTypeSize("CDOUBLE"));
|
||
|
dataType.push_back("CLONGDOUBLE");
|
||
|
size.push_back(getTypeSize("CLONGDOUBLE"));
|
||
|
}
|
||
|
void LineAccessor::finalizeLineAccessor()
|
||
|
{
|
||
|
if(NeedToFlush)
|
||
|
{
|
||
|
FileObject.write(PtArray,(LineCounter - 1)*SizeV*FileWidth);
|
||
|
}
|
||
|
FileObject.close();
|
||
|
delete [] PtArray;
|
||
|
}
|
||
|
|
||
|
void LineAccessor::getStream(char * dataLine, int * numEl)
|
||
|
{
|
||
|
FileObject.read(dataLine,(*numEl)*SizeV);
|
||
|
(*numEl) = FileObject.gcount()/SizeV;
|
||
|
|
||
|
}
|
||
|
void LineAccessor::getStreamAtPos(char * dataLine, int * pos, int * numEl)
|
||
|
{
|
||
|
streampos off = (streampos) ((*pos) - 1)*SizeV;
|
||
|
FileObject.seekg(off, ios_base::beg);
|
||
|
FileObject.read(dataLine,(*numEl)*SizeV);
|
||
|
(*numEl) = FileObject.gcount()/SizeV;
|
||
|
|
||
|
}
|
||
|
void LineAccessor::getElements(char * dataLine, int * row, int * col, int * numEl)
|
||
|
{
|
||
|
vector<int> indx((*numEl),0);
|
||
|
vector<int> colCp((*numEl),0);
|
||
|
vector<int> rowCp((*numEl),0);
|
||
|
for(int i = 0; i < (*numEl); ++i)
|
||
|
{
|
||
|
checkRowRange(row[i]);
|
||
|
checkColumnRange(col[i]);
|
||
|
indx[i] = i;
|
||
|
colCp[i] = col[i];
|
||
|
rowCp[i] = row[i];
|
||
|
}
|
||
|
quickSort(&rowCp[0],&colCp[0],&indx[0],0,(*numEl) - 1);//so could check if some elements are close by and load
|
||
|
// a tile that might contain some.
|
||
|
int elementsRead = 0;
|
||
|
int rowPos = rowCp[0];
|
||
|
|
||
|
char * buffer = new char[LineSize*ReadBufferSize];
|
||
|
while(true)
|
||
|
{
|
||
|
streampos off = (streampos) (rowPos - 1)*LineSize;
|
||
|
FileObject.seekg(off, ios_base::beg);
|
||
|
FileObject.read(buffer,LineSize*ReadBufferSize);
|
||
|
int lineIndx = elementsRead;
|
||
|
int startIndx = elementsRead;
|
||
|
while(true)
|
||
|
{
|
||
|
if(rowCp[lineIndx] < (rowPos) + ReadBufferSize)
|
||
|
{
|
||
|
++lineIndx;
|
||
|
if(lineIndx == (*numEl))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
for(int i = startIndx; i < lineIndx; ++i)
|
||
|
{
|
||
|
for(int j = 0; j < SizeV; ++j)
|
||
|
{
|
||
|
|
||
|
dataLine[j + indx[i]*SizeV] = buffer[j + (colCp[i] - 1)*SizeV + (rowCp[i] - rowPos)*LineSize];
|
||
|
}
|
||
|
}
|
||
|
if(lineIndx == (*numEl))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
elementsRead = lineIndx;
|
||
|
rowPos = rowCp[lineIndx];
|
||
|
|
||
|
}
|
||
|
|
||
|
delete [] buffer;
|
||
|
|
||
|
int numElForSwap = (*numEl)*SizeV/SizeForSwap;
|
||
|
if(EndianMachine != EndianFile)
|
||
|
{
|
||
|
swapBytes(dataLine,numElForSwap,SizeForSwap);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void LineAccessor::getSequentialElements(char * dataLine, int * row, int * col, int * numEl)
|
||
|
{
|
||
|
checkRowRange((*row));
|
||
|
checkColumnRange((*col));
|
||
|
streampos off = (streampos) ((*row) - 1)*LineSize + ((*col) - 1)*SizeV;
|
||
|
FileObject.seekg(off, ios_base::beg);
|
||
|
FileObject.read(dataLine,(*numEl)*SizeV);
|
||
|
(*numEl) = FileObject.gcount()/SizeV;
|
||
|
int numElForSwap = FileObject.gcount()/SizeForSwap;
|
||
|
if(EndianMachine != EndianFile)
|
||
|
{
|
||
|
swapBytes(dataLine,numElForSwap,SizeForSwap);
|
||
|
}
|
||
|
}
|
||
|
void LineAccessor::getLine(char * dataLine, int * row)
|
||
|
{
|
||
|
if((*row) > FileLength || (*row) < 1)
|
||
|
{
|
||
|
(*row) = -1;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
streampos off = (streampos) ((*row) - 1)*LineSize;
|
||
|
FileObject.seekg(off, ios_base::beg);
|
||
|
FileObject.read(dataLine,LineSize);
|
||
|
int numElForSwap = FileObject.gcount()/SizeForSwap;
|
||
|
if(EndianMachine != EndianFile)
|
||
|
{
|
||
|
swapBytes(dataLine,numElForSwap,SizeForSwap);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
void LineAccessor::getLineSequential(char * dataLine, int * eof)
|
||
|
{
|
||
|
if(LinePosition > FileLength)// return negative val to signify the eof
|
||
|
{
|
||
|
(*eof) = -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(SizeYTile == 1)
|
||
|
{
|
||
|
FileObject.read(dataLine,LineSize);
|
||
|
int numElForSwap = LineSize/SizeForSwap;
|
||
|
if(EndianMachine != EndianFile)
|
||
|
{
|
||
|
swapBytes(dataLine,numElForSwap,SizeForSwap);
|
||
|
}
|
||
|
(*eof) = LinePosition;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if( ((LineCounter))%(SizeYTile + 1) == 0)
|
||
|
{
|
||
|
FileObject.read(PtArray,TileSize);
|
||
|
int numElForSwap = FileObject.gcount()/SizeForSwap;
|
||
|
if(EndianMachine != EndianFile)
|
||
|
{
|
||
|
swapBytes(PtArray,numElForSwap,SizeForSwap);
|
||
|
}
|
||
|
LineCounter = 1;
|
||
|
}
|
||
|
for(int i = 0; i < FileWidth*SizeV; ++i)
|
||
|
{
|
||
|
dataLine[i] = PtArray[i + (LineCounter - 1)*SizeV*FileWidth];
|
||
|
}
|
||
|
(*eof) = LinePosition;
|
||
|
++LineCounter;
|
||
|
}
|
||
|
}
|
||
|
++LinePosition;
|
||
|
|
||
|
}
|
||
|
|
||
|
bool LineAccessor::isInit()
|
||
|
{
|
||
|
return IsInit;
|
||
|
}
|
||
|
|
||
|
void LineAccessor::initLineAccessor(string filename, string filemode, char endianFile, string type,int row,int col)
|
||
|
{
|
||
|
IsInit = true;
|
||
|
DataType = getAvailableDataTypes();
|
||
|
SizeV = getTypeSize(type);
|
||
|
SizeForSwap = getSizeForSwap(type);
|
||
|
FileDataType = type;
|
||
|
|
||
|
Filename = filename;
|
||
|
if(col <= 0)
|
||
|
{
|
||
|
|
||
|
SizeXTile = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
SizeXTile = col;
|
||
|
}
|
||
|
|
||
|
SizeYTile = row;
|
||
|
FileWidth = SizeXTile;
|
||
|
LineSize = SizeXTile*SizeV;
|
||
|
TileSize = SizeXTile*SizeYTile*SizeV;
|
||
|
PtArray = new char[SizeXTile*SizeYTile*SizeV];
|
||
|
EndianMachine = getMachineEndianness();
|
||
|
if(endianFile == 'l' || endianFile == 'L' || endianFile == 'b' || endianFile == 'B')
|
||
|
{
|
||
|
EndianFile = endianFile;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cout << "Error. Endianness must be \"l,L,b,B\"" << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
setAccessMode(filemode);
|
||
|
openFile(Filename,AccessMode, FileObject);
|
||
|
MachineSize = getMachineSize();
|
||
|
}
|
||
|
// move the fstream pointer to the begLine
|
||
|
void LineAccessor::initSequentialAccessor(int * begLine)
|
||
|
{
|
||
|
if((AccessMode == "write") && ((*begLine) > FileLength))
|
||
|
{
|
||
|
cout << "Error. Cannot position the file pointer at line " << (*begLine) << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
LinePosition = (* begLine);
|
||
|
checkRowRange(LinePosition);
|
||
|
streampos off = (streampos) ((*begLine) - 1)*LineSize;
|
||
|
FileObject.seekg(off, ios_base::beg);
|
||
|
FileObject.seekp(off, ios_base::beg);
|
||
|
//the first check is due to avoid that the file pointer move past the first line. see getLineSequential where it checks for SizeYTile == 1.
|
||
|
if((SizeYTile > 1) && (AccessMode == "read"))
|
||
|
{
|
||
|
FileObject.read(PtArray,TileSize);
|
||
|
int numElForSwap = FileObject.gcount()/SizeForSwap;
|
||
|
if(EndianMachine != EndianFile)
|
||
|
{
|
||
|
swapBytes(PtArray,numElForSwap,SizeForSwap);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void LineAccessor::printObjectInfo()
|
||
|
{
|
||
|
cout << "File name: " << Filename << endl;
|
||
|
cout << "File access mode: " << AccessMode << endl;
|
||
|
cout << "File datatype: " << FileDataType << endl;
|
||
|
cout << "File datatype size: " << SizeV << endl;
|
||
|
cout << "File endiannes: " << (EndianFile == 'b' ? "big endian": "little endian") << endl;
|
||
|
cout << "Machine endiannes: " << (EndianMachine == 'b' ? "big endian": "little endian") << endl;
|
||
|
cout << "File size: " << FileSize << " bytes" << endl;
|
||
|
cout << "File width (number of columns): " << FileWidth << endl;
|
||
|
cout << "File length (number of rows): " << FileLength << endl;
|
||
|
cout << "Tile size: " << SizeYTile << (SizeYTile == 1 ? " row, ": " rows, ") << SizeXTile << (SizeXTile == 1 ? " column" : " columns") << endl;
|
||
|
|
||
|
}
|
||
|
|
||
|
void LineAccessor::setStream(char * dataLine, int * numEl)
|
||
|
{
|
||
|
FileObject.write(dataLine,(*numEl)*SizeV);
|
||
|
|
||
|
}
|
||
|
void LineAccessor::setStreamAtPos(char * dataLine, int * pos, int * numEl)
|
||
|
{
|
||
|
streampos off = (streampos) ((*pos) - 1)*SizeV;
|
||
|
FileObject.seekp(off, ios_base::beg);
|
||
|
FileObject.write(dataLine,(*numEl)*SizeV);
|
||
|
|
||
|
}
|
||
|
void LineAccessor::setElements(char * dataLine, int * row, int * col, int * numEl)
|
||
|
{
|
||
|
//make sure rows and colums are in range
|
||
|
for(int i = 0; i < (*numEl); ++i)
|
||
|
{
|
||
|
checkRowRange(row[i]);
|
||
|
checkColumnRange(col[i]);
|
||
|
}
|
||
|
int elementsRead = 0;//how many elements were in a given tile
|
||
|
int rowPos = row[0];//beginning of buffer read
|
||
|
//allocate a tile
|
||
|
char * buffer = new char[LineSize*ReadBufferSize];
|
||
|
while(true)
|
||
|
{
|
||
|
int lineIndx = elementsRead;//last line (relative to posRow) were data are
|
||
|
int startIndx = elementsRead;//first line (relative to rowPos) were data are
|
||
|
//count how many lines are in a tile
|
||
|
while(true)
|
||
|
{
|
||
|
if(row[lineIndx] < (rowPos) + ReadBufferSize)
|
||
|
{
|
||
|
++lineIndx;
|
||
|
if(lineIndx == (*numEl))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if(lineIndx == startIndx + 1)//there is only one element contained in the tile, so don't load it and just write the element
|
||
|
{
|
||
|
streampos off = (streampos) (rowPos - 1)*LineSize + (col[startIndx] - 1)*SizeV;
|
||
|
FileObject.seekp(off, ios_base::beg);
|
||
|
for(int j = 0; j < SizeV; ++j)
|
||
|
{
|
||
|
buffer[j] = dataLine[j + startIndx*SizeV];
|
||
|
}
|
||
|
FileObject.write(buffer,SizeV);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
streampos off = (streampos) (rowPos - 1)*LineSize;
|
||
|
FileObject.seekg(off, ios_base::beg);
|
||
|
FileObject.read(buffer,LineSize*ReadBufferSize);
|
||
|
if(FileObject.eof())
|
||
|
{
|
||
|
FileObject.clear();
|
||
|
}
|
||
|
int countG = FileObject.gcount();
|
||
|
|
||
|
FileObject.seekp(off, ios_base::beg);
|
||
|
//copy elements in the tile and write back
|
||
|
for(int i = startIndx; i < lineIndx; ++i)
|
||
|
{
|
||
|
for(int j = 0; j < SizeV; ++j)
|
||
|
{
|
||
|
|
||
|
buffer[j + (col[i] - 1)*SizeV + (row[i] - rowPos)*LineSize] = dataLine[j + i*SizeV];
|
||
|
}
|
||
|
}
|
||
|
FileObject.write(buffer,countG);
|
||
|
}
|
||
|
//wrote all elements, break
|
||
|
if(lineIndx == (*numEl))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
elementsRead = lineIndx;
|
||
|
rowPos = row[lineIndx];
|
||
|
|
||
|
}
|
||
|
|
||
|
delete [] buffer;
|
||
|
|
||
|
}
|
||
|
|
||
|
void LineAccessor::setLineSequential(char * dataLine)
|
||
|
{
|
||
|
if(SizeYTile == 1)
|
||
|
{
|
||
|
FileObject.write(dataLine,LineSize);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for(int i = 0; i < FileWidth*SizeV; ++i)
|
||
|
{
|
||
|
PtArray[i + (LineCounter - 1)*FileWidth*SizeV] = dataLine[i];
|
||
|
}
|
||
|
if( ((LineCounter))%(SizeYTile) == 0)
|
||
|
{
|
||
|
|
||
|
FileObject.write(PtArray,TileSize);
|
||
|
NeedToFlush = false;
|
||
|
LineCounter = 1;
|
||
|
}
|
||
|
else // just increase the counter
|
||
|
{
|
||
|
NeedToFlush = true;
|
||
|
++LineCounter;
|
||
|
}
|
||
|
}
|
||
|
++LinePosition;
|
||
|
}
|
||
|
|
||
|
void LineAccessor::setLine(char * dataLine, int * row)
|
||
|
{
|
||
|
if(((*row) > FileLength) || ((*row) < 1))
|
||
|
{
|
||
|
cout << "Error. The line to be set is out of range. Total number of line in the file = " << FileLength << ", line requested = " << (*row) << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
LinePosition = (*row);
|
||
|
streampos off = (streampos) ((*row) - 1)*LineSize;
|
||
|
FileObject.seekp(off, ios_base::beg);
|
||
|
FileObject.write(dataLine,LineSize);
|
||
|
}
|
||
|
void LineAccessor::setSequentialElements(char * dataLine, int * row, int * col, int * numEl)
|
||
|
{
|
||
|
if(!((*row) == LinePosition) && ((*col) == ColumnPosition))
|
||
|
{
|
||
|
//is not sequential w/respect to previous write, check if it's in range.
|
||
|
// in this case the file needs to be already allocated.
|
||
|
|
||
|
checkRowRange((*row));
|
||
|
checkColumnRange((*col));
|
||
|
}
|
||
|
LinePosition = (*row) + ((*col) + (*numEl))/FileWidth;
|
||
|
ColumnPosition = ((*col) + (*numEl))%FileWidth;//next column where to write
|
||
|
if(FileLength > 0 && (LinePosition > FileLength) && ColumnPosition > 1)
|
||
|
{
|
||
|
cout << "Error. Writing outside file bounds." << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
streampos off = (streampos) ((*row) - 1)*LineSize + ((*col) - 1)*SizeV;
|
||
|
FileObject.seekp(off, ios_base::beg);
|
||
|
FileObject.write(dataLine,(*numEl)*SizeV);
|
||
|
}
|
||
|
|
||
|
//PRIVATE
|
||
|
|
||
|
|
||
|
void LineAccessor::checkColumnRange(int col)
|
||
|
{
|
||
|
if(( col) > FileWidth)
|
||
|
{
|
||
|
cout << "Error. Trying to access the column " << col <<" that is larger than the file width " << FileWidth << " ." << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
if(( col) < 1)
|
||
|
{
|
||
|
cout << "Error. The column number has to be a positive." << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
void LineAccessor::checkRowRange(int row)
|
||
|
{
|
||
|
if(( row) > FileLength)
|
||
|
{
|
||
|
|
||
|
cout << "Error. Trying to access the line "<< row << " that is larger than the number of lines in the file " << FileLength << "." << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
if(( row) < 1)
|
||
|
{
|
||
|
cout << "Error. The line number has to be a positive" << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
streampos LineAccessor::getFileSize(fstream & fin)
|
||
|
{
|
||
|
if(!fin.is_open())
|
||
|
{
|
||
|
cout << "File must be open" << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
streampos savePos = fin.tellg();
|
||
|
fin.seekg(0,ios::end);
|
||
|
streampos retPos = fin.tellg();
|
||
|
fin.seekg(savePos,ios::beg);
|
||
|
return retPos;
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
streampos LineAccessor::getFileSize(string filename)
|
||
|
{
|
||
|
ifstream fin;
|
||
|
fin.open(filename.c_str());
|
||
|
if(!fin)
|
||
|
{
|
||
|
cout << "Cannot open file " << filename << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
streampos savePos = fin.tellg();
|
||
|
fin.seekg(0,ios::end);
|
||
|
streampos retPos = fin.tellg();
|
||
|
fin.seekg(savePos,ios::beg);
|
||
|
return retPos;
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
void LineAccessor::openFile(string filename, string accessMode, fstream & fd)
|
||
|
{
|
||
|
if(accessMode == "read" || accessMode == "READ")
|
||
|
{
|
||
|
|
||
|
fd.open(filename.c_str(), ios_base::in);
|
||
|
if(fd.fail())
|
||
|
{
|
||
|
cout << "Error. Cannot open the file " << filename << " in " << accessMode << " mode." <<endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
if(SizeYTile > 1)// only in this case tiling and prebuffering is used
|
||
|
{
|
||
|
fd.read(PtArray,TileSize);// read first tile
|
||
|
}
|
||
|
int numElForSwap = fd.gcount()/SizeForSwap;
|
||
|
if(EndianMachine != EndianFile)
|
||
|
{
|
||
|
swapBytes(PtArray,numElForSwap,SizeForSwap);
|
||
|
}
|
||
|
FileSize = getFileSize(fd);
|
||
|
FileLength = FileSize/(SizeV*FileWidth);// number of lines
|
||
|
if(FileSize%(SizeV*FileWidth))
|
||
|
{
|
||
|
//better be divisable by sizeV*FileWidth
|
||
|
cout << "Error. The number of lines in the file " << Filename << " computed as file_size/(line_size) is not integer. Filesize = " << FileSize << " number element per line = " << FileWidth << " size of one element = " << SizeV << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else if(accessMode == "write" || accessMode == "WRITE")
|
||
|
{
|
||
|
fd.open(filename.c_str(), ios_base::out);
|
||
|
}
|
||
|
else if(accessMode == "append" || accessMode == "APPEND")
|
||
|
{
|
||
|
fd.open(filename.c_str(), ios_base::app);
|
||
|
}
|
||
|
else if(accessMode == "writeread" || accessMode == "WRITEREAD")
|
||
|
{
|
||
|
fd.open(filename.c_str(), ios_base::trunc | ios_base::in | ios_base::out);
|
||
|
}
|
||
|
else if(accessMode == "readwrite" || accessMode == "READWRITE")
|
||
|
{
|
||
|
fd.open(filename.c_str(), ios_base::in | ios_base::out);
|
||
|
if(SizeYTile > 1)// only in this case tiling and prebuffering is used
|
||
|
{
|
||
|
fd.read(PtArray,TileSize);
|
||
|
}
|
||
|
int numElForSwap = fd.gcount()/SizeForSwap;
|
||
|
if(EndianMachine != EndianFile)
|
||
|
{
|
||
|
swapBytes(PtArray,numElForSwap,SizeForSwap);
|
||
|
}
|
||
|
FileSize = getFileSize(fd);
|
||
|
FileLength = FileSize/(SizeV*FileWidth);// number of lines
|
||
|
if(FileSize%(SizeV*FileWidth))
|
||
|
{
|
||
|
//better be divisable by sizeV*FileWidth
|
||
|
cout << "Error. The number of lines in the file computed as file_size/(line_size) is not integer. Filesize = " << FileSize << " number element per line = " << FileWidth << " size of one element = " << SizeV << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cout << "Error. Unrecognized open mode " << accessMode << " for file " << filename << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
if(!fd)
|
||
|
{
|
||
|
cout << "Cannot open file " << filename << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
void LineAccessor::setAccessMode(string accessMode)
|
||
|
{
|
||
|
if(accessMode == "read" || accessMode == "READ")
|
||
|
{
|
||
|
AccessMode = "read";
|
||
|
}
|
||
|
else if(accessMode == "write" || accessMode == "WRITE")
|
||
|
{
|
||
|
AccessMode = "write";
|
||
|
}
|
||
|
else if(accessMode == "append" || accessMode == "APPEND")
|
||
|
{
|
||
|
AccessMode = "append";
|
||
|
}
|
||
|
else if(accessMode == "writeread" || accessMode == "WRITEREAD")
|
||
|
{
|
||
|
AccessMode = "writeread";
|
||
|
}
|
||
|
else if(accessMode == "readwrite" || accessMode == "READWRITE")
|
||
|
{
|
||
|
AccessMode = "readwrite";
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cout << "Error. Unrecognized open mode " << accessMode << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void LineAccessor::quickSort(int * row, int * col ,int * indx, int lo, int hi)
|
||
|
{
|
||
|
int i = lo;
|
||
|
int j = hi;
|
||
|
int tmpIndxR = 0;
|
||
|
int tmpIndxC = 0;
|
||
|
int tmpIndx = 0;
|
||
|
int half = row[(lo + hi)/2];
|
||
|
do
|
||
|
{
|
||
|
while (row[i] < half) ++i;
|
||
|
while (row[j] > half) --j;
|
||
|
if(i <= j )
|
||
|
{
|
||
|
tmpIndxR = row[i];
|
||
|
tmpIndxC = col[i];
|
||
|
tmpIndx = indx[i];
|
||
|
row[i] = row[j];
|
||
|
col[i] = col[j];
|
||
|
indx[i] = indx[j];
|
||
|
row[j] = tmpIndxR;
|
||
|
col[j] = tmpIndxC;
|
||
|
indx[j] = tmpIndx;
|
||
|
++i;
|
||
|
--j;
|
||
|
}
|
||
|
}
|
||
|
while(i <= j);
|
||
|
if(lo < j) quickSort(row,col,indx,lo,j);
|
||
|
if(hi > i) quickSort(row,col,indx,i,hi);
|
||
|
}
|
||
|
void LineAccessor::swapBytes(char * buffer, int numElements, int sizeV)
|
||
|
{
|
||
|
switch(sizeV)
|
||
|
{
|
||
|
case 2:
|
||
|
{
|
||
|
for(int i = 0; i < numElements; ++i)
|
||
|
{
|
||
|
|
||
|
(* (uint16_t *) &buffer[i*sizeV]) = swap2Bytes((uint16_t *) &buffer[i*sizeV]);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case 4:
|
||
|
{
|
||
|
|
||
|
for(int i = 0; i < numElements; ++i)
|
||
|
{
|
||
|
(* ((uint32_t *) &buffer[i*sizeV])) = swap4Bytes((uint32_t *)&buffer[i*sizeV]);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
case 8:
|
||
|
{
|
||
|
|
||
|
#ifndef MACHINE_64
|
||
|
for(int i = 0; i < numElements; ++i)
|
||
|
{
|
||
|
swap8BytesSlow(&buffer[i*sizeV]);
|
||
|
}
|
||
|
#else
|
||
|
for(int i = 0; i < numElements; ++i)
|
||
|
{
|
||
|
|
||
|
(* (uint64_t *) &buffer[i*sizeV]) = swap8BytesFast((uint64_t *) &buffer[i*sizeV]);
|
||
|
}
|
||
|
#endif
|
||
|
break;
|
||
|
}
|
||
|
case 12:
|
||
|
{
|
||
|
|
||
|
for(int i = 0; i < numElements; ++i)
|
||
|
{
|
||
|
swap12Bytes(&buffer[i*sizeV]);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case 16:
|
||
|
{
|
||
|
|
||
|
for(int i = 0; i < numElements; ++i)
|
||
|
{
|
||
|
swap16Bytes(&buffer[i*sizeV]);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
{
|
||
|
cout << "Unexpected variable size" << endl;
|
||
|
ERR_MESSAGE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
uint16_t LineAccessor::swap2Bytes(uint16_t * x)
|
||
|
{
|
||
|
return ((*x) & 0xFF00) >> 8 |
|
||
|
((*x) & 0x00FF) << 8;
|
||
|
}
|
||
|
uint32_t LineAccessor::swap4Bytes(uint32_t * x)
|
||
|
{
|
||
|
return ((*x) & 0xFF000000) >> 24 |
|
||
|
((*x) & 0x00FF0000) >> 8 |
|
||
|
((*x) & 0x0000FF00) << 8 |
|
||
|
((*x) & 0x000000FF) << 24;
|
||
|
}
|
||
|
|
||
|
// had to do it since some g++ compiler give a warning if the number is larger then the register, others give an error
|
||
|
#ifdef MACHINE_64
|
||
|
// if the machine is not 64 bit this cannot be used since the registers are too small (>> and << is done into register, not memory => fast)
|
||
|
uint64_t LineAccessor::swap8BytesFast(uint64_t * x)
|
||
|
{
|
||
|
return ((*x) & 0xFF00000000000000) >> 56 |
|
||
|
((*x) & 0x00FF000000000000) >> 40 |
|
||
|
((*x) & 0x0000FF0000000000) >> 24 |
|
||
|
((*x) & 0x000000FF00000000) >> 8 |
|
||
|
((*x) & 0x00000000FF000000) << 8 |
|
||
|
((*x) & 0x0000000000FF0000) << 24 |
|
||
|
((*x) & 0x000000000000FF00) << 40 |
|
||
|
((*x) & 0x00000000000000FF) << 56;
|
||
|
}
|
||
|
#endif
|
||
|
void LineAccessor::swap8BytesSlow(char * x)
|
||
|
{
|
||
|
char tmp;
|
||
|
int size = 8;
|
||
|
int half = 4;
|
||
|
for(int i = 0; i < half; ++i)
|
||
|
{
|
||
|
tmp = x[i];
|
||
|
x[i] = x[size-1-i];
|
||
|
x[size-1-i] = tmp;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
void LineAccessor::swap12Bytes(char * x) //for some architecture size(long double) = 12
|
||
|
{
|
||
|
char tmp;
|
||
|
int size = 12;
|
||
|
int half = 6;
|
||
|
for(int i = 0; i < half; ++i)
|
||
|
{
|
||
|
tmp = x[i];
|
||
|
x[i] = x[size-1-i];
|
||
|
x[size-1-i] = tmp;
|
||
|
}
|
||
|
}
|
||
|
void LineAccessor::swap16Bytes(char * x) //for some architecture size(long double) = 12
|
||
|
{
|
||
|
char tmp;
|
||
|
int size = 16;
|
||
|
int half = 8;
|
||
|
for(int i = 0; i < half; ++i)
|
||
|
{
|
||
|
tmp = x[i];
|
||
|
x[i] = x[size-1-i];
|
||
|
x[size-1-i] = tmp;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//end-of-file
|