BitMaskIterator.h

Go to the documentation of this file.
00001 /*
00002  * The information in this file is
00003  * Copyright(c) 2009 Ball Aerospace & Technologies Corporation
00004  * and is subject to the terms and conditions of the
00005  * GNU Lesser General Public License Version 2.1
00006  * The license text is available from   
00007  * http://www.gnu.org/licenses/lgpl.html
00008  */
00009 
00010 #ifndef BITMASKITERATOR_H
00011 #define BITMASKITERATOR_H
00012 
00013 #include "LocationType.h"
00014 
00015 class BitMask;
00016 class RasterElement;
00017 
00018 /**
00019  * Traverses selected pixels within a BitMask.
00020  * This class provides a convenient way to traverse the selected pixels within a
00021  * given area of a BitMask object.  The BitMaskIterator extents can be set to either
00022  * custom values or the extents of a RasterElement.
00023  *  \image html BitMaskIterator.JPG
00024  *  \image html BitMaskIteratorExample1.jpg
00025  *  \image html BitMaskIteratorExample2.jpg
00026  *
00027  * The iterator incorporates the outside flag of the BitMask when determining
00028  * whether a pixel is selected.  The getPixel(int,int) const method is provided to
00029  * query the selected state of any pixel within the extents. A call to getPixel() for
00030  * pixel locations outside the extents of the BitMasKIterator will return false.
00031  *
00032  *  \image html BitMaskIteratorExample3.jpg
00033  *  \image html BitMaskIteratorExample4.jpg
00034  *
00035  * This class is intended to be used in place of directly traversing the
00036  * BitMask.
00037  *
00038  * @warning    The iterator does not assume ownership over the BitMask.  It is
00039  *             intended to be used in place of directly traversing the BitMask.
00040  *             Also for efficiency purposes, this class assumes that the BitMask
00041  *             is valid (i.e. not deleted) throughout the lifetime of the
00042  *             iterator.
00043  */
00044 class BitMaskIterator
00045 {
00046 public:
00047    /**
00048     * Constructs a BitMaskIterator with given extents.
00049     *
00050     * All parameters are zero-based and inclusive.  Upon construction, the iterator's pixel
00051     * location is set to the first selected pixel within the iterator's bounding box (the
00052     * intersection of the iterator extents and the BitMask minimal bounding box). If no pixels within
00053     * the iterator's bounding box are selected, the pixel location is set to (-1, -1), which is
00054     * equivalent to BitMaskIterator::end().
00055     *
00056     * @param   pBitMask
00057     *          The BitMask to traverse. \c NULL is a valid value for the BitMask.
00058     *          Use of a \c NULL BitMask allows algorithms to be designed with
00059     *          a single code path, e.g., BitMaskIterator bit(pAoi, 0, 0, 100, 100) where pAoi can be
00060     *          NULL or a valid pointer.
00061     * @param   x1
00062     *          The first column of the area over which the iterator may operate. The intersection between
00063     *          this area and the BitMask determines the area to be traversed. This
00064     *          value must be non-negative and less than or equal to the maximum value that the int
00065     *          type will support on the platform. This is enforced by setting
00066     *          larger values to that maximum value.
00067     * @param   y1
00068     *          The first row of the area over which the iterator may operate. The intersection between
00069     *          this area and the BitMask determines the area to be traversed. This
00070     *          value must be non-negative and less than or equal to the maximum value that the int
00071     *          type will support on the platform. This is enforced by setting
00072     *          larger values to that maximum value.
00073     * @param   x2
00074     *          The last column of the area over which the iterator may operate. The intersection between
00075     *          this area and the BitMask determines the area to be traversed. This
00076     *          value must be non-negative and less than or equal to the maximum value that the int
00077     *          type will support on the platform. This is enforced by setting
00078     *          larger values to that maximum value.
00079     * @param   y2
00080     *          The last row of the area over which the iterator may operate. The intersection between
00081     *          this area and the BitMask determines the area to be traversed. This
00082     *          value must be non-negative and less than or equal to the maximum value that the int
00083     *          type will support on the platform. This is enforced by setting
00084     *          larger values to that maximum value.
00085     */
00086    BitMaskIterator(const BitMask* pBitMask, unsigned int x1, unsigned int y1,
00087                    unsigned int x2, unsigned int y2);
00088 
00089    /**
00090     * Constructs a BitMaskIterator using the extents from a given RasterElement.
00091     *
00092     * Upon construction, the iterator's pixel location is set to the first selected pixel within
00093     * the iterator's bounding box (the intersection of the iterator extents and the BitMask minimal
00094     * bounding box). If no pixels within the iterator's bounding box are selected, the pixel location
00095     * is set to (-1, -1), which is equivalent to BitMaskIterator::end().
00096     *
00097     * @param   pBitMask
00098     *          The BitMask to traverse. \c NULL is a valid value for the BitMask.
00099     *          Use of a \c NULL BitMask allows algorithms to be designed with
00100     *          a single code path, e.g., BitMaskIterator bit(pAoi, pRaster) where pAoi can be NULL or a valid pointer.
00101     * @param   pRasterElement
00102     *          The RasterElement supplying the extents that will define the area over which the iterator may operate.
00103     *          The extents are defined by the number of rows and columns in the
00104     *          RasterElement, i.e., (0, 0) to (num cols - 1, num rows - 1).  %Any offset to other elements is ignored.
00105     */
00106    BitMaskIterator(const BitMask* pBitMask, const RasterElement* pRasterElement);
00107 
00108    /**
00109     * Resets the pixel location to the first pixel.
00110     *
00111     * This method re-initializes the state of the BitMaskIterator to point at
00112     * the first selected pixel of the BitMask within the extents provided when
00113     * the iterator was constructed (the iterator's bounding box).
00114     *
00115     * @see     nextPixel()
00116     */
00117    void firstPixel();
00118 
00119    /**
00120     * Gets the number of selected pixels.
00121     *
00122     * To get the number of selected pixels, this method must iterate over the
00123     * entire extents, which may be slow based on the size of the extents.  After
00124     * this method is called once, the selected pixel count is stored internally,
00125     * so subsequent calls to getCount() are much faster.
00126     *
00127     * @return  Returns the number of selected pixels within the extents.
00128     */
00129    int getCount() const;
00130 
00131    /**
00132     * Queries whether a given pixel is selected.
00133     *
00134     * @param   col
00135     *          The zero-based column number of the pixel to query.
00136     * @param   row
00137     *          The zero-based row number of the pixel to query.
00138     *
00139     * @return  Returns \c true if the given pixel is selected or if the BitMask is \c NULL
00140     *          and the pixel is contained within the iterator's extents; otherwise returns \c false.
00141     *          Also returns \c false if the given pixel is outside the iterator's extents.
00142     *
00143     * @see     getPixelLocation()
00144     */
00145    bool getPixel(int col, int row) const;
00146 
00147    /**
00148     * Gets the current pixel location.
00149     *
00150     * @param   pixelLocation
00151     *          Populated with the current pixel location.  When an iterator is
00152     *          constructed, its pixel location is the first selected pixel. If
00153     *          no pixels are selected, the pixel location is (-1, -1),
00154     *          which is equivalent to BitMaskIterator::end().
00155     */
00156    void getPixelLocation(LocationType& pixelLocation) const;
00157 
00158    /**
00159     * Gets the bounding box over which the iterator iterates.
00160     *
00161     * If the outside flag in the underlying BitMask is on, this method populates
00162     * the given parameters with the iterator extents set in the constructor.  All
00163     * parameter values are zero-based and inclusive.
00164     *
00165     * @param   x1
00166     *          The starting column for iteration.
00167     * @param   y1
00168     *          The starting row for iteration.
00169     * @param   x2
00170     *          The ending column for iteration.
00171     * @param   y2
00172     *          The ending row for iteration.
00173     *
00174     * @see     getNumSelectedRows() getNumSelectedColumns()
00175     */
00176    void getBoundingBox(int& x1, int& y1, int& x2, int& y2) const;
00177 
00178    /**
00179     * Advances the pixel location to the next selected pixel.
00180     *
00181     * If there are no more selected pixels within the extents, the state of the
00182     * iterator is equivalent to BitMaskIterator::end().
00183     *
00184     * @see     operator++(), operator++(int)
00185     */
00186    void nextPixel();
00187 
00188    /**
00189     * Advances the pixel location to the next selected pixel. This overloads the prefix increment operator.
00190     *
00191     * @return  Returns \c true if the iterator advanced to the next selected
00192     *          pixel or the BitMask is \c NULL and the pixel is contained within the extents of the iterator.
00193     *          If there are no more selected pixels within the iterator extents, the state of the
00194     *          iterator is equivalent to BitMaskIterator::end() and \c false is returned.
00195     *
00196     * @see     nextPixel(), operator++(int)
00197     */
00198    bool operator++();
00199 
00200    /**
00201     * Advances the pixel location to the next selected pixel. This overloads the postfix increment operator.
00202     * A dummy parameter is used to differentiate between the signatures of the postfix (var++) operator
00203     * and the prefix (++var) operator.
00204     *
00205     * @return  Returns \c true if the iterator advanced to the next selected
00206     *          pixel or the BitMask is \c NULL and the pixel is contained within the extents of the iterator.
00207     *          If there are no more selected pixels within the iterator extents, the state of the
00208     *          iterator is equivalent to BitMaskIterator::end() and \c false is returned.
00209     *
00210     * @see     nextPixel(), operator++()
00211     */
00212    bool operator++(int);
00213 
00214    /**
00215     * Creates an iterator that is ready to start traversing the BitMask.
00216     *
00217     * @return  Returns a valid iterator with the conditions set to the initial
00218     *          conditions of this iterator.
00219     */
00220    BitMaskIterator begin();
00221 
00222    /**
00223     * Creates an iterator that has finished traversing the BitMask.
00224     *
00225     * @return  Returns an invalid iterator with invalid conditions to represent an iterator
00226     *          that has finished traversing the BitMask.
00227     */
00228    BitMaskIterator end();
00229 
00230    /**
00231    * Gets the number of rows contained within the intersection of the iterator extents and the minimal
00232    * bounding box for the BitMask selected pixels. If the BitMask Outside flag is set, this will be equal
00233    * to the number of rows in the iterator extents.
00234     *
00235     * @return  Returns the number of rows spanning the range of the BitMaskIterator bounding box.
00236     *
00237     * @see     getBoundingBox()
00238     */
00239    int getNumSelectedRows() const;
00240 
00241    /**
00242     * Gets the number of columns contained within the intersection of the iterator extents and the minimal
00243     * bounding box for the BitMask selected pixels. If the BitMask Outside flag is set, this will be equal
00244     * to the number of columns in the iterator extents.
00245     *
00246     * @return  Returns the number of columns spanning the range of the BitMaskIterator bounding box.
00247     *
00248     * @see     getBoundingBox()
00249     */
00250    int getNumSelectedColumns() const;
00251 
00252    /**
00253     * Gets the distance in pixels from the beginning of the iterator extents to the start of the iterator bounding box.
00254     * For an unrotated, rectangular BitMap, it will be the distance between the beginning of the iterator extents
00255     * and the first selected pixel in the BitMask.
00256     *
00257     * @return  Returns the offset in (column, row) coordinates from the beginning of the iterator
00258     *          extents to the start of the iterator bounding box. A default constructed
00259     *          LocationType indicating no offset is returned in the following cases:
00260     *             - The BitMask is \c NULL.
00261     *             - The method BitMask::isOutsideSelected() returns \c true.
00262     *
00263     * @see     getBoundingBox()
00264     */
00265    LocationType getOffset() const;
00266 
00267    /**
00268     * Determines if the iterator will iterate over every every pixel within the iterator extents, i.e., every pixel
00269     * within the iterator extends is selected.
00270     *
00271     * @return  Returns \c true if every pixel within the iterator extents is selected; otherwise
00272     *          returns \c false.
00273     *
00274     * @see     getBoundingBox()
00275     */
00276    bool useAllPixels() const;
00277 
00278    /**
00279     * Queries whether the current pixel is selected.
00280     *
00281     * @return  Returns \c true if the current pixel is selected or the BitMask is \c NULL
00282     *           and the pixel is contained within the iterator extents; otherwise returns \c false.
00283     *
00284     * @see     getPixel(int,int) const
00285     */
00286    bool operator*() const;
00287 
00288    /**
00289     * Compares the position of this iterator with that of another.
00290     *
00291     * @param   other
00292     *          The iterator with which to compare its position.
00293     *
00294     * @return  Returns \c true if the position of the given iterator matches
00295     *          the position of this iterator; otherwise returns \c false.
00296     *
00297     * @see     operator!=()
00298     */
00299    bool operator==(const BitMaskIterator& other) const;
00300 
00301    /**
00302     * Compares the position of this iterator with that of another.
00303     *
00304     * @param   other
00305     *          The iterator with which to compare its position.
00306     *
00307     * @return  Returns \c true if the position of the given iterator does not
00308     *          match the position of this iterator; otherwise returns \c false.
00309     *
00310     * @see     operator==()
00311     */
00312    bool operator!=(const BitMaskIterator& other) const;
00313 
00314    /**
00315     * Gets the number of rows contained within the full extents of the iterator. This method just returns
00316     * either the number of rows in the extents passed to the constructor or the number of rows in the
00317     * raster element passed to the constructor. It should not be used in iterating over the BitMask passed
00318     * to the constructor. Use getNumSelectedRows() instead.
00319     *
00320     * @return  Returns the number of rows within the iterator extents.
00321     *
00322     * @see     getNumSelectedRows(), getNumSelectedColumns()
00323     */
00324    int getNumRows() const;
00325 
00326    /**
00327     * Gets the number of columns contained within the full extents of the iterator. This method just returns
00328     * either the number of columns in the extents passed to the constructor or the number of columns in the
00329     * raster element passed to the constructor. It should not be used in iterating over the BitMask passed
00330     * to the constructor. Use getNumSelectedColumns() instead.
00331     *
00332     * @return  Returns the number of columns within the iterator extents.
00333     *
00334     * @see     getNumSelectedRows(), getNumSelectedColumns()
00335     */
00336    int getNumColumns() const;
00337 
00338    /**
00339     * Gets the starting row in pixel coordinates of the bounding box over which the iterator iterates.
00340     *
00341     * @return  Returns the starting row for iteration.  This will be the number in pixel
00342     *          coordinates of the first row in the iterator bounding box if the Outside flag in
00343     *          the underlying BitMask is off. If the Outside flag is on, this method returns
00344     *          the number of the first row in the full extents of the iterator.
00345     *          The return value is zero-based and inclusive.
00346     *
00347     * @see     getBoundingBox(), getBoundingBoxStartColumn()
00348     */
00349    int getBoundingBoxStartRow() const;
00350 
00351    /**
00352     * Gets the starting column in pixel coordinates of the bounding box over which the iterator iterates.
00353     *
00354     * @return  Returns the starting column for iteration.  This will be the number in pixel
00355     *          coordinates of the first column in the iterator bounding box if the Outside flag in
00356     *          the underlying BitMask is off. If the Outside flag is on, this method returns
00357     *          the number of the first column in the full extents of the iterator.
00358     *          The return value is zero-based and inclusive.
00359     *
00360     * @see     getBoundingBox(), getBoundingBoxStartRow()
00361     */
00362    int getBoundingBoxStartColumn() const;
00363 
00364    /**
00365     * Gets the ending row in pixel coordinates of the bounding box over which the iterator iterates.
00366     *
00367     * @return  Returns the ending row for iteration.  This will be the number in pixel
00368     *          coordinates of the last row in the iterator bounding box if the Outside flag in
00369     *          the underlying BitMask is off. If the Outside flag is on, this method returns
00370     *          the number of the last row in the full extents of the iterator.
00371     *          The return value is zero-based and inclusive.
00372     *
00373     * @see     getBoundingBox(), getBoundingBoxEndColumn()
00374     */
00375    int getBoundingBoxEndRow() const;
00376 
00377    /**
00378     * Gets the ending column in pixel coordinates of the bounding box over which the iterator iterates.
00379     *
00380     * @return  Returns the ending column for iteration.  This will be the number in pixel
00381     *          coordinates of the last column in the iterator bounding box if the Outside flag in
00382     *          the underlying BitMask is off. If the Outside flag is on, this method returns
00383     *          the number of the last column in the full extents of the iterator.
00384     *          The return value is zero-based and inclusive.
00385     *
00386     * @see     getBoundingBox(), getBoundingBoxEndRow()
00387     */
00388    int getBoundingBoxEndColumn() const;
00389 
00390    /**
00391     * Gets the distance in pixels from the beginning of the iterator extents to the first row in
00392     * the iterator bounding box.
00393     *
00394     * @return  Returns the offset in row coordinates from the beginning of the
00395     *          iterator extents to the first row in the iterator bounding box. A value of zero
00396     *          indicating no offset is returned in the following cases:
00397     *             - The BitMask is \c NULL.
00398     *             - The method BitMask::isOutsideSelected() returns \c true.
00399     *
00400     * @see     getOffset(), getColumnOffset()
00401     */
00402    int getRowOffset() const;
00403 
00404    /**
00405     * Gets the distance in pixels from the beginning of the iterator extents to the first column
00406     * in the iterator bounding box.
00407     *
00408     * @return  Returns the offset in column coordinates from the beginning of the
00409     *          iterator extents to the first column in the iterator bounding box. A value of zero
00410     *          indicating no offset is returned in the following cases:
00411     *             - The BitMask is \c NULL.
00412     *             - The method BitMask::isOutsideSelected() returns \c true.
00413     *
00414     * @see     getOffset(), getRowOffset()
00415     */
00416    int getColumnOffset() const;
00417 
00418    /**
00419     * Gets the row of the current pixel.
00420     *
00421     * @return  Returns the row of the current pixel location.  When an iterator is
00422     *          constructed, its pixel row location is the row of the first selected
00423     *          pixel. If no pixels are selected, the pixel row and column are -1,
00424     *          which is equivalent to BitMaskIterator::end().
00425     *
00426     * @see     getPixelColumnLocation()
00427     */
00428    int getPixelRowLocation() const;
00429 
00430    /**
00431     * Gets the column of the current pixel.
00432     *
00433     * @return  Returns the column of the current pixel location.  When an iterator is
00434     *          constructed, its pixel column location is the column of the first selected
00435     *          pixel. If no pixels are selected, the pixel row and column are -1,
00436     *          which is equivalent to BitMaskIterator::end().
00437     *
00438     * @see     getPixelRowLocation()
00439     */
00440    int getPixelColumnLocation() const;
00441 
00442 private:
00443    BitMaskIterator(BitMaskIterator, bool);
00444    bool getPixel() const;
00445    void computeCount();
00446 
00447    const BitMask* mpBitMask;
00448    int mX1;
00449    int mY1;
00450    int mX2;
00451    int mY2;
00452    int mCurrentPixelX; // Begin state = first selected pixel, end state = -1
00453    int mCurrentPixelY; // Begin state = first selected pixel, end state = -1
00454    int mFirstPixelX;
00455    int mFirstPixelY;
00456    unsigned int mCurrentPixelCount;
00457    int mPixelCount;
00458    int mMinX;
00459    int mMinY;
00460    int mMaxX;
00461    int mMaxY;
00462 };
00463 
00464 #endif

Software Development Kit - Opticks 4.9.0 Build 16218