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 .......: ltiBMPFunctor.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 19.04.99 00030 * revisions ..: $Id: ltiBMPFunctor.h,v 1.7 2006/02/08 12:01:04 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_BMPFUNCTOR_H_ 00034 #define _LTI_BMPFUNCTOR_H_ 00035 00036 #include "ltiIOFunctor.h" 00037 #include "ltiImage.h" 00038 #include <fstream> 00039 00040 namespace lti { 00041 /** Base class to functors which load and save images in BMP format. 00042 00043 This class includes types for read and write %header objects of the 00044 BMP file format. 00045 @param class lti::ioBMP::parameters 00046 @see lti::ioBMP::header,lti::ioBMP::infoHeader,lti::ioBMP::palette 00047 */ 00048 class ioBMP : public ioFunctor { 00049 public: 00050 /** 00051 * Parameter class of the ioBMP class 00052 */ 00053 class parameters : public ioFunctor::parameters { 00054 public: 00055 /** 00056 * default constructor 00057 */ 00058 parameters(); 00059 00060 /** 00061 * copy constructor 00062 */ 00063 parameters(const parameters& other) : ioFunctor::parameters() { 00064 copy(other); 00065 }; 00066 00067 /** 00068 * copy member 00069 */ 00070 parameters& copy(const parameters& other); 00071 00072 /** 00073 * returns a pointer to a clone of the parameters. 00074 */ 00075 virtual functor::parameters* clone() const; 00076 00077 /** 00078 * returns name of this class 00079 */ 00080 virtual const char* getTypeName() const; 00081 00082 /** 00083 * write the parameters in the given ioHandler 00084 * @param handler the ioHandler to be used 00085 * @param complete if true (the default) the enclosing begin/end will 00086 * be also written, otherwise only the data block will be written. 00087 * @return true if write was successful 00088 */ 00089 virtual bool write(ioHandler& handler,const bool complete=true) const; 00090 00091 /** 00092 * write the parameters in the given ioHandler 00093 * @param handler the ioHandler to be used 00094 * @param complete if true (the default) the enclosing begin/end will 00095 * be also written, otherwise only the data block will be written. 00096 * @return true if write was successful 00097 */ 00098 virtual bool read(ioHandler& handler,const bool complete=true); 00099 00100 # ifdef _LTI_MSC_6 00101 /** 00102 * this function is required by MSVC only, as a workaround for a 00103 * very awful bug, which exists since MSVC V.4.0, and still by 00104 * V.6.0 with all bugfixes (so called "service packs") remains 00105 * there... This method is public due to another bug, so please 00106 * NEVER EVER call this method directly: use read() instead! 00107 */ 00108 bool readMS(ioHandler& handler,const bool complete=true); 00109 00110 /** 00111 * this function is required by MSVC only, as a workaround for a 00112 * very awful bug, which exists since MSVC V.4.0, and still by 00113 * V.6.0 with all bugfixes (so called "service packs") remains 00114 * there... This method is public due to another bug, so please 00115 * NEVER EVER call this method directly: use write() instead! 00116 */ 00117 bool writeMS(ioHandler& handler,const bool complete=true) const; 00118 # endif 00119 00120 // ------------------------------------------------ 00121 // the parameters 00122 // ------------------------------------------------ 00123 00124 /** 00125 * compress the data. 00126 * (RLE4 or RLE8 will be used if the number of bits are 4 or 8). 00127 * The default value is false 00128 */ 00129 bool compression; 00130 00131 /** 00132 * bits per pixel (default value 24) 00133 */ 00134 int bitsPerPixel; 00135 00136 /** 00137 * quantization of colors. 00138 * If 0 no quantization needed 00139 * If >0 then a k-mean analysis of the colors will be made and 00140 * the used color number will be reduce to <em>quantColors</em> 00141 * (unused by now) 00142 */ 00143 int quantColors; 00144 }; 00145 00146 /** 00147 * BITMAPFILEHEADER: 00148 * 00149 * This class is defined within the class lti::ioBMP. 00150 */ 00151 class header { 00152 public: 00153 /** 00154 * file type. For Bitmaps this must be 'BM' 00155 */ 00156 const uint16 type ; 00157 00158 /** 00159 * file size in byte 00160 */ 00161 uint32 size ; 00162 00163 /** 00164 * must be 0 00165 */ 00166 const uint16 reserved1 ; 00167 00168 /** 00169 * must be 0 00170 */ 00171 const uint16 reserved2 ; 00172 00173 /** 00174 * offset (in bytes) from this header to the bitmap pixels 00175 */ 00176 uint32 offsetPixels ; 00177 00178 /** 00179 * default constructor 00180 */ 00181 header(); 00182 00183 /** 00184 * reads header from the stream "in". 00185 * @return false if stream had an invalid header. 00186 */ 00187 bool read(std::ifstream& in); 00188 00189 /** 00190 * writes header to the stream "out". 00191 * @return false if an error occurs. 00192 */ 00193 bool write(std::ofstream& out); 00194 00195 /** 00196 * size of the header (in bytes) 00197 */ 00198 inline int length() const {return 14;}; 00199 00200 protected: 00201 endianness io; 00202 }; 00203 00204 /** 00205 * BITMAPINFOHEADER 00206 * 00207 * This class is defined within the class lti::ioBMP. 00208 */ 00209 class infoHeader { 00210 public: 00211 /** 00212 * constructor 00213 */ 00214 infoHeader(); 00215 00216 /** 00217 * size 00218 */ 00219 uint32 size; 00220 00221 /** 00222 * width 00223 */ 00224 uint32 width; 00225 00226 /** 00227 * height 00228 */ 00229 uint32 height; 00230 00231 /** 00232 * planes 00233 */ 00234 uint16 planes ; 00235 00236 /** 00237 * bitcount 00238 */ 00239 uint16 bitCount ; 00240 00241 /** 00242 * compression 00243 */ 00244 uint32 compression; 00245 00246 /** 00247 * sizeImage 00248 */ 00249 uint32 sizeImage; 00250 00251 /** 00252 * xPixPerMeter 00253 */ 00254 uint32 xPixPerMeter; 00255 00256 /** 00257 * yPixPerMeter 00258 */ 00259 uint32 yPixPerMeter; 00260 00261 /** 00262 * colorsUsed 00263 */ 00264 uint32 colorsUsed; 00265 00266 /** 00267 * colorsImportant 00268 */ 00269 uint32 colorsImportant; 00270 00271 /** 00272 * read 00273 */ 00274 bool read(std::ifstream& in); 00275 00276 /** 00277 * write 00278 */ 00279 bool write(std::ofstream& out); 00280 00281 /** 00282 * size of the info header (in bytes) 00283 */ 00284 inline int length() const {return 40;}; 00285 00286 protected: 00287 endianness io; 00288 }; 00289 00290 /** Color Palette 00291 * 00292 * This class is defined within the class lti::ioBMP. 00293 */ 00294 class palette : public vector<rgbPixel> { 00295 public: 00296 /** 00297 * default constructor 00298 * @param entries number of entries in the palette 00299 */ 00300 palette(int entries = 0) : vector<rgbPixel>(entries) {}; 00301 00302 /** 00303 * read the palette from the in stream 00304 * @param in input stream 00305 * @return true if everything is ok, false otherwise 00306 */ 00307 bool read(std::ifstream& in); 00308 00309 /** 00310 * write palette to the out stream 00311 * @param out output stream 00312 * @return true if everything is ok, false otherwise 00313 */ 00314 bool write(std::ofstream& out); 00315 00316 protected: 00317 /** 00318 * use the correct endianness to read and write! 00319 */ 00320 endianness io; 00321 }; 00322 00323 /** 00324 * default constructor 00325 */ 00326 ioBMP(); 00327 00328 /** 00329 * destructor 00330 */ 00331 ~ioBMP() {}; 00332 00333 /** 00334 * returns current parameters. 00335 */ 00336 const parameters& getParameters() const; 00337 00338 /** 00339 * returns the name of this type 00340 */ 00341 virtual const char* getTypeName() const; 00342 }; 00343 00344 /** 00345 * Functor to read a bitmap (BMP) file. 00346 * 00347 * It is NOT thread save, this means, the SAME instance can not be 00348 * used from different threads or processes at the same time. If 00349 * this occurs an unpredictible behaviour must be expected!. If you 00350 * need to read or write many BMPs at the same time, use in each 00351 * thread an instance of this functor, or protect your code with 00352 * semaphores. 00353 */ 00354 class loadBMP : public ioBMP { 00355 public: 00356 /** 00357 * default constructor 00358 */ 00359 loadBMP(); 00360 00361 /** 00362 * destructor 00363 */ 00364 ~loadBMP() {}; 00365 00366 /** 00367 * returns the name of this type ("loadBMP") 00368 */ 00369 virtual const char* getTypeName() const; 00370 00371 /** load Image 00372 * @param theImage the file specified in the parameters will be loaded 00373 * in this image. Note that independently of the soft 00374 * of image in the file, this will always be converted to 00375 * a color lti::image. 00376 * @return a reference to the loaded image. 00377 */ 00378 bool apply(image& theImage); 00379 00380 /** 00381 * load channel 00382 * 00383 * Use this method if you know that the file contains a gray 00384 * valued image. If you try to load a 24-bit image with this 00385 * method, some quantization algorithms will be used to reduce the 00386 * number of colors to 256. 00387 * 00388 * @param theChannel the image on the file will be loaded here 00389 * @param colors theChannel contains just indexes to the pixel values 00390 * in this vector. 00391 * @return true if successful, false otherwise. 00392 */ 00393 bool apply(channel8& theChannel,lti::palette& colors); 00394 00395 /** 00396 * load channel 00397 * 00398 * Use this method if you know that the file contains a gray 00399 * valued image. 00400 * 00401 * @param theChannel the image on the file will be loaded here 00402 * @return true if successful, false otherwise. 00403 */ 00404 bool apply(channel& theChannel); 00405 00406 /** 00407 * this method loads an image or a channel8, depending on the contents 00408 * of the file header. 00409 * if the number of bits per pixel is 24, the image will be initialized, 00410 * if the number of bits is less or equal 8, the channel and palette 00411 * will be initialized. 00412 * 00413 * If the file contains an indexed image, the palette will contain the 00414 * corresponding colors. If the file containes a "true color" image, the 00415 * palette will have size 0. 00416 * 00417 * @param theImage if the file contains a 24-bit image, this parameter 00418 * will be initialized 00419 * @param theChannel if the channel contains an 8-bit image, this 00420 * parameters will contain the readed data 00421 * @param colors if the channel was loaded this parameter will contain 00422 * the used colors. 00423 * @return the number of bits per pixel of the loaded image or 0 if an 00424 * error occured. The valid values are 1, 4, 8, or 24 00425 */ 00426 int apply(image& theImage, channel8& theChannel,lti::palette& colors); 00427 00428 /** 00429 * shortcut for load BMP 00430 * @param filename name of the file to be readed 00431 * @param theImage variable where the image will to be stored 00432 */ 00433 bool load(const std::string& filename,image& theImage); 00434 00435 /** 00436 * shortcut for load BMP 00437 * @param file an already opened stream for reading binary data 00438 * @param theImage variable where the image will to be stored 00439 */ 00440 bool load(std::ifstream& file,image& theImage); 00441 00442 /** 00443 * shortcut for load BMP. 00444 * 00445 * Use this method if you know that the file contains a gray valued image. 00446 * If you try to load a 24-bit image with this method, some quantization 00447 * algorithms will be used to reduce the number of colors to 256. 00448 * 00449 * @param filename name of the file to be readed 00450 * @param theChannel variable where the image will be stored 00451 * @param colors the palette used will be stored here 00452 */ 00453 bool load(const std::string& filename, 00454 channel8& theChannel, 00455 lti::palette& colors); 00456 00457 /** 00458 * shortcut for load BMP. 00459 * 00460 * Use this method if you know that the file contains a gray valued image. 00461 * 00462 * @param filename name of the file to be readed 00463 * @param theChannel variable where the image will be stored 00464 */ 00465 bool load(const std::string& filename, 00466 channel& theChannel); 00467 00468 /** 00469 * this method loads an image or a channel8, depending on the contents 00470 * of the file header. 00471 * if the number of bits per pixel is 24, the image will be initialized, 00472 * if the number of bits is less or equal 8, the channel and palette 00473 * will be initialized. 00474 * 00475 * The wrong type will be resized to (0,0) 00476 * @param filename name of the file to be readed 00477 * @param theImage if the file contains a 24bit color image, this 00478 * parameter will be resized and initialized with 00479 * the contents of the file 00480 * @param theChannel if the file contains a 8bit or less indexed image, 00481 * this parameter and the palette will be initialized 00482 * with the contents of the file. 00483 * @param colors the color palette for the indexed image. 00484 * @return the number of bits per pixel of the loaded image or 0 if an 00485 * error occured. The valid values are 1, 4, 8, or 24 00486 */ 00487 int load(const std::string& filename, 00488 image& theImage, 00489 channel8& theChannel, 00490 lti::palette& colors); 00491 00492 /** 00493 * check the data of the bitmap header 00494 * @param filename name of the bitmap file to be tested 00495 * @param imageSize returns the size of the bitmap: imageSize.x is the 00496 * number of columns and imageSize.y the numbeer of 00497 * rows. 00498 * @param bitsPerPixel number of bits per pixel 00499 * @param colorEntries number of color entries in the palette (only 00500 * used if bitsPerPixel<=8 00501 * @return true if file is ok 00502 */ 00503 bool checkHeader(const std::string& filename, 00504 point& imageSize, 00505 int& bitsPerPixel, 00506 int& colorEntries); 00507 00508 /** 00509 * returns a pointer to a clone of the functor. 00510 */ 00511 virtual functor* clone() const; 00512 00513 private: 00514 bool load1bit(std::ifstream& in,image& theImage); 00515 bool load1bit(std::ifstream& in,channel8& theChannel); 00516 bool load4bit(std::ifstream& in,image& theImage); 00517 bool load4bit(std::ifstream& in,channel8& theChannel); 00518 bool load8bit(std::ifstream& in,image& theImage); 00519 bool load8bit(std::ifstream& in,channel8& theChannel); 00520 bool load24bit(std::ifstream& in,image& theImage); 00521 00522 bool applyFromStream(std::ifstream& in, image& theImage); 00523 00524 header theHeader; 00525 infoHeader theInfoHeader; 00526 palette thePalette; 00527 }; 00528 00529 /** 00530 * Functor to save a bitmap (BMP) file. 00531 * 00532 * To save a BMP image just initialize the %parameters of the 00533 * "%saveBMP" %object and call the apply member, or use one of the 00534 * shortcuts. 00535 * 00536 * Example: 00537 * 00538 * \code 00539 * lti::image anImg; // an image 00540 * lti::channel8 aChnl; // an 8-bit Channel 00541 * ... 00542 * lti::saveBMP saveImg; // the save functor 00543 * 00544 * // save the image as a 24 bit bitmap file: 00545 * saveImg.save("/tmp/theFile.bmp",anImg); 00546 * 00547 * // save the channel as a 8 bit bitmap file: 00548 * saveImg.save("/the/theChnl8.bmp",aChnl); 00549 * 00550 * // save the channel as a 24 bit bitmap file: 00551 * lti::saveBMP::parameters param; // functor parameters 00552 * 00553 * param.filename = "~/tmp/theChnl24.bmp"; // name of the BMP file 00554 * param.bitsPerPixel = 24; // use 24 bits! 00555 * saveImg.setParameters(param); // set the functor parameters 00556 * 00557 * saveImg.apply(aChnl); // save the channel 00558 * \endcode 00559 * 00560 * @see ioBMP::parameters 00561 */ 00562 class saveBMP : public ioBMP { 00563 public: 00564 /** 00565 * default constructor 00566 */ 00567 saveBMP(); 00568 00569 /** 00570 * destructor 00571 */ 00572 ~saveBMP() {}; 00573 00574 /** 00575 * returns the name of this type 00576 */ 00577 virtual const char* getTypeName() const; 00578 00579 /** 00580 * save image as BMP. 00581 * 00582 * Note that if the parameters contain a number of bits per pixels 00583 * less than 24 (this means 8, 4 or 1)(see 00584 * lti::ioBMP::parameters), this method will apply a quantization 00585 * algorithm, which will reduce the number of used colors as 00586 * requested. This is very time consuming! For 24 images this 00587 * method is relativly fast. 00588 * 00589 * For a faster 8-bit BMP use the method apply(const 00590 * channel8&,const lti::palette). 00591 * @param theImage the image to be stored. 00592 */ 00593 bool apply(const image& theImage); 00594 00595 /** 00596 * save float channel 00597 * @param theChannel channel to be stored. 00598 * This channel must contain values between 0.0f and 00599 * 1.0f. 00600 */ 00601 bool apply(const channel& theChannel); 00602 00603 /** 00604 * save 8-bit channel as a bitmap. 00605 * @param theChannel the channel to be saved 00606 * @param colors if a color palette is given, <code>theChannel</code> 00607 * will be considered to contain indices to this palette. 00608 * If nothing (or an empty palette) is given, 00609 * <code>theChannel</code> will be considered as a gray 00610 * valued channel. 00611 * See ioBMP::parameters for more options 00612 */ 00613 bool apply(const channel8& theChannel, 00614 const lti::palette& colors=emptyPalette); 00615 00616 /** 00617 * this will save an image as a 24 bit RGB bitmap image 00618 */ 00619 bool save(const std::string& filename, 00620 const image& theImage); 00621 00622 /** 00623 * this will save a channel8 as an 8 bit RGB bitmap image 00624 * @param filename name of the destination file 00625 * @param theChannel the channel to be save 00626 * @param colors the palette to be used 00627 * (see apply(const channel& theChannel) for details) 00628 */ 00629 bool save(const std::string& filename, 00630 const channel8& theChannel, 00631 const lti::palette& colors=emptyPalette); 00632 00633 /** 00634 * this will save a channel as an 8 bit RGB bitmap image. 00635 * The values of the channel must be between 0.0f and 1.0f! 00636 * @param filename name of the destination file 00637 * @param theChannel the channel to be save 00638 * @param colors the palette to be used 00639 * (see apply(const channel8& theChannel) for details) 00640 */ 00641 bool save(const std::string& filename, 00642 const channel& theChannel, 00643 const lti::palette& colors=emptyPalette); 00644 00645 /** 00646 * returns a pointer to a clone of the functor. 00647 */ 00648 virtual functor* clone() const; 00649 00650 private: 00651 bool save1bit(std::ofstream& out,const image& theImage); 00652 bool save1bit(std::ofstream& out,const channel8& theChannel); 00653 bool save4bit(std::ofstream& out,const image& theImage); 00654 bool save4bit(std::ofstream& out,const channel8& theChannel); 00655 bool save8bit(std::ofstream& out,const image& theImage); 00656 bool save8bit(std::ofstream& out,const channel8& theChannel); 00657 bool save24bit(std::ofstream& out,const image& theImage); 00658 00659 header theHeader; 00660 infoHeader theInfoHeader; 00661 palette thePalette; 00662 }; 00663 } //namespace lti 00664 00665 #endif