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 .......: ltiIOFunctor.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 19.04.99 00030 * revisions ..: $Id: ltiIOFunctor.h,v 1.8 2007/03/02 23:47:44 alvarado Exp $ 00031 */ 00032 00033 #ifndef _LTI_IOFUNCTOR_H_ 00034 #define _LTI_IOFUNCTOR_H_ 00035 00036 #include <iostream> 00037 #include <string> 00038 #include "ltiFunctor.h" 00039 #include "ltiImage.h" 00040 00041 namespace lti { 00042 /** Base class to all io functors. 00043 * 00044 * All functors to load and save images are considered io functors. 00045 * 00046 * This is an abstract class and therefore no instances of this class 00047 * should exist! 00048 */ 00049 class ioFunctor : public functor { 00050 public: 00051 /** 00052 * ioFunctor parameters class 00053 */ 00054 class parameters : public functor::parameters { 00055 public: 00056 /** 00057 * default constructor 00058 */ 00059 parameters() : functor::parameters() {}; 00060 00061 /** 00062 * copy constructor 00063 */ 00064 parameters(const parameters& other) : functor::parameters() { 00065 copy(other); 00066 }; 00067 00068 /** 00069 * copy member 00070 */ 00071 parameters& copy(const parameters& other); 00072 00073 /** 00074 * returns a pointer to a clone of the parameters. 00075 */ 00076 virtual functor::parameters* clone() const; 00077 00078 /** 00079 * returns name of this type 00080 */ 00081 virtual const char* getTypeName() const; 00082 00083 /** 00084 * write the parameters in the given ioHandler 00085 * @param handler the ioHandler to be used 00086 * @param complete if true (the default) the enclosing begin/end will 00087 * be also written, otherwise only the data block will be written. 00088 * @return true if write was successful 00089 */ 00090 virtual bool write(ioHandler& handler,const bool complete=true) const; 00091 00092 /** 00093 * write the parameters in the given ioHandler 00094 * @param handler the ioHandler to be used 00095 * @param complete if true (the default) the enclosing begin/end will 00096 * be also written, otherwise only the data block will be written. 00097 * @return true if write was successful 00098 */ 00099 virtual bool read(ioHandler& handler,const bool complete=true); 00100 00101 # ifdef _LTI_MSC_6 00102 /** 00103 * this function is required by MSVC only, as a workaround for a 00104 * very awful bug, which exists since MSVC V.4.0, and still by 00105 * V.6.0 with all bugfixes (so called "service packs") remains 00106 * there... This method is public due to another bug, so please 00107 * NEVER EVER call this method directly: use read() instead! 00108 */ 00109 bool readMS(ioHandler& handler,const bool complete=true); 00110 00111 /** 00112 * this function is required by MSVC only, as a workaround for a 00113 * very awful bug, which exists since MSVC V.4.0, and still by 00114 * V.6.0 with all bugfixes (so called "service packs") remains 00115 * there... This method is public due to another bug, so please 00116 * NEVER EVER call this method directly: use write() instead! 00117 */ 00118 bool writeMS(ioHandler& handler,const bool complete=true) const; 00119 # endif 00120 00121 // ------------------------------------------------ 00122 // the parameters 00123 // ------------------------------------------------ 00124 00125 /** 00126 * name of the file to read/write 00127 */ 00128 std::string filename; 00129 }; 00130 00131 /** 00132 * default constructor 00133 */ 00134 ioFunctor() 00135 : functor() {}; 00136 00137 /** 00138 * constructor, sets the parameters 00139 */ 00140 ioFunctor(const parameters& theParam); 00141 00142 /** 00143 * constructor, sets the filename 00144 */ 00145 ioFunctor(const std::string& theFilename); 00146 00147 /** 00148 * destructor 00149 */ 00150 virtual ~ioFunctor(); 00151 00152 /** 00153 * returns current parameters. 00154 */ 00155 const parameters& getParameters() const; 00156 00157 /** 00158 * load Image 00159 * @param theImage the file specified in the parameters will be loaded 00160 * in this image. Note that independently of the sort 00161 * of image in the file, this will always be converted to 00162 * a color lti::image. 00163 * @return a reference to the loaded image. 00164 */ 00165 virtual bool apply(image& ) { 00166 throw invalidMethodException("apply(image) not implemented for this functor"); 00167 }; 00168 00169 /** 00170 * load Channel 00171 * Use this method if you know that the file contains a gray valued image. 00172 * @param theChannel the image on the file will be loaded here 00173 * @param colors theChannel contains just indexes to the pixel values 00174 * in this palette (vector or rgbPixel). 00175 * @return true if successful, false otherwise. 00176 */ 00177 virtual bool apply(channel8& ,lti::palette& ) { 00178 throw invalidMethodException("apply(channel8,palette) not implemented"); 00179 }; 00180 00181 /** 00182 * this method loads an image or a channel8, depending on the contents 00183 * of the file header. 00184 * if the number of bits per pixel is 24, the image will be initialized, 00185 * if the number of bits is less or equal 8, the channel and palette 00186 * will be initialized. 00187 * 00188 * If the file contains an indexed image, the palette will contain the 00189 * corresponding colors. If the file contains a "true color" image, the 00190 * palette will have size 0. 00191 * 00192 * @param theImage if the file contains a 24-bit image, this parameter 00193 * will be initialized 00194 * @param theChannel if the channel contains an 8-bit image, this 00195 * parameters will contain the readed data 00196 * @param colors if the channel was loaded this parameter will contain 00197 * the used colors. 00198 * @return the number of bits per pixel of the loaded image or 0 if an 00199 * error occured. The valid values are 1, 4, 8, or 24 00200 */ 00201 virtual int apply(image& , channel8& ,lti::palette& ) { 00202 throw invalidMethodException("apply(image&,channel&) not implemented"); 00203 }; 00204 00205 /** 00206 * save image. 00207 * The file name is specified in the parameters. 00208 * @param theImage the image to be stored. 00209 * @return false if error, otherwise true 00210 */ 00211 virtual bool apply(const image& ) { 00212 throw invalidMethodException("apply(const image&) not implemented"); 00213 }; 00214 00215 /** 00216 * save float channel 00217 * @param theChannel channel to be stored. 00218 * This channel must contain values between 00219 * 0.0f and 1.0f. 00220 * @return false if error, otherwise true 00221 */ 00222 virtual bool apply(const channel& ) { 00223 throw invalidMethodException("apply(const channel&) not implemented"); 00224 }; 00225 00226 /** 00227 * save 8-bit channel with the given color palette. 00228 * @param theChannel the channel to be saved 00229 * @param colors if a color palette is given, <code>theChannel</code> 00230 * will be considered to contain indices to this palette. 00231 * If nothing (or an empty palette) is given, 00232 * <code>theChannel</code> will be considered as a gray 00233 * valued channel. 00234 * @return false if error, otherwise true 00235 */ 00236 virtual bool apply(const channel8& , 00237 const lti::palette& =emptyPalette) { 00238 throw invalidMethodException("apply(const channel&) not implemented"); 00239 }; 00240 00241 /** 00242 * this will save an image as a 24 bit RGB image 00243 */ 00244 virtual bool save(const std::string& , 00245 const image& ) { 00246 throw invalidMethodException("save not implemented for this functor"); 00247 return false; 00248 }; 00249 00250 /** 00251 * this will save a channel8 00252 * @param filename name of the destination file 00253 * @param theChannel the channel to be save 00254 * @param colors the palette to be used 00255 */ 00256 virtual bool save(const std::string& , 00257 const channel8& , 00258 const lti::palette& =emptyPalette) { 00259 throw invalidMethodException("save not implemented for this functor"); 00260 return false; 00261 }; 00262 00263 /** 00264 * shortcut for load image 00265 * @param filename name of the file to be readed 00266 * @param theImage variable where the image will to be stored 00267 */ 00268 virtual bool load(const std::string& ,image& ) { 00269 throw invalidMethodException("load not implemented for this functor"); 00270 return false; 00271 }; 00272 00273 /** 00274 * shortcut for load image. 00275 * 00276 * Use this method if you know that the file contains a gray valued image. 00277 * @param filename name of the file to be readed 00278 * @param theChannel variable where the image will be stored 00279 * @param colors the palette used will be stored here 00280 */ 00281 virtual bool load(const std::string& ,channel8& , 00282 lti::palette& ) { 00283 throw invalidMethodException("load not implemented for this functor"); 00284 return false; 00285 }; 00286 00287 /** 00288 * returns the name of this type 00289 */ 00290 virtual const char* getTypeName() const; 00291 }; 00292 00293 /** 00294 * Endianness 00295 * This class is used to read data from a file with a known 00296 * endianness. 00297 * 00298 * The problem this class try to solve is following: 00299 * 00300 * Let us assume we have a binary file (and not an ASCII file) with 00301 * following byte stream: 00302 * 00303 * 0x01 0x02 0x03 0x04 ... 00304 * 00305 * and we use following code to read an int (4 bytes integers): 00306 * 00307 * \code 00308 * lti::uint32 integer; // hold the values been readed 00309 * std::istream in("theFile.dat"); // the input stream 00310 * 00311 * ... 00312 * in.read(&integer,4); // reads 4 bytes on "integer" 00313 * \endcode 00314 * 00315 * With a little endian system (for example Intel Pentium), the 00316 * contents of <code>integer</code> will be 0x04030201. 00317 * 00318 * With a big endian system (for example Motorola/IBM PowerPC), the 00319 * contents of <code>integer</code> will be 0x01020304. 00320 * 00321 * We need a class, which allow us to load data from a file with the 00322 * correct endiannes!!! 00323 * 00324 * The actual system endianess should be already defined: 00325 * 00326 * - For Windows systems there is no problem if they run on Intel 00327 * Processors (always little-endian). If you need to change this 00328 * (for example you have an Alpha processor, change the endianness 00329 * on the file ltiWinConfig.h) 00330 * 00331 * - For Unix systems the processor and endianness are determined 00332 * automatically by the configure script. If the file config.h 00333 * exists, everything should be ok!! 00334 */ 00335 class endianness : public object { 00336 public: 00337 /** eEndianness 00338 which sort of endianness uses the file 00339 */ 00340 enum eEndianness { 00341 LittleEndian, /**< the file uses little endianness */ 00342 BigEndian /**< the file uses big endianness */ 00343 }; 00344 00345 /** default constructor 00346 @param fileEndianness specify which endianness uses the file stream 00347 */ 00348 endianness(const eEndianness fileEndianness = LittleEndian); 00349 00350 /** 00351 * destructor 00352 */ 00353 virtual ~endianness(); 00354 00355 /** 00356 * returns the name of this class ("endianness") 00357 */ 00358 virtual const char* getTypeName() const; 00359 00360 /** read a byte from the stream 00361 @param in input stream 00362 @param data variable where the data should be stored 00363 @return a reference to the variable with the readed data 00364 */ 00365 byte& read(std::istream& in,byte& data) const; 00366 00367 /** read an unsigned byte from the stream 00368 @param in input stream 00369 @param data variable where the data should be stored 00370 @return a reference to the variable with the readed data 00371 */ 00372 ubyte& read(std::istream& in,ubyte& data) const; 00373 00374 /** read a int16 (2 bytes) 00375 @param in input stream 00376 @param data variable where the data should be stored 00377 @return a reference to the variable with the readed data 00378 */ 00379 int16& read(std::istream& in,int16& data) const; 00380 00381 /** read a uint16 (2 bytes) 00382 @param in input stream 00383 @param data variable where the data should be stored 00384 @return a reference to the variable with the readed data 00385 */ 00386 uint16& read(std::istream& in,uint16& data) const; 00387 00388 /** read a int32 00389 @param in input stream 00390 @param data variable where the data should be stored 00391 @return a reference to the variable with the readed data 00392 */ 00393 int32& read(std::istream& in,int32& data) const; 00394 00395 /** read a uint32 00396 @param in input stream 00397 @param data variable where the data should be stored 00398 @return a reference to the variable with the readed data 00399 */ 00400 uint32& read(std::istream& in,uint32& data) const; 00401 00402 /** write a byte 00403 @param out output stream 00404 @param data variable with the data to be stored on the file 00405 @return a reference to the variable with the data 00406 */ 00407 const byte& write(std::ostream& out,const byte& data) const; 00408 00409 /** write a ubyte 00410 @param out output stream 00411 @param data variable with the data to be stored on the file 00412 @return a reference to the variable with the data 00413 */ 00414 const ubyte& write(std::ostream& out,const ubyte& data) const; 00415 00416 /** write a int16 (2 bytes) 00417 @param out output stream 00418 @param data variable with the data to be stored on the file 00419 @return a reference to the variable with the data 00420 */ 00421 const int16& write(std::ostream& out,const int16& data) const; 00422 00423 /** write a uint16 (2 bytes) 00424 @param out output stream 00425 @param data variable with the data to be stored on the file 00426 @return a reference to the variable with the data 00427 */ 00428 const uint16& write(std::ostream& out,const uint16& data) const; 00429 00430 /** write a int32 00431 @param out output stream 00432 @param data variable with the data to be stored on the file 00433 @return a reference to the variable with the data 00434 */ 00435 const int32& write(std::ostream& out,const int32& data) const; 00436 00437 /** write a uint32 00438 @param out output stream 00439 @param data variable with the data to be stored on the file 00440 @return a reference to the variable with the data 00441 */ 00442 const uint32& write(std::ostream& out,const uint32& data) const; 00443 00444 protected: 00445 /** 00446 * This class encapsulates the endianness of the processor used. 00447 * The "defaultEndian" will always be the same as the system one. 00448 */ 00449 class defaultEndian : public object { 00450 public: 00451 virtual const char* getTypeName() const; 00452 /** 00453 * read a byte 00454 */ 00455 virtual byte& read(std::istream& in,byte& data) const; 00456 /** 00457 * read a ubyte 00458 */ 00459 virtual ubyte& read(std::istream& in,ubyte& data) const; 00460 /** 00461 * read a int16 (2 bytes) 00462 */ 00463 virtual int16& read(std::istream& in,int16& data) const; 00464 /** 00465 * read a uint16 (2 bytes) 00466 */ 00467 virtual uint16& read(std::istream& in,uint16& data) const; 00468 /** 00469 * read a int32 00470 */ 00471 virtual int32& read(std::istream& in,int32& data) const; 00472 /** 00473 * read a uint32 00474 */ 00475 virtual uint32& read(std::istream& in,uint32& data) const; 00476 00477 /** 00478 * write a byte 00479 */ 00480 virtual const byte& write(std::ostream& out,const byte& data) const; 00481 /** 00482 * write a ubyte 00483 */ 00484 virtual const ubyte& write(std::ostream& out,const ubyte& data) const; 00485 /** 00486 * write a int16 (2 bytes) 00487 */ 00488 virtual const int16& write(std::ostream& out,const int16& data) const; 00489 /** 00490 * write a uint16 (2 bytes) 00491 */ 00492 virtual const uint16& write(std::ostream& out,const uint16& data) const; 00493 /** 00494 * write a int32 00495 */ 00496 virtual const int32& write(std::ostream& out,const int32& data) const; 00497 /** 00498 * write a uint32 00499 */ 00500 virtual const uint32& write(std::ostream& out,const uint32& data) const; 00501 }; 00502 00503 /** 00504 * if file endianness is the opposite as the system endianness 00505 */ 00506 class oppositeEndian : public defaultEndian { 00507 public: 00508 virtual const char* getTypeName() const; 00509 /** 00510 * read a int16 (2 bytes) 00511 */ 00512 int16& read(std::istream& in,int16& data) const; 00513 /** 00514 * read a uint16 (2 bytes) 00515 */ 00516 uint16& read(std::istream& in,uint16& data) const; 00517 /** 00518 * read a int32 00519 */ 00520 int32& read(std::istream& in,int32& data) const; 00521 /** 00522 * read a uint32 00523 */ 00524 uint32& read(std::istream& in,uint32& data) const; 00525 00526 /** 00527 * write a int16 (2 bytes) 00528 */ 00529 const int16& write(std::ostream& out,const int16& data) const; 00530 /** 00531 * write a uint16 (2 bytes) 00532 */ 00533 const uint16& write(std::ostream& out,const uint16& data) const; 00534 /** 00535 * write a int32 00536 */ 00537 const int32& write(std::ostream& out,const int32& data) const; 00538 /** 00539 * write a uint32 00540 */ 00541 const uint32& write(std::ostream& out,const uint32& data) const; 00542 }; 00543 00544 // the correct read operator is pointed by this pointer: 00545 defaultEndian* theEndian; 00546 }; 00547 } 00548 00549 #endif