ISIS Core Library 0.7.2 (api 3.0.0)
|
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 ¶meters, 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 ¶meters, 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 ¶meters, 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 ¶meters, 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 ¶meters, 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