LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiBMPFunctor.h

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

Generated on Sat Apr 10 15:25:09 2010 for LTI-Lib by Doxygen 1.6.1