[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

pixelneighborhood.hxx
1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2005 by Hans Meine, Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 #ifndef VIGRA_PIXELNEIGHBORHOOD_HXX
37 #define VIGRA_PIXELNEIGHBORHOOD_HXX
38 
39 #include "utilities.hxx"
40 
41 namespace vigra {
42 
43 /** \addtogroup PixelNeighborhood Utilities to manage pixel neighborhoods
44 
45  4- and 8-neighborhood definitions and circulators.
46 
47  <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
48 
49  <b>See also:</b> \ref vigra::NeighborhoodCirculator
50  */
51 //@{
52 
53 /********************************************************/
54 /* */
55 /* AtImageBorder */
56 /* */
57 /********************************************************/
58 
59 /** \brief Encode whether a point is near the image border.
60 
61  This enum is used with \ref isAtImageBorder() and
62  \ref vigra::RestrictedNeighborhoodCirculator.
63 
64  <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
65  Namespace: vigra
66 */
67 
69 {
70  NotAtBorder = 0, ///< &nbsp;
71  RightBorder = 1, ///< &nbsp;
72  LeftBorder = 2, ///< &nbsp;
73  TopBorder = 4, ///< &nbsp;
74  BottomBorder = 8, ///< &nbsp;
75  FrontBorder = 16, ///< &nbsp;
76  RearBorder = 32,
77  TopRightBorder = TopBorder | RightBorder, //5
78  TopLeftBorder = TopBorder | LeftBorder, //6
79  TopFrontBorder = TopBorder | FrontBorder, //20
80  TopRearBorder = TopBorder | RearBorder, //36
81  BottomLeftBorder = BottomBorder | LeftBorder, //10
82  BottomRightBorder = BottomBorder | RightBorder, //9
83  BottomFrontBorder = BottomBorder | FrontBorder, //24
84  BottomRearBorder = BottomBorder | RearBorder, //40
85  FrontLeftBorder = FrontBorder | LeftBorder, //18
86  FrontRightBorder = FrontBorder | RightBorder, //17
87  RearLeftBorder = RearBorder | LeftBorder, //34
88  RearRightBorder = RearBorder | RightBorder, //33
89 
90  TopRightFrontBorder = TopBorder | RightBorder | FrontBorder, //21
91  TopLeftFrontBorder = TopBorder | LeftBorder | FrontBorder, //22
92  BottomLeftFrontBorder = BottomBorder | LeftBorder | FrontBorder, //26
93  BottomRightFrontBorder = BottomBorder | RightBorder | FrontBorder, //25
94  TopRightRearBorder = TopBorder | RightBorder | RearBorder, //37
95  TopLeftRearBorder = TopBorder | LeftBorder | RearBorder, //38
96  BottomLeftRearBorder = BottomBorder | LeftBorder | RearBorder, //42
97  BottomRightRearBorder = BottomBorder | RightBorder | RearBorder //41
98 };
99 
100 
101 /** \brief Find out whether a point is at the image border.
102 
103  This function checks if \a x == 0 or \a x == \a width - 1 and
104  \a y == 0 or \a y == \a height - 1 and returns the appropriate value
105  of \ref vigra::AtImageBorder, or zero when the point is not at te image border.
106  The behavior of the function is undefined if (x,y) is not inside the image.
107 
108  <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
109  Namespace: vigra
110 */
111 inline AtImageBorder isAtImageBorder(int x, int y, int width, int height)
112 {
113  return static_cast<AtImageBorder>((x == 0
114  ? LeftBorder
115  : x == width-1
116  ? RightBorder
117  : NotAtBorder) |
118  (y == 0
119  ? TopBorder
120  : y == height-1
121  ? BottomBorder
122  : NotAtBorder));
123 }
124 
125 /********************************************************/
126 /* */
127 /* FourNeighborhood */
128 /* */
129 /********************************************************/
130 
131 /** Utilities for 4-neighborhood. */
132 namespace FourNeighborhood
133 {
134 
135 /** \brief Encapsulation of direction management for 4-neighborhood.
136 
137  This helper class allows the transformation between Freeman chain codes
138  (East = 0, North = 1 etc.) and the corresponding Diff2D instances
139  and back.
140 
141  You can either use the chain codes by explicit qualification:
142 
143  \code
144  // the following three lines are equivalent
145  FourNeighborhood::NeighborCode::Direction d = FourNeighborhood::NeighborCode::East;
146  FourNeighborCode::Direction d = FourNeighborCode::East;
147  FourNeighborhood::Direction d = FourNeighborhood::East;
148  \endcode
149 
150  or you can fix 4-neighborhood by importing the entire namespace in
151  your function:
152 
153  \code
154  using namespace FourNeighborhood;
155 
156  Direction d = East;
157  \endcode
158 
159  If you want to pass 4-neighborhood codes as a template parameter, use
160  the class FourNeighborhood::NeighborCode.
161 
162  <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
163  Namespace: vigra::FourNeighborhood
164 */
166 {
167  public:
168 
169  typedef Diff2D difference_type;
170 
171  /** Freeman direction codes for the 4-neighborhood.
172  <tt>East = 0</tt>, <tt>North = 1</tt> etc.
173  <tt>DirectionCount</tt> may be used for portable loop termination conditions.
174  <tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and last (inclusive)
175  neighbors in the causal neighborhood, i.e. in the set of neighbors that have
176  already been visited when the image is traversed in scan order.
177  <tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the opposite.
178  */
179  enum Direction {
180  Error = -1, ///< &nbsp;
181  East = 0, ///< &nbsp;
182  North, ///< &nbsp;
183  West, ///< &nbsp;
184  South, ///< &nbsp;
185  DirectionCount, ///< &nbsp;
186  CausalFirst = North, ///< &nbsp;
187  CausalLast = West, ///< &nbsp;
188  AntiCausalFirst = South, ///< &nbsp;
189  AntiCausalLast = East, ///< &nbsp;
190 
191  InitialDirection = East,
192  OppositeDirPrefix = 1,
193  OppositeOffset = West
194  };
195 
196  static unsigned int directionBit(Direction d)
197  {
198  static unsigned int b[] = {1 << East,
199  1 << North,
200  1 << West,
201  1 << South };
202  return b[d];
203  };
204 
205  /** The number of valid neighbors if the current center is at the image border.
206  */
208  {
209  static unsigned int c[] = { 4, 3, 3, 0, 3, 2, 2, 0, 3, 2, 2};
210  return c[b];
211  }
212 
213  /** The valid direction codes when the center is at the image border.
214  \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
215  */
217  {
218  static Direction c[11][4] = {
219  { East, North, West, South},
220  { North, West, South, Error},
221  { East, North, South, Error},
222  { Error, Error, Error, Error},
223  { East, West, South, Error},
224  { West, South, Error, Error},
225  { East, South, Error, Error},
226  { Error, Error, Error, Error},
227  { East, North, West, Error},
228  { North, West, Error, Error},
229  { East, North, Error, Error}
230  };
231  return c[b][index];
232  }
233 
234  /** Transform direction code into corresponding Diff2D offset.
235  (note: there is no bounds checking on the code you pass.)
236  */
237  static Diff2D const & diff(Direction code)
238  {
239  static Diff2D d[] = {
240  Diff2D(1, 0), Diff2D(0, -1), Diff2D(-1, 0), Diff2D(0, 1)
241  };
242  return d[code];
243  }
244 
245  /** Equivalent to <tt>diff(static_cast<Direction>(code))</tt>.
246  (note: there is no bounds checking on the code you pass.)
247  */
248  static Diff2D const & diff(int code) { return diff(static_cast<Direction>(code)); }
249 
250  /** Get the relative offset from one neighbor to the other.
251  For example, <tt>relativeDiff(East, West) == Diff2D(-2,0)</tt>.
252  (note: there is no bounds checking on the code you pass.)
253  */
254  static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
255  {
256  static Diff2D d[][4] = {
257  { Diff2D(0, 0), Diff2D(-1, -1), Diff2D(-2, 0), Diff2D(-1, 1) },
258  { Diff2D(1, 1), Diff2D(0, 0), Diff2D(-1, 1), Diff2D(0, 2) },
259  { Diff2D(2, 0), Diff2D(1, -1), Diff2D(0, 0), Diff2D(1, 1) },
260  { Diff2D(1, -1), Diff2D(0, -2), Diff2D(-1, -1), Diff2D(0, 0) }
261  };
262 
263  return d[fromCode][toCode];
264  }
265 
266  /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
267  (note: there is no bounds checking on the code you pass.)
268  */
269  static Diff2D const & relativeDiff(int fromCode, int toCode)
270  {
271  return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
272  }
273 
274  /** X-component of diff() */
275  static int dX(Direction code) { return diff(code).x; }
276  /** Y-component of diff() */
277  static int dY(Direction code) { return diff(code).y; }
278  /** X-component of diff() */
279  static int dX(int code) { return diff(code).x; }
280  /** Y-component of diff() */
281  static int dY(int code) { return diff(code).y; }
282 
283  /** Transform Diff2D offset into corresponding direction code.
284  The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
285  is not in the 4-neighborhood.
286  */
287  static Direction code(Diff2D const & diff)
288  {
289  switch(diff.x)
290  {
291  case 0:
292  {
293  switch(diff.y)
294  {
295  case 1:
296  return South;
297  case -1:
298  return North;
299  default:
300  return Error;
301  }
302  }
303  case -1:
304  {
305  return (diff.y == 0) ?
306  West :
307  Error;
308  }
309  case 1:
310  {
311  return (diff.y == 0) ?
312  East :
313  Error;
314  }
315  }
316  return Error;
317  }
318 
319  /** Check whether a code refers to a diagonal direction.
320  Useful if you want to abstract the differences between 4- and 8-neighborhood.
321  Always <tt>false</tt> for 4-neighborhood.
322  */
323  static bool isDiagonal(Direction) { return false; }
324 
325  static Diff2D const & right() { return diff(East); } /**< Offset to the right neighbor */
326  static Diff2D const & top() { return diff(North); } /**< Offset to the top neighbor */
327  static Diff2D const & left() { return diff(West); } /**< Offset to the left neighbor */
328  static Diff2D const & bottom() { return diff(South); } /**< Offset to the bottom neighbor */
329 
330  static Diff2D const & east() { return diff(East); } /**< Offset to the east neighbor */
331  static Diff2D const & north() { return diff(North); } /**< Offset to the north neighbor */
332  static Diff2D const & west() { return diff(West); } /**< Offset to the west neighbor */
333  static Diff2D const & south() { return diff(South); } /**< Offset to the south neighbor */
334 };
335 
336  /** Export NeighborCode::Direction into the scope of namespace FourNeighborhood.
337  */
339 
340 static const Direction Error = NeighborCode::Error; /**< Export NeighborCode::Error to namespace FourNeighborhood */
341 static const Direction East = NeighborCode::East; /**< Export NeighborCode::East to namespace FourNeighborhood */
342 static const Direction North = NeighborCode::North; /**< Export NeighborCode::North to namespace FourNeighborhood */
343 static const Direction West = NeighborCode::West; /**< Export NeighborCode::West to namespace FourNeighborhood */
344 static const Direction South = NeighborCode::South; /**< Export NeighborCode::South to namespace FourNeighborhood */
345 static const Direction DirectionCount = NeighborCode::DirectionCount; /**< Export NeighborCode::DirectionCount to namespace FourNeighborhood */
346 
347 inline Diff2D const & east() { return NeighborCode::diff(East); } /**< Offset to the east neighbor */
348 inline Diff2D const & north() { return NeighborCode::diff(North); } /**< Offset to the north neighbor */
349 inline Diff2D const & west() { return NeighborCode::diff(West); } /**< Offset to the west neighbor */
350 inline Diff2D const & south() { return NeighborCode::diff(South); } /**< Offset to the south neighbor */
351 
352 } // namespace FourNeighborhood
353 
354  /** Export \ref vigra::FourNeighborhood::NeighborCode into the scope of namespace vigra.
355  */
357 
358 /********************************************************/
359 /* */
360 /* EightNeighborhood */
361 /* */
362 /********************************************************/
363 
364 /** Utilities for 8-neighborhood. */
365 namespace EightNeighborhood
366 {
367 /** \brief Encapsulation of direction management for the 8-neighborhood.
368 
369  This helper class allows the transformation between Freeman chain codes
370  (East = 0, NorthEast = 1 etc.) and the corresponding Diff2D instances
371  and back.
372 
373  You can either use the chain codes by explicit qualification:
374 
375  \code
376  // the following three lines are equivalent
377  EightNeighborhood::NeighborCode::Direction d = EightNeighborhood::NeighborCode::East;
378  EightNeighborCode::Direction d = EightNeighborCode::East;
379  EightNeighborhood::Direction d = EightNeighborhood::East;
380  \endcode
381 
382  or you can fix 8-neighborhood by importing the entire namespace in
383  your function:
384 
385  \code
386  using namespace EightNeighborhood;
387 
388  Direction d = East;
389  \endcode
390 
391  If you want to pass 8-neighborhood codes as a template parameter, use
392  the class EightNeighborhood::NeighborCode.
393 
394  <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
395  Namespace: vigra::EightNeighborhood
396 */
398 {
399  public:
400 
401  typedef Diff2D difference_type;
402 
403  /** Freeman direction codes for the 8-neighborhood.
404  <tt>East = 0</tt>, <tt>North = 1</tt> etc.
405  <tt>DirectionCount</tt> may be used for portable loop termination conditions.
406  <tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and last (inclusive)
407  neighbors in the causal neighborhood, i.e. in the set of neighbors that have
408  already been visited when the image is traversed in scan order.
409  <tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the opposite.
410  */
411  enum Direction {
412  Error = -1, ///< &nbsp;
413  East = 0, ///< &nbsp;
414  NorthEast, ///< &nbsp;
415  North, ///< &nbsp;
416  NorthWest, ///< &nbsp;
417  West, ///< &nbsp;
418  SouthWest, ///< &nbsp;
419  South, ///< &nbsp;
420  SouthEast, ///< &nbsp;
421  DirectionCount, ///< &nbsp;
422  CausalFirst = NorthEast, ///< &nbsp;
423  CausalLast = West, ///< &nbsp;
424  AntiCausalFirst = SouthWest, ///< &nbsp;
425  AntiCausalLast = East, ///< &nbsp;
426 
427  InitialDirection = East,
428  OppositeDirPrefix = 1,
429  OppositeOffset = West
430  };
431 
432  static unsigned int directionBit(Direction d)
433  {
434  static unsigned int b[] = {1 << East,
435  1 << NorthEast,
436  1 << North,
437  1 << NorthWest,
438  1 << West,
439  1 << SouthWest,
440  1 << South,
441  1 << SouthEast};
442  return b[d];
443  };
444 
445  /** The number of valid neighbors if the current center is at the image border.
446  */
448  {
449  static unsigned int c[] = { 8, 5, 5, 0, 5, 3, 3, 0, 5, 3, 3};
450  return c[b];
451  }
452 
453  /** The valid direction codes when the center is at the image border.
454  \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
455  */
457  {
458  static Direction c[11][8] = {
460  { North, NorthWest, West, SouthWest, South, Error, Error, Error},
461  { East, NorthEast, North, South, SouthEast, Error, Error, Error},
462  { Error, Error, Error, Error, Error, Error, Error, Error},
463  { East, West, SouthWest, South, SouthEast, Error, Error, Error},
464  { West, SouthWest, South, Error, Error, Error, Error, Error},
465  { East, South, SouthEast, Error, Error, Error, Error, Error},
466  { Error, Error, Error, Error, Error, Error, Error, Error},
467  { East, NorthEast, North, NorthWest, West, Error, Error, Error},
468  { North, NorthWest, West, Error, Error, Error, Error, Error},
469  { East, NorthEast, North, Error, Error, Error, Error, Error}
470  };
471  return c[b][index];
472  }
473 
474  /** Transform direction code into corresponding Diff2D offset.
475  (note: there is no bounds checking on the code you pass.)
476  */
477  static Diff2D const & diff(Direction code)
478  {
479  static Diff2D d[] = {
480  Diff2D(1, 0), Diff2D(1, -1), Diff2D(0, -1), Diff2D(-1, -1),
481  Diff2D(-1, 0), Diff2D(-1, 1), Diff2D(0, 1), Diff2D(1, 1)
482  };
483  return d[code];
484  }
485 
486  /** Equivalent to diff(static_cast<Direction>(code)).
487  (note: there is no bounds checking on the code you pass.)
488  */
489  static Diff2D const & diff(int code) { return diff(static_cast<Direction>(code)); }
490 
491  /** Get the relative offset from one neighbor to the other.
492  For example, <tt>relativeDiff(East, West) == Diff2D(-2,0)</tt>.
493  (note: there is no bounds checking on the code you pass.)
494  */
495  static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
496  {
497  static Diff2D d[][8] = {
498  { Diff2D(0, 0), Diff2D(0, -1), Diff2D(-1, -1), Diff2D(-2, -1),
499  Diff2D(-2, 0), Diff2D(-2, 1), Diff2D(-1, 1), Diff2D(0, 1) },
500  { Diff2D(0, 1), Diff2D(0, 0), Diff2D(-1, 0), Diff2D(-2, 0),
501  Diff2D(-2, 1), Diff2D(-2, 2), Diff2D(-1, 2), Diff2D(0, 2) },
502  { Diff2D(1, 1), Diff2D(1, 0), Diff2D(0, 0), Diff2D(-1, 0),
503  Diff2D(-1, 1), Diff2D(-1, 2), Diff2D(0, 2), Diff2D(1, 2) },
504  { Diff2D(2, 1), Diff2D(2, 0), Diff2D(1, 0), Diff2D(0, 0),
505  Diff2D(0, 1), Diff2D(0, 2), Diff2D(1, 2), Diff2D(2, 2) },
506  { Diff2D(2, 0), Diff2D(2, -1), Diff2D(1, -1), Diff2D(0, -1),
507  Diff2D(0, 0), Diff2D(0, 1), Diff2D(1, 1), Diff2D(2, 1) },
508  { Diff2D(2, -1), Diff2D(2, -2), Diff2D(1, -2), Diff2D(0, -2),
509  Diff2D(0, -1), Diff2D(0, 0), Diff2D(1, 0), Diff2D(2, 0) },
510  { Diff2D(1, -1), Diff2D(1, -2), Diff2D(0, -2), Diff2D(-1, -2),
511  Diff2D(-1, -1), Diff2D(-1, 0), Diff2D(0, 0), Diff2D(1, 0) },
512  { Diff2D(0, -1), Diff2D(0, -2), Diff2D(-1, -2), Diff2D(-2, -2),
513  Diff2D(-2, -1), Diff2D(-2, 0), Diff2D(-1, 0), Diff2D(0, 0) }
514  };
515 
516  return d[fromCode][toCode];
517  }
518 
519  /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
520  (note: there is no bounds checking on the code you pass.)
521  */
522  static Diff2D const & relativeDiff(int fromCode, int toCode)
523  {
524  return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
525  }
526 
527  /** X-component of diff() */
528  static int dX(Direction code) { return diff(code).x; }
529  /** Y-component of diff() */
530  static int dY(Direction code) { return diff(code).y; }
531  /** X-component of diff() */
532  static int dX(int code) { return diff(code).x; }
533  /** Y-component of diff() */
534  static int dY(int code) { return diff(code).y; }
535 
536  /** Transform 4-neighborhood code into 8-neighborhood code.
537  */
539  { return static_cast<Direction>(2*d); }
540 
541  /** Transform Diff2D offset into corresponding direction code.
542  The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
543  is not in the 8-neighborhood.
544  */
545  static Direction code(Diff2D const & diff)
546  {
547  switch(diff.x)
548  {
549  case 0:
550  {
551  switch(diff.y)
552  {
553  case 1:
554  return South;
555  case -1:
556  return North;
557  default:
558  return Error;
559  }
560  }
561  case -1:
562  {
563  switch(diff.y)
564  {
565  case 0:
566  return West;
567  case 1:
568  return SouthWest;
569  case -1:
570  return NorthWest;
571  default:
572  return Error;
573  }
574  }
575  case 1:
576  {
577  switch(diff.y)
578  {
579  case 0:
580  return East;
581  case 1:
582  return SouthEast;
583  case -1:
584  return NorthEast;
585  default:
586  return Error;
587  }
588  }
589  }
590  return Error;
591  }
592 
593  /** Check whether a code refers to a diagonal direction.
594  Useful if you want to abstract the differences between 4- and 8-neighborhood.
595  */
596  static bool isDiagonal(Direction code) { return (code % 2) != 0; }
597 
598  static Diff2D const & right() { return diff(East); } /**< Offset to the right neighbor */
599  static Diff2D const & topRight() { return diff(NorthEast); } /**< Offset to the topRight neighbor */
600  static Diff2D const & top() { return diff(North); } /**< Offset to the top neighbor */
601  static Diff2D const & topLeft() { return diff(NorthWest); } /**< Offset to the topLeft neighbor */
602  static Diff2D const & left() { return diff(West); } /**< Offset to the left neighbor */
603  static Diff2D const & bottomLeft() { return diff(SouthWest); } /**< Offset to the bottomLeft neighbor */
604  static Diff2D const & bottom() { return diff(South); } /**< Offset to the bottom neighbor */
605  static Diff2D const & bottomRight() { return diff(SouthEast); } /**< Offset to the bottomRight neighbor */
606 
607  static Diff2D const & east() { return diff(East); } /**< Offset to the east neighbor */
608  static Diff2D const & northEast() { return diff(NorthEast); } /**< Offset to the northEast neighbor */
609  static Diff2D const & north() { return diff(North); } /**< Offset to the north neighbor */
610  static Diff2D const & northWest() { return diff(NorthWest); } /**< Offset to the northWest neighbor */
611  static Diff2D const & west() { return diff(West); } /**< Offset to the west neighbor */
612  static Diff2D const & southWest() { return diff(SouthWest); } /**< Offset to the southWest neighbor */
613  static Diff2D const & south() { return diff(South); } /**< Offset to the south neighbor */
614  static Diff2D const & southEast() { return diff(SouthEast); } /**< Offset to the southEast neighbor */
615 };
616 
617  /** Export NeighborCode::Direction into the scope of namespace EightNeighborhood.
618  */
620 
621 static const Direction East = NeighborCode::East; /**< Export NeighborCode::East to namespace EightNeighborhood */
622 static const Direction NorthEast = NeighborCode::NorthEast; /**< Export NeighborCode::NorthEast to namespace EightNeighborhood */
623 static const Direction North = NeighborCode::North; /**< Export NeighborCode::North to namespace EightNeighborhood */
624 static const Direction NorthWest = NeighborCode::NorthWest; /**< Export NeighborCode::NorthWest to namespace EightNeighborhood */
625 static const Direction West = NeighborCode::West; /**< Export NeighborCode::West to namespace EightNeighborhood */
626 static const Direction SouthWest = NeighborCode::SouthWest; /**< Export NeighborCode::SouthWest to namespace EightNeighborhood */
627 static const Direction South = NeighborCode::South; /**< Export NeighborCode::South to namespace EightNeighborhood */
628 static const Direction SouthEast = NeighborCode::SouthEast; /**< Export NeighborCode::SouthEast to namespace EightNeighborhood */
629 static const Direction DirectionCount = NeighborCode::DirectionCount; /**< Export NeighborCode::DirectionCount to namespace EightNeighborhood */
630 
631 inline Diff2D const & east() { return NeighborCode::diff(East); } /**< Offset to the east neighbor */
632 inline Diff2D const & northEast() { return NeighborCode::diff(NorthEast); } /**< Offset to the northEast neighbor */
633 inline Diff2D const & north() { return NeighborCode::diff(North); } /**< Offset to the north neighbor */
634 inline Diff2D const & northWest() { return NeighborCode::diff(NorthWest); } /**< Offset to the northWest neighbor */
635 inline Diff2D const & west() { return NeighborCode::diff(West); } /**< Offset to the west neighbor */
636 inline Diff2D const & southWest() { return NeighborCode::diff(SouthWest); } /**< Offset to the southWest neighbor */
637 inline Diff2D const & south() { return NeighborCode::diff(South); } /**< Offset to the south neighbor */
638 inline Diff2D const & southEast() { return NeighborCode::diff(SouthEast); } /**< Offset to the southEast neighbor */
639 
640 } // namespace EightNeighborhood
641 
642  /** Export \ref vigra::EightNeighborhood::NeighborCode into the scope of namespace vigra.
643  */
645 
646 /********************************************************/
647 /* */
648 /* NeighborOffsetCirculator */
649 /* */
650 /********************************************************/
651 
652 /** \brief Circulator that walks around a given location.
653 
654  The template parameter defines the kind of neighborhood used, e.g.
655 
656  \code
657  NeighborOffsetCirculator<EightNeighborCode> eight_circulator;
658  NeighborOffsetCirculator<FourNeighborCode> four_circulator;
659  \endcode
660 
661  Since this circulator doesn't now about the pixels in any particular image,
662  you usually doesn't use it directly but rather as a base class or helper for
663  neighborhood circulators refering to a particular image (e.g. NeighborhoodCirculator)
664 
665  <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
666  Namespace: vigra
667 */
668 template<class NEIGHBORCODE>
670 : public NEIGHBORCODE
671 {
672 public:
673  typedef NEIGHBORCODE NeighborCode;
674 
675  /** return type of direction()
676  */
677  typedef typename NEIGHBORCODE::Direction Direction;
678 
679  /** the circulator's value type
680  */
681  typedef typename NEIGHBORCODE::difference_type value_type;
682 
683  /** the circulator's reference type (return type of <TT>*circ</TT>)
684  */
685  typedef value_type const & reference;
686 
687  /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
688  */
689  typedef value_type const & index_reference;
690 
691  /** the circulator's pointer type (return type of <TT>operator-></TT>)
692  */
693  typedef value_type const * pointer;
694 
695  /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
696  */
697  typedef int difference_type;
698 
699  /** the circulator tag (random access iterator)
700  */
701  typedef random_access_circulator_tag iterator_category;
702 
703 protected:
704  Direction direction_;
705 
706 public:
707  /** Create circulator refering to the given direction.
708  */
709  NeighborOffsetCirculator(Direction dir = NEIGHBORCODE::InitialDirection)
710  : direction_(dir)
711  {
712  }
713 
714  /** pre-increment */
716  {
717  direction_ = static_cast<Direction>((direction_+1) % NEIGHBORCODE::DirectionCount);
718  return *this;
719  }
720 
721  /** pre-decrement */
723  {
724  direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::DirectionCount-1) % NEIGHBORCODE::DirectionCount);
725  return *this;
726  }
727 
728  /** post-increment */
730  {
731  NeighborOffsetCirculator ret(*this);
732  operator++();
733  return ret;
734  }
735 
736  /** post-decrement */
738  {
739  NeighborOffsetCirculator ret(*this);
740  operator--();
741  return ret;
742  }
743 
744  /** add-assignment */
746  {
747  direction_ = static_cast<Direction>((direction_ + d) % NEIGHBORCODE::DirectionCount);
748  if(direction_ < 0)
749  direction_ = static_cast<Direction>(direction_ + NEIGHBORCODE::DirectionCount);
750  return *this;
751  }
752 
753  /** subtract-assignment */
755  {
756  direction_ = static_cast<Direction>((direction_ - d) % NEIGHBORCODE::DirectionCount);
757  if(direction_ < 0)
758  direction_ = static_cast<Direction>(direction_ + NEIGHBORCODE::DirectionCount);
759  return *this;
760  }
761 
762  /** addition */
764  {
765  return NeighborOffsetCirculator(*this) += d;
766  }
767 
768  /** subtraction */
770  {
771  return NeighborOffsetCirculator(*this) -= d;
772  }
773 
774  /** Move to the direction that is 'right' relative to the current direction.
775  This is equivalent to <tt>four_circulator--</tt> and
776  <tt>eight_circulator -= 2</tt> respectively.
777  */
779  {
780  direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::South) % NEIGHBORCODE::DirectionCount);
781  return *this;
782  }
783 
784  /** Move to the direction that is 'left' relative to the current direction.
785  This is equivalent to <tt>four_circulator++</tt> and
786  <tt>eight_circulator += 2</tt> respectively.
787  */
789  {
790  direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::North) % NEIGHBORCODE::DirectionCount);
791  return *this;
792  }
793 
794  /** Move to the opposite direction of the current direction.
795  This is equivalent to <tt>four_circulator += 2</tt> and
796  <tt>eight_circulator += 4</tt> respectively.
797  */
799  {
800  direction_ = opposite();
801  return *this;
802  }
803 
804  /** Move to the given direction.
805  */
807  {
808  direction_ = d;
809  return *this;
810  }
811 
812  /** equality */
813  bool operator==(NeighborOffsetCirculator const & o) const
814  {
815  return direction_ == o.direction_;
816  }
817 
818  /** unequality */
819  bool operator!=(NeighborOffsetCirculator const & o) const
820  {
821  return direction_ != o.direction_;
822  }
823 
824  /** subtraction */
826  {
827  return direction_ - o.direction_;
828  }
829 
830  /** dereference */
832  {
833  return diff();
834  }
835 
836  /** index */
838  {
839  return NEIGHBORCODE::diff(direction(d));
840  }
841 
842  /** member access */
844  {
845  return &diff();
846  }
847 
848  /** Get offset from center to current neighbor.
849  */
850  reference diff() const
851  {
852  return NEIGHBORCODE::diff(direction_);
853  }
854 
855  /** Get offset to given direction.
856  */
858  {
859  return NEIGHBORCODE::diff(dir);
860  }
861 
862  /** Get relative distance from current neighbor to neighbor
863  at given offset.
864  */
866  {
867  Direction toDir = static_cast<Direction>((direction_ + offset) % NEIGHBORCODE::DirectionCount);
868  if(toDir < 0)
869  toDir = static_cast<Direction>(toDir + NEIGHBORCODE::DirectionCount);
870  return NEIGHBORCODE::relativeDiff(direction_, toDir);
871  }
872 
873  /** X-component of diff() */
874  int dX() const
875  {
876  return NEIGHBORCODE::dX(direction_);
877  }
878 
879  /** Y-component of diff() */
880  int dY() const
881  {
882  return NEIGHBORCODE::dY(direction_);
883  }
884 
885  /** Check whether current direction is a diagonal one.
886  */
887  bool isDiagonal() const
888  {
889  return NEIGHBORCODE::isDiagonal(direction_);
890  }
891 
892  /** Get current direction.
893  */
895  {
896  return direction_;
897  }
898 
899  /** Get current direction bit.
900  */
901  unsigned int directionBit() const
902  {
903  return NEIGHBORCODE::directionBit(direction_);
904  }
905 
906  /** Get opposite of current direction.
907  */
909  {
910  return static_cast<Direction>((NEIGHBORCODE::OppositeDirPrefix*direction_ + NEIGHBORCODE::OppositeOffset) % NEIGHBORCODE::DirectionCount);
911  }
912 
913  /** Get opposite bit of current direction.
914  */
915  unsigned int oppositeDirectionBit() const
916  {
918  }
919 
920  /** Get direction code at offset of current direction.
921  */
923  {
924  int result = (direction_ + offset) % NEIGHBORCODE::DirectionCount;
925  if(result < 0)
926  result += NEIGHBORCODE::DirectionCount;
927  return static_cast<Direction>(result);
928  }
929 };
930 
931 /** Specialization of NeighborOffsetCirculator for 8-neighborhood.
932 */
934 
935 /** Specialization of NeighborOffsetCirculator for 4-neighborhood.
936 */
938 
939 
940 //@}
941 
942 /** \addtogroup ImageIteratorAdapters
943  */
944 //@{
945 
946 /********************************************************/
947 /* */
948 /* NeighborhoodCirculator */
949 /* */
950 /********************************************************/
951 
952 /** \brief Circulator that walks around a given location in a given image.
953 
954  The template parameters define the kind of neighborhood used and the underlying
955  image. The access functions return the value of the current neighbor pixel.
956  Use <tt>center()</tt> to access the center pixel of the neighborhood.
957  The center can be changed by calling <tt>moveCenterToNeighbor()</tt>
958  or <tt>swapCenterNeighbor()</tt>. Note that this circulator cannot
959  when the center is at the image border. You must then use
960  \ref vigra::RestrictedNeighborhoodCirculator
961 
962  <b>Usage:</b><br>
963 
964  <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
965  Namespace: vigra
966 
967  \code
968  BImage::traverser upperleft(...), lowerright(...);
969 
970  int width = lowerright.x - upperleft.x;
971  int height = lowerright.y - upperleft.y;
972 
973  ++upperleft.y; // avoid image border
974  for(int y=1; y<height-1; ++y, ++upperleft.y)
975  {
976  BImage::traverser ix = upperleft + Diff2D(1,0);
977  for(int x=1; x<width-1; ++x, ++ix.x)
978  {
979  // analyse all neighbors of a pixel (use FourNeighborCode
980  // instead of EightNeighborCode for 4-neighborhood):
981  NeighborhoodCirculator<BImage::traverser, EightNeighborCode>
982  circulator(ix),
983  end(circulator);
984  do
985  {
986  analysisFunc(*circulator, ...); // do sth. with current neighbor
987  }
988  while(++circulator != end); // compare with start/end circulator
989  }
990  }
991  \endcode
992 */
993 template <class IMAGEITERATOR, class NEIGHBORCODE>
994 class NeighborhoodCirculator : private IMAGEITERATOR
995 {
997 
998 
999 public:
1000  /** type of the underlying image iterator
1001  */
1002  typedef IMAGEITERATOR base_type;
1003 
1004  /** type of the used neighbor code
1005  */
1006  typedef NEIGHBORCODE NeighborCode;
1007 
1008  /** the circulator's value type
1009  */
1010  typedef typename IMAGEITERATOR::value_type value_type;
1011 
1012  /** type of the direction code
1013  */
1014  typedef typename NEIGHBORCODE::Direction Direction;
1015 
1016  /** the circulator's reference type (return type of <TT>*circ</TT>)
1017  */
1018  typedef typename IMAGEITERATOR::reference reference;
1019 
1020  /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
1021  */
1022 
1024 
1025  /** the circulator's pointer type (return type of <TT>operator-></TT>)
1026  */
1027  typedef typename IMAGEITERATOR::pointer pointer;
1028 
1029  /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
1030  */
1032 
1033  /** the circulator tag (random_access_circulator_tag)
1034  */
1036 
1037  /** Construct circulator with given <tt>center</tt> pixel, pointing to the neighbor
1038  at the given direction <tt>d</tt>.
1039  */
1040  NeighborhoodCirculator(IMAGEITERATOR const & center = IMAGEITERATOR(),
1041  Direction d = NEIGHBOROFFSETCIRCULATOR::InitialDirection)
1042  : IMAGEITERATOR(center), neighborCode_(d)
1043  {
1044  IMAGEITERATOR::operator+=(neighborCode_.diff());
1045  }
1046 
1047  /** pre-increment */
1049  {
1050  return operator+=(1);
1051  }
1052 
1053  /** pre-decrement */
1055  {
1056  NeighborhoodCirculator ret(*this);
1057  operator++();
1058  return ret;
1059  }
1060 
1061  /** post-increment */
1063  {
1064  return operator+=(-1);
1065  }
1066 
1067  /** post-decrement */
1069  {
1070  NeighborhoodCirculator ret(*this);
1071  operator--();
1072  return ret;
1073  }
1074 
1075  /** add-assignment */
1077  {
1078  IMAGEITERATOR::operator+=(neighborCode_.relativeDiff(d));
1079  neighborCode_+= d;
1080  return *this;
1081  }
1082 
1083  /** subtract-assignment */
1085  {
1086  return operator+=(-d);
1087  }
1088 
1089  /** addition */
1091  {
1092  NeighborhoodCirculator result(*this);
1093  result+= d;
1094  return result;
1095  }
1096 
1097  /** subtraction */
1099  {
1100  NeighborhoodCirculator result(*this);
1101  result-= d;
1102  return result;
1103  }
1104 
1105  /** Move to the direction that is 'right' relative to the current direction.
1106  This is equivalent to <tt>four_circulator--</tt> and
1107  <tt>eight_circulator -= 2</tt> respectively.
1108  */
1110  {
1111  Direction oldDirection = neighborCode_.direction();
1112  neighborCode_.turnRight();
1113  IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
1114  (oldDirection, neighborCode_.direction()));
1115  return *this;
1116  }
1117 
1118  /** Move to the direction that is 'left' relative to the current direction.
1119  This is equivalent to <tt>four_circulator++</tt> and
1120  <tt>eight_circulator += 2</tt> respectively.
1121  */
1123  {
1124  Direction oldDirection = neighborCode_.direction();
1125  neighborCode_.turnLeft();
1126  IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
1127  (oldDirection, neighborCode_.direction()));
1128  return *this;
1129  }
1130 
1131  /** Move to the opposite direction of the current direction.
1132  This is equivalent to <tt>four_circulator += 2</tt> and
1133  <tt>eight_circulator += 4</tt> respectively.
1134  */
1136  {
1137  Direction oldDirection = neighborCode_.direction();
1138  neighborCode_.turnRound();
1139  IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
1140  (oldDirection, neighborCode_.direction()));
1141  return *this;
1142  }
1143 
1144  /** Move to the given direction.
1145  */
1147  {
1148  Direction oldDirection = neighborCode_.direction();
1149  neighborCode_.turnTo(d);
1150  IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
1151  (oldDirection, neighborCode_.direction()));
1152  return *this;
1153  }
1154 
1155  /** Move the center in the current direction.
1156  The current neighbor becomes the new center, the direction does not change.
1157  */
1159  {
1160  IMAGEITERATOR::operator+=(neighborCode_.diff());
1161  return *this;
1162  }
1163 
1164  /** Exchange the center with the current neighbor.
1165  Equivalent to <tt>circ.moveCenterToNeighbor().turnRound()</tt>
1166  (but shorter and more efficient).
1167  */
1169  {
1170  neighborCode_.turnRound();
1171  IMAGEITERATOR::operator+=(neighborCode_.diff());
1172  return *this;
1173  }
1174 
1175  /** equality */
1176  bool operator==(NeighborhoodCirculator const & rhs) const
1177  {
1178  return neighborCode_ == rhs.neighborCode_ &&
1180  }
1181 
1182  /** inequality */
1183  bool operator!=(NeighborhoodCirculator const & rhs) const
1184  {
1185  return neighborCode_ != rhs.neighborCode_ ||
1187  }
1188 
1189  /** subtraction */
1191  {
1192  return neighborCode_ - rhs.neighborCode_;
1193  }
1194 
1195  /** dereference */
1197  {
1198  return IMAGEITERATOR::operator*();
1199  }
1200 
1201  /** index */
1203  {
1204  return IMAGEITERATOR::operator[](neighborCode_.relativeDiff(d));
1205  }
1206 
1207  /** member access */
1209  {
1210  return IMAGEITERATOR::operator->();
1211  }
1212 
1213  /** Get the base iterator for the current neighbor. */
1214  base_type const & base() const
1215  {
1216  return *this;
1217  }
1218 
1219  /** Get the base iterator for the center of the circulator. */
1221  {
1222  return (base_type)*this - neighborCode_.diff();
1223  }
1224 
1225  /** Get the current direction. */
1227  {
1228  return neighborCode_.direction();
1229  }
1230 
1231  /** Get the current direction bit. */
1232  unsigned int directionBit() const
1233  {
1234  return neighborCode_.directionBit();
1235  }
1236 
1237  /** Get the difference vector (Diff2D) from the center to the current neighbor. */
1239  {
1240  return neighborCode_.diff();
1241  }
1242 
1243  /** Is the current neighbor a diagonal neighbor? */
1244  bool isDiagonal() const
1245  {
1246  return neighborCode_.isDiagonal();
1247  }
1248 
1249 private:
1250  NEIGHBOROFFSETCIRCULATOR neighborCode_;
1251 };
1252 
1253 /********************************************************/
1254 /* */
1255 /* RestrictedNeighborhoodCirculator */
1256 /* */
1257 /********************************************************/
1258 
1259 /** \brief Circulator that walks around a given location in a given image,
1260  unsing a restricted neighborhood.
1261 
1262  This circulator behaves essentially like \ref vigra::NeighborhoodCirculator,
1263  but can also be used near the image border, where some of the neighbor points
1264  would be outside the image und must not be accessed.
1265  The template parameters define the kind of neighborhood used (four or eight)
1266  and the underlying image, whereas the required neighbirhood restriction is
1267  given by the last constructur argument. This below for typical usage.
1268 
1269  The access functions return the value of the current neighbor pixel. Use <tt>center()</tt> to
1270  access the center pixel of the neighborhood.
1271 
1272  <b>Usage:</b><br>
1273 
1274  <b>\#include</b> <<a href="pixelneighborhood_8hxx-source.html">vigra/pixelneighborhood.hxx</a>><br>
1275  Namespace: vigra
1276 
1277  \code
1278  BImage::traverser upperleft(...), lowerright(...);
1279 
1280  int width = lowerright.x - upperleft.x;
1281  int height = lowerright.y - upperleft.y;
1282 
1283  for(int y=0; y<height; ++y, ++upperleft.y)
1284  {
1285  BImage::traverser ix = upperleft;
1286  for(int x=0; x<width; ++x, ++ix.x)
1287  {
1288  // use FourNeighborCode instead of EightNeighborCode for 4-neighborhood
1289  RestrictedNeighborhoodCirculator<BImage::traverser, EightNeighborCode>
1290  circulator(ix, isAtImageBorder(x, y, width, height)),
1291  end(circulator);
1292  do
1293  {
1294  ... // do something with the circulator
1295  }
1296  while(++circulator != end); // out-of-range pixels will be automatically skipped
1297  }
1298  }
1299  \endcode
1300 */
1301 template <class IMAGEITERATOR, class NEIGHBORCODE>
1303 : private NeighborhoodCirculator<IMAGEITERATOR, NEIGHBORCODE>
1304 {
1306 
1307 public:
1308  /** type of the underlying image iterator
1309  */
1310  typedef IMAGEITERATOR base_type;
1311 
1312  /** type of the used neighbor code
1313  */
1314  typedef NEIGHBORCODE NeighborCode;
1315 
1316  /** the circulator's value type
1317  */
1319 
1320  /** type of the direction code
1321  */
1322  typedef typename BaseType::Direction Direction;
1323 
1324  /** the circulator's reference type (return type of <TT>*circ</TT>)
1325  */
1326  typedef typename BaseType::reference reference;
1327 
1328  /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
1329  */
1331 
1332  /** the circulator's pointer type (return type of <TT>operator-></TT>)
1333  */
1334  typedef typename BaseType::pointer pointer;
1335 
1336  /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
1337  */
1339 
1340  /** the circulator tag (random_access_circulator_tag)
1341  */
1343 
1344  /** Construct circulator with given <tt>center</tt> pixel, using the restricted
1345  neighborhood given by \a atBorder.
1346  */
1347  RestrictedNeighborhoodCirculator(IMAGEITERATOR const & center = IMAGEITERATOR(),
1348  AtImageBorder atBorder = NotAtBorder)
1349  : BaseType(center, NEIGHBORCODE::nearBorderDirections(atBorder, 0)),
1350  whichBorder_(atBorder),
1351  count_(NEIGHBORCODE::nearBorderDirectionCount(atBorder)),
1352  current_(0)
1353  {}
1354 
1355  /** pre-increment */
1357  {
1358  return operator+=(1);
1359  }
1360 
1361  /** pre-decrement */
1363  {
1365  operator++();
1366  return ret;
1367  }
1368 
1369  /** post-increment */
1371  {
1372  return operator+=(-1);
1373  }
1374 
1375  /** post-decrement */
1377  {
1379  operator--();
1380  return ret;
1381  }
1382 
1383  /** add-assignment */
1385  {
1386  current_ = static_cast<Direction>((current_ + count_ + d) % count_);
1387  BaseType::turnTo(NEIGHBORCODE::nearBorderDirections(whichBorder_, current_));
1388  return *this;
1389  }
1390 
1391  /** subtract-assignment */
1393  {
1394  return operator+=(-d);
1395  }
1396 
1397  /** addition */
1399  {
1400  RestrictedNeighborhoodCirculator result(*this);
1401  result+= d;
1402  return result;
1403  }
1404 
1405  /** subtraction */
1407  {
1408  RestrictedNeighborhoodCirculator result(*this);
1409  result-= d;
1410  return result;
1411  }
1412 
1413  /** equality */
1415  {
1416  return current_ == rhs.current_;
1417  }
1418 
1419  /** inequality */
1421  {
1422  return current_ != rhs.current_;
1423  }
1424 
1425  /** subtraction */
1427  {
1428  return (current_ - rhs.current_) % count_;
1429  }
1430 
1431  /** dereference */
1433  {
1434  return BaseType::operator*();
1435  }
1436 
1437  /** member access */
1439  {
1440  return BaseType::operator->();
1441  }
1442 
1443  /** Get the base iterator for the current neighbor. */
1444  base_type const & base() const
1445  {
1446  return BaseType::base();
1447  }
1448 
1449  /** Get the base iterator for the center of the circulator. */
1451  {
1452  return BaseType::center();
1453  }
1454 
1455  /** Get the current direction. */
1457  {
1458  return BaseType::direction();
1459  }
1460 
1461  /** Get the current direction bit. */
1462  unsigned int directionBit() const
1463  {
1464  return BaseType::directionBit();
1465  }
1466 
1467  /** Get the difference vector (Diff2D) from the center to the current neighbor. */
1468  typename NeighborCode::difference_type const & diff() const
1469  {
1470  return BaseType::diff();
1471  }
1472 
1473  /** Is the current neighbor a diagonal neighbor? */
1474  bool isDiagonal() const
1475  {
1476  return BaseType::isDiagonal();
1477  }
1478 
1479 private:
1480  AtImageBorder whichBorder_;
1481  signed char count_, current_;
1482 };
1483 
1484 //@}
1485 
1486 } // namespace vigra
1487 
1488 #endif /* VIGRA_PIXELNEIGHBORHOOD_HXX */

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.7.1 (Tue Jul 10 2012)