server host (default: " << DEFAULT_HOST << ")" << endl;
cout << " --port server port (default: " << DEFAULT_PORT << ")" << endl;
cout << " -d, --database database name (default: " << DEFAULT_DB << ")" << endl;
cout << " -u, --user user name (default: " << DEFAULT_USER << ")" << endl;
cout << " -p, --passwd password (default: " << DEFAULT_PASSWD << ")" << endl << endl;
cout << " --transferformat transfer format. default: " << DEFAULT_TR_FMT << ")" << endl;
cout << " --transferformatparams transfer format parameters.(default: '')" << endl;
cout << " --storageformat storage format (default: " << DEFAULT_ST_FMT << ")" << endl;
cout << " --storageformatparams storage format parameters.(default: '')" << endl;
cout << " -v, --verbose be verbose (default: be brief)" << endl;
cout << "Note: If one file is passed, then a 2D object will be generated. " << endl
<< " If several files are passed, then a 3D object will be generated (in the sequence passed)," << endl
<< " In this case all files must have same pixel type and x/y extent." << endl;
}
int
main( int argc, char** argv )
{
const char *prog = argv[0]; // our name
int retval = EXIT_OK; // program exit code
PixelType pixType = DEFAULT_PIXEL_TYPE; // image pixel type
const char *typeString = DEFAULT_TYPE; // image pixel type
r_Bytes typeSize=DEFAULT_PIXSIZE; // pixel size [bytes]
const char *tileString = NULL; // transfer format string
const char *transferFormatString = DEFAULT_TR_FMT; // transfer format string
r_Data_Format transferFormat=r_Array; // transfer format used
const char *transferFormatParams = ""; // transfer format parameters
const char *storageFormatString = DEFAULT_ST_FMT; // storage format string
r_Data_Format storageFormat=r_Array; // storage format used
char *storageFormatParams = ""; // storage format parameters
const char *collName=NULL; // name of collection
r_Minterval imgSize; // size of image
r_Minterval tileSize; // size of tiles
const char *dbName=DEFAULT_DB; // name of database
const char *serverName=DEFAULT_HOST; // name of RasDaMan server host
const char *serverPortString = DEFAULT_PORT; // string parameter for port
unsigned int serverPort=0; // port of RasDaMan server
const char *userName=DEFAULT_USER; // name of RasDaMan user
const char *passwd=DEFAULT_PASSWD; // password of RasDaMan user
list fileNameList; // input file name list
bool mdd3d = false; // flag for 3D MDD
bool tiled = false; // flag for tiling
bool rescale = false; // flag for rescaling pixel values to 0:255
r_Database database; // rasdaman database object, for connection
// --- collect cmd line parameters --------------------------------------------------
int c;
int digit_optind = 0;
if (argc==1) // no params at all?
{
printUsage( prog );
return EXIT_USAGE;
}
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
c = getopt_long (argc, argv, short_options, long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0: // long option
if (strcmp(long_options[option_index].name,OPTION_HELP)==0)
{
printUsage( prog );
return EXIT_USAGE;
}
else if (strcmp(long_options[option_index].name,OPTION_COLLECTION)==0)
collName = optarg;
else if (strcmp(long_options[option_index].name,OPTION_TYPE)==0)
typeString = optarg;
else if (strcmp(long_options[option_index].name,OPTION_RESCALE)==0)
rescale = true;
else if (strcmp(long_options[option_index].name,OPTION_TILE)==0)
tileString = optarg;
else if (strcmp(long_options[option_index].name,OPTION_SERVER)==0)
serverName = optarg;
else if (strcmp(long_options[option_index].name,OPTION_PORT)==0)
serverPortString = optarg;
else if (strcmp(long_options[option_index].name,OPTION_DATABASE)==0)
dbName = optarg;
else if (strcmp(long_options[option_index].name,OPTION_USER)==0)
userName = optarg;
else if (strcmp(long_options[option_index].name,OPTION_PASSWD)==0)
passwd = optarg;
else if (strcmp(long_options[option_index].name,OPTION_TRANSFERFORMAT)==0)
transferFormatString = optarg;
else if (strcmp(long_options[option_index].name,OPTION_TRANSFERFORMATPARAMS)==0)
transferFormatParams = optarg;
else if (strcmp(long_options[option_index].name,OPTION_STORAGEFORMAT)==0)
storageFormatString = optarg;
else if (strcmp(long_options[option_index].name,OPTION_STORAGEFORMATPARAMS)==0)
storageFormatParams = optarg;
else if (strcmp(long_options[option_index].name,OPTION_VERBOSE)==0)
verbose = true;
else
{
cerr << "Error: invalid option: " << long_options[option_index].name << endl;
return EXIT_ERROR;
}
break;
case 'h':
printUsage( prog );
return EXIT_USAGE;
break;
case 'c':
if (!optarg)
{
cerr << "Error: missing collection name." << endl;
return EXIT_ERROR;
}
collName = optarg;
break;
case 't':
if (!optarg)
{
cerr << "Error: missing type." << endl;
return EXIT_ERROR;
}
typeString = optarg;
break;
case 'r':
rescale = true;
break;
case 's':
if (!optarg)
{
cerr << "Error: missing server name." << endl;
return EXIT_ERROR;
}
serverName = optarg;
break;
case 'd':
if (!optarg)
{
cerr << "Error: missing database name." << endl;
return EXIT_ERROR;
}
dbName = optarg;
break;
case 'u':
if (!optarg)
{
cerr << "Error: missing user name." << endl;
return EXIT_ERROR;
}
userName = optarg;
break;
case 'p':
if (!optarg)
{
cerr << "Error: missing password." << endl;
return EXIT_ERROR;
}
passwd = optarg;
break;
case 'v':
verbose = true;
break;
default:
printf ("Error: illegal option letter %c\n", c);
break;
}
} // while
// get non-option arguments (ie, file names)
if (optind < argc)
{
while (optind < argc)
fileNameList.push_back(string(argv[optind++]));
mdd3d = (fileNameList.size() > 1);
}
else
{
cerr << "Error: no input file name provided." << endl;
return EXIT_ERROR;
}
// check mandatory parameters
if (collName==NULL)
{
cerr << "Error: missing collection name; use option '--" << OPTION_COLLECTION << "'." << endl;
return EXIT_ERROR;
}
// transform parameters where necessary
serverPort = strtol(serverPortString, (char **)NULL, 10);
if (errno==ERANGE || errno==EINVAL)
{
cerr << "Error: port not an integer number: " << serverPortString << endl;
return EXIT_ERROR;
}
if( tileString )
{
try
{
tileSize = r_Minterval(tileString);
tiled = true;
}
catch (r_Error e)
{
cerr << "Error " << e.get_errorno() << ": " << e.what() << endl;
return EXIT_ERROR;
}
}
else
{
// use default tile sizes
if(mdd3d)
tileSize = r_Minterval(3)
<< r_Sinterval((r_Range)DEFAULT_TILE_LO, (r_Range)DEFAULT_TILE_HI)
<< r_Sinterval((r_Range)DEFAULT_TILE_LO, (r_Range)DEFAULT_TILE_HI)
<< r_Sinterval((r_Range)DEFAULT_TILE_LO, (r_Range)DEFAULT_TILE_HI);
else
tileSize = r_Minterval(2)
<< r_Sinterval((r_Range)DEFAULT_TILE_LO, (r_Range)DEFAULT_TILE_HI)
<< r_Sinterval((r_Range)DEFAULT_TILE_LO, (r_Range)DEFAULT_TILE_HI);
LOG << "tileSize = " << tileSize << endl;
}
transferFormat = get_data_format_from_name( transferFormatString );
if(transferFormat == r_Data_Format_NUMBER)
{
cerr << "Error: Invalid transfer format '" << transferFormatString << "'" << endl;
return EXIT_ERROR;
}
storageFormat = get_data_format_from_name( storageFormatString );
if(storageFormat == r_Data_Format_NUMBER)
{
cerr << "Error: Invalid storage format '" << storageFormatString << "'" << endl;
return EXIT_ERROR;
}
if (typeString!=NULL)
{
if (strcmp(typeString,PIXEL_TYPE_BOOL)==0)
pixType = PIXEL_BOOL;
else if (strcmp(typeString,PIXEL_TYPE_GREY)==0)
pixType = PIXEL_GREY;
else if (strcmp(typeString,PIXEL_TYPE_COLOR)==0)
pixType = PIXEL_COLOR;
else if (strcmp(typeString,PIXEL_TYPE_UNSIGNED)==0)
pixType = PIXEL_UNSIGNED;
else
{
cerr << "Error: illegal pixel type: " << typeString << endl;
return EXIT_ERROR;
}
}
LOG << prog << " v2.0 rasdaman PPM image insert utility" << endl;
LOG << OPTION_COLLECTION << " = " << collName << ", ";
LOG << OPTION_TYPE << " = " << typeString << ", ";
LOG << "3d = " << mdd3d << ", ";
LOG << OPTION_RESCALE << " = " << rescale << ", ";
LOG << OPTION_TILE << " = " << tileSize << endl;
LOG << OPTION_SERVER << " = " << serverName << ", ";
LOG << OPTION_PORT << " = " << serverPort << ", ";
LOG << OPTION_DATABASE << " = " << dbName << ", ";
LOG << OPTION_USER << " = " << userName << ", ";
LOG << OPTION_PASSWD << " = " << passwd << endl;
LOG << OPTION_TRANSFERFORMAT << " = " << transferFormatString << ", ";
LOG << OPTION_TRANSFERFORMATPARAMS << " = " << transferFormatParams << ", ";
LOG << OPTION_STORAGEFORMAT << " = " << storageFormatString << ", ";
LOG << OPTION_STORAGEFORMATPARAMS << " = " << storageFormatParams << endl;
LOG << OPTION_VERBOSE << " = " << verbose << endl;
LOG << "file list = " ;
for ( list::iterator from = fileNameList.begin(); from != fileNameList.end(); ++from )
LOG << *from << " ";
LOG << endl;
// --- action --------------------------------------------------
try
{
LOG << "connecting to " << serverName << ":" << serverPort << "..." << flush;
database.set_servername(serverName, serverPort);
database.set_useridentification(userName, passwd);
database.open( dbName );
// note: partial insert implicitly opens/closes TA
// determine MDD object's parameters
const char *mddTypeName=NULL;
const char *collTypeName=NULL;
switch (pixType)
{
case PIXEL_BOOL:
collTypeName = mdd3d ? "BoolSet3" : "BoolSet";
mddTypeName = mdd3d ? "BoolCube" : "BoolImage";
typeSize = PIXSIZE_BW;
break;
case PIXEL_GREY:
collTypeName = mdd3d ? "GreySet3" : "GreySet";
mddTypeName = mdd3d ? "GreyCube" : "GreyImage";
typeSize = PIXSIZE_GREY;
break;
case PIXEL_COLOR:
collTypeName = mdd3d ? "RGBSet3" : "RGBSet";
mddTypeName = mdd3d ? "RGBCube" : "RGBImage";
typeSize = PIXSIZE_COL;
break;
case PIXEL_UNSIGNED:
collTypeName = mdd3d ? "UShortSet3" : "UShortSet";
mddTypeName = mdd3d ? "UShortCube" : "UShortImage";
typeSize = PIXSIZE_UNSIGNED;
break;
default:
cerr << "Error: unknown pixel type code: " << pixType << endl;
throw r_Error( r_Error::r_Error_General );
}
LOG << "mdd type = " << mddTypeName << ", set type = " << collTypeName << endl;
// read header information for imgSize
imgSize = readHeader(fileNameList.front().c_str(),mdd3d, fileNameList.size()); // we know we have at least 1 elem in list
if(!tiled)
tileSize = imgSize; // if not tiled then tile size = image size
// Create a partial insert object with regular tiling
r_Partial_Insert pins(database, collName, mddTypeName, collTypeName, tileSize, typeSize);
r_Ref mddPtr;
r_Minterval cacheDom;
// iterate through all the pictures
if(mdd3d)
{
cout << "creating 3D object of extent " << imgSize << " from: " << flush;
r_Range numImgs = imgSize[0].high()+1; // X
r_Range imgRows = imgSize[2].high()+1; // Y
r_Range imgCols = imgSize[1].high()+1; // Z
r_Range tileX = tileSize[0].high()+1;
// create domain of first cache
cacheDom = r_Minterval(3) << r_Sinterval((r_Range)0, tileX - 1)
<< r_Sinterval((r_Range)0, imgCols - 1)
<< r_Sinterval((r_Range)0, imgRows - 1);
createMarray(cacheDom, mddPtr, pixType);
char *contents = mddPtr->get_array();
unsigned int k = 0;
list::iterator currentFileName = fileNameList.begin();
while ( k < fileNameList.size() )
{
cout << (*currentFileName).c_str() << "..." << flush;
LOG << "#" << k << " " << cacheDom << "..." << flush;
readImage(contents, (*currentFileName).c_str(), true, pixType, rescale, k, k%tileX);
if (k % tileX == tileX-1 || k == fileNameList.size()-1)
{
if (pins.update(mddPtr.ptr(), transferFormat, transferFormatParams, storageFormat, storageFormatParams) != 0)
throw r_Error( r_Error::r_Error_General );
mddPtr.destroy();
// we are done:
if(k == fileNameList.size()-1)
break;
// create domain of next tile
cacheDom = r_Minterval(3)
<< r_Sinterval( (r_Range) (k + 1),
(r_Range) (k+tileX > fileNameList.size()-1 ? fileNameList.size()-1 : k+tileX) )
<< r_Sinterval((r_Range)0, imgCols - 1)
<< r_Sinterval((r_Range)0, imgRows - 1);
createMarray(cacheDom, mddPtr, pixType);
const char *contents = mddPtr->get_array();
}
++currentFileName, ++k;
}
}
else
{
r_Range imgCols = imgSize[0].high()+1;
r_Range imgRows = imgSize[1].high()+1;
r_Range tileRows = tileSize[0].high()+1;
const char *fName = fileNameList.front().c_str(); // we know we have 1 element in list
cout << "creating 2D object of extent " << imgSize << " from " << fName << "..." << flush;
openImage(fName,false); // open image for reading
for( int k = 0; k < imgRows; k += tileRows )
{
// create domain of next tile
cacheDom = r_Minterval(2)
<< r_Sinterval((r_Range)0, imgCols - 1)
<< r_Sinterval(k, k + min(tileRows-1, imgRows-k-1));
LOG << "#" << k << " " << cacheDom << "..." << flush;
createMarray(cacheDom, mddPtr, pixType);
char *contents = mddPtr->get_array();
readRows(contents, k, min(tileRows, imgRows - k), pixType, rescale);
if (pins.update(mddPtr.ptr(), transferFormat, transferFormatParams, storageFormat, storageFormatParams) != 0)
throw r_Error( r_Error::r_Error_General );
mddPtr.destroy();
}
}
database.close();
cout << "ok" << endl;
}
catch(r_Error &err)
{
cerr << err.what() << endl;
// emergency abort/close, ignoring any eventual further exception
try
{
database.close();
}
catch(...)
{ }
retval = EXIT_ERROR;
}
catch (...)
{
cout << "Panic: unexpected exception." << endl;
}
LOG << argv[0] << " done." << endl;
return retval;
}