latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 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 .......: ltiLTIFunctor.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 03.06.2003 00030 * revisions ..: $Id: ltiLTIFunctor.h,v 1.15 2007/01/10 02:26:15 alvarado Exp $ 00031 */ 00032 00033 #ifndef _LTI_LTIFUNCTOR_H_ 00034 #define _LTI_LTIFUNCTOR_H_ 00035 00036 #include "ltiIOFunctor.h" 00037 #include "ltiImage.h" 00038 #include "ltiDataCodec.h" 00039 #include <fstream> 00040 00041 #undef None 00042 00043 namespace lti { 00044 /** 00045 * Base class to functors which load and save images in LTI format. 00046 * 00047 * The LTI format is a raw data file, in which only size of the image 00048 * and the data, without any compression type (yet), are stored. 00049 * 00050 * It is necessary because standard file formats do not provide functionaly 00051 * to save floating-point or integer (32 bit) channels. 00052 * 00053 * @see lti::ioLTI::parameters 00054 * @see lti::ioLTI::header 00055 * 00056 * This functor is at a very primitive development stage. The 00057 * format will change in the future, mainly because at this time, it 00058 * depends on the implemented platform, i.e. maybe a file stored on 00059 * Linux won't be readable on Windows and vice-versa. Endianness and 00060 * floating point number format still need to be formally specified. 00061 * 00062 * It is although provided for those applications which need to store 00063 * imatrices or channels, for which no other alternative is provided. 00064 */ 00065 class ioLTI : public ioFunctor { 00066 public: 00067 00068 /** 00069 * The compression methods usable for compressing the data. 00070 * You should be aware that runlength compression makes only 00071 * sense with matrices of bytes. RunLength tries to find 00072 * runs of equal bytes, which basically never happens in 00073 * matrices of elements that occupy more than one byte. 00074 */ 00075 enum eCompressionType { 00076 None=0, ///< use no compression 00077 RunLength=1, ///< uses runlength compression 00078 Flate=2 ///< uses zLib deflate compression 00079 }; 00080 00081 /** 00082 * Parameter class of the ioLTI class 00083 */ 00084 class parameters : public ioFunctor::parameters { 00085 public: 00086 /** 00087 * default constructor 00088 */ 00089 parameters(); 00090 00091 /** 00092 * copy constructor 00093 */ 00094 parameters(const parameters& other) : ioFunctor::parameters() { 00095 copy(other); 00096 }; 00097 00098 /** 00099 * copy member 00100 */ 00101 parameters& copy(const parameters& other); 00102 00103 /** 00104 * returns a pointer to a clone of the parameters. 00105 */ 00106 virtual functor::parameters* clone() const; 00107 00108 /** 00109 * returns name of this class 00110 */ 00111 virtual const char* getTypeName() const; 00112 00113 /** 00114 * write the parameters in the given ioHandler 00115 * @param handler the ioHandler to be used 00116 * @param complete if true (the default) the enclosing begin/end will 00117 * be also written, otherwise only the data block will be written. 00118 * @return true if write was successful 00119 */ 00120 virtual bool write(ioHandler& handler,const bool complete=true) const; 00121 00122 /** 00123 * write the parameters in the given ioHandler 00124 * @param handler the ioHandler to be used 00125 * @param complete if true (the default) the enclosing begin/end will 00126 * be also written, otherwise only the data block will be written. 00127 * @return true if write was successful 00128 */ 00129 virtual bool read(ioHandler& handler,const bool complete=true); 00130 00131 # ifdef _LTI_MSC_6 00132 /** 00133 * this function is required by MSVC only, as a workaround for a 00134 * very awful bug, which exists since MSVC V.4.0, and still by 00135 * V.6.0 with all bugfixes (so called "service packs") remains 00136 * there... This method is public due to another bug, so please 00137 * NEVER EVER call this method directly: use read() instead! 00138 */ 00139 bool readMS(ioHandler& handler,const bool complete=true); 00140 00141 /** 00142 * this function is required by MSVC only, as a workaround for a 00143 * very awful bug, which exists since MSVC V.4.0, and still by 00144 * V.6.0 with all bugfixes (so called "service packs") remains 00145 * there... This method is public due to another bug, so please 00146 * NEVER EVER call this method directly: use write() instead! 00147 */ 00148 bool writeMS(ioHandler& handler,const bool complete=true) const; 00149 # endif 00150 00151 // ------------------------------------------------ 00152 // the parameters 00153 // ------------------------------------------------ 00154 00155 // no parameters at this point 00156 /** 00157 * Compression method used when storing the data. 00158 */ 00159 eCompressionType compression; 00160 }; 00161 00162 /** 00163 * LTI-Format file header 00164 * 00165 * This class is defined within the class lti::ioLTI. The header is 00166 * always stored uncompressed. 00167 */ 00168 class header { 00169 public: 00170 /** 00171 * file type. For LTI-Types this must be 'LT' 00172 */ 00173 const uint16 type; 00174 00175 /** 00176 * Contents type: 00177 * - 0 : undefined 00178 * - 'b': ubyte channel 00179 * - 'i': int channel 00180 * - 'f': float channel 00181 * - 'c': rgbPixel image 00182 */ 00183 union { 00184 uint16 contents; 00185 struct { 00186 /** 00187 * Contents type: 00188 * - 0 : undefined 00189 * - 'b': ubyte channel 00190 * - 'i': int channel 00191 * - 'f': float channel 00192 * - 'c': rgbPixel image 00193 */ 00194 ubyte contents; 00195 /** 00196 * Compression type: 00197 * - 0 : no compression 00198 * - 1 : runlength compression 00199 * - 2 : flate compression (only with zlib) 00200 */ 00201 ubyte compression; 00202 } encoding; 00203 }; 00204 00205 /** 00206 * file size in byte (excluding the header, so only the data section 00207 * is counted). 00208 */ 00209 uint32 size; 00210 00211 /** 00212 * Must be 0 00213 * This can be used in the future to define some compressed formats 00214 */ 00215 const uint32 reserved1; 00216 00217 /** 00218 * Must be 0 00219 * This can be used in the future to define some compressed formats 00220 */ 00221 const uint32 reserved2; 00222 00223 /** 00224 * number of rows 00225 */ 00226 uint32 rows; 00227 00228 /** 00229 * number of columns 00230 */ 00231 uint32 columns; 00232 00233 /** 00234 * default constructor 00235 */ 00236 header(); 00237 00238 /** 00239 * reads header from the stream "in". 00240 * @return false if stream had an invalid header. 00241 */ 00242 bool read(std::ifstream& in); 00243 00244 /** 00245 * writes header to the stream "out". 00246 * @return false if an error occurs. 00247 */ 00248 bool write(std::ofstream& out); 00249 00250 /** 00251 * size of the header (in bytes) 00252 */ 00253 inline int length() const {return 24;}; 00254 00255 protected: 00256 endianness io; 00257 }; 00258 00259 /** 00260 * default constructor 00261 */ 00262 ioLTI(); 00263 00264 /** 00265 * destructor 00266 */ 00267 ~ioLTI(); 00268 00269 /** 00270 * returns current parameters. 00271 */ 00272 const parameters& getParameters() const; 00273 00274 /** 00275 * returns the name of this type 00276 */ 00277 virtual const char* getTypeName() const; 00278 00279 /** 00280 * set functor's parameters. 00281 * This member makes a copy of <em>theParam</em>: the functor 00282 * will keep its own copy of the parameters. Furthermore, 00283 * the method will create the appropriate compression 00284 * codec from the parameters compression value. 00285 * @return true if successful, false otherwise 00286 */ 00287 virtual bool updateParameters(); 00288 00289 protected: 00290 /** 00291 * Pointer to compression functor used 00292 */ 00293 dataCodec* codec; 00294 00295 }; 00296 00297 /** 00298 * Functor to read a bitmap (LTI) file. 00299 * 00300 * It is NOT thread save, this means, the SAME instance can not be 00301 * used from different threads or processes at the same time. If 00302 * this occurs an unpredictible behaviour must be expected!. If you 00303 * need to read or write many LTIs at the same time, use in each 00304 * thread an instance of this functor, or protect your code with 00305 * semaphores. 00306 */ 00307 class loadLTI : public ioLTI { 00308 public: 00309 /** 00310 * default constructor 00311 */ 00312 loadLTI(); 00313 00314 /** 00315 * destructor 00316 */ 00317 ~loadLTI() {}; 00318 00319 /** 00320 * returns the name of this type ("loadLTI") 00321 */ 00322 virtual const char* getTypeName() const; 00323 00324 00325 /** 00326 * Loads a matrix of a given type. There are implementations for 00327 * image, channel, channel8, imatrix, and dmatrix. 00328 * If the content of the file does not match the parameter type, 00329 * the method will try to convert it by using the matrix's castFrom 00330 * method, if such a conversion makes sense. Otherwise, it will 00331 * return false. 00332 * 00333 * @param theChannel the matrix on the file will be loaded here 00334 * @return true if successful, false otherwise. 00335 */ 00336 //@{ 00337 bool apply(matrix<rgbPixel>& theChannel); 00338 bool apply(imatrix& theChannel); 00339 bool apply(dmatrix& theChannel); 00340 bool apply(fmatrix& theChannel); 00341 bool apply(matrix<ubyte>& theChannel); 00342 //@} 00343 00344 00345 /** 00346 * shortcut for load LTI. 00347 * 00348 * @param filename name of the file to be readed 00349 * @param theChannel variable where the matrix will be stored 00350 * @return true if successful, false otherwise. 00351 */ 00352 //@{ 00353 bool load(const std::string& filename, matrix<rgbPixel>& theChannel); 00354 bool load(const std::string& filename, fmatrix& theChannel); 00355 bool load(const std::string& filename, matrix<ubyte>& theChannel); 00356 bool load(const std::string& filename, imatrix& theChannel); 00357 bool load(const std::string& filename, dmatrix& theChannel); 00358 //@} 00359 00360 /** 00361 * check the data of the bitmap header 00362 * @param filename name of the bitmap file to be tested 00363 * @param imageSize returns the size of the bitmap: imageSize.x is the 00364 * number of columns and imageSize.y the numbeer of 00365 * rows. 00366 * @param imageType type of the image found in file. It can be: 00367 * - 'c' for images (from color image) 00368 * - 'b' for channel8 (from byte channel) 00369 * - 'f' for channel (from float channel) 00370 * - 'i' for imatrix (from int) 00371 * 00372 * @param compr compression type. It can be: 00373 * - None 00374 * - RunLength 00375 * - Flate (only available if zLib is found) 00376 * @return true if file is ok 00377 */ 00378 bool checkHeader(const std::string& filename, 00379 point& imageSize, 00380 char& imageType, 00381 eCompressionType& compr); 00382 /** 00383 * returns a pointer to a clone of the functor. 00384 */ 00385 virtual functor* clone() const; 00386 00387 header theHeader; 00388 }; 00389 00390 /** 00391 * Functor to save a bitmap (LTI) file. 00392 * 00393 * To save a LTI image just initialize the %parameters of the 00394 * "%saveLTI" %object and call the apply member, or use one of the 00395 * shortcuts. 00396 * 00397 * Example: 00398 * 00399 * \code 00400 * lti::image anImg; // an image 00401 * lti::channel8 aChnl; // an 8-bit Channel 00402 * ... 00403 * lti::saveLTI saveImg; // the save functor 00404 * 00405 * // save the image as a 24 bit bitmap file: 00406 * saveImg.save("/tmp/theFile.lti",anImg); 00407 * 00408 * // save the channel as a 8 bit bitmap file: 00409 * saveImg.save("/the/theChnl8.lti",aChnl); 00410 * 00411 * // save the channel as a 24 bit bitmap file: 00412 * lti::saveLTI::parameters param; // functor parameters 00413 * 00414 * param.filename = "~/tmp/theChnl24.lti"; // name of the LTI file 00415 * param.bitsPerPixel = 24; // use 24 bits! 00416 * saveImg.setParameters(param); // set the functor parameters 00417 * 00418 * saveImg.apply(aChnl); // save the channel 00419 * \endcode 00420 * 00421 * @see ioLTI::parameters 00422 */ 00423 class saveLTI : public ioLTI { 00424 public: 00425 /** 00426 * default constructor 00427 */ 00428 saveLTI(); 00429 00430 /** 00431 * destructor 00432 */ 00433 ~saveLTI() {}; 00434 00435 /** 00436 * returns the name of this type 00437 */ 00438 virtual const char* getTypeName() const; 00439 00440 // /** 00441 // * save image as LTI. 00442 // * 00443 // * Note that if the parameters contain a number of bits per pixels 00444 // * less than 24 (this means 8, 4 or 1)(see 00445 // * lti::ioLTI::parameters), this method will apply a quantization 00446 // * algorithm, which will reduce the number of used colors as 00447 // * requested. This is very time consuming! For 24 images this 00448 // * method is relativly fast. 00449 // * 00450 // * For a faster 8-bit LTI use the method apply(const 00451 // * channel8&,const lti::palette). 00452 // * @param theImage the image to be stored. 00453 // * @return true if successful, false otherwise. 00454 // */ 00455 // bool apply(const image& theImage); 00456 00457 /** 00458 * @name Apply methods. 00459 * 00460 * Save matrix of any type. There is a template implementation 00461 * for the types image (matrix<rgbPixel>), imatrix (matrix<int>), 00462 * channel (matrix<float>) and channel8 (matrix<ubyte>). 00463 * @param theChannel matrix to be stored. 00464 */ 00465 //@{ 00466 bool apply(const matrix<rgbPixel>& theChannel); 00467 bool apply(const fmatrix& theChannel); 00468 bool apply(const matrix<ubyte>& theChannel); 00469 bool apply(const imatrix& theChannel); 00470 bool apply(const dmatrix& theChannel); 00471 00472 00473 /** 00474 * This will save a matrix in the appropriate file format. 00475 * @param filename the name of the file which will receive the matrix 00476 * @param theImage the matrix to be written 00477 * @return true, iff the matrix could be saved successfully 00478 */ 00479 //@{ 00480 bool save(const std::string& filename, const matrix<rgbPixel>& theImage); 00481 bool save(const std::string& filename, const imatrix& theImage); 00482 bool save(const std::string& filename, const dmatrix& theImage); 00483 bool save(const std::string& filename, const fmatrix& theImage); 00484 bool save(const std::string& filename, const matrix<ubyte>& theImage); 00485 //@} 00486 00487 /** 00488 * returns a pointer to a clone of the functor. 00489 */ 00490 virtual functor* clone() const; 00491 00492 private: 00493 00494 header theHeader; 00495 }; 00496 } //namespace lti 00497 00498 #endif