latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*---------------------------------------------------------------- 00025 * project ....: LTI Digital Image/Signal Processing Library 00026 * file .......: ltiFunctor.h 00027 * authors ....: Thomas Rusert 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 14.04.99 00030 * revisions ..: $Id: ltiFunctor.h,v 1.11 2006/02/07 18:08:47 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_FUNCTOR_H_ 00034 #define _LTI_FUNCTOR_H_ 00035 00036 #include "ltiIoObject.h" 00037 #include "ltiStatus.h" 00038 #include "ltiException.h" 00039 #include "ltiIoHandler.h" 00040 00041 namespace lti { 00042 /** 00043 * Base class for all lti functors. 00044 * 00045 * Every lti fuctor must have at least the member <em>apply()</em>, 00046 * which "applies" the functor's functionality on the data given through the 00047 * arguments of the apply method. 00048 * 00049 * There are two kinds of apply methods: 00050 * - the "on-copy"-apply returns the result in a new 00051 * object, and the original data will not be modified. 00052 * - the "on-place"-apply returns the result on the same input object and 00053 * therefore the original data will be destroyed. 00054 * 00055 * The operation of the functor can be controled with some parameters, 00056 * which will can be set with the "setParameters" member-function. 00057 * 00058 * Each functor may have also other setABC() members, to allow the 00059 * change of just one parameter-item at the time. 00060 */ 00061 class functor : public ioObject, public status { 00062 public: 00063 /** 00064 * Base class for all lti parameter objects 00065 */ 00066 class parameters : public ioObject { 00067 public: 00068 /** 00069 * default constructor 00070 */ 00071 parameters(); 00072 00073 /** 00074 * copy constructor 00075 */ 00076 parameters(const parameters& other); 00077 00078 /** 00079 * destructor 00080 */ 00081 virtual ~parameters(); 00082 00083 /** 00084 * copy data of "other" parameters 00085 */ 00086 parameters& copy(const parameters& other); 00087 00088 /** 00089 * returns a pointer to a clone of the parameters. 00090 */ 00091 virtual parameters* clone() const = 0; 00092 00093 /** 00094 * return the name of this type 00095 */ 00096 const char* getTypeName() const; 00097 00098 /** 00099 * write the parameters in the given ioHandler 00100 * @param handler the ioHandler to be used 00101 * @param complete if true (the default) the enclosing begin/end will 00102 * be also written, otherwise only the data block will be written. 00103 * @return true if write was successful 00104 */ 00105 virtual bool write(ioHandler& handler, 00106 const bool complete=true) const; 00107 00108 /** 00109 * read the parameters from the given ioHandler 00110 * @param handler the ioHandler to be used 00111 * @param complete if true (the default) the enclosing begin/end will 00112 * be also written, otherwise only the data block will be written. 00113 * @return true if write was successful 00114 */ 00115 virtual bool read(ioHandler& handler,const bool complete=true); 00116 00117 # ifdef _LTI_MSC_6 00118 /** 00119 * this function is required by MSVC only, as a workaround for a 00120 * very awful bug, which exists since MSVC V.4.0, and still by 00121 * V.6.0 with all bugfixes (so called "service packs") remains 00122 * there... This method is public due to another bug!, so please 00123 * NEVER EVER call this method directly 00124 */ 00125 bool readMS(ioHandler& handler,const bool complete=true); 00126 00127 /** 00128 * this function is required by MSVC only, as a workaround for a 00129 * very awful bug, which exists since MSVC V.4.0, and still by 00130 * V.6.0 with all bugfixes (so called "service packs") remains 00131 * there... This method is public due to another bug!, so please 00132 * NEVER EVER call this method directly 00133 */ 00134 bool writeMS(ioHandler& handler,const bool complete=true) const; 00135 # endif 00136 00137 protected: 00138 /** 00139 * copy data of "other" parameters 00140 */ 00141 parameters& operator=(const parameters& other); 00142 }; 00143 00144 /** 00145 * Exception thrown when the parameters are not set 00146 */ 00147 class invalidParametersException : public exception { 00148 public: 00149 /** 00150 * Default constructor 00151 */ 00152 invalidParametersException() 00153 : exception("wrong parameter type or parameters not set yet") {}; 00154 00155 /** 00156 * Constructor with the alternative object name, where the exception 00157 * was thrown 00158 */ 00159 invalidParametersException(const std::string& str) 00160 : exception(std::string("wrong parameter type or parameters not set " \ 00161 "yet at ")+str) {}; 00162 00163 /** 00164 * Constructor with the alternative object name, where the exception 00165 * was thrown 00166 */ 00167 invalidParametersException(const char* str) 00168 : exception(std::string("wrong parameter type or parameters not set " \ 00169 "yet at ")+std::string(str)) {}; 00170 00171 00172 /** 00173 * returns the name of this exception 00174 */ 00175 virtual const char* getTypeName() const; 00176 }; 00177 00178 /** 00179 * Exception thrown when a method of a functor is not implemented for 00180 * a specific parameter set. 00181 */ 00182 class invalidMethodException : public exception { 00183 public: 00184 /** 00185 * Default constructor 00186 */ 00187 invalidMethodException() 00188 : exception("Method not implemented for given parameters") {}; 00189 00190 /** 00191 * Constructor with alternative message 00192 */ 00193 invalidMethodException(const std::string& str) 00194 : exception(str) {}; 00195 00196 /** 00197 * returns the name of this exception 00198 */ 00199 virtual const char* getTypeName() const; 00200 }; 00201 00202 /** 00203 * default constructor 00204 */ 00205 functor(); 00206 00207 /** 00208 * copy constructor 00209 */ 00210 functor(const functor& other); 00211 00212 /** 00213 * destructor 00214 */ 00215 virtual ~functor(); 00216 00217 /** 00218 * Set functor's parameters. 00219 * 00220 * This member makes a copy of \a theParam: the functor 00221 * will keep its own copy of the parameters! 00222 * 00223 * Additionally, the updateParameters will be called, which in some 00224 * functors initializes some Look-Up Tables, or filters, etc. in order to 00225 * improve the execution times later in the apply methods. 00226 * 00227 * Since the LTI-Lib follows a deep-copy philosophy, if you copy the 00228 * functor, the copy will create an exact copy of the parameters, no 00229 * matter if they have been specified with useParameters() or with 00230 * setParameters(). 00231 * 00232 * You should always prefer this method over useParameters(). The latter 00233 * one is used only in very special cases, when the user needs to control 00234 * an instance of parameters outside the functor and he/she wants to take 00235 * care of the memory management. 00236 * 00237 * This method should never be overloaded. If you want to make some 00238 * precomputations when setting the parameters, please overload 00239 * updateParameters(). 00240 * 00241 * @see useParameters(),updateParameters() 00242 * 00243 * @return true if successful, false otherwise 00244 */ 00245 virtual bool setParameters(const parameters& theParam); 00246 00247 /** 00248 * Use the given parameters exactly as they are. 00249 * 00250 * The difference of this method with set parameters is that the parameters 00251 * will not be copied. They will be used exactly as they are given. It 00252 * is therefore your responsability to ensure that the parameters instance 00253 * you give exists as long as the functor is being used. 00254 * 00255 * Of course, if the parameters content is changed while the functor makes 00256 * its computations, unpredictable behaviour has to be expected. It is 00257 * also your responsibility to take care of all multi-threading details. 00258 * 00259 * Since the LTI-Lib follows a deep-copy philosophy, if you copy the 00260 * functor, the copy will create an exact copy of the parameters, no 00261 * matter if they have been specified with useParameters() or with 00262 * setParameters(). 00263 * 00264 * This member will not administrate the given instance. If you create it 00265 * with new, you have to take care about the deletion. 00266 * 00267 * If you are not sure what to use, always prefer setParameters() since it 00268 * is more secure than useParameters(), as the functor will take care of 00269 * the memory management. 00270 * 00271 * This method always calls updateParameters(). 00272 * 00273 * \warning Use this method only if you really know what you are doing. 00274 * If you are not sure, use setParameters() instead. 00275 * 00276 * Note that the given reference can be rewritten by the functor, specially 00277 * if some shortcuts are used or the read method is called, then their 00278 * content will be changed (another reason to prefer setParameters()). 00279 * 00280 * @return true if successful, false otherwise 00281 */ 00282 virtual bool useParameters(parameters& theParam); 00283 00284 /** 00285 * Update parameters. 00286 * 00287 * Some functors make some pre-computations when the parameters are set. 00288 * For example, they initialize look-up tables, build some filter kernels, 00289 * etc. This job has to be done by update parameters. 00290 * 00291 * In principle, you only need to overload this method if you need such 00292 * initializations, as setParameters() and useParameters() will always 00293 * call this method. 00294 * 00295 * For disobedient people, who ignore the recomendation of using 00296 * setParameters() over useParameters(), this method should be called 00297 * if attributes of the parameters instance are changed, before calling 00298 * the apply() method. 00299 * 00300 * \warning If you call an apply() method of a functor in which you 00301 * changed the attributes of the parameters instance without updating 00302 * them, you have to expect an unpredictible behaviour: segmentation 00303 * fault, system crash, blue screens, etc. can occur as the sizes of 00304 * internal structures may not be consistent with the given parameters. 00305 * This problem does not exist if you indicate the parameters to be used 00306 * with setParameters(), as the functor will have an instance of its own. 00307 */ 00308 virtual bool updateParameters(); 00309 00310 /** 00311 * returns current parameters. 00312 */ 00313 const parameters& getParameters() const; 00314 00315 /** 00316 * returns true if the parameters are valid 00317 */ 00318 virtual bool validParameters() const; 00319 00320 /** 00321 * copy data of "other" functor. 00322 * Please note that the status string will _NOT_ be copied! 00323 */ 00324 functor& copy(const functor& other); 00325 00326 /** 00327 * clone member 00328 */ 00329 virtual functor* clone() const = 0; 00330 00331 /** 00332 * returns the name of this type 00333 */ 00334 const char* getTypeName() const; 00335 00336 // /** 00337 // * return the last message set with setStatusString(). This will 00338 // * never return 0. If no status-string has been set yet an empty string 00339 // * (pointer to a string with only the char(0)) will be returned. 00340 // */ 00341 // virtual const char* getStatusString() const; 00342 00343 // /** 00344 // * set a status string. 00345 // * 00346 // * @param msg the const string to be reported next time by 00347 // * getStatusString(). The given string will be copied. 00348 // * This message will be usually set within the apply methods to indicate 00349 // * an error cause. 00350 // * 00351 // * Note that the change of the status string is not considered as 00352 // * a change in the functor status. 00353 // */ 00354 // virtual void setStatusString(const char* msg) const; 00355 00356 // /** 00357 // * append a message to the current status string. Take care to 00358 // * reset the status string by calling setStatusString() for each 00359 // * call of an apply() or similar method. appendStatusString() 00360 // * should only be used after setStatusString() has been called. 00361 // * 00362 // * @param msg message to be appended to the current status string. 00363 // * 00364 // * Note that the change of the status string is not considered as 00365 // * a change in the functor status. 00366 // */ 00367 // virtual void appendStatusString(const char* msg) const; 00368 00369 // /** 00370 // * append an integer value to the current status string. Take care 00371 // * to reset the status string by calling setStatusString() for 00372 // * each call of an apply() or similar method. appendStatusString() 00373 // * should only be used after setStatusString() has been called. 00374 // * 00375 // * @param msg integer value to be appended to the current status 00376 // * string. 00377 // * 00378 // * Note that the change of the status string is not considered as 00379 // * a change in the functor status. 00380 // */ 00381 // virtual void appendStatusString(const int& msg) const; 00382 00383 // /** 00384 // * append a double value to the current status string. Take care 00385 // * to reset the status string by calling setStatusString() for 00386 // * each call of an apply() or similar method. appendStatusString() 00387 // * should only be used after setStatusString() has been called. 00388 // * 00389 // * @param msg double value to be appended to the current status 00390 // * string. 00391 // * 00392 // * Note that the change of the status string is not considered as 00393 // * a change in the functor status. 00394 // */ 00395 // virtual void appendStatusString(const double& msg) const; 00396 00397 // /** 00398 // * Append the status string of another %functor to this functors 00399 // * status string. To achieve better readability of the resulting 00400 // * message a new line is started with the other functor's name and 00401 // * the message. 00402 // * 00403 // * @param other %functor whose status string is to be append to this 00404 // * status string. 00405 // * 00406 // * Note that the change of the status string is not considered as 00407 // * a change in the functor status. 00408 // */ 00409 // virtual void appendStatusString(const functor& other) const; 00410 00411 /** 00412 * write the functor in the given ioHandler. The default implementation 00413 * is to write just the parameters object. 00414 * @param handler the ioHandler to be used 00415 * @param complete if true (the default) the enclosing begin/end will 00416 * be also written, otherwise only the data block will be written. 00417 * @return true if write was successful 00418 */ 00419 virtual bool write(ioHandler& handler, 00420 const bool complete=true) const; 00421 00422 /** 00423 * Read the functor from the given ioHandler. 00424 * 00425 * The default implementation is to read just the parameters object. 00426 * 00427 * Since this virtual method needs to know the exact type of the 00428 * parameters to call the proper read method, it will just assume that the 00429 * current functor instance has a valid parameter set. If this is not 00430 * the case, you need to reimplement the read method to set first a dummy 00431 * parameter object. 00432 * 00433 * @param handler the ioHandler to be used 00434 * @param complete if true (the default) the enclosing begin/end will 00435 * be also written, otherwise only the data block will be written. 00436 * @return true if write was successful 00437 */ 00438 virtual bool read(ioHandler& handler,const bool complete=true); 00439 00440 protected: 00441 /** 00442 * returns current parameters. (non const! -> protected) 00443 */ 00444 parameters& getParameters() {return *params;}; 00445 00446 private: 00447 00448 /** 00449 * This is private to avoid default implementation. 00450 * 00451 * alias for copy (MUST be reimplemented by each class or an 00452 * exception will be thrown!) 00453 */ 00454 functor& operator=(const functor& other); 00455 00456 /** 00457 * current parameters. 00458 */ 00459 parameters* params; 00460 00461 /** 00462 * Flag that indicates if the functor owns the parameters or not 00463 */ 00464 bool ownParams; 00465 00466 // /** 00467 // * the status string written with setStatusString 00468 // */ 00469 // mutable char* statusString; 00470 00471 // /** 00472 // * the empty string returned if the statusString is empty 00473 // */ 00474 // static const char *const emptyString; 00475 }; 00476 00477 /** 00478 * write the functor::parameters in the given ioHandler. 00479 * The complete flag indicates 00480 * if the enclosing begin and end should be also be written or not 00481 */ 00482 bool write(ioHandler& handler,const functor::parameters& p, 00483 const bool complete = true); 00484 00485 /** 00486 * read the functor::parameters from the given ioHandler. 00487 * The complete flag indicates 00488 * if the enclosing begin and end should be also be written or not 00489 */ 00490 bool read(ioHandler& handler,functor::parameters& p, 00491 const bool complete = true); 00492 00493 /** 00494 * write the functor in the given ioHandler. 00495 * The complete flag indicates 00496 * if the enclosing begin and end should be also be written or not. 00497 * The default implementation is to write only the parameters object, 00498 * since most functors do not have a state. 00499 */ 00500 bool write(ioHandler& handler,const functor& p, 00501 const bool complete = true); 00502 00503 /** 00504 * read the functor from the given ioHandler. 00505 * The complete flag indicates 00506 * if the enclosing begin and end should be also be written or not. 00507 * The default implementation is to write only the parameters object, 00508 * since most functors do not have a state. 00509 */ 00510 bool read(ioHandler& handler,functor& p, 00511 const bool complete = true); 00512 00513 } // namespace lti 00514 00515 #endif