Logo Search packages:      
Sourcecode: gamera version File versions  Download package

pixelneighborhood.hxx

/************************************************************************/
/*                                                                      */
/*          Copyright 1998-2005 by Hans Meine, Ullrich Koethe           */
/*       Cognitive Systems Group, University of Hamburg, Germany        */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    ( Version 1.6.0, Aug 13 2008 )                                    */
/*    The VIGRA Website is                                              */
/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
/*    Please direct questions, bug reports, and contributions to        */
/*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
/*        vigra@informatik.uni-hamburg.de                               */
/*                                                                      */
/*    Permission is hereby granted, free of charge, to any person       */
/*    obtaining a copy of this software and associated documentation    */
/*    files (the "Software"), to deal in the Software without           */
/*    restriction, including without limitation the rights to use,      */
/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
/*    sell copies of the Software, and to permit persons to whom the    */
/*    Software is furnished to do so, subject to the following          */
/*    conditions:                                                       */
/*                                                                      */
/*    The above copyright notice and this permission notice shall be    */
/*    included in all copies or substantial portions of the             */
/*    Software.                                                         */
/*                                                                      */
/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
/*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
/*                                                                      */
/************************************************************************/

#ifndef VIGRA_PIXELNEIGHBORHOOD_HXX
#define VIGRA_PIXELNEIGHBORHOOD_HXX

#include "utilities.hxx"

namespace vigra {

/** \addtogroup PixelNeighborhood Utilities to manage pixel neighborhoods

    4- and 8-neighborhood definitions and circulators.

    <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>

    <b>See also:</b> \ref vigra::NeighborhoodCirculator
 */
//@{

/********************************************************/
/*                                                      */
/*                      AtImageBorder                   */
/*                                                      */
/********************************************************/

/** \brief Encode whether a point is near the image border.

    This enum is used with \ref isAtImageBorder() and
    \ref vigra::RestrictedNeighborhoodCirculator.

    <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
    Namespace: vigra
*/

00070 enum AtImageBorder
{
00072         NotAtBorder       = 0,     ///< &nbsp;
00073         RightBorder       = 1,     ///< &nbsp;
00074         LeftBorder        = 2,     ///< &nbsp;
00075         TopBorder         = 4,     ///< &nbsp;
00076         BottomBorder      = 8,     ///< &nbsp;
00077         FrontBorder       = 16,    ///< &nbsp;
        RearBorder        = 32,
        TopRightBorder    = TopBorder    | RightBorder,   //5
        TopLeftBorder     = TopBorder    | LeftBorder,    //6
        TopFrontBorder    = TopBorder    | FrontBorder,   //20
        TopRearBorder     = TopBorder    | RearBorder,    //36
        BottomLeftBorder  = BottomBorder | LeftBorder,    //10
        BottomRightBorder = BottomBorder | RightBorder,   //9
        BottomFrontBorder = BottomBorder | FrontBorder,   //24
        BottomRearBorder  = BottomBorder | RearBorder,    //40
        FrontLeftBorder   = FrontBorder  | LeftBorder,    //18
        FrontRightBorder  = FrontBorder  | RightBorder,   //17
        RearLeftBorder    = RearBorder   | LeftBorder,    //34
        RearRightBorder   = RearBorder   | RightBorder,   //33
        
        TopRightFrontBorder    = TopBorder    | RightBorder | FrontBorder,    //21
        TopLeftFrontBorder     = TopBorder    | LeftBorder  | FrontBorder,    //22
        BottomLeftFrontBorder  = BottomBorder | LeftBorder  | FrontBorder,    //26
        BottomRightFrontBorder = BottomBorder | RightBorder | FrontBorder,    //25
        TopRightRearBorder     = TopBorder    | RightBorder | RearBorder,     //37
        TopLeftRearBorder      = TopBorder    | LeftBorder  | RearBorder,     //38
        BottomLeftRearBorder   = BottomBorder | LeftBorder  | RearBorder,     //42
        BottomRightRearBorder  = BottomBorder | RightBorder | RearBorder      //41
};


/** \brief Find out whether a point is at the image border.

    This function checks if \a x == 0 or \a x == \a width - 1 and
    \a y == 0 or \a y == \a height - 1 and returns the appropriate value
    of \ref vigra::AtImageBorder, or zero when the point is not at te image border.
    The behavior of the function is undefined if (x,y) is not inside the image.

    <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
    Namespace: vigra
*/
00113 inline AtImageBorder isAtImageBorder(int x, int y, int width, int height)
{
    return static_cast<AtImageBorder>((x == 0
                                         ? LeftBorder
                                         : x == width-1
                                             ? RightBorder
                                             : NotAtBorder) |
                                       (y == 0
                                         ? TopBorder
                                         : y == height-1
                                             ? BottomBorder
                                             : NotAtBorder));
}

/********************************************************/
/*                                                      */
/*                    FourNeighborhood                  */
/*                                                      */
/********************************************************/

/** Utilities for 4-neighborhood. */
00134 namespace FourNeighborhood
{

/** \brief Encapsulation of direction management for 4-neighborhood.

    This helper class allows the transformation between Freeman chain codes
    (East = 0, North = 1 etc.) and the corresponding Diff2D instances
    and back.

    You can either use the chain codes by explicit qualification:

    \code
    // the following three lines are equivalent
    FourNeighborhood::NeighborCode::Direction d = FourNeighborhood::NeighborCode::East;
    FourNeighborCode::Direction d = FourNeighborCode::East;
    FourNeighborhood::Direction d = FourNeighborhood::East;
    \endcode

    or you can fix 4-neighborhood by importing the entire namespace in
    your function:

    \code
    using namespace FourNeighborhood;

    Direction d = East;
    \endcode

    If you want to pass 4-neighborhood codes as a template parameter, use
    the class FourNeighborhood::NeighborCode.

    <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
    Namespace: vigra::FourNeighborhood
*/
00167 class NeighborCode
{
  public:

    typedef Diff2D difference_type;
    
        /** Freeman direction codes for the 4-neighborhood.
            <tt>East = 0</tt>, <tt>North = 1</tt> etc.
            <tt>DirectionCount</tt> may be used for portable loop termination conditions.
            <tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and last (inclusive)
            neighbors in the causal neighborhood, i.e. in the set of neighbors that have
            already been visited when the image is traversed in scan order.
            <tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the opposite.
        */
00181     enum Direction {
00182         Error = -1,     ///< &nbsp;
00183         East = 0,       ///< &nbsp;
00184         North,          ///< &nbsp;
00185         West,           ///< &nbsp;
00186         South,          ///< &nbsp;
00187         DirectionCount, ///< &nbsp;
00188         CausalFirst = North,     ///< &nbsp;
00189         CausalLast  = West,      ///< &nbsp;
00190         AntiCausalFirst = South, ///< &nbsp;
00191         AntiCausalLast  = East,   ///< &nbsp;
   
        InitialDirection = East,
        OppositeDirPrefix = 1,
        OppositeOffset = West
 };

    static unsigned int directionBit(Direction d)
    {
        static unsigned int b[] = {1 << (East + 1),
                                   1 << (North + 1),
                                   1 << (West + 1),
                                   1 << (South + 1)};
        return b[d];
    };

        /** The number of valid neighbors if the current center is at the image border.
        */
00209     static unsigned int nearBorderDirectionCount(AtImageBorder b)
    {
        static unsigned int c[] = { 4, 3, 3, 0, 3, 2, 2, 0, 3, 2, 2};
        return c[b];
    }

        /** The valid direction codes when the center is at the image border.
            \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
        */
00218     static Direction nearBorderDirections(AtImageBorder b, int index)
    {
        static Direction c[11][4] = {
                { East, North, West, South},
                { North, West, South, Error},
                { East, North, South, Error},
                { Error, Error, Error, Error},
                { East, West, South, Error},
                { West, South, Error, Error},
                { East, South, Error, Error},
                { Error, Error, Error, Error},
                { East, North, West, Error},
                { North, West, Error, Error},
                { East, North, Error, Error}
             };
        return c[b][index];
    }

        /** Transform direction code into corresponding Diff2D offset.
            (note: there is no bounds checking on the code you pass.)
        */
00239     static Diff2D const & diff(Direction code)
    {
        static Diff2D d[] = {
            Diff2D(1, 0), Diff2D(0, -1), Diff2D(-1, 0), Diff2D(0, 1)
        };
        return d[code];
    }

        /** Equivalent to <tt>diff(static_cast<Direction>(code))</tt>.
            (note: there is no bounds checking on the code you pass.)
        */
00250     static Diff2D const & diff(int code) { return diff(static_cast<Direction>(code)); }

        /** Get the relative offset from one neighbor to the other.
            For example, <tt>relativeDiff(East, West) == Diff2D(-2,0)</tt>.
            (note: there is no bounds checking on the code you pass.)
        */
00256     static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
    {
        static Diff2D d[][4] = {
            { Diff2D(0, 0), Diff2D(-1, -1), Diff2D(-2, 0), Diff2D(-1, 1) },
            { Diff2D(1, 1), Diff2D(0, 0), Diff2D(-1, 1), Diff2D(0, 2) },
            { Diff2D(2, 0), Diff2D(1, -1), Diff2D(0, 0), Diff2D(1, 1) },
            { Diff2D(1, -1), Diff2D(0, -2), Diff2D(-1, -1), Diff2D(0, 0) }
        };

        return d[fromCode][toCode];
    }

        /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
            (note: there is no bounds checking on the code you pass.)
        */
00271     static Diff2D const & relativeDiff(int fromCode, int toCode)
    {
        return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
    }

        /**  X-component of diff() */
00277     static int dX(Direction code) { return diff(code).x; }
        /**  Y-component of diff() */
00279     static int dY(Direction code) { return diff(code).y; }
        /**  X-component of diff() */
00281     static int dX(int code) { return diff(code).x; }
        /**  Y-component of diff() */
00283     static int dY(int code) { return diff(code).y; }

        /** Transform Diff2D offset into corresponding direction code.
            The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
            is not in the 4-neighborhood.
        */
00289     static Direction code(Diff2D const & diff)
    {
        switch(diff.x)
        {
            case  0:
            {
                switch(diff.y)
                {
                    case 1:
                        return South;
                    case -1:
                        return North;
                    default:
                        return Error;
                }
            }
            case -1:
            {
                return (diff.y == 0) ?
                            West :
                            Error;
            }
            case  1:
            {
                return (diff.y == 0) ?
                            East :
                            Error;
            }
        }
        return Error;
    }

        /** Check whether a code refers to a diagonal direction.
            Useful if you want to abstract the differences between 4- and 8-neighborhood.
            Always <tt>false</tt> for 4-neighborhood.
        */
00325     static bool isDiagonal(Direction) { return false; }

00327     static Diff2D const & right()        { return diff(East); }    /**<  Offset to the right neighbor */
00328     static Diff2D const & top()          { return diff(North); }   /**<  Offset to the top neighbor */
00329     static Diff2D const & left()         { return diff(West); }    /**<  Offset to the left neighbor */
00330     static Diff2D const & bottom()       { return diff(South); }   /**<  Offset to the bottom neighbor */

00332     static Diff2D const & east()       { return diff(East); }    /**<  Offset to the east neighbor */
00333     static Diff2D const & north()      { return diff(North); }   /**<  Offset to the north neighbor */
00334     static Diff2D const & west()       { return diff(West); }    /**<  Offset to the west neighbor */
00335     static Diff2D const & south()      { return diff(South); }   /**<  Offset to the south neighbor */
};

    /** Export NeighborCode::Direction into the scope of namespace FourNeighborhood.
    */
00340 typedef NeighborCode::Direction Direction;

00342 static const Direction East           = NeighborCode::East;           /**<  Export NeighborCode::East to namespace FourNeighborhood */
00343 static const Direction North          = NeighborCode::North;          /**<  Export NeighborCode::North to namespace FourNeighborhood */
00344 static const Direction West           = NeighborCode::West;           /**<  Export NeighborCode::West to namespace FourNeighborhood */
00345 static const Direction South          = NeighborCode::South;          /**<  Export NeighborCode::South to namespace FourNeighborhood */
00346 static const Direction DirectionCount = NeighborCode::DirectionCount; /**<  Export NeighborCode::DirectionCount to namespace FourNeighborhood */

00348 inline Diff2D const & east()       { return NeighborCode::diff(East); }    /**<  Offset to the east neighbor */
00349 inline Diff2D const & north()      { return NeighborCode::diff(North); }   /**<  Offset to the north neighbor */
00350 inline Diff2D const & west()       { return NeighborCode::diff(West); }    /**<  Offset to the west neighbor */
00351 inline Diff2D const & south()      { return NeighborCode::diff(South); }   /**<  Offset to the south neighbor */

} // namespace FourNeighborhood

    /** Export \ref vigra::FourNeighborhood::NeighborCode into the scope of namespace vigra.
    */
00357 typedef FourNeighborhood::NeighborCode FourNeighborCode;

/********************************************************/
/*                                                      */
/*                   EightNeighborhood                  */
/*                                                      */
/********************************************************/

/** Utilities for 8-neighborhood. */
00366 namespace EightNeighborhood
{
/** \brief Encapsulation of direction management for the 8-neighborhood.

    This helper class allows the transformation between Freeman chain codes
    (East = 0, NorthEast = 1 etc.) and the corresponding Diff2D instances
    and back.

    You can either use the chain codes by explicit qualification:

    \code
    // the following three lines are equivalent
    EightNeighborhood::NeighborCode::Direction d = EightNeighborhood::NeighborCode::East;
    EightNeighborCode::Direction d               = EightNeighborCode::East;
    EightNeighborhood::Direction d               = EightNeighborhood::East;
    \endcode

    or you can fix 8-neighborhood by importing the entire namespace in
    your function:

    \code
    using namespace EightNeighborhood;

    Direction d = East;
    \endcode

    If you want to pass 8-neighborhood codes as a template parameter, use
    the class EightNeighborhood::NeighborCode.

    <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
    Namespace: vigra::EightNeighborhood
*/
00398 class NeighborCode
{
  public:

    typedef Diff2D difference_type;
    
        /** Freeman direction codes for the 8-neighborhood.
            <tt>East = 0</tt>, <tt>North = 1</tt> etc.
            <tt>DirectionCount</tt> may be used for portable loop termination conditions.
            <tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and last (inclusive)
            neighbors in the causal neighborhood, i.e. in the set of neighbors that have
            already been visited when the image is traversed in scan order.
            <tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the opposite.
        */
00412     enum Direction {
00413         Error = -1,     ///< &nbsp;
00414         East = 0,       ///< &nbsp;
00415         NorthEast,      ///< &nbsp;
00416         North,          ///< &nbsp;
00417         NorthWest,      ///< &nbsp;
00418         West,           ///< &nbsp;
00419         SouthWest,      ///< &nbsp;
00420         South,          ///< &nbsp;
00421         SouthEast,      ///< &nbsp;
00422         DirectionCount, ///< &nbsp;
00423         CausalFirst = NorthEast,     ///< &nbsp;
00424         CausalLast  = West,          ///< &nbsp;
00425         AntiCausalFirst = SouthWest, ///< &nbsp;
00426         AntiCausalLast  = East,       ///< &nbsp;
   
        InitialDirection = East,
        OppositeDirPrefix = 1,
        OppositeOffset = West
    };

    static unsigned int directionBit(Direction d)
    {
        static unsigned int b[] = {1 << (East + 1),
                                   1 << (NorthEast + 1),
                                   1 << (North + 1),
                                   1 << (NorthWest + 1),
                                   1 << (West + 1),
                                   1 << (SouthWest + 1),
                                   1 << (South + 1),
                                   1 << (SouthEast + 1)};
        return b[d];
    };

        /** The number of valid neighbors if the current center is at the image border.
        */
00448     static unsigned int nearBorderDirectionCount(AtImageBorder b)
    {
        static unsigned int c[] = { 8, 5, 5, 0, 5, 3, 3, 0, 5, 3, 3};
        return c[b];
    }

        /** The valid direction codes when the center is at the image border.
            \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
        */
00457     static Direction nearBorderDirections(AtImageBorder b, int index)
    {
        static Direction c[11][8] = {
                { East, NorthEast, North, NorthWest, West, SouthWest, South, SouthEast},
                { North, NorthWest, West, SouthWest, South, Error, Error, Error},
                { East, NorthEast, North, South, SouthEast, Error, Error, Error},
                { Error, Error, Error, Error, Error, Error, Error, Error},
                { East, West, SouthWest, South, SouthEast, Error, Error, Error},
                { West, SouthWest, South, Error, Error, Error, Error, Error},
                { East, South, SouthEast, Error, Error, Error, Error, Error},
                { Error, Error, Error, Error, Error, Error, Error, Error},
                { East, NorthEast, North, NorthWest, West, Error, Error, Error},
                { North, NorthWest, West, Error, Error, Error, Error, Error},
                { East, NorthEast, North, Error, Error, Error, Error, Error}
             };
        return c[b][index];
    }

        /** Transform direction code into corresponding Diff2D offset.
            (note: there is no bounds checking on the code you pass.)
        */
00478     static Diff2D const & diff(Direction code)
    {
        static Diff2D d[] = {
            Diff2D(1, 0), Diff2D(1, -1), Diff2D(0, -1), Diff2D(-1, -1),
            Diff2D(-1, 0), Diff2D(-1, 1), Diff2D(0, 1), Diff2D(1, 1)
        };
        return d[code];
    }

        /** Equivalent to diff(static_cast<Direction>(code)).
            (note: there is no bounds checking on the code you pass.)
        */
00490     static Diff2D const & diff(int code) { return diff(static_cast<Direction>(code)); }

        /** Get the relative offset from one neighbor to the other.
            For example, <tt>relativeDiff(East, West) == Diff2D(-2,0)</tt>.
            (note: there is no bounds checking on the code you pass.)
        */
00496     static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
    {
        static Diff2D d[][8] = {
            { Diff2D(0, 0), Diff2D(0, -1), Diff2D(-1, -1), Diff2D(-2, -1),
              Diff2D(-2, 0), Diff2D(-2, 1), Diff2D(-1, 1), Diff2D(0, 1) },
            { Diff2D(0, 1), Diff2D(0, 0), Diff2D(-1, 0), Diff2D(-2, 0),
              Diff2D(-2, 1), Diff2D(-2, 2), Diff2D(-1, 2), Diff2D(0, 2) },
            { Diff2D(1, 1), Diff2D(1, 0), Diff2D(0, 0), Diff2D(-1, 0),
              Diff2D(-1, 1), Diff2D(-1, 2), Diff2D(0, 2), Diff2D(1, 2) },
            { Diff2D(2, 1), Diff2D(2, 0), Diff2D(1, 0), Diff2D(0, 0),
              Diff2D(0, 1), Diff2D(0, 2), Diff2D(1, 2), Diff2D(2, 2) },
            { Diff2D(2, 0), Diff2D(2, -1), Diff2D(1, -1), Diff2D(0, -1),
              Diff2D(0, 0), Diff2D(0, 1), Diff2D(1, 1), Diff2D(2, 1) },
            { Diff2D(2, -1), Diff2D(2, -2), Diff2D(1, -2), Diff2D(0, -2),
              Diff2D(0, -1), Diff2D(0, 0), Diff2D(1, 0), Diff2D(2, 0) },
            { Diff2D(1, -1), Diff2D(1, -2), Diff2D(0, -2), Diff2D(-1, -2),
              Diff2D(-1, -1), Diff2D(-1, 0), Diff2D(0, 0), Diff2D(1, 0) },
            { Diff2D(0, -1), Diff2D(0, -2), Diff2D(-1, -2), Diff2D(-2, -2),
              Diff2D(-2, -1), Diff2D(-2, 0), Diff2D(-1, 0), Diff2D(0, 0) }
        };

        return d[fromCode][toCode];
    }

        /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
            (note: there is no bounds checking on the code you pass.)
        */
00523     static Diff2D const & relativeDiff(int fromCode, int toCode)
    {
        return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
    }

        /**  X-component of diff() */
00529     static int dX(Direction code) { return diff(code).x; }
        /**  Y-component of diff() */
00531     static int dY(Direction code) { return diff(code).y; }
        /**  X-component of diff() */
00533     static int dX(int code) { return diff(code).x; }
        /**  Y-component of diff() */
00535     static int dY(int code) { return diff(code).y; }

        /** Transform 4-neighborhood code into 8-neighborhood code.
        */
00539     static Direction code(FourNeighborhood::Direction d)
        { return static_cast<Direction>(2*d); }

        /** Transform Diff2D offset into corresponding direction code.
            The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
            is not in the 8-neighborhood.
        */
00546     static Direction code(Diff2D const & diff)
    {
        switch(diff.x)
        {
            case  0:
            {
                switch(diff.y)
                {
                    case 1:
                        return South;
                    case -1:
                        return North;
                    default:
                        return Error;
                }
            }
            case -1:
            {
                switch(diff.y)
                {
                    case 0:
                        return West;
                    case 1:
                        return SouthWest;
                    case -1:
                        return NorthWest;
                    default:
                        return Error;
                }
            }
            case  1:
            {
                switch(diff.y)
                {
                    case 0:
                        return East;
                    case 1:
                        return SouthEast;
                    case -1:
                        return NorthEast;
                    default:
                        return Error;
                }
            }
        }
        return Error;
    }

        /** Check whether a code refers to a diagonal direction.
            Useful if you want to abstract the differences between 4- and 8-neighborhood.
        */
00597     static bool isDiagonal(Direction code) { return (code % 2) != 0; }

00599     static Diff2D const & right()        { return diff(East); }        /**<  Offset to the right neighbor */
00600     static Diff2D const & topRight()     { return diff(NorthEast); }   /**<  Offset to the topRight neighbor */
00601     static Diff2D const & top()          { return diff(North); }       /**<  Offset to the top neighbor */
00602     static Diff2D const & topLeft()      { return diff(NorthWest); }   /**<  Offset to the topLeft neighbor */
00603     static Diff2D const & left()         { return diff(West); }        /**<  Offset to the left neighbor */
00604     static Diff2D const & bottomLeft()   { return diff(SouthWest); }   /**<  Offset to the bottomLeft neighbor */
00605     static Diff2D const & bottom()       { return diff(South); }       /**<  Offset to the bottom neighbor */
00606     static Diff2D const & bottomRight()  { return diff(SouthEast); }   /**<  Offset to the bottomRight neighbor */

00608     static Diff2D const & east()       { return diff(East); }        /**<  Offset to the east neighbor */
00609     static Diff2D const & northEast()  { return diff(NorthEast); }   /**<  Offset to the northEast neighbor */
00610     static Diff2D const & north()      { return diff(North); }       /**<  Offset to the north neighbor */
00611     static Diff2D const & northWest()  { return diff(NorthWest); }   /**<  Offset to the northWest neighbor */
00612     static Diff2D const & west()       { return diff(West); }        /**<  Offset to the west neighbor */
00613     static Diff2D const & southWest()  { return diff(SouthWest); }   /**<  Offset to the southWest neighbor */
00614     static Diff2D const & south()      { return diff(South); }       /**<  Offset to the south neighbor */
00615     static Diff2D const & southEast()  { return diff(SouthEast); }   /**<  Offset to the southEast neighbor */
};

    /** Export NeighborCode::Direction into the scope of namespace EightNeighborhood.
    */
00620 typedef NeighborCode::Direction Direction;

00622 static const Direction East           = NeighborCode::East;        /**<  Export NeighborCode::East to namespace EightNeighborhood */
00623 static const Direction NorthEast      = NeighborCode::NorthEast;   /**<  Export NeighborCode::NorthEast to namespace EightNeighborhood */
00624 static const Direction North          = NeighborCode::North;       /**<  Export NeighborCode::North to namespace EightNeighborhood */
00625 static const Direction NorthWest      = NeighborCode::NorthWest;   /**<  Export NeighborCode::NorthWest to namespace EightNeighborhood */
00626 static const Direction West           = NeighborCode::West;        /**<  Export NeighborCode::West to namespace EightNeighborhood */
00627 static const Direction SouthWest      = NeighborCode::SouthWest;   /**<  Export NeighborCode::SouthWest to namespace EightNeighborhood */
00628 static const Direction South          = NeighborCode::South;       /**<  Export NeighborCode::South to namespace EightNeighborhood */
00629 static const Direction SouthEast      = NeighborCode::SouthEast;   /**<  Export NeighborCode::SouthEast to namespace EightNeighborhood */
00630 static const Direction DirectionCount = NeighborCode::DirectionCount;   /**<  Export NeighborCode::DirectionCount to namespace EightNeighborhood */

00632 inline Diff2D const & east()       { return NeighborCode::diff(East); }        /**<  Offset to the east neighbor */
00633 inline Diff2D const & northEast()  { return NeighborCode::diff(NorthEast); }   /**<  Offset to the northEast neighbor */
00634 inline Diff2D const & north()      { return NeighborCode::diff(North); }       /**<  Offset to the north neighbor */
00635 inline Diff2D const & northWest()  { return NeighborCode::diff(NorthWest); }   /**<  Offset to the northWest neighbor */
00636 inline Diff2D const & west()       { return NeighborCode::diff(West); }        /**<  Offset to the west neighbor */
00637 inline Diff2D const & southWest()  { return NeighborCode::diff(SouthWest); }   /**<  Offset to the southWest neighbor */
00638 inline Diff2D const & south()      { return NeighborCode::diff(South); }       /**<  Offset to the south neighbor */
00639 inline Diff2D const & southEast()  { return NeighborCode::diff(SouthEast); }   /**<  Offset to the southEast neighbor */

} // namespace EightNeighborhood

    /** Export \ref vigra::EightNeighborhood::NeighborCode into the scope of namespace vigra.
    */
00645 typedef EightNeighborhood::NeighborCode EightNeighborCode;

/********************************************************/
/*                                                      */
/*              NeighborOffsetCirculator                */
/*                                                      */
/********************************************************/

/** \brief Circulator that walks around a given location.

    The template parameter defines the kind of neighborhood used, e.g.

    \code
    NeighborOffsetCirculator<EightNeighborCode> eight_circulator;
    NeighborOffsetCirculator<FourNeighborCode>  four_circulator;
    \endcode

    Since this circulator doesn't now about the pixels in any particular image,
    you usually doesn't use it directly but rather as a base class or helper for
    neighborhood circulators refering to a particular image (e.g. NeighborhoodCirculator)

    <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
    Namespace: vigra
*/
template<class NEIGHBORCODE>
00670 class NeighborOffsetCirculator
: public NEIGHBORCODE
{
public:
    typedef NEIGHBORCODE NeighborCode;

        /** return type of direction()
        */
00678     typedef typename NEIGHBORCODE::Direction Direction;

        /** the circulator's value type
        */
00682     typedef typename NEIGHBORCODE::difference_type value_type;

        /** the circulator's reference type (return type of <TT>*circ</TT>)
        */
00686     typedef value_type const & reference;

        /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
        */
00690     typedef value_type const & index_reference;

        /** the circulator's pointer type (return type of <TT>operator-></TT>)
        */
00694     typedef value_type const * pointer;

        /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
        */
00698     typedef int difference_type;

        /** the circulator tag (random access iterator)
        */
00702     typedef random_access_circulator_tag iterator_category;

protected:
    Direction direction_;

public:
        /** Create circulator refering to the given direction.
        */
00710     NeighborOffsetCirculator(Direction dir = NEIGHBORCODE::InitialDirection)
        : direction_(dir)
    {
    }

        /** pre-increment */
00716     NeighborOffsetCirculator & operator++()
    {
        direction_ = static_cast<Direction>((direction_+1) % NEIGHBORCODE::DirectionCount);
        return *this;
    }

        /** pre-decrement */
00723     NeighborOffsetCirculator & operator--()
    {
        direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::DirectionCount-1) % NEIGHBORCODE::DirectionCount);
        return *this;
    }

        /** post-increment */
00730     NeighborOffsetCirculator operator++(int)
    {
        NeighborOffsetCirculator ret(*this);
        operator++();
        return ret;
    }

        /** post-decrement */
00738     NeighborOffsetCirculator operator--(int)
    {
        NeighborOffsetCirculator ret(*this);
        operator--();
        return ret;
    }

        /** add-assignment */
00746     NeighborOffsetCirculator & operator+=(difference_type d)
    {
        direction_ = static_cast<Direction>((direction_ + d) % NEIGHBORCODE::DirectionCount);
        if(direction_ < 0)
            direction_ = static_cast<Direction>(direction_ + NEIGHBORCODE::DirectionCount);
        return *this;
    }

        /** subtract-assignment */
00755     NeighborOffsetCirculator & operator-=(difference_type d)
    {
        direction_ = static_cast<Direction>((direction_ - d) % NEIGHBORCODE::DirectionCount);
        if(direction_ < 0)
            direction_ = static_cast<Direction>(direction_ + NEIGHBORCODE::DirectionCount);
        return *this;
    }

        /** addition */
00764     NeighborOffsetCirculator operator+(difference_type d) const
    {
        return NeighborOffsetCirculator(*this) += d;
    }

        /** subtraction */
00770     NeighborOffsetCirculator operator-(difference_type d) const
    {
        return NeighborOffsetCirculator(*this) -= d;
    }

        /** Move to the direction that is 'right' relative to the current direction.
            This is equivalent to <tt>four_circulator--</tt> and
            <tt>eight_circulator -= 2</tt> respectively.
        */
00779     NeighborOffsetCirculator & turnRight()
    {
        direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::South) % NEIGHBORCODE::DirectionCount);
        return *this;
    }

        /** Move to the direction that is 'left' relative to the current direction.
            This is equivalent to <tt>four_circulator++</tt> and
            <tt>eight_circulator += 2</tt> respectively.
        */
00789     NeighborOffsetCirculator & turnLeft()
    {
        direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::North) % NEIGHBORCODE::DirectionCount);
        return *this;
    }

        /** Move to the opposite direction of the current direction.
            This is equivalent to <tt>four_circulator += 2</tt> and
            <tt>eight_circulator += 4</tt> respectively.
        */
00799     NeighborOffsetCirculator & turnRound()
    {
        direction_ = opposite();
        return *this;
    }

        /** Move to the given direction.
        */
00807     NeighborOffsetCirculator & turnTo(Direction d)
    {
        direction_ = d;
        return *this;
    }

        /** equality */
00814     bool operator==(NeighborOffsetCirculator const & o) const
    {
        return direction_ == o.direction_;
    }

        /** unequality */
00820     bool operator!=(NeighborOffsetCirculator const & o) const
    {
        return direction_ != o.direction_;
    }

        /** subtraction */
00826     difference_type operator-(NeighborOffsetCirculator const & o) const
    {
        return direction_ - o.direction_;
    }

        /** dereference */
00832     reference operator*() const
    {
        return diff();
    }

        /** index */
00838     index_reference operator[](difference_type d) const
    {
        return NEIGHBORCODE::diff(direction(d));
    }

        /** member access */
00844     pointer operator->() const
    {
        return &diff();
    }

        /** Get offset from center to current neighbor.
        */
00851     reference diff() const
    {
        return NEIGHBORCODE::diff(direction_);
    }

        /** Get offset to given direction.
        */
00858     static reference diff(Direction dir)
    {
        return NEIGHBORCODE::diff(dir);
    }

        /** Get relative distance from current neighbor to neighbor
            at given offset.
        */
00866     value_type relativeDiff(difference_type offset) const
    {
        Direction toDir = static_cast<Direction>((direction_ + offset) % NEIGHBORCODE::DirectionCount);
        if(toDir < 0)
            toDir = static_cast<Direction>(toDir + NEIGHBORCODE::DirectionCount);
        return NEIGHBORCODE::relativeDiff(direction_, toDir);
    }

        /** X-component of diff()  */
00875     int dX() const
    {
        return NEIGHBORCODE::dX(direction_);
    }

        /** Y-component of diff() */
00881     int dY() const
    {
        return NEIGHBORCODE::dY(direction_);
    }

        /** Check whether current direction is a diagonal one.
        */
00888     bool isDiagonal() const
    {
        return NEIGHBORCODE::isDiagonal(direction_);
    }

        /** Get current direction.
        */
00895     Direction direction() const
    {
        return direction_;
    }

        /** Get current direction bit.
        */
00902     unsigned int directionBit() const
    {
        return NEIGHBORCODE::directionBit(direction_);
    }

        /** Get opposite of current direction.
        */
00909     Direction opposite() const
    {
        return static_cast<Direction>((NEIGHBORCODE::OppositeDirPrefix*direction_ + NEIGHBORCODE::OppositeOffset) % NEIGHBORCODE::DirectionCount);
    }

        /** Get opposite bit of current direction.
        */
00916     unsigned int oppositeDirectionBit() const
    {
        return NEIGHBORCODE::directionBit(opposite());
    }

        /** Get direction code at offset of current direction.
        */
00923     Direction direction(difference_type offset) const
    {
        int result = (direction_ + offset) % NEIGHBORCODE::DirectionCount;
        if(result < 0)
            result += NEIGHBORCODE::DirectionCount;
        return static_cast<Direction>(result);
    }
};

/** Specialization of NeighborOffsetCirculator for 8-neighborhood.
*/
00934 typedef NeighborOffsetCirculator<EightNeighborCode> EightNeighborOffsetCirculator;

/** Specialization of NeighborOffsetCirculator for 4-neighborhood.
*/
00938 typedef NeighborOffsetCirculator<FourNeighborCode> FourNeighborOffsetCirculator;


//@}

/** \addtogroup ImageIteratorAdapters
 */
//@{

/********************************************************/
/*                                                      */
/*                NeighborhoodCirculator                */
/*                                                      */
/********************************************************/

/** \brief Circulator that walks around a given location in a given image.

    The template parameters define the kind of neighborhood used and the underlying
    image. The access functions return the value of the current neighbor pixel.
    Use <tt>center()</tt> to access the center pixel of the neighborhood.
    The center can be changed by calling <tt>moveCenterToNeighbor()</tt>
    or <tt>swapCenterNeighbor()</tt>. Note that this circulator cannot
    when the center is at the image border. You must then use
    \ref vigra::RestrictedNeighborhoodCirculator

    <b>Usage:</b><br>

    <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
    Namespace: vigra

    \code
    BImage::traverser upperleft(...), lowerright(...);

    int width  = lowerright.x - upperleft.x;
    int height = lowerright.y - upperleft.y;

    ++upperleft.y; // avoid image border
    for(int y=1; y<height-1; ++y, ++upperleft.y)
    {
        BImage::traverser ix = upperleft + Diff2D(1,0);
        for(int x=1; x<width-1; ++x, ++ix.x)
        {
            // analyse all neighbors of a pixel (use FourNeighborCode
            // instead of EightNeighborCode for 4-neighborhood):
            NeighborhoodCirculator<BImage::traverser, EightNeighborCode>
                           circulator(ix),
                           end(circulator);
            do
            {
                analysisFunc(*circulator, ...); // do sth. with current neighbor
            }
            while(++circulator != end); // compare with start/end circulator
        }
    }
    \endcode
*/
template <class IMAGEITERATOR, class NEIGHBORCODE>
00995 class NeighborhoodCirculator : private IMAGEITERATOR
{
    typedef NeighborOffsetCirculator<NEIGHBORCODE> NEIGHBOROFFSETCIRCULATOR;


public:
        /** type of the underlying image iterator
        */
01003     typedef IMAGEITERATOR base_type;

        /** type of the used neighbor code
        */
01007     typedef NEIGHBORCODE NeighborCode;

        /** the circulator's value type
        */
01011     typedef typename IMAGEITERATOR::value_type value_type;

        /** type of the direction code
        */
01015     typedef typename NEIGHBORCODE::Direction Direction;

        /** the circulator's reference type (return type of <TT>*circ</TT>)
        */
01019     typedef typename IMAGEITERATOR::reference reference;

        /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
        */

01024     typedef reference index_reference;

        /** the circulator's pointer type (return type of <TT>operator-></TT>)
        */
01028     typedef typename IMAGEITERATOR::pointer pointer;

        /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
        */
01032     typedef typename NEIGHBOROFFSETCIRCULATOR::difference_type difference_type;

        /** the circulator tag (random_access_circulator_tag)
        */
01036     typedef typename NEIGHBOROFFSETCIRCULATOR::iterator_category iterator_category;

        /** Construct circulator with given <tt>center</tt> pixel, pointing to the neighbor
            at the given direction <tt>d</tt>.
        */
01041     NeighborhoodCirculator(IMAGEITERATOR const & center = IMAGEITERATOR(),
                           Direction d = NEIGHBOROFFSETCIRCULATOR::InitialDirection)
        : IMAGEITERATOR(center), neighborCode_(d)
    {
        IMAGEITERATOR::operator+=(neighborCode_.diff());
    }

        /** pre-increment */
01049     NeighborhoodCirculator & operator++()
    {
        return operator+=(1);
    }

        /** pre-decrement */
01055     NeighborhoodCirculator operator++(int)
    {
        NeighborhoodCirculator ret(*this);
        operator++();
        return ret;
    }

        /** post-increment */
01063     NeighborhoodCirculator & operator--()
    {
        return operator+=(-1);
    }

        /** post-decrement */
01069     NeighborhoodCirculator operator--(int)
    {
        NeighborhoodCirculator ret(*this);
        operator--();
        return ret;
    }

        /** add-assignment */
01077     NeighborhoodCirculator & operator+=(difference_type d)
    {
        IMAGEITERATOR::operator+=(neighborCode_.relativeDiff(d));
        neighborCode_+= d;
        return *this;
    }

        /** subtract-assignment */
01085     NeighborhoodCirculator & operator-=(difference_type d)
    {
        return operator+=(-d);
    }

        /** addition */
01091     NeighborhoodCirculator operator+(difference_type d) const
    {
        NeighborhoodCirculator result(*this);
        result+= d;
        return result;
    }

        /** subtraction */
01099     NeighborhoodCirculator operator-(difference_type d) const
    {
        NeighborhoodCirculator result(*this);
        result-= d;
        return result;
    }

        /** Move to the direction that is 'right' relative to the current direction.
            This is equivalent to <tt>four_circulator--</tt> and
            <tt>eight_circulator -= 2</tt> respectively.
        */
01110     NeighborhoodCirculator & turnRight()
    {
        Direction oldDirection = neighborCode_.direction();
        neighborCode_.turnRight();
        IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
                                  (oldDirection, neighborCode_.direction()));
        return *this;
    }

        /** Move to the direction that is 'left' relative to the current direction.
            This is equivalent to <tt>four_circulator++</tt> and
            <tt>eight_circulator += 2</tt> respectively.
        */
01123     NeighborhoodCirculator & turnLeft()
    {
        Direction oldDirection = neighborCode_.direction();
        neighborCode_.turnLeft();
        IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
                                  (oldDirection, neighborCode_.direction()));
        return *this;
    }

        /** Move to the opposite direction of the current direction.
            This is equivalent to <tt>four_circulator += 2</tt> and
            <tt>eight_circulator += 4</tt> respectively.
        */
01136     NeighborhoodCirculator & turnRound()
    {
        Direction oldDirection = neighborCode_.direction();
        neighborCode_.turnRound();
        IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
                                  (oldDirection, neighborCode_.direction()));
        return *this;
    }

        /** Move to the given direction.
        */
01147     NeighborhoodCirculator & turnTo(Direction d)
    {
        Direction oldDirection = neighborCode_.direction();
        neighborCode_.turnTo(d);
        IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
                                  (oldDirection, neighborCode_.direction()));
        return *this;
    }

        /** Move the center in the current direction.
            The current neighbor becomes the new center, the direction does not change.
        */
01159     NeighborhoodCirculator & moveCenterToNeighbor()
    {
        IMAGEITERATOR::operator+=(neighborCode_.diff());
        return *this;
    }

        /** Exchange the center with the current neighbor.
            Equivalent to <tt>circ.moveCenterToNeighbor().turnRound()</tt>
            (but shorter and more efficient).
        */
01169     NeighborhoodCirculator & swapCenterNeighbor()
    {
        neighborCode_.turnRound();
        IMAGEITERATOR::operator+=(neighborCode_.diff());
        return *this;
    }

        /** equality */
01177     bool operator==(NeighborhoodCirculator const & rhs) const
    {
        return neighborCode_ == rhs.neighborCode_ &&
               IMAGEITERATOR::operator==(rhs);
    }

        /** inequality */
01184     bool operator!=(NeighborhoodCirculator const & rhs) const
    {
        return neighborCode_ != rhs.neighborCode_ ||
               IMAGEITERATOR::operator!=(rhs);
    }

        /** subtraction */
01191     difference_type operator-(NeighborhoodCirculator const & rhs) const
    {
        return neighborCode_ - rhs.neighborCode_;
    }

        /** dereference */
01197     reference operator*() const
    {
        return IMAGEITERATOR::operator*();
    }

        /** index */
01203     index_reference operator[](difference_type d) const
    {
        return IMAGEITERATOR::operator[](neighborCode_.relativeDiff(d));
    }

        /** member access */
01209     pointer operator->() const
    {
        return IMAGEITERATOR::operator->();
    }

        /** Get the base iterator for the current neighbor. */
01215     base_type const & base() const
    {
        return *this;
    }

        /** Get the base iterator for the center of the circulator. */
01221     base_type center() const
    {
        return (base_type)*this - neighborCode_.diff();
    }

        /** Get the current direction. */
01227     Direction direction() const
    {
        return neighborCode_.direction();
    }

        /** Get the current direction bit. */
01233     unsigned int directionBit() const
    {
        return neighborCode_.directionBit();
    }

        /** Get the difference vector (Diff2D) from the center to the current neighbor. */
01239     Diff2D const & diff() const
    {
        return neighborCode_.diff();
    }

        /** Is the current neighbor a diagonal neighbor? */
01245     bool isDiagonal() const
    {
        return neighborCode_.isDiagonal();
    }

private:
    NEIGHBOROFFSETCIRCULATOR neighborCode_;
};

/********************************************************/
/*                                                      */
/*            RestrictedNeighborhoodCirculator          */
/*                                                      */
/********************************************************/

/** \brief Circulator that walks around a given location in a given image,
           unsing a restricted neighborhood.

    This circulator behaves essentially like \ref vigra::NeighborhoodCirculator,
    but can also be used near the image border, where some of the neighbor points
    would be outside the image und must not be accessed.
    The template parameters define the kind of neighborhood used (four or eight)
    and the underlying image, whereas the required neighbirhood restriction is
    given by the last constructur argument. This below for typical usage.

    The access functions return the value of the current neighbor pixel. Use <tt>center()</tt> to
    access the center pixel of the neighborhood.

    <b>Usage:</b><br>

    <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
    Namespace: vigra

    \code
    BImage::traverser upperleft(...), lowerright(...);

    int width  = lowerright.x - upperleft.x;
    int height = lowerright.y - upperleft.y;

    for(int y=0; y<height; ++y, ++upperleft.y)
    {
        BImage::traverser ix = upperleft;
        for(int x=0; x<width; ++x, ++ix.x)
        {
            // use FourNeighborCode instead of EightNeighborCode for 4-neighborhood
            RestrictedNeighborhoodCirculator<BImage::traverser, EightNeighborCode>
                           circulator(ix, isAtImageBorder(x, y, width, height)),
                           end(circulator);
            do
            {
                ... // do something with the circulator
            }
            while(++circulator != end); // out-of-range pixels will be automatically skipped
        }
    }
    \endcode
*/
template <class IMAGEITERATOR, class NEIGHBORCODE>
01303 class RestrictedNeighborhoodCirculator
: private NeighborhoodCirculator<IMAGEITERATOR, NEIGHBORCODE>
{
    typedef NeighborhoodCirculator<IMAGEITERATOR, NEIGHBORCODE> BaseType;

public:
        /** type of the underlying image iterator
        */
01311     typedef IMAGEITERATOR base_type;

        /** type of the used neighbor code
        */
01315     typedef NEIGHBORCODE NeighborCode;

        /** the circulator's value type
        */
01319     typedef typename BaseType::value_type value_type;

        /** type of the direction code
        */
01323     typedef typename BaseType::Direction Direction;

        /** the circulator's reference type (return type of <TT>*circ</TT>)
        */
01327     typedef typename BaseType::reference reference;

        /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
        */
01331     typedef typename BaseType::index_reference index_reference;

        /** the circulator's pointer type (return type of <TT>operator-></TT>)
        */
01335     typedef typename BaseType::pointer pointer;

        /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
        */
01339     typedef typename BaseType::difference_type difference_type;

        /** the circulator tag (random_access_circulator_tag)
        */
01343     typedef typename BaseType::iterator_category iterator_category;

        /** Construct circulator with given <tt>center</tt> pixel, using the restricted
            neighborhood given by \a atBorder.
        */
01348     RestrictedNeighborhoodCirculator(IMAGEITERATOR const & center = IMAGEITERATOR(),
                                     AtImageBorder atBorder = NotAtBorder)
        : BaseType(center, NEIGHBORCODE::nearBorderDirections(atBorder, 0)),
          whichBorder_(atBorder),
          count_(NEIGHBORCODE::nearBorderDirectionCount(atBorder)),
          current_(0)
    {}

        /** pre-increment */
01357     RestrictedNeighborhoodCirculator & operator++()
    {
        return operator+=(1);
    }

        /** pre-decrement */
01363     RestrictedNeighborhoodCirculator operator++(int)
    {
        RestrictedNeighborhoodCirculator ret(*this);
        operator++();
        return ret;
    }

        /** post-increment */
01371     RestrictedNeighborhoodCirculator & operator--()
    {
        return operator+=(-1);
    }

        /** post-decrement */
01377     RestrictedNeighborhoodCirculator operator--(int)
    {
        RestrictedNeighborhoodCirculator ret(*this);
        operator--();
        return ret;
    }

        /** add-assignment */
01385     RestrictedNeighborhoodCirculator & operator+=(difference_type d)
    {
        current_ = static_cast<Direction>((current_ + count_ + d) % count_);
        BaseType::turnTo(NEIGHBORCODE::nearBorderDirections(whichBorder_, current_));
        return *this;
    }

        /** subtract-assignment */
01393     RestrictedNeighborhoodCirculator & operator-=(difference_type d)
    {
        return operator+=(-d);
    }

        /** addition */
01399     RestrictedNeighborhoodCirculator operator+(difference_type d) const
    {
        RestrictedNeighborhoodCirculator result(*this);
        result+= d;
        return result;
    }

        /** subtraction */
01407     RestrictedNeighborhoodCirculator operator-(difference_type d) const
    {
        RestrictedNeighborhoodCirculator result(*this);
        result-= d;
        return result;
    }

        /** equality */
01415     bool operator==(RestrictedNeighborhoodCirculator const & rhs) const
    {
        return current_ == rhs.current_;
    }

        /** inequality */
01421     bool operator!=(RestrictedNeighborhoodCirculator const & rhs) const
    {
        return current_ != rhs.current_;
    }

        /** subtraction */
01427     difference_type operator-(RestrictedNeighborhoodCirculator const & rhs) const
    {
        return (current_ - rhs.current_) % count_;
    }

        /** dereference */
01433     reference operator*() const
    {
        return BaseType::operator*();
    }

        /** member access */
01439     pointer operator->() const
    {
        return BaseType::operator->();
    }

        /** Get the base iterator for the current neighbor. */
01445     base_type const & base() const
    {
        return BaseType::base();
    }

        /** Get the base iterator for the center of the circulator. */
01451     base_type center() const
    {
        return BaseType::center();
    }

        /** Get the current direction. */
01457     Direction direction() const
    {
        return BaseType::direction();
    }

        /** Get the current direction bit. */
01463     unsigned int directionBit() const
    {
        return BaseType::directionBit();
    }

        /** Get the difference vector (Diff2D) from the center to the current neighbor. */
01469     Diff2D const & diff() const
    {
        return BaseType::diff();
    }

        /** Is the current neighbor a diagonal neighbor? */
01475     bool isDiagonal() const
    {
        return BaseType::isDiagonal();
    }

private:
     AtImageBorder whichBorder_;
     signed char count_, current_;
};

//@}

} // namespace vigra

#endif /* VIGRA_PIXELNEIGHBORHOOD_HXX */

Generated by  Doxygen 1.6.0   Back to index