ISIS Core Library 0.7.2 (api 3.0.0)

/scr/tee1/isis/lib/Core/DataStorage/io_application.cpp

Go to the documentation of this file.
00001 /*
00002     <one line to give the program's name and a brief idea of what it does.>
00003     Copyright (C) <year>  <name of author>
00004 
00005     This program is free software: you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation, either version 3 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017 
00018 */
00019 
00020 #ifdef _MSC_VER
00021 #pragma warning(disable:4996)
00022 #endif
00023 
00024 #include "io_application.hpp"
00025 #include "io_factory.hpp"
00026 #include <boost/mpl/for_each.hpp>
00027 
00028 
00029 namespace isis
00030 {
00031 namespace data
00032 {
00033 IOApplication::IOApplication( const char name[], bool have_input, bool have_output ):
00034     Application( name ),
00035     m_input( have_input ), m_output( have_output ), feedback( new util::ConsoleFeedback )
00036 {
00037     if ( have_input )
00038         addInput( parameters );
00039 
00040     if ( have_output )
00041         addOutput( parameters );
00042 
00043     parameters["help-io"] = false;
00044     parameters["help-io"].needed() = false;
00045     parameters["help-io"].setDescription( "List all loaded IO plugins and their supported formats, exit after that" );
00046 }
00047 
00048 IOApplication::~IOApplication()
00049 {
00050     data::IOFactory::setProgressFeedback( boost::shared_ptr<util::ProgressFeedback>() );
00051 }
00052 
00053 bool IOApplication::init( int argc, char **argv, bool exitOnError )
00054 {
00055     const bool ok = util::Application::init( argc, argv, exitOnError );
00056 
00057     if ( !ok  )
00058         return false;
00059 
00060     if ( m_input ) {
00061         return autoload( exitOnError );
00062     }
00063 
00064     return true;
00065 }
00066 
00067 void IOApplication::addInput ( util::ParameterMap &parameters, bool needed, const std::string &suffix, const std::string &desc )
00068 {
00069     parameters[std::string( "in" )+suffix] = util::slist();
00070     parameters[std::string( "in" )+suffix].setDescription( std::string( "input file(s) or directory(s)" ) + desc );
00071     parameters[std::string( "in" )+suffix].needed() = needed;
00072 
00073     parameters[std::string( "rf" )+suffix] = std::string();
00074     parameters[std::string( "rf" )+suffix].needed() = false;
00075     parameters[std::string( "rf" )+suffix].hidden() = true;
00076 
00077     parameters[std::string( "rf" )+suffix].setDescription( std::string( "Override automatic detection of file suffix for reading" + desc + " with given value" ) );
00078     parameters[std::string( "rdialect" )+suffix] = std::string();
00079     parameters[std::string( "rdialect" )+suffix].needed() = false;
00080     parameters[std::string( "rdialect" )+suffix].setDescription(
00081         std::string( "choose dialect for reading" ) + desc + ". The available dialects depend on the capabilities of the used IO plugin" );
00082 
00083     if( parameters.find( "np" ) == parameters.end() ) {
00084         parameters["np"] = false;
00085         parameters["np"].needed() = false;
00086         parameters["np"].setDescription( "suppress progress bar" );
00087         parameters["np"].hidden() = true;
00088     }
00089 }
00090 
00091 void IOApplication::addOutput ( util::ParameterMap &parameters, bool needed, const std::string &suffix, const std::string &desc )
00092 {
00093     parameters[std::string( "out" )+suffix] = std::string();
00094     parameters[std::string( "out" )+suffix].setDescription( "output filename" + desc );
00095     parameters[std::string( "out" )+suffix].needed() = needed;
00096 
00097     parameters[std::string( "wf" )+suffix] = std::string();
00098     parameters[std::string( "wf" )+suffix].needed() = false;
00099     parameters[std::string( "wf" )+suffix].setDescription( "Override automatic detection of file suffix for writing" + desc + " with given value" );
00100     parameters[std::string( "wf" )+suffix].hidden() = true;
00101 
00102     parameters[std::string( "wdialect" )+suffix] = std::string();
00103     parameters[std::string( "wdialect" )+suffix].needed() = false;
00104     parameters[std::string( "wdialect" )+suffix].setDescription( "Choose dialect for writing" + desc + ". Use \"--help-io\" for a list of the plugins and their supported dialects" );
00105     std::map<unsigned short, std::string> types = util::getTypeMap( false, true );
00106     // remove some types which are useless as representation
00107     // "(unsigned short)" is needed because otherwise erase would take the reference of a static constant which is only there during compile time
00108     types.erase( ( unsigned short )data::ValueArray<util::Selection>::staticID );
00109     types.erase( ( unsigned short )data::ValueArray<std::string>::staticID );
00110     types.erase( ( unsigned short )data::ValueArray<boost::posix_time::ptime>::staticID );
00111     types.erase( ( unsigned short )data::ValueArray<boost::gregorian::date>::staticID );
00112     types.erase( ( unsigned short )data::ValueArray<util::ilist>::staticID );
00113     types.erase( ( unsigned short )data::ValueArray<util::dlist>::staticID );
00114     types.erase( ( unsigned short )data::ValueArray<util::slist>::staticID );
00115 
00116     for( std::map<unsigned short, std::string>::iterator i = types.begin(); i != types.end(); i++ ) {
00117         i->second.resize( i->second.find_last_not_of( '*' ) + 1 );
00118     }
00119 
00120     parameters[std::string( "repn" )+suffix] = util::Selection( types );
00121     parameters[std::string( "repn" )+suffix].needed() = false;
00122     parameters[std::string( "repn" )+suffix].setDescription(
00123         "Representation in which the data" + desc + " shall be written" );
00124 
00125     parameters[std::string( "scale_mode" )+suffix] = util::Selection( "noscale,autoscale,noupscale,upscale", "autoscale" );
00126     parameters[std::string( "scale_mode" )+suffix].needed() = false;
00127     parameters[std::string( "scale_mode" )+suffix].hidden() = true;
00128 
00129     parameters[std::string( "scale_mode" )+suffix].setDescription(
00130         "Scaling strategy to be used when converting into the datatype given in with -repn" + suffix );
00131 
00132     if( parameters.find( "np" ) == parameters.end() ) {
00133         parameters["np"] = false;
00134         parameters["np"].needed() = false;
00135         parameters["np"].setDescription( "suppress progress bar" );
00136         parameters["np"].hidden() = true;
00137     }
00138 }
00139 
00140 
00141 void IOApplication::printHelp( bool withHidden ) const
00142 {
00143     if( !parameters["help-io"].isSet() ) { // if help-io was not set - print normal help
00144         Application::printHelp( withHidden );
00145     } else if( parameters["help-io"].as<bool>() ) { // if help-io was set to true
00146         std::cerr << std::endl << "Available IO Plugins:" << std::endl;
00147         data::IOFactory::FileFormatList plugins = data::IOFactory::getFormats();
00148         BOOST_FOREACH( data::IOFactory::FileFormatList::const_reference pi, plugins ) {
00149             std::cerr << std::endl << "\t" << pi->getName() << " (" << pi->plugin_file.file_string() << ")" << std::endl;
00150             std::cerr << "\t=======================================" << std::endl;
00151             const std::list<util::istring> suff = pi->getSuffixes();
00152             const std::list<util::istring> dialects = util::stringToList<util::istring>( pi->dialects( "" ).c_str() );
00153             std::cerr << "\tsupported suffixes: " << util::listToString( suff.begin(), suff.end(), "\", \"", "\"", "\"" )  << std::endl;
00154 
00155             if( !dialects.empty() )
00156                 std::cerr << "\tsupported dialects: " << util::listToString( dialects.begin(), dialects.end(), "\", \"", "\"", "\"" )  << std::endl;
00157         }
00158     }
00159 }
00160 
00161 bool IOApplication::autoload( bool exitOnError )
00162 {
00163     return autoload( parameters, images, exitOnError, "", feedback );
00164 
00165 }
00166 bool IOApplication::autoload ( const util::ParameterMap &parameters, std::list<Image> &images, bool exitOnError, const std::string &suffix,  boost::shared_ptr<util::ConsoleFeedback> feedback )
00167 {
00168     util::slist input = parameters[std::string( "in" )+suffix];
00169     std::string rf = parameters[std::string( "rf" )+suffix];
00170     std::string dl = parameters[std::string( "rdialect" )+suffix];
00171     LOG( Runtime, info )
00172             << "loading " << util::MSubject( input )
00173             << ( rf.empty() ? "" : std::string( " using the format: " ) + rf )
00174             << ( ( !rf.empty() && !dl.empty() ) ? " and" : "" )
00175             << ( dl.empty() ? "" : std::string( " using the dialect: " ) + dl );
00176 
00177     bool no_progress = parameters["np"];
00178 
00179     if( !no_progress && feedback ) {
00180         data::IOFactory::setProgressFeedback( feedback );
00181     }
00182 
00183     const std::list< Image > tImages = data::IOFactory::load( input, rf.c_str(), dl.c_str() );
00184 
00185     images.insert( images.end(), tImages.begin(), tImages.end() );
00186 
00187     if ( images.empty() ) {
00188         if ( exitOnError ) {
00189             LOG( Runtime, notice ) << "No data acquired, exiting...";
00190             exit( 1 );
00191         } else
00192             return false;
00193     } else {
00194         for( std::list<data::Image>::const_iterator a = images.begin(); a != images.end(); a++ ) {
00195             for( std::list<data::Image>::const_iterator b = a; ( ++b ) != images.end(); ) {
00196                 const util::PropertyMap &aref = *a, bref = *b;
00197                 LOG_IF( aref.getDifference( bref ).empty(), Runtime, warning ) << "The metadata of the images from "
00198                         << aref.getPropertyAs<std::string>( "source" ) << ":" << std::distance<std::list<Image> ::const_iterator>( images.begin(), a )
00199                         << " and " << bref.getPropertyAs<std::string>( "source" ) << ":" << std::distance<std::list<Image> ::const_iterator>( images.begin(), b )
00200                         << " are equal. Maybe they are duplicates.";
00201             }
00202         }
00203     }
00204 
00205     return true;
00206 }
00207 
00208 
00209 bool IOApplication::autowrite( Image out_image, bool exitOnError ) {return autowrite( std::list<Image>( 1, out_image ), exitOnError );}
00210 bool IOApplication::autowrite( std::list<Image> out_images, bool exitOnError )
00211 {
00212     const bool no_progress = parameters["np"];
00213     return autowrite( parameters, out_images, exitOnError, "", no_progress ? boost::shared_ptr<util::ConsoleFeedback>() : feedback );
00214 }
00215 
00216 bool IOApplication::autowrite ( const util::ParameterMap &parameters, Image out_image, bool exitOnError, const std::string &suffix, boost::shared_ptr<util::ConsoleFeedback> feedback )
00217 {
00218     return autowrite( parameters, std::list<Image>( 1, out_image ), exitOnError, suffix, feedback );
00219 }
00220 bool IOApplication::autowrite ( const util::ParameterMap &parameters, std::list< Image > out_images, bool exitOnError, const std::string &suffix, boost::shared_ptr<util::ConsoleFeedback> feedback )
00221 {
00222     const util::Selection repn = parameters[std::string( "repn" )+suffix];
00223     const util::Selection scale_mode = parameters[std::string( "scale_mode" )+suffix];
00224     const std::string output = parameters[std::string( "out" )+suffix];
00225     const std::string wf = parameters[std::string( "wf" )+suffix];
00226     const std::string dl = parameters[std::string( "wdialect" )+suffix];
00227     LOG( Runtime, info )
00228             << "Writing " << out_images.size() << " images"
00229             << ( repn ? std::string( " as " ) + ( std::string )repn : "" )
00230             << " to " << util::MSubject( output )
00231             << ( wf.empty() ? "" : std::string( " using the format: " ) + wf )
00232             << ( ( !wf.empty() && !dl.empty() ) ? " and" : "" )
00233             << ( dl.empty() ? "" : std::string( " using the dialect: " ) + dl );
00234 
00235 
00236     LOG_IF( parameters[std::string( "scale_mode" )+suffix].isSet() && repn == 0, Runtime, warning )
00237             << "Ignoring -scale_mode" << suffix << " " << util::MSubject( scale_mode )
00238             <<  ", because -repn" << suffix << " was not given";
00239 
00240     if( repn != 0 ) {
00241         BOOST_FOREACH( std::list<Image>::reference ref, out_images ) {
00242             ref.convertToType( repn, static_cast<autoscaleOption>( scale_mode - 1 ) ); //noscale is 0 but 1 in the selection
00243         }
00244     }
00245 
00246     if( feedback )
00247         data::IOFactory::setProgressFeedback( feedback );
00248 
00249     if ( ! IOFactory::write( out_images, output, wf.c_str(), dl.c_str() ) ) {
00250         if ( exitOnError ) {
00251             LOG( Runtime, notice ) << "Failed to write, exiting...";
00252             exit( 1 );
00253         }
00254 
00255         return false;
00256     } else
00257         return true;
00258 }
00259 
00260 Image IOApplication::fetchImage()
00261 {
00262     assert( !images.empty() );
00263     Image ret = images.front();
00264     images.pop_front();
00265     return ret;
00266 }
00267 
00268 boost::shared_ptr< util::MessageHandlerBase > IOApplication::getLogHandler( std::string module, LogLevel level ) const
00269 {
00270     return isis::util::Application::getLogHandler( module, level );
00271 }
00272 
00273 
00274 }
00275 }
00276