Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

GenImage.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------+
00002  | Library QgarLib, graphics analysis and recognition                  |
00003  | Copyright (C) 2002  Qgar Project, LORIA                             |
00004  |                                                                     |
00005  | This library is free software; you can redistribute it and/or       |
00006  | modify it under the terms of the GNU Lesser General Public          |
00007  | License version 2.1, as published by the Free Software Foundation.  |
00008  |                                                                     |
00009  | This library is distributed in the hope that it will be useful,     |
00010  | but WITHOUT ANY WARRANTY; without even the implied warranty of      |
00011  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                |
00012  | See the GNU Lesser General Public License for more details.         |
00013  |                                                                     |
00014  | The GNU Lesser General Public License is included in the file       |
00015  | LICENSE.LGPL, in the root directory of the Qgar packaging. See      |
00016  | http://www.gnu.org/licenses/lgpl.html for the terms of the licence. |
00017  | To receive a paper copy, write to the Free Software Foundation,     |
00018  | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.       |
00019  |                                                                     |
00020  | Contact Project Qgar for any information:                           |
00021  |   LORIA - équipe Qgar                                               |
00022  |   B.P. 239, 54506 Vandoeuvre-lès-Nancy Cedex, France                |
00023  |   email: qgar-contact@loria.fr                                      |
00024  |   http://www.qgar.org/                                              |
00025  *---------------------------------------------------------------------*/
00026 
00027 
00028 #ifndef __GENIMAGE_H_INCLUDED__
00029 #define __GENIMAGE_H_INCLUDED__
00030 
00031 /**
00032  * @file   GenImage.H
00033  * @brief  Header file of class qgar::GenImage.
00034  *
00035  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00036  * @date   March 4, 2003  14:09
00037  * @since  Qgar 2.1
00038  */
00039 
00040 
00041 // For RCS/CVS use: Do not delete
00042 /* $Id: GenImage.H,v 1.38 2005/10/14 17:05:46 masini Exp $ */
00043 
00044 
00045 
00046 // STD
00047 #include <sstream>
00048 #include <string>
00049 // QGAR
00050 #include <qgarlib/AbstractPbmPlusFile.H>
00051 #include <qgarlib/BoundingBox.H>
00052 #include <qgarlib/image.H>
00053 #include <qgarlib/primitives.H>
00054 #include <qgarlib/QgarErrorDomain.H>
00055 #include <qgarlib/QgarErrorInvalidArg.H>
00056 
00057 
00058 
00059 // _____________________________________________________________________
00060 //
00061 // WARNING: The following comment represents the documentation of
00062 // namespace qgar. If the class is removed or altered, this comment
00063 // must be moved to another QgarLib class file (.H).
00064 // _____________________________________________________________________
00065 //
00066 /**
00067  * @brief Namespace of the QgarLib library.
00068  *
00069  * All classes, types, globals, etc. of the Qgar library are defined
00070  * in this namespace.
00071  */
00072 namespace qgar
00073 {
00074 
00075 
00076 
00077 /*---------------------------------------------------------------------+
00078  |                                                                     |
00079  |          P O L I C Y    C H E C K I N G    C L A S S E S            |
00080  |                                                                     |
00081  *---------------------------------------------------------------------*/
00082 
00083 /**
00084  * @ingroup DS_IMG
00085  *
00086  * @class GenImage_NoCheck GenImage.H
00087  *
00088  * @brief No-check policy.
00089  *
00090  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Jan Rendek">Jan Rendek</a>
00091  * @date   November 5, 2003  7:47
00092  * @since Qgar 2.1.1
00093  */
00094 template<typename T> class GenImage_NoCheck
00095 {
00096 // -------------------------------------------------------------------
00097 // P U B L I C   M E M B E R S
00098 // -------------------------------------------------------------------
00099 public:
00100 
00101 /**
00102  * @brief Check a range.
00103  *
00104  * @param aPPixmap  a pointer to the pixel map of an image
00105  * @param aWidth
00106  * @param aRange
00107  *
00108  * @exception qgar::QgarErrorDomain (pixel value out of range)
00109  */
00110 void checkRange(const T* const aPPixmap,
00111                 int aWidth, 
00112                 const BoundingBox& aRange) const
00113 {
00114   // VOID
00115 }
00116 
00117 // -------------------------------------------------------------------
00118 }; // class GenImage_NoCheck
00119 
00120 
00121 
00122 
00123 /**
00124  * @ingroup DS_IMG
00125  *
00126  * @class GenImage_BoundCheck GenImage.H "qgarlib/GenImage_BoundCheck.H"
00127  *
00128  * @brief Policy to check bounds of pixel values.
00129  *
00130  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Jan Rendek">Jan Rendek</a>
00131  * @date   November 5, 2003  7:47
00132  * @since Qgar 2.1.1
00133  */
00134 template <typename T>
00135 class GenImage_BoundCheck
00136 {
00137 // -------------------------------------------------------------------
00138 // P U B L I C   M E M B E R S
00139 // -------------------------------------------------------------------
00140 public:
00141 
00142 /** @name Constructors */
00143 //        ============
00144 //@{
00145 
00146 /**
00147  * @brief Default constructor.
00148  *
00149  * Lower and upper bounds are intialized to zero.
00150  */
00151 GenImage_BoundCheck()
00152 
00153  : _lowerBound(0),
00154    _upperBound(0)
00155 
00156 {
00157   // VOID
00158 }
00159 
00160 /**
00161  * @brief Construct from bounds.
00162  *
00163  * @param aLowerBnd    lower bound
00164  * @param anUpperBnd   upper bound
00165  */
00166 GenImage_BoundCheck(T aLowerBnd, T anUpperBnd)
00167 
00168   : _lowerBound(aLowerBnd),
00169     _upperBound(anUpperBnd)
00170 
00171 {
00172   // VOID
00173 }
00174 
00175 //@}
00176 
00177 
00178 /** @name Checking */
00179 //        ========
00180 //@{
00181 
00182 /**
00183  * @brief Check that a pixel value is between the bounds.
00184  *
00185  * @param aPixel  a pixel value
00186  *
00187  * @exception qgar::QgarErrorDomain (pixel value out of range)
00188  */
00189 void
00190 checkPixel(const T& aPixel) const
00191 
00192   throw (QgarErrorDomain)
00193 
00194 {
00195   if ((aPixel < _lowerBound) || (aPixel > _upperBound))
00196     { 
00197       std::ostringstream os;
00198       os << "Pixel value out of range: "
00199          << aPixel;
00200 
00201       throw QgarErrorDomain(__FILE__, __LINE__,
00202                             "template <typename T> void qgar::GenImage_BoundCheck::checkPixel(const T&) const",
00203                             os.str());
00204     }
00205 }
00206 
00207 /**
00208  * @brief Check that all the pixel values  is between the bounds.
00209  *
00210  * @param aPPixmap  a pointer to the pixel map of an image
00211  * @param aWidth
00212  * @param aRange
00213  *
00214  * @exception qgar::QgarErrorDomain (pixel value out of range)
00215  */
00216 void checkRange(const T* const aPPixmap,
00217                 int aWidth, 
00218                 const BoundingBox& aRange) const throw (QgarErrorDomain)
00219 {
00220   for (int iCnt = aRange.xTopLeft() ; iCnt < aRange.width() ; ++iCnt)
00221     {
00222       for (int jCnt = aRange.yTopLeft() ; jCnt < aRange.height() ; ++jCnt)
00223         {
00224           checkPixel(aPPixmap[(iCnt * aWidth) + jCnt]);
00225         }
00226     }
00227 }
00228 
00229 //@}
00230 
00231 
00232 /** @name Accessor */
00233 //        ========
00234 //@{
00235 
00236 /**
00237  * @brief Get lower bound.
00238  */
00239 T lowerBound() const
00240 {
00241   return _lowerBound;
00242 }
00243 
00244 /**
00245  * @brief Get upper bound.
00246  */
00247 T upperBound() const
00248 {
00249   return _upperBound;
00250 }
00251 
00252 //@}
00253 
00254 
00255 /** @name Mutator */
00256 //        =======
00257 //@{
00258 
00259 /**
00260  * @brief Set lower bound.
00261  *
00262  * @param aBound  new value of the lower bound
00263  */
00264 void setLowerBound(const T& aBound)
00265 {
00266   _lowerBound = aBound;
00267 }
00268 
00269 /**
00270  * @brief Set upper bound.
00271  *
00272  * @param aBound  new value of the upper bound
00273  */
00274 void setUpperBound(const T& aBound)
00275 {
00276   _upperBound = aBound;
00277 }
00278 
00279 //@}
00280 
00281 
00282 // -------------------------------------------------------------------
00283 // P R I V A T E   M E M B E R S
00284 // -------------------------------------------------------------------
00285 private:
00286 
00287 
00288 /** @name Bounds */
00289 //        ======
00290 //@{
00291 
00292 /**
00293  * @brief Lower bound of pixel value.
00294  */
00295 T _lowerBound;
00296 
00297 /**
00298  * @brief Upper bound of pixel value.
00299  */
00300 T _upperBound;
00301 
00302 //@}
00303 
00304 
00305 // -------------------------------------------------------------------
00306 }; //  class GenImage_BoundCheck
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 /*---------------------------------------------------------------------+
00316  |                                                                     |
00317  |             C  L  A  S  S       G  E  N  I  M  A  G  E              |
00318  |                                                                     |
00319  *---------------------------------------------------------------------*/
00320 
00321 /**
00322  * @ingroup DS_IMG
00323  *
00324  * @class GenImage GenImage.H "qgarlib/GenImage.H"
00325  *
00326  * @brief Template class for a generic image with pixels of type <b>T</b>.
00327  *
00328  * <ul>
00329  * <li>
00330  * Such an image is stored as <b>consecutive rows</b> im memory space.
00331  * </li>
00332  * <li>
00333  * The origin of the coordinate system is at top left corner of the
00334  * image.
00335 @verbatim
00336    O
00337     +---------------->  X
00338     |
00339     |
00340     |
00341     V
00342 
00343     Y
00344 @endverbatim
00345  * </li>
00346  * </ul>
00347  *
00348  * Predefined types:
00349  * - qgar::BinaryImage
00350  * - qgar::GreyLevelImage
00351  * - qgar::IntImage
00352  * - qgar::FloatImage
00353  * - qgar::DoubleImage
00354  *
00355  * The implementation code uses some of Scott Meyers' tips from
00356  * [<a href="Bibliography.html#Meyer-1996">Meyer,&nbsp;1996</a>].
00357  * See especially item #20, pages 101-104,
00358  * about the return value optimization (RVO).
00359  *
00360  * @warning
00361  * The following operators and functions are <b>not normalized</b>:
00362  * - qgar::GenImage::operator+
00363  * - qgar::GenImage::operator-
00364  * - qgar::GenImage::operator*
00365  * - qgar::GenImage::operator+=
00366  * - qgar::GenImage::operator-=
00367  * - qgar::GenImage::operator*=
00368  * - qgar::GenImage::plus
00369  * - qgar::GenImage::minus
00370  * - qgar::GenImage::times
00371  * - qgar::GenImage::plusEqual
00372  * - qgar::GenImage::minusEqual
00373  * - qgar::GenImage::timesEqual
00374  *
00375  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00376  * @date   March 4, 2003  14:09
00377  * @since  Qgar 2.1
00378  */
00379 template 
00380 <
00381   class T, 
00382   template<class> class CheckPolicy = GenImage_NoCheck 
00383 >
00384 class GenImage
00385 
00386   : public CheckPolicy<T>
00387 
00388 {
00389 // -------------------------------------------------------------------
00390 // T Y P E   D E F I N I T I O N S
00391 // -------------------------------------------------------------------
00392 public:
00393 
00394 
00395   /** @name Types */
00396   //        =====
00397   //@{
00398 
00399   /**
00400    * @brief Type of the elements stored in the pixel map.
00401    */
00402   typedef T value_type;
00403 
00404   /**
00405    * @brief Reference to qgar::GenImage::value_type.
00406    */
00407   typedef value_type& reference;
00408 
00409   /**
00410    * @brief Constant reference to qgar::GenImage::value_type.
00411    */
00412   typedef const value_type& const_reference;
00413 
00414   /**
00415    * @brief Pointer to qgar::GenImage::value_type.
00416    */
00417   typedef value_type* pointer;
00418 
00419   /**
00420    * @brief Constant pointer to qgar::GenImage::value_type.
00421    */
00422   typedef const value_type* const_pointer;
00423 
00424   //@}
00425 
00426 
00427 // -------------------------------------------------------------------
00428 // P U B L I C    M E M B E R S
00429 // -------------------------------------------------------------------
00430 public:
00431 
00432 
00433   /** @name Constructors */
00434   //        ============
00435   //@{
00436 
00437   /**
00438    * @brief Default constructor.
00439    *
00440    * Set <b>0</b> to width, to height,
00441    * to pointer to pixel map, and to reference counter.
00442    */
00443   GenImage();
00444 
00445   /**
00446    * @brief Initialize with given width and height.
00447    *
00448    * @param aWidth   width of the image (in pixels)
00449    * @param aHeight  height of the image (in pixels)
00450    *
00451    * @warning The pixel map is allocated but is not initialized.
00452    */
00453   GenImage(unsigned int aWidth, unsigned int aHeight);
00454  
00455   //@}
00456 
00457 
00458   /** @name Constructor from raw data */
00459   //        =========================
00460   //@{
00461 
00462   /**
00463    * @brief Initialize from a pixmap.
00464    *
00465    * @param aWidth     width of the image (in pixels)
00466    * @param aHeight    height of the image (in pixels)
00467    * @param aPtPixMap  pointer to a pixel map
00468    *
00469    * @warning
00470    * <b>This constructor takes the ownership of the given pixmap.
00471    * The created instance will be responsible for deleting it</b>.
00472    *
00473    * @exception qgar::QgarErrorInvalidArg (pixel map not allocated)
00474    */
00475   GenImage(unsigned int aWidth,
00476            unsigned int aHeight,
00477            pointer aPtPixMap)
00478     throw(QgarErrorInvalidArg);
00479 
00480   //@}
00481 
00482 
00483   /** @name Constructors from images */
00484   //        ========================
00485   //@{
00486 
00487   /**
00488    * @brief Copy constructor.
00489    *
00490    * Perform a <b>deep copy</b>: The pixel map of the source
00491    * image is duplicated.
00492    *
00493    * @param anImg image to be copied
00494    *
00495    * @see qgar::GenImage::operator= and qgar::GenImage::shallowCopy
00496    */
00497   GenImage(const GenImage& anImg);
00498 
00499   /**
00500    * @brief Conversion of an image of the same type, using policies.
00501    *
00502    * @param anImg  an image with the same pixel type
00503    *               <b>having different policies</b>
00504    */
00505   template<template <class> class OtherCheckPolicy>
00506   GenImage(const GenImage<value_type, OtherCheckPolicy>& anImg);
00507 
00508   /**
00509    * @brief Initialize from an image with pixels
00510    *        of a type different from <b>T</b>.
00511    *
00512    * @param anImg an image with pixels of type <b>U</b>
00513    *        (different from <b>T</b>)
00514    *
00515    * @warning Perform a <b>deep copy</b>: The pixel map of the source
00516    * image is duplicated.
00517    * This kind of conversion must be explicitely specified by the client.
00518    */
00519   template<class U,template<class> class UCheckPolicy> 
00520   explicit GenImage(const GenImage<U, UCheckPolicy>& anImg);
00521 
00522   /**
00523    * @brief Initialize by copying a rectangular area, defined by a bounding
00524    *        box, of a given image.
00525    *
00526    * The rectangle sides are parallel to the coordinate axis.
00527    *
00528    * @param anImg    initial image
00529    * @param aBox     box defining the rectangular area to copy
00530    * @param aPixVal  pixel value to fill non-overlaping zones
00531    *                 (default <b>(T)0</b>)
00532    *
00533    * @warning The intersection between the rectangle and the given image must
00534    * be non-empty. If the overlaping zone is only partial, the non-overlaping
00535    * zone(s) are filled with pixels having value <b>aPixVal</b>.
00536    */
00537   template<template<class> class OtherCheckPolicy>
00538   GenImage(const GenImage<value_type,OtherCheckPolicy>& anImg,
00539            const BoundingBox& aBox,
00540            value_type aPixVal = static_cast<value_type>(0));
00541 
00542   /**
00543    * @brief Initialize by copying a rectangular area, defined by the
00544    * coordinates of its top left and bottom right corners, of a given image.
00545    *
00546    * The rectangle sides are parallel to the coordinate axis.
00547    *
00548    * @param anImg          initial image
00549    * @param aXTopLeft      X coordinate of the area top left corner
00550    * @param aYTopLeft      Y coordinate of the area top left corner
00551    * @param aXBottomRight  X coordinate of the area bottom right corner
00552    * @param aYBottomRight  Y coordinate of the area bottom right corner
00553    * @param aPixVal        pixel value to fill non-overlaping zones
00554    *                       (default <b>(T)0</b>)
00555    *
00556    * @warning The intersection between the rectangle and the given image must
00557    * be non-empty. If the overlaping zone is only partial, the non-overlaping
00558    * zone(s) are filled with pixels having value <b>aPixVal</b>.
00559    */
00560   template<template<class> class OtherCheckPolicy>
00561   GenImage(const GenImage<value_type, OtherCheckPolicy>& anImg,
00562            unsigned int aXTopLeft,
00563            unsigned int aYTopLeft,
00564            unsigned int aXBottomRight,
00565            unsigned int aYBottomRight,
00566            value_type aPixVal = static_cast<value_type>(0));
00567 
00568   //@}
00569 
00570 
00571   /** @name Constructors from image files */
00572   //        =============================
00573   //@{
00574 
00575   /**
00576    * @brief Initialize with an image in a PBM+ file.
00577    *
00578    * The given PBM+ file is opened (in READ ONLY mode) at the call,
00579    * and closed before returning.
00580    *
00581    * @param aPbmPlusFile  a PBM+ file containing an image
00582    *
00583    * @warning This kind of conversion must be explicitely
00584    *   specified by the client.
00585    *
00586    * @todo Constructor qgar::GenImage::GenImage(AbstractPbmPlusFile&)
00587    * should just work when <b>T</b> is instantiated by an unsigned char
00588    * because function qgar::AbstractPbmPlusFile::readRow only works
00589    * with rows of unsigned integers whereas the first argument of
00590    * function qgar::GenImage::setRow is a pointer to a row of
00591    * type <b>T</b>!
00592    */
00593   explicit GenImage(AbstractPbmPlusFile& aPbmPlusFile);
00594 
00595   //@}
00596 
00597 
00598   /** @name Destructor */
00599   //        ==========
00600   //@{
00601 
00602   /**
00603    * @brief Free space allocated to the pixel map
00604    * if and only if the reference counter is null.
00605    */
00606   virtual ~GenImage();
00607 
00608   //@}
00609 
00610 
00611   /** @name Access to image characteristics */
00612   //        ===============================
00613   //@{
00614 
00615   /**
00616    * @brief Get the image width.
00617    */
00618   inline int width() const;
00619 
00620   /**
00621    * @brief Get the image height.
00622    */
00623   inline int height() const;
00624   
00625   /**
00626    * @brief Get the number of bytes per pixel.
00627    */
00628   inline int bytesPerPixel() const;
00629 
00630   //@}
00631 
00632 
00633   /** @name Access to pixel values */
00634   //        ======================
00635   //@{
00636 
00637   /**
00638    * @brief Get a pixel value.
00639    *
00640    * @param aX  X coordinate (column index) of the pixel
00641    * @param aY  Y coordinate (row index) of the pixel
00642    */
00643   value_type pixel(unsigned int aX, unsigned int aY) const;
00644 
00645   /**
00646    * @brief Get a row of pixels.
00647    *
00648    * @param aRowIdx  row index in image
00649    * @param aRow     buffer to store the row of pixels
00650    *
00651    * @warning The behavior of the function is undefined
00652    * if the buffer size is smaller than the row size.
00653    */
00654   void row(unsigned int aRowIdx, pointer aRow) const;
00655 
00656   /**
00657    * @brief Get a column of pixels.
00658    *
00659    * @param aColIdx  column index in image
00660    * @param aCol     buffer to store the column of pixels
00661    *
00662    * @warning The behavior of the function is undefined
00663    * if the buffer size is smaller than the column size.
00664    */
00665   void column(unsigned int aColIdx, pointer aCol) const;
00666 
00667   //@}
00668 
00669 
00670   /** @name Access to direct transformations of the pixel map */
00671   //        =================================================
00672   //@{
00673 
00674   /**
00675    * @brief Get a pointer on a given pixel of the image
00676    *
00677    * @param aRowIdx  row index of the pixel
00678    * @param aColIdx  column index of the pixel
00679    */
00680   inline pointer pPixel(unsigned int aRowIdx, unsigned int aColIdx) const;
00681 
00682   /**
00683    * @brief Get a pointer on a row of pixels.
00684    *
00685    * @param aRowIdx  row index in image
00686    */
00687   inline pointer pRow(unsigned int aRowIdx) const;
00688 
00689   /**
00690    * @brief Get a pointer on a column of pixels.
00691    *
00692    * @param aColIdx  column index in image
00693    */
00694   inline pointer pColumn(unsigned int aColIdx) const;
00695 
00696   /**
00697    * @brief Get the pointer to the pixel map.
00698    */
00699   inline pointer pPixMap() const;
00700 
00701   //@}
00702 
00703 
00704   /** @name Set pixel values */
00705   //        ================
00706   //@{
00707 
00708   /**
00709    * @brief Set a pixel value.
00710    *
00711    * @param aX       X coordinate (column index) of the pixel
00712    * @param aY       Y coordinate (row index) of the pixel
00713    * @param aPixVal  value of the pixel
00714    */
00715   void setPixel(unsigned int aX, unsigned int aY, value_type aPixVal);
00716 
00717   /**
00718    * @brief Set a given row of pixels.
00719    *
00720    * @param aRowIdx   row index in image
00721    * @param aRow      row of pixels to store into the pixel map
00722    */
00723   void setRow(unsigned int aRowIdx, const_pointer const aRow);
00724 
00725   /**
00726    * @brief Set a given column of pixels.
00727    *
00728    * @param aColIdx  column index in image
00729    * @param aCol     column of pixels to store into the pixel map
00730    */
00731   void setColumn(unsigned int aColIdx, const_pointer const aCol);
00732 
00733   //@}
00734 
00735 
00736   /** @name Draw in the pixel map */
00737   //        =====================
00738   //@{
00739 
00740   /**
00741    * @brief Draw a segment in the pixel map.
00742    *
00743    * The segment pixels are set using Bresenham's algorithm.
00744    * See <i>W.M. Newman and R.F. Sproull, Principles of Interactive
00745    * Computer Graphics, pp. 25-26.</i>
00746    *
00747    * @param aSeg     segment to be drawn
00748    * @param aPixVal  value to set pixels with (default <b>(T)1</b>)
00749    */
00750   void draw(const Segment& aSeg, value_type aPixVal = (value_type)1);
00751 
00752   //@}
00753 
00754 
00755   /** @name Copy */
00756   //        ====
00757   //@{
00758 
00759   /**
00760    * @brief Shallow copy: The pixel map of the current image
00761    * is <b>not duplicated</b>.
00762    *
00763    * @see qgar::GenImage::operator= and copy constructor.
00764    *
00765    * @warning When the copy is completed, the pixel map of the new image
00766    * is the same memory space as the pixel map of the current image.
00767    */
00768   GenImage shallowCopy();
00769 
00770   //@}
00771 
00772 
00773   // =======================================================================
00774   /** @name Operators
00775 
00776       @warning Using stand-alone versions of operators
00777       (<b>operator+</b>, <b>operator-</b>,
00778       <b>operator*</b>) is much less efficient then using
00779       assignment versions (<b>operator+=</b>, <b>operator-=</b>,
00780       <b>operator*=</b>). For example, an expression like:
00781 @verbatim
00782     res = a + b - c;
00783 @endverbatim
00784       uses 2 temporary objects, one for each call to <b>operator+</b>
00785       and <b>operator-</b>(the pixel map of the last temporary object
00786       is then copied into the pixel map of <b>res</b>). These
00787       considerations also apply to functional operators (see the
00788       corresponding section). To preserve efficiency, the code should be
00789       written in this way:
00790 @verbatim
00791     res = a;
00792     res += b;  // no temporary needed
00793     res -= c;  // no temporary needed
00794 @endverbatim
00795   */
00796   // =======================================================================
00797   //@{
00798 
00799   /**
00800    * @brief Assign given image to current image.
00801    *
00802    * The current image must have the same dimensions as the given image.
00803    * The pixel map of the given image is copied into the pixel map of the
00804    * current image.
00805    *
00806    * @param anImg  image to assign to the current image
00807    *
00808    * @see qgar::GenImage::shallowCopy and copy constructor.
00809    *
00810    * @warning Perform a <b>deep copy</b>: The pixel map of the given
00811    * image is duplicated.
00812    */
00813   GenImage& operator=(const GenImage& anImg);
00814 
00815   /**
00816    * @brief Assign given image to current image.
00817    *
00818    * The current image is not supposed to initially have the same
00819    * dimensions as the given image.
00820    *
00821    * @param anImg  image to assign to the current image
00822    *
00823    * @see qgar::GenImage::shallowCopy and copy constructor.
00824    *
00825    * @warning Perform a <b>deep copy</b>: The pixel map of the given
00826    * image is duplicated.
00827    */
00828   template<template <class> class OtherCheckPolicy>
00829   GenImage& operator=(const GenImage<value_type, OtherCheckPolicy>& anImg);
00830 
00831   /**
00832    * @brief Same as function qgar::GenImage::plus.
00833    */
00834   template <template<class> class OtherCheckPolicy>
00835   GenImage<value_type, GenImage_NoCheck>
00836   operator+(const GenImage<value_type, OtherCheckPolicy>& anImg) const;
00837 
00838   /**
00839    * @brief Same as function qgar::GenImage::plusEqual.
00840    */
00841   template <template<class> class OtherCheckPolicy>
00842   GenImage& operator+=(const GenImage<value_type, OtherCheckPolicy>& anImg);
00843 
00844   /**
00845    * @brief Same as function qgar::GenImage::minus.
00846    */
00847   template <template<class> class OtherCheckPolicy>
00848   GenImage <value_type, GenImage_NoCheck>
00849   operator-(const GenImage<value_type, OtherCheckPolicy>& anImg) const;
00850 
00851   /**
00852    * @brief Same as function qgar::GenImage::minusEqual.
00853    */
00854   template <template<class> class OtherCheckPolicy>
00855   GenImage& operator-=(const GenImage<value_type, OtherCheckPolicy>& anImg);
00856 
00857   /**
00858    * @brief Same as function qgar::GenImage::times.
00859    */
00860   template <template<class> class OtherCheckPolicy>
00861   GenImage<value_type, GenImage_NoCheck>
00862   operator*(const GenImage<value_type, OtherCheckPolicy>& anImg) const;
00863 
00864   /**
00865    * @brief Same as function qgar::GenImage::timesEqual.
00866    */
00867   template <template<class> class OtherCheckPolicy>
00868   GenImage& operator*=(const GenImage<value_type, OtherCheckPolicy>& anImg);
00869 
00870   //@}
00871 
00872 
00873   // =====================================================================
00874   /** @name Functional operators
00875 
00876       @warning Using stand-alone versions of these functions
00877       (<b>plus</b>, <b>minus</b>, <b>times</b>) is
00878       much less efficient then using assignment versions
00879       (<b>plusEqual</b>, <b>minusEqual</b>,
00880       <b>timesEqual</b>). For example, an expression like:
00881 @verbatim
00882     res = a.plus(b).minus(c);
00883 @endverbatim
00884       uses 2 temporary objects, one for each call to <b>plusEqual</b>
00885       and <b>minusEqual</b> (the pixel map of the last temporary
00886       object is then copied into the pixel map of <b>res</b>). These
00887       considerations also apply to operators (see the corresponding section).
00888       To preserve efficiency, the code should be written in this way:
00889 @verbatim
00890     res = a;
00891     res.plusEqual(b);   // no temporary needed
00892     res.minusEqual(c);  // no temporary needed
00893 @endverbatim
00894   
00895       Operators implementation uses Scott Meyers' tips from
00896       [<a href="Bibliography.html#Meyer-1996">Meyer,&nbsp;1996</a>]:
00897       item #22, pages 107-110.
00898   */
00899   // =====================================================================
00900   //@{
00901 
00902   /**
00903    * @brief Add each pixel of the given image to the corresponding pixel
00904    * of the current image and store each result in a new pixel map.
00905    *
00906    * @param anImg image to be added to the current image
00907    *
00908    * @return A new image constructed from this new pixel map
00909    *
00910    * @warning Given and current images must have the same width and height.
00911    * The addition is not normalized: Each result is stored in the new
00912    * pixel map without any checking.
00913    */
00914   template<template<class> class OtherCheckPolicy>
00915   GenImage<value_type, GenImage_NoCheck> 
00916   plus(const GenImage<value_type, OtherCheckPolicy>& anImg) const;
00917 
00918   /**
00919    * @brief Add a given image to the current image.
00920    *
00921    * Add each pixel of the given image to the corresponding pixel
00922    * of the current image and store each result in the pixel map
00923    * of the current image.
00924    *
00925    * @param anImg image to be added to the current image
00926    *
00927    * @warning Given and current images must have the same width
00928    * and height. The addition is not normalized: Each result is
00929    * stored in the pixel map of the current image without any checking.
00930    *
00931    * @exception qgar::QgarErrorDomain (image sizes do not match)
00932    */
00933   template<template<class> class OtherCheckPolicy>
00934   GenImage&
00935   plusEqual(const GenImage<value_type, OtherCheckPolicy>& anImg)
00936     throw(QgarErrorDomain);
00937 
00938   /**
00939    * @brief Subtract each pixel of the given image to the corresponding
00940    * pixel of the current image and store each result in a new pixel map.
00941    *
00942    * @return A new image constructed from this new pixel map
00943    *
00944    * @param anImg image to be subtracted to the current image
00945    *
00946    * @warning Given and current images must have the same width and height.
00947    * The subtraction is not normalized: Each result is stored in the new
00948    * pixel map without any checking.
00949    */
00950   template<template<class> class OtherCheckPolicy>
00951   GenImage<value_type, GenImage_NoCheck>
00952   minus(const GenImage<value_type, OtherCheckPolicy>& anImg) const;
00953 
00954   /**
00955    * @brief Subtract a given image to the current image.
00956    * @param anImg image to be subtracted to the current image
00957    *
00958    * Subtract each pixel of the given image to the corresponding pixel
00959    * of the current image and store each result in the pixel map
00960    * of the current image.
00961    *
00962    * @warning Given and current images must have the same width and height.
00963    * The subtraction is not normalized: Each result is stored in the pixel map
00964    * of the current image without any checking.
00965    *
00966    * @exception qgar::QgarErrorDomain (image sizes do not match)
00967    */
00968   template<template<class> class OtherCheckPolicy>
00969   GenImage&
00970   minusEqual(const GenImage<value_type, OtherCheckPolicy>& anImg)
00971     throw(QgarErrorDomain);
00972 
00973   /**
00974    * @brief Multiply each pixel of the given image to the corresponding
00975    * pixel of the current image and store each result in a new pixel map.
00976    *
00977    * @param anImg image to be multiplied by the current image
00978    *
00979    * @return A new image constructed from this new pixel map
00980    *
00981    * @warning Given and current images must have the same width and height.
00982    * The multiplication is not normalized: Each result is stored in the new
00983    * pixel map without any checking.
00984    */
00985   template<template<class> class OtherCheckPolicy>
00986   GenImage<value_type, GenImage_NoCheck>
00987   times(const GenImage<value_type, OtherCheckPolicy>& anImg) const;
00988 
00989   /**
00990    * @brief Multiply a given image by the current image.
00991    *
00992    * Multiply each pixel of the given image by the corresponding pixel
00993    * of the current image and store each result in the pixel map
00994    * of the current image.
00995    *
00996    * @param anImg image to be multiplied by the current image
00997    *
00998    * @warning Given and current images must have the same width and height.
00999    * The multiplication is not normalized: Each result is stored
01000    * in the pixel map of the current image without any checking.
01001    *
01002    * @exception qgar::QgarErrorDomain (image sizes do not match)
01003    */
01004   template<template<class> class OtherCheckPolicy>
01005   GenImage&
01006   timesEqual(const GenImage<value_type, OtherCheckPolicy>& anImg)
01007     throw(QgarErrorDomain);
01008 
01009   //@}
01010 
01011 
01012   /** @name File storage */
01013   //        ============
01014   //@{
01015 
01016   /**
01017    * @brief Store current image into a PBM+ file.
01018    *
01019    * The given PBM+ file is opened (in WRITE ONLY mode) at the call,
01020    * and closed before returning.
01021    *
01022    * @param aPbmPlusFile  a PBM+ file
01023    */
01024   void save(AbstractPbmPlusFile& aPbmPlusFile) const;
01025 
01026   //@}
01027 
01028 
01029   /** @name Border mirroring */
01030   //        ================
01031   //@{
01032 
01033   /**
01034    * @brief Mirror border rows for convolutions.
01035    *
01036    * @param aRowIdx index of the row
01037    */
01038   int borderRows(int aRowIdx) const;
01039   
01040   /**
01041    * @brief Mirror border columns for convolutions.
01042    *
01043    * @param aColIdx index of the column
01044    */
01045   int borderCols(int aColIdx) const;
01046 
01047   //@}
01048 
01049 
01050 // -------------------------------------------------------------------
01051 // P R O T E C T E D    M E M B E R S
01052 // -------------------------------------------------------------------
01053 protected:
01054 
01055 
01056   /** @name Constructor from raw data */
01057   //        =========================
01058   //@{
01059 
01060   /**
01061    * @brief Initialize from all data.
01062    *
01063    * @param aBytesCnt    bytes per pixel
01064    * @param aPtRefCnt    pointer to a reference counter
01065    * @param aWidth       width of the image
01066    * @param aHeight      height of the image
01067    * @param aPtPixMap    pointer to a pixel map
01068    *
01069    * @warning Using this constructor may lead to serious bugs
01070    * due to dynamic memory space management.
01071    * Be sure that the value of the given reference counter (pointed
01072    * by <b>aPtRefCnt</b>) is correct: If the given pixel map 
01073    * (pointed by <b>aPtPixMap</b>) is not shared by another
01074    * object, this value must be <b>0</b>. Otherwise, one must
01075    * add <b>1</b> to the value, before using the constructor:
01076 @verbatim
01077 (*_pRefCnt)++;
01078 @endverbatim   
01079    */
01080   GenImage(unsigned int  aBytesCnt,
01081            int*          aPtRefCnt,
01082            unsigned int  aWidth,
01083            unsigned int  aHeight,
01084            pointer       aPtPixMap);
01085 
01086   //@}
01087 
01088 
01089   /** @name Representation of an image */
01090   //        ==========================
01091   //@{
01092 
01093   /**
01094    * @brief Number of bytes per pixel.
01095    */
01096   unsigned int _bytesPerPixel;
01097 
01098   /**
01099    * @brief Reference counter.
01100    *
01101    * Its value represent the number of other images with which 
01102    * the current image shares its pixel map.
01103    */
01104   int* _pRefCnt;
01105 
01106   /**
01107    * @brief Image width.
01108    */
01109   int _width;
01110 
01111   /**
01112    * @brief Image height.
01113    */
01114   int _height;
01115 
01116   /**
01117    * @brief Pointer to the pixel map,
01118    * organized as <b>consecutive rows</b>.
01119    */
01120   pointer _pPixMap;
01121 
01122   //@}
01123 
01124 
01125   /** @name Auxiliaries */
01126   //        ===========
01127   //@{
01128 
01129   /**
01130    * @brief Copy a rectangular area of the given image
01131    *        into the current image.
01132    *
01133    * The sides of the rectangle are parallel to the coordinate axis.
01134    *
01135    * @param anImg          initial image
01136    * @param aXTopLeft      X coordinate of the area top left corner
01137    * @param aYTopLeft      Y coordinate of the area left corner
01138    * @param aXBottomRight  X coordinate of the area bottom right corner
01139    * @param aYBottomRight  Y coordinate of the area bottom right corner
01140    * @param aPixVal        pixel value to fill non-overlaping zones
01141    *                       (default <b>(T)0</b>)
01142    *
01143    * @warning The intersection between the rectangle and the given image must
01144    * be non-empty. If the overlaping zone is only partial, the non-overlaping
01145    * zone(s) are filled with pixels having value <b>aPixVal</b>.
01146    *
01147    * @todo To be reimplemented.
01148    */
01149   void copyBox(const GenImage<value_type, CheckPolicy>& anImg,
01150                unsigned int aXTopLeft,
01151                unsigned int aYTopLeft,
01152                unsigned int aXBottomRight,
01153                unsigned int aYBottomRight,
01154                value_type aPixVal = static_cast<value_type>(0));
01155 
01156   //@}
01157 
01158 
01159 // -------------------------------------------------------------------
01160 }; // class GenImage
01161 
01162 
01163 } // namespace qgar
01164 
01165 
01166 
01167 
01168 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
01169 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
01170 // I M P L E M E N T A T I O N
01171 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
01172 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
01173 
01174 #include <qgarlib/GenImage.TCC>
01175 
01176 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
01177 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
01178 
01179 
01180 
01181 
01182 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
01183 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
01184 // P R E D E F I N E D    I M A G E    T Y P E S
01185 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
01186 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
01187 
01188 
01189 namespace qgar
01190 {
01191 
01192 
01193 /**
01194  * @name Basic Image Types
01195  * @ingroup DS_IMG
01196  */
01197 //@{
01198 
01199 /**
01200  * @brief Binary image (pixels of type <b>unsigned char</b>).
01201  */
01202 typedef GenImage<unsigned char> BinaryImage;
01203 
01204 /**
01205  * @brief Grey-level Image (pixels of type <b>unsigned char</b>).
01206  */
01207 typedef GenImage<unsigned char> GreyLevelImage;
01208 
01209 /**
01210  * @brief Image with <b>unsigned char</b> pixels.
01211  */
01212 typedef GenImage<unsigned char> UCharImage;
01213 
01214 /**
01215  * @brief Image with <b>int</b> pixels.
01216  */
01217 typedef GenImage<int> IntImage;
01218 
01219 /**
01220  * @brief Images with <b>float</b> pixels.
01221  */
01222 typedef GenImage<float> FloatImage;
01223 
01224 /**
01225  * @brief Images with <b>double</b> pixels.
01226  */
01227 typedef GenImage<double> DoubleImage;
01228 
01229 //@}
01230 
01231 
01232 /**
01233  * @name Bounded Image Types
01234  * @ingroup DS_IMG
01235  */
01236 //@{
01237 
01238 /**
01239  * @brief Bounded Binary Image (pixel of type <b>unsigned int</b>)
01240  */
01241 typedef GenImage<unsigned int, GenImage_BoundCheck> BoundedBinaryImage;
01242 
01243 /**
01244  * @brief Bounded Greylevel Image (pixel of type <b>unsigned int</b>)
01245  */
01246 typedef GenImage<unsigned int, GenImage_BoundCheck> BoundedGreylevelImage;
01247 
01248 /**
01249  * @brief Bounded image with <b>unsigned char</b> pixels.
01250  */
01251 typedef GenImage<unsigned char, GenImage_BoundCheck> BoundedUCharImage;
01252 
01253 /**
01254  * @brief Bounded Image with <b>int</b> pixels.
01255  */
01256 typedef GenImage<int, GenImage_BoundCheck> BoundedIntImage;
01257 
01258 /**
01259  * @brief Bounded Image with <b>float</b> pixels.
01260  */
01261 typedef GenImage<float, GenImage_BoundCheck> BoundedFloatImage;
01262 
01263 /**
01264  * @brief Bounded Image with <b>double</b> pixels.
01265  */
01266 typedef GenImage<double, GenImage_BoundCheck> BoundedDoubleImage;
01267 
01268 //@}
01269 
01270 
01271 } // namespace qgar
01272 
01273 
01274 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
01275 // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
01276 
01277 
01278 #endif /* __GENIMAGE_H_INCLUDED__ */