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, 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, 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__ */