#include #include #include #include #include #include #include #include "mat.h" using namespace std; void makeNames( string &outname, string &inname, string &vname, const string &dimName, int ni, int mu ); void writeOneArray( int kwidth, int kheight, int ni, int mu, string vname, mxArray *array, ostream &os ); mxArray * readImageMat( const char *fileName ); void writeGenerationInfo( ostream &os, string &fname ); // file name and date/time stamp bool checkArgs( int argc, char *argv[] ); bool silent = false; string kernelDir; int main( int argc, char *argv[] ) { if( !checkArgs( argc, argv ) ) { return 1; } /* Main gabor kernel loop, uses one kernel per inner loop with filenames of the form: kernels-96x96/ker__.mat */ int kwidth = 96; int kheight = 96; ostringstream dimStream; dimStream << kwidth << "x" << kheight; // << ends(dimStream); string dimName(dimStream.str()); // portion of the file names that represent the matrix dimensions ostringstream headerName; headerName << "kernels"; headerName << dimName; // << ".h"; // ends( headerName ); string baseHeaderName( headerName.str() ); string hName(baseHeaderName + ".h"); ofstream header( (kernelDir + hName).c_str(), ios::out); writeGenerationInfo( header, hName ); // Change headerString to be used for the ifdef wrapper string headerString( baseHeaderName ); transform( headerString.begin(), headerString.end(), headerString.begin(), ::toupper); headerString.insert( 0, "__" ); headerString.append( "_H__" ); header << "#ifndef " << headerString << endl; header << "#define " << headerString << endl << endl; header << "typedef double (*kernelAccess)(int);" << endl << endl; // This will end up being an array in the header with pointers to all the other arrays ostringstream arrays; arrays << "kernelAccess kernelFuncs" << dimName << "[] = {" << endl; for( int ni=-2; ni<=8; ++ni ) { for( int mu=0; mu<=7; ++mu ) { string fname, matname, vname; makeNames( fname, matname, vname, dimName, ni, mu ); if( !silent ) cout << "Writing " << vname << " to file " << fname << endl; ofstream os( (kernelDir + fname).c_str(), ios::out); writeGenerationInfo( os, fname ); mxArray *array = readImageMat( (kernelDir + matname).c_str() ); writeOneArray( kwidth, kheight, ni, mu, vname, array, os ); // header << "extern double *" << vname << ";" << endl; header << "double " << vname << "(int);" << endl; arrays << " " << vname << "," << endl; } } arrays << " };" << endl; // ends(arrays); string cppName(baseHeaderName + ".cpp"); ofstream mainCPP( (kernelDir + cppName).c_str(), ios::out); mainCPP << "#include \"" << hName << "\"" << endl; mainCPP << endl << arrays.str() << endl; header << endl << "extern kernelAccess kernelFuncs" << dimName << "[];" << endl; // header << endl << "extern double *kernels" << dimName << "[];" << endl; header << endl << "#endif " << headerString << endl; return 0; } void makeNames( string &outname, string &inname, string &vname, const string &dimName, int ni, int mu ) { ostringstream namestr, hstr; namestr << "kernels" << dimName.c_str() << "_ker_" << ni << "_" << mu << ".cpp"; // ends(namestr); outname = namestr.str(); inname = outname; inname.replace( inname.find(".cpp"), 4, ".mat" ); inname.replace( 0, (inname.find('_')+1), "Data/" ); // inname = string( "Data/" ) + inname; vname = outname; vname.erase( vname.find( '.') ); string::size_type loc = vname.find('-'); if( loc != string::npos ) { vname.replace( vname.find('-'), 1, "n" ); loc = vname.find('-'); if( loc != string::npos ) vname.replace( vname.find('-'), 1, "n" ); } } void writeOneArray( int kwidth, int kheight, int ni, int mu, string vname, mxArray *array, ostream &os ) { if( !array ) { os << "// Unable to read/write data for " << vname << endl; return; } double *realArray = mxGetPr(array); double *imaginaryArray = mxGetPi(array); if( !imaginaryArray ) { os << "// Unable to read/write data for " << vname << endl; } else { int rowmax = static_cast(mxGetM(array)); int colmax = static_cast(mxGetN(array)); int count = colmax * rowmax; os << "double " << vname << "_arr[] = {" << endl << " "; //#define TRANSPOSE #ifdef TRANSPOSE for( int col=0; col= 0) && (index < 96*96*2) ); os << "return " << vname << "_arr[index];" << endl; os << "}" << endl; } } /** Read one Matlab array from a file. * The first variable in a Matlab .mat file will be read in and returned. * This is primarily used to create an RImage object from a saved .mat file and hasn't been tested for any other use. * * See also writeImageMat() for saving the array into the file. */ mxArray * readImageMat( const char *fileName ) { MATFile *fileID = matOpen( fileName, "r" ); const char *name; mxArray *pa; if ( fileID == NULL ) { #ifdef DEBUG printf("Error opening file %s for reading\n", fileName ); #endif return NULL; } pa = matGetNextVariable( fileID, &name); if( pa == NULL ) { matClose( fileID ); return NULL; } matClose(fileID); return pa; } void writeGenerationInfo( ostream &os, string &fname ) { os << "/* " << fname << " - generated by KernelExport" << endl; { time_t atime; time( &atime ); os << " * Generated at " << ctime( &atime ) << endl; } os << " */" << endl; } bool checkArgs( int argc, char *argv[] ) { int optind=1; // decode arguments while ((optind < argc) && (argv[optind][0]=='-')) { string sw = argv[optind]; if( sw == "-s" ) { optind++; silent = true; } else { cout << "Unknown option for KernelExport: " << sw << endl; return false; } } if( optind < argc ) { kernelDir = argv[optind]; // ignore any extra arguments if( kernelDir[ kernelDir.size() - 1 ] != '/' ) kernelDir += "/"; } return true; }