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

pixelneighborhood.hxx VIGRA

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> <vigra/pixelneighborhood.hxx><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> <vigra/pixelneighborhood.hxx><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 the image border.
106  The behavior of the function is undefined if (x,y) is not inside the image.
107 
108  <b>\#include</b> <vigra/pixelneighborhood.hxx><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> <vigra/pixelneighborhood.hxx><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  template <int DUMMY>
197  struct StaticData
198  {
199  static unsigned int b[];
200  static unsigned int c[];
201  static Direction bd[11][4];
202  static Diff2D d[];
203  static Diff2D rd[][4];
204  };
205 
206  static unsigned int directionBit(Direction d)
207  {
208  return StaticData<0>::b[d];
209  };
210 
211  /** The number of valid neighbors if the current center is at the image border.
212  */
214  {
215  return StaticData<0>::c[b];
216  }
217 
218  /** The valid direction codes when the center is at the image border.
219  \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
220  */
222  {
223  return StaticData<0>::bd[b][index];
224  }
225 
226  /** Transform direction code into corresponding Diff2D offset.
227  (note: there is no bounds checking on the code you pass.)
228  */
229  static Diff2D const & diff(Direction code)
230  {
231  return StaticData<0>::d[code];
232  }
233 
234  /** Equivalent to <tt>diff(static_cast<Direction>(code))</tt>.
235  (note: there is no bounds checking on the code you pass.)
236  */
237  static Diff2D const & diff(int code) { return diff(static_cast<Direction>(code)); }
238 
239  /** Get the relative offset from one neighbor to the other.
240  For example, <tt>relativeDiff(East, West) == Diff2D(-2,0)</tt>.
241  (note: there is no bounds checking on the code you pass.)
242  */
243  static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
244  {
245  return StaticData<0>::rd[fromCode][toCode];
246  }
247 
248  /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
249  (note: there is no bounds checking on the code you pass.)
250  */
251  static Diff2D const & relativeDiff(int fromCode, int toCode)
252  {
253  return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
254  }
255 
256  /** X-component of diff() */
257  static int dX(Direction code) { return diff(code).x; }
258  /** Y-component of diff() */
259  static int dY(Direction code) { return diff(code).y; }
260  /** X-component of diff() */
261  static int dX(int code) { return diff(code).x; }
262  /** Y-component of diff() */
263  static int dY(int code) { return diff(code).y; }
264 
265  /** Transform Diff2D offset into corresponding direction code.
266  The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
267  is not in the 4-neighborhood.
268  */
269  static Direction code(Diff2D const & diff)
270  {
271  switch(diff.x)
272  {
273  case 0:
274  {
275  switch(diff.y)
276  {
277  case 1:
278  return South;
279  case -1:
280  return North;
281  default:
282  return Error;
283  }
284  }
285  case -1:
286  {
287  return (diff.y == 0) ?
288  West :
289  Error;
290  }
291  case 1:
292  {
293  return (diff.y == 0) ?
294  East :
295  Error;
296  }
297  }
298  return Error;
299  }
300 
301  /** Check whether a code refers to a diagonal direction.
302  Useful if you want to abstract the differences between 4- and 8-neighborhood.
303  Always <tt>false</tt> for 4-neighborhood.
304  */
305  static bool isDiagonal(Direction) { return false; }
306 
307  static Diff2D const & right() { return diff(East); } /**< Offset to the right neighbor */
308  static Diff2D const & top() { return diff(North); } /**< Offset to the top neighbor */
309  static Diff2D const & left() { return diff(West); } /**< Offset to the left neighbor */
310  static Diff2D const & bottom() { return diff(South); } /**< Offset to the bottom neighbor */
311 
312  static Diff2D const & east() { return diff(East); } /**< Offset to the east neighbor */
313  static Diff2D const & north() { return diff(North); } /**< Offset to the north neighbor */
314  static Diff2D const & west() { return diff(West); } /**< Offset to the west neighbor */
315  static Diff2D const & south() { return diff(South); } /**< Offset to the south neighbor */
316 };
317 
318 
319  /** Export NeighborCode::Direction into the scope of namespace FourNeighborhood.
320  */
322 
323 static const Direction Error = NeighborCode::Error; /**< Export NeighborCode::Error to namespace FourNeighborhood */
324 static const Direction East = NeighborCode::East; /**< Export NeighborCode::East to namespace FourNeighborhood */
325 static const Direction North = NeighborCode::North; /**< Export NeighborCode::North to namespace FourNeighborhood */
326 static const Direction West = NeighborCode::West; /**< Export NeighborCode::West to namespace FourNeighborhood */
327 static const Direction South = NeighborCode::South; /**< Export NeighborCode::South to namespace FourNeighborhood */
328 static const Direction DirectionCount = NeighborCode::DirectionCount; /**< Export NeighborCode::DirectionCount to namespace FourNeighborhood */
329 
330 inline Diff2D const & east() { return NeighborCode::diff(East); } /**< Offset to the east neighbor */
331 inline Diff2D const & north() { return NeighborCode::diff(North); } /**< Offset to the north neighbor */
332 inline Diff2D const & west() { return NeighborCode::diff(West); } /**< Offset to the west neighbor */
333 inline Diff2D const & south() { return NeighborCode::diff(South); } /**< Offset to the south neighbor */
334 
335 
336 template <int DUMMY>
337 unsigned int NeighborCode::StaticData<DUMMY>::b[] = {1 << East,
338  1 << North,
339  1 << West,
340  1 << South };
341 
342 template <int DUMMY>
343 unsigned int NeighborCode::StaticData<DUMMY>::c[] = { 4, 3, 3, 0, 3, 2, 2, 0, 3, 2, 2};
344 
345 template <int DUMMY>
346 Direction NeighborCode::StaticData<DUMMY>::bd[11][4] = {
347  { East, North, West, South},
348  { North, West, South, Error},
349  { East, North, South, Error},
350  { Error, Error, Error, Error},
351  { East, West, South, Error},
352  { West, South, Error, Error},
353  { East, South, Error, Error},
354  { Error, Error, Error, Error},
355  { East, North, West, Error},
356  { North, West, Error, Error},
357  { East, North, Error, Error}
358  };
359 
360 template <int DUMMY>
361 Diff2D NeighborCode::StaticData<DUMMY>::d[] = {
362  Diff2D(1, 0), Diff2D(0, -1), Diff2D(-1, 0), Diff2D(0, 1)
363  };
364 
365 template <int DUMMY>
366 Diff2D NeighborCode::StaticData<DUMMY>::rd[][4] = {
367  { Diff2D(0, 0), Diff2D(-1, -1), Diff2D(-2, 0), Diff2D(-1, 1) },
368  { Diff2D(1, 1), Diff2D(0, 0), Diff2D(-1, 1), Diff2D(0, 2) },
369  { Diff2D(2, 0), Diff2D(1, -1), Diff2D(0, 0), Diff2D(1, 1) },
370  { Diff2D(1, -1), Diff2D(0, -2), Diff2D(-1, -1), Diff2D(0, 0) }
371  };
372 
373 } // namespace FourNeighborhood
374 
375 
376 
377  /** Export \ref vigra::FourNeighborhood::NeighborCode into the scope of namespace vigra.
378  */
380 
381 /********************************************************/
382 /* */
383 /* EightNeighborhood */
384 /* */
385 /********************************************************/
386 
387 /** Utilities for 8-neighborhood. */
388 namespace EightNeighborhood
389 {
390 /** \brief Encapsulation of direction management for the 8-neighborhood.
391 
392  This helper class allows the transformation between Freeman chain codes
393  (East = 0, NorthEast = 1 etc.) and the corresponding Diff2D instances
394  and back.
395 
396  You can either use the chain codes by explicit qualification:
397 
398  \code
399  // the following three lines are equivalent
400  EightNeighborhood::NeighborCode::Direction d = EightNeighborhood::NeighborCode::East;
401  EightNeighborCode::Direction d = EightNeighborCode::East;
402  EightNeighborhood::Direction d = EightNeighborhood::East;
403  \endcode
404 
405  or you can fix 8-neighborhood by importing the entire namespace in
406  your function:
407 
408  \code
409  using namespace EightNeighborhood;
410 
411  Direction d = East;
412  \endcode
413 
414  If you want to pass 8-neighborhood codes as a template parameter, use
415  the class EightNeighborhood::NeighborCode.
416 
417  <b>\#include</b> <vigra/pixelneighborhood.hxx><br>
418  Namespace: vigra::EightNeighborhood
419 */
421 {
422  public:
423 
424  typedef Diff2D difference_type;
425 
426  /** Freeman direction codes for the 8-neighborhood.
427  <tt>East = 0</tt>, <tt>North = 1</tt> etc.
428  <tt>DirectionCount</tt> may be used for portable loop termination conditions.
429  <tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and last (inclusive)
430  neighbors in the causal neighborhood, i.e. in the set of neighbors that have
431  already been visited when the image is traversed in scan order.
432  <tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the opposite.
433  */
434  enum Direction {
435  Error = -1, ///< &nbsp;
436  East = 0, ///< &nbsp;
437  NorthEast, ///< &nbsp;
438  North, ///< &nbsp;
439  NorthWest, ///< &nbsp;
440  West, ///< &nbsp;
441  SouthWest, ///< &nbsp;
442  South, ///< &nbsp;
443  SouthEast, ///< &nbsp;
444  DirectionCount, ///< &nbsp;
445  CausalFirst = NorthEast, ///< &nbsp;
446  CausalLast = West, ///< &nbsp;
447  AntiCausalFirst = SouthWest, ///< &nbsp;
448  AntiCausalLast = East, ///< &nbsp;
449 
450  InitialDirection = East,
451  OppositeDirPrefix = 1,
452  OppositeOffset = West
453  };
454 
455  template <int DUMMY>
456  struct StaticData
457  {
458  static unsigned int b[];
459  static unsigned int c[];
460  static Direction bd[11][8];
461  static Diff2D d[];
462  static Diff2D rd[][8];
463  };
464 
465  static unsigned int directionBit(Direction d)
466  {
467  return StaticData<0>::b[d];
468  };
469 
470  /** The number of valid neighbors if the current center is at the image border.
471  */
473  {
474  return StaticData<0>::c[b];
475  }
476 
477  /** The valid direction codes when the center is at the image border.
478  \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
479  */
481  {
482  return StaticData<0>::bd[b][index];
483  }
484 
485  /** Transform direction code into corresponding Diff2D offset.
486  (note: there is no bounds checking on the code you pass.)
487  */
488  static Diff2D const & diff(Direction code)
489  {
490  return StaticData<0>::d[code];
491  }
492 
493  /** Equivalent to diff(static_cast<Direction>(code)).
494  (note: there is no bounds checking on the code you pass.)
495  */
496  static Diff2D const & diff(int code) { return diff(static_cast<Direction>(code)); }
497 
498  /** Get the relative offset from one neighbor to the other.
499  For example, <tt>relativeDiff(East, West) == Diff2D(-2,0)</tt>.
500  (note: there is no bounds checking on the code you pass.)
501  */
502  static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
503  {
504  return StaticData<0>::rd[fromCode][toCode];
505  }
506 
507  /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
508  (note: there is no bounds checking on the code you pass.)
509  */
510  static Diff2D const & relativeDiff(int fromCode, int toCode)
511  {
512  return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
513  }
514 
515  /** X-component of diff() */
516  static int dX(Direction code) { return diff(code).x; }
517  /** Y-component of diff() */
518  static int dY(Direction code) { return diff(code).y; }
519  /** X-component of diff() */
520  static int dX(int code) { return diff(code).x; }
521  /** Y-component of diff() */
522  static int dY(int code) { return diff(code).y; }
523 
524  /** Transform 4-neighborhood code into 8-neighborhood code.
525  */
527  { return static_cast<Direction>(2*d); }
528 
529  /** Transform Diff2D offset into corresponding direction code.
530  The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
531  is not in the 8-neighborhood.
532  */
533  static Direction code(Diff2D const & diff)
534  {
535  switch(diff.x)
536  {
537  case 0:
538  {
539  switch(diff.y)
540  {
541  case 1:
542  return South;
543  case -1:
544  return North;
545  default:
546  return Error;
547  }
548  }
549  case -1:
550  {
551  switch(diff.y)
552  {
553  case 0:
554  return West;
555  case 1:
556  return SouthWest;
557  case -1:
558  return NorthWest;
559  default:
560  return Error;
561  }
562  }
563  case 1:
564  {
565  switch(diff.y)
566  {
567  case 0:
568  return East;
569  case 1:
570  return SouthEast;
571  case -1:
572  return NorthEast;
573  default:
574  return Error;
575  }
576  }
577  }
578  return Error;
579  }
580 
581  /** Check whether a code refers to a diagonal direction.
582  Useful if you want to abstract the differences between 4- and 8-neighborhood.
583  */
584  static bool isDiagonal(Direction code) { return (code % 2) != 0; }
585 
586  static Diff2D const & right() { return diff(East); } /**< Offset to the right neighbor */
587  static Diff2D const & topRight() { return diff(NorthEast); } /**< Offset to the topRight neighbor */
588  static Diff2D const & top() { return diff(North); } /**< Offset to the top neighbor */
589  static Diff2D const & topLeft() { return diff(NorthWest); } /**< Offset to the topLeft neighbor */
590  static Diff2D const & left() { return diff(West); } /**< Offset to the left neighbor */
591  static Diff2D const & bottomLeft() { return diff(SouthWest); } /**< Offset to the bottomLeft neighbor */
592  static Diff2D const & bottom() { return diff(South); } /**< Offset to the bottom neighbor */
593  static Diff2D const & bottomRight() { return diff(SouthEast); } /**< Offset to the bottomRight neighbor */
594 
595  static Diff2D const & east() { return diff(East); } /**< Offset to the east neighbor */
596  static Diff2D const & northEast() { return diff(NorthEast); } /**< Offset to the northEast neighbor */
597  static Diff2D const & north() { return diff(North); } /**< Offset to the north neighbor */
598  static Diff2D const & northWest() { return diff(NorthWest); } /**< Offset to the northWest neighbor */
599  static Diff2D const & west() { return diff(West); } /**< Offset to the west neighbor */
600  static Diff2D const & southWest() { return diff(SouthWest); } /**< Offset to the southWest neighbor */
601  static Diff2D const & south() { return diff(South); } /**< Offset to the south neighbor */
602  static Diff2D const & southEast() { return diff(SouthEast); } /**< Offset to the southEast neighbor */
603 };
604 
605  /** Export NeighborCode::Direction into the scope of namespace EightNeighborhood.
606  */
608 
609 static const Direction East = NeighborCode::East; /**< Export NeighborCode::East to namespace EightNeighborhood */
610 static const Direction NorthEast = NeighborCode::NorthEast; /**< Export NeighborCode::NorthEast to namespace EightNeighborhood */
611 static const Direction North = NeighborCode::North; /**< Export NeighborCode::North to namespace EightNeighborhood */
612 static const Direction NorthWest = NeighborCode::NorthWest; /**< Export NeighborCode::NorthWest to namespace EightNeighborhood */
613 static const Direction West = NeighborCode::West; /**< Export NeighborCode::West to namespace EightNeighborhood */
614 static const Direction SouthWest = NeighborCode::SouthWest; /**< Export NeighborCode::SouthWest to namespace EightNeighborhood */
615 static const Direction South = NeighborCode::South; /**< Export NeighborCode::South to namespace EightNeighborhood */
616 static const Direction SouthEast = NeighborCode::SouthEast; /**< Export NeighborCode::SouthEast to namespace EightNeighborhood */
617 static const Direction DirectionCount = NeighborCode::DirectionCount; /**< Export NeighborCode::DirectionCount to namespace EightNeighborhood */
618 
619 inline Diff2D const & east() { return NeighborCode::diff(East); } /**< Offset to the east neighbor */
620 inline Diff2D const & northEast() { return NeighborCode::diff(NorthEast); } /**< Offset to the northEast neighbor */
621 inline Diff2D const & north() { return NeighborCode::diff(North); } /**< Offset to the north neighbor */
622 inline Diff2D const & northWest() { return NeighborCode::diff(NorthWest); } /**< Offset to the northWest neighbor */
623 inline Diff2D const & west() { return NeighborCode::diff(West); } /**< Offset to the west neighbor */
624 inline Diff2D const & southWest() { return NeighborCode::diff(SouthWest); } /**< Offset to the southWest neighbor */
625 inline Diff2D const & south() { return NeighborCode::diff(South); } /**< Offset to the south neighbor */
626 inline Diff2D const & southEast() { return NeighborCode::diff(SouthEast); } /**< Offset to the southEast neighbor */
627 
628 template <int DUMMY>
629 unsigned int NeighborCode::StaticData<DUMMY>::b[] = {
630  1 << East,
631  1 << NorthEast,
632  1 << North,
633  1 << NorthWest,
634  1 << West,
635  1 << SouthWest,
636  1 << South,
637  1 << SouthEast};
638 
639 template <int DUMMY>
640 unsigned int NeighborCode::StaticData<DUMMY>::c[] = { 8, 5, 5, 0, 5, 3, 3, 0, 5, 3, 3};
641 
642 template <int DUMMY>
643 Direction NeighborCode::StaticData<DUMMY>::bd[11][8] = {
645  { North, NorthWest, West, SouthWest, South, Error, Error, Error},
646  { East, NorthEast, North, South, SouthEast, Error, Error, Error},
647  { Error, Error, Error, Error, Error, Error, Error, Error},
648  { East, West, SouthWest, South, SouthEast, Error, Error, Error},
649  { West, SouthWest, South, Error, Error, Error, Error, Error},
650  { East, South, SouthEast, Error, Error, Error, Error, Error},
651  { Error, Error, Error, Error, Error, Error, Error, Error},
652  { East, NorthEast, North, NorthWest, West, Error, Error, Error},
653  { North, NorthWest, West, Error, Error, Error, Error, Error},
654  { East, NorthEast, North, Error, Error, Error, Error, Error}
655  };
656 
657 template <int DUMMY>
658 Diff2D NeighborCode::StaticData<DUMMY>::d[] = {
659  Diff2D(1, 0), Diff2D(1, -1), Diff2D(0, -1), Diff2D(-1, -1),
660  Diff2D(-1, 0), Diff2D(-1, 1), Diff2D(0, 1), Diff2D(1, 1)
661  };
662 
663 template <int DUMMY>
664 Diff2D NeighborCode::StaticData<DUMMY>::rd[][8] = {
665  { Diff2D(0, 0), Diff2D(0, -1), Diff2D(-1, -1), Diff2D(-2, -1),
666  Diff2D(-2, 0), Diff2D(-2, 1), Diff2D(-1, 1), Diff2D(0, 1) },
667  { Diff2D(0, 1), Diff2D(0, 0), Diff2D(-1, 0), Diff2D(-2, 0),
668  Diff2D(-2, 1), Diff2D(-2, 2), Diff2D(-1, 2), Diff2D(0, 2) },
669  { Diff2D(1, 1), Diff2D(1, 0), Diff2D(0, 0), Diff2D(-1, 0),
670  Diff2D(-1, 1), Diff2D(-1, 2), Diff2D(0, 2), Diff2D(1, 2) },
671  { Diff2D(2, 1), Diff2D(2, 0), Diff2D(1, 0), Diff2D(0, 0),
672  Diff2D(0, 1), Diff2D(0, 2), Diff2D(1, 2), Diff2D(2, 2) },
673  { Diff2D(2, 0), Diff2D(2, -1), Diff2D(1, -1), Diff2D(0, -1),
674  Diff2D(0, 0), Diff2D(0, 1), Diff2D(1, 1), Diff2D(2, 1) },
675  { Diff2D(2, -1), Diff2D(2, -2), Diff2D(1, -2), Diff2D(0, -2),
676  Diff2D(0, -1), Diff2D(0, 0), Diff2D(1, 0), Diff2D(2, 0) },
677  { Diff2D(1, -1), Diff2D(1, -2), Diff2D(0, -2), Diff2D(-1, -2),
678  Diff2D(-1, -1), Diff2D(-1, 0), Diff2D(0, 0), Diff2D(1, 0) },
679  { Diff2D(0, -1), Diff2D(0, -2), Diff2D(-1, -2), Diff2D(-2, -2),
680  Diff2D(-2, -1), Diff2D(-2, 0), Diff2D(-1, 0), Diff2D(0, 0) }
681  };
682 
683 } // namespace EightNeighborhood
684 
685  /** Export \ref vigra::EightNeighborhood::NeighborCode into the scope of namespace vigra.
686  */
688 
689 /********************************************************/
690 /* */
691 /* NeighborOffsetCirculator */
692 /* */
693 /********************************************************/
694 
695 /** \brief Circulator that walks around a given location.
696 
697  The template parameter defines the kind of neighborhood used, e.g.
698 
699  \code
700  NeighborOffsetCirculator<EightNeighborCode> eight_circulator;
701  NeighborOffsetCirculator<FourNeighborCode> four_circulator;
702  \endcode
703 
704  Since this circulator doesn't know about the pixels in any particular image,
705  you usually don't use it directly but rather as a base class or helper for
706  neighborhood circulators referring to a particular image (e.g. NeighborhoodCirculator)
707 
708  <b>\#include</b> <vigra/pixelneighborhood.hxx><br>
709  Namespace: vigra
710 */
711 template<class NEIGHBORCODE>
713 : public NEIGHBORCODE
714 {
715 public:
716  typedef NEIGHBORCODE NeighborCode;
717 
718  /** return type of direction()
719  */
720  typedef typename NEIGHBORCODE::Direction Direction;
721 
722  /** the circulator's value type
723  */
724  typedef typename NEIGHBORCODE::difference_type value_type;
725 
726  /** the circulator's reference type (return type of <TT>*circ</TT>)
727  */
728  typedef value_type const & reference;
729 
730  /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
731  */
732  typedef value_type const & index_reference;
733 
734  /** the circulator's pointer type (return type of <TT>operator-></TT>)
735  */
736  typedef value_type const * pointer;
737 
738  /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
739  */
740  typedef int difference_type;
741 
742  /** the circulator tag (random access iterator)
743  */
744  typedef random_access_circulator_tag iterator_category;
745 
746 protected:
747  Direction direction_;
748 
749 public:
750  /** Create circulator referring to the given direction.
751  */
752  NeighborOffsetCirculator(Direction dir = NEIGHBORCODE::InitialDirection)
753  : direction_(dir)
754  {
755  }
756 
757  /** pre-increment */
759  {
760  direction_ = static_cast<Direction>((direction_+1) % NEIGHBORCODE::DirectionCount);
761  return *this;
762  }
763 
764  /** pre-decrement */
766  {
767  direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::DirectionCount-1) % NEIGHBORCODE::DirectionCount);
768  return *this;
769  }
770 
771  /** post-increment */
773  {
774  NeighborOffsetCirculator ret(*this);
775  operator++();
776  return ret;
777  }
778 
779  /** post-decrement */
781  {
782  NeighborOffsetCirculator ret(*this);
783  operator--();
784  return ret;
785  }
786 
787  /** add-assignment */
789  {
790  direction_ = static_cast<Direction>((direction_ + d) % NEIGHBORCODE::DirectionCount);
791  if(direction_ < 0)
792  direction_ = static_cast<Direction>(direction_ + NEIGHBORCODE::DirectionCount);
793  return *this;
794  }
795 
796  /** subtract-assignment */
798  {
799  direction_ = static_cast<Direction>((direction_ - d) % NEIGHBORCODE::DirectionCount);
800  if(direction_ < 0)
801  direction_ = static_cast<Direction>(direction_ + NEIGHBORCODE::DirectionCount);
802  return *this;
803  }
804 
805  /** addition */
807  {
808  return NeighborOffsetCirculator(*this) += d;
809  }
810 
811  /** subtraction */
813  {
814  return NeighborOffsetCirculator(*this) -= d;
815  }
816 
817  /** Move to the direction that is 'right' relative to the current direction.
818  This is equivalent to <tt>four_circulator--</tt> and
819  <tt>eight_circulator -= 2</tt> respectively.
820  */
822  {
823  direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::South) % NEIGHBORCODE::DirectionCount);
824  return *this;
825  }
826 
827  /** Move to the direction that is 'left' relative to the current direction.
828  This is equivalent to <tt>four_circulator++</tt> and
829  <tt>eight_circulator += 2</tt> respectively.
830  */
832  {
833  direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::North) % NEIGHBORCODE::DirectionCount);
834  return *this;
835  }
836 
837  /** Move to the opposite direction of the current direction.
838  This is equivalent to <tt>four_circulator += 2</tt> and
839  <tt>eight_circulator += 4</tt> respectively.
840  */
842  {
843  direction_ = opposite();
844  return *this;
845  }
846 
847  /** Move to the given direction.
848  */
850  {
851  direction_ = d;
852  return *this;
853  }
854 
855  /** equality */
856  bool operator==(NeighborOffsetCirculator const & o) const
857  {
858  return direction_ == o.direction_;
859  }
860 
861  /** inequality */
862  bool operator!=(NeighborOffsetCirculator const & o) const
863  {
864  return direction_ != o.direction_;
865  }
866 
867  /** subtraction */
869  {
870  return direction_ - o.direction_;
871  }
872 
873  /** dereference */
875  {
876  return diff();
877  }
878 
879  /** index */
881  {
882  return NEIGHBORCODE::diff(direction(d));
883  }
884 
885  /** member access */
887  {
888  return &diff();
889  }
890 
891  /** Get offset from center to current neighbor.
892  */
893  reference diff() const
894  {
895  return NEIGHBORCODE::diff(direction_);
896  }
897 
898  /** Get offset to given direction.
899  */
901  {
902  return NEIGHBORCODE::diff(dir);
903  }
904 
905  /** Get relative distance from current neighbor to neighbor
906  at given offset.
907  */
909  {
910  Direction toDir = static_cast<Direction>((direction_ + offset) % NEIGHBORCODE::DirectionCount);
911  if(toDir < 0)
912  toDir = static_cast<Direction>(toDir + NEIGHBORCODE::DirectionCount);
913  return NEIGHBORCODE::relativeDiff(direction_, toDir);
914  }
915 
916  /** X-component of diff() */
917  int dX() const
918  {
919  return NEIGHBORCODE::dX(direction_);
920  }
921 
922  /** Y-component of diff() */
923  int dY() const
924  {
925  return NEIGHBORCODE::dY(direction_);
926  }
927 
928  /** Check whether current direction is a diagonal one.
929  */
930  bool isDiagonal() const
931  {
932  return NEIGHBORCODE::isDiagonal(direction_);
933  }
934 
935  /** Get current direction.
936  */
938  {
939  return direction_;
940  }
941 
942  /** Get current direction bit.
943  */
944  unsigned int directionBit() const
945  {
946  return NEIGHBORCODE::directionBit(direction_);
947  }
948 
949  /** Get opposite of current direction.
950  */
952  {
953  return static_cast<Direction>((NEIGHBORCODE::OppositeDirPrefix*direction_ + NEIGHBORCODE::OppositeOffset) % NEIGHBORCODE::DirectionCount);
954  }
955 
956  /** Get opposite bit of current direction.
957  */
958  unsigned int oppositeDirectionBit() const
959  {
960  return NEIGHBORCODE::directionBit(opposite());
961  }
962 
963  /** Get direction code at offset of current direction.
964  */
966  {
967  int result = (direction_ + offset) % NEIGHBORCODE::DirectionCount;
968  if(result < 0)
969  result += NEIGHBORCODE::DirectionCount;
970  return static_cast<Direction>(result);
971  }
972 };
973 
974 /** Specialization of NeighborOffsetCirculator for 8-neighborhood.
975 */
977 
978 /** Specialization of NeighborOffsetCirculator for 4-neighborhood.
979 */
981 
982 
983 //@}
984 
985 /** \addtogroup ImageIteratorAdapters
986  */
987 //@{
988 
989 /********************************************************/
990 /* */
991 /* NeighborhoodCirculator */
992 /* */
993 /********************************************************/
994 
995 /** \brief Circulator that walks around a given location in a given image.
996 
997  The template parameters define the kind of neighborhood used and the underlying
998  image. The access functions return the value of the current neighbor pixel.
999  Use <tt>center()</tt> to access the center pixel of the neighborhood.
1000  The center can be changed by calling <tt>moveCenterToNeighbor()</tt>
1001  or <tt>swapCenterNeighbor()</tt>. Note that this circulator cannot be used
1002  when the center is at the image border. You must then use
1003  \ref vigra::RestrictedNeighborhoodCirculator
1004 
1005  <b>Usage:</b><br>
1006 
1007  <b>\#include</b> <vigra/pixelneighborhood.hxx><br>
1008  Namespace: vigra
1009 
1010  \code
1011  BImage::traverser upperleft(...), lowerright(...);
1012 
1013  int width = lowerright.x - upperleft.x;
1014  int height = lowerright.y - upperleft.y;
1015 
1016  ++upperleft.y; // avoid image border
1017  for(int y=1; y<height-1; ++y, ++upperleft.y)
1018  {
1019  BImage::traverser ix = upperleft + Diff2D(1,0);
1020  for(int x=1; x<width-1; ++x, ++ix.x)
1021  {
1022  // analyse all neighbors of a pixel (use FourNeighborCode
1023  // instead of EightNeighborCode for 4-neighborhood):
1024  NeighborhoodCirculator<BImage::traverser, EightNeighborCode>
1025  circulator(ix),
1026  end(circulator);
1027  do
1028  {
1029  analysisFunc(*circulator, ...); // do sth. with current neighbor
1030  }
1031  while(++circulator != end); // compare with start/end circulator
1032  }
1033  }
1034  \endcode
1035 */
1036 template <class IMAGEITERATOR, class NEIGHBORCODE>
1037 class NeighborhoodCirculator : private IMAGEITERATOR
1038 {
1040 
1041 
1042 public:
1043  /** type of the underlying image iterator
1044  */
1045  typedef IMAGEITERATOR base_type;
1046 
1047  /** type of the used neighbor code
1048  */
1049  typedef NEIGHBORCODE NeighborCode;
1050 
1051  /** the circulator's value type
1052  */
1053  typedef typename IMAGEITERATOR::value_type value_type;
1054 
1055  /** type of the direction code
1056  */
1057  typedef typename NEIGHBORCODE::Direction Direction;
1058 
1059  /** the circulator's reference type (return type of <TT>*circ</TT>)
1060  */
1061  typedef typename IMAGEITERATOR::reference reference;
1062 
1063  /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
1064  */
1065 
1067 
1068  /** the circulator's pointer type (return type of <TT>operator-></TT>)
1069  */
1070  typedef typename IMAGEITERATOR::pointer pointer;
1071 
1072  /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
1073  */
1075 
1076  /** the circulator tag (random_access_circulator_tag)
1077  */
1079 
1080  /** Construct circulator with given <tt>center</tt> pixel, pointing to the neighbor
1081  at the given direction <tt>d</tt>.
1082  */
1083  NeighborhoodCirculator(IMAGEITERATOR const & aCenter = IMAGEITERATOR(),
1084  Direction d = NEIGHBOROFFSETCIRCULATOR::InitialDirection)
1085  : IMAGEITERATOR(aCenter), neighborCode_(d)
1086  {
1087  IMAGEITERATOR::operator+=(neighborCode_.diff());
1088  }
1089 
1090  /** pre-increment */
1092  {
1093  return operator+=(1);
1094  }
1095 
1096  /** post-increment */
1098  {
1099  NeighborhoodCirculator ret(*this);
1100  operator++();
1101  return ret;
1102  }
1103 
1104  /** pre-decrement */
1106  {
1107  return operator+=(-1);
1108  }
1109 
1110  /** post-decrement */
1112  {
1113  NeighborhoodCirculator ret(*this);
1114  operator--();
1115  return ret;
1116  }
1117 
1118  /** add-assignment */
1120  {
1121  IMAGEITERATOR::operator+=(neighborCode_.relativeDiff(d));
1122  neighborCode_+= d;
1123  return *this;
1124  }
1125 
1126  /** subtract-assignment */
1128  {
1129  return operator+=(-d);
1130  }
1131 
1132  /** addition */
1134  {
1135  NeighborhoodCirculator result(*this);
1136  result+= d;
1137  return result;
1138  }
1139 
1140  /** subtraction */
1142  {
1143  NeighborhoodCirculator result(*this);
1144  result-= d;
1145  return result;
1146  }
1147 
1148  /** Move to the direction that is 'right' relative to the current direction.
1149  This is equivalent to <tt>four_circulator--</tt> and
1150  <tt>eight_circulator -= 2</tt> respectively.
1151  */
1153  {
1154  Direction oldDirection = neighborCode_.direction();
1155  neighborCode_.turnRight();
1156  IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
1157  (oldDirection, neighborCode_.direction()));
1158  return *this;
1159  }
1160 
1161  /** Move to the direction that is 'left' relative to the current direction.
1162  This is equivalent to <tt>four_circulator++</tt> and
1163  <tt>eight_circulator += 2</tt> respectively.
1164  */
1166  {
1167  Direction oldDirection = neighborCode_.direction();
1168  neighborCode_.turnLeft();
1169  IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
1170  (oldDirection, neighborCode_.direction()));
1171  return *this;
1172  }
1173 
1174  /** Move to the opposite direction of the current direction.
1175  This is equivalent to <tt>four_circulator += 2</tt> and
1176  <tt>eight_circulator += 4</tt> respectively.
1177  */
1179  {
1180  Direction oldDirection = neighborCode_.direction();
1181  neighborCode_.turnRound();
1182  IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
1183  (oldDirection, neighborCode_.direction()));
1184  return *this;
1185  }
1186 
1187  /** Move to the given direction.
1188  */
1190  {
1191  Direction oldDirection = neighborCode_.direction();
1192  neighborCode_.turnTo(d);
1193  IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
1194  (oldDirection, neighborCode_.direction()));
1195  return *this;
1196  }
1197 
1198  /** Move the center in the current direction.
1199  The current neighbor becomes the new center, the direction does not change.
1200  */
1202  {
1203  IMAGEITERATOR::operator+=(neighborCode_.diff());
1204  return *this;
1205  }
1206 
1207  /** Exchange the center with the current neighbor.
1208  Equivalent to <tt>circ.moveCenterToNeighbor().turnRound()</tt>
1209  (but shorter and more efficient).
1210  */
1212  {
1213  neighborCode_.turnRound();
1214  IMAGEITERATOR::operator+=(neighborCode_.diff());
1215  return *this;
1216  }
1217 
1218  /** equality */
1219  bool operator==(NeighborhoodCirculator const & rhs) const
1220  {
1221  return neighborCode_ == rhs.neighborCode_ &&
1223  }
1224 
1225  /** inequality */
1226  bool operator!=(NeighborhoodCirculator const & rhs) const
1227  {
1228  return neighborCode_ != rhs.neighborCode_ ||
1230  }
1231 
1232  /** subtraction */
1234  {
1235  return neighborCode_ - rhs.neighborCode_;
1236  }
1237 
1238  /** dereference */
1240  {
1241  return IMAGEITERATOR::operator*();
1242  }
1243 
1244  /** index */
1246  {
1247  return IMAGEITERATOR::operator[](neighborCode_.relativeDiff(d));
1248  }
1249 
1250  /** member access */
1252  {
1253  return IMAGEITERATOR::operator->();
1254  }
1255 
1256  /** Get the base iterator for the current neighbor. */
1257  base_type const & base() const
1258  {
1259  return *this;
1260  }
1261 
1262  /** Get the base iterator for the center of the circulator. */
1264  {
1265  return (base_type)*this - neighborCode_.diff();
1266  }
1267 
1268  /** Get the current direction. */
1270  {
1271  return neighborCode_.direction();
1272  }
1273 
1274  /** Get the current direction bit. */
1275  unsigned int directionBit() const
1276  {
1277  return neighborCode_.directionBit();
1278  }
1279 
1280  /** Get the difference vector (Diff2D) from the center to the current neighbor. */
1282  {
1283  return neighborCode_.diff();
1284  }
1285 
1286  /** Is the current neighbor a diagonal neighbor? */
1287  bool isDiagonal() const
1288  {
1289  return neighborCode_.isDiagonal();
1290  }
1291 
1292 private:
1293  NEIGHBOROFFSETCIRCULATOR neighborCode_;
1294 };
1295 
1296 /********************************************************/
1297 /* */
1298 /* RestrictedNeighborhoodCirculator */
1299 /* */
1300 /********************************************************/
1301 
1302 /** \brief Circulator that walks around a given location in a given image,
1303  using a restricted neighborhood.
1304 
1305  This circulator behaves essentially like \ref vigra::NeighborhoodCirculator,
1306  but can also be used near the image border, where some of the neighbor points
1307  would be outside the image und must not be accessed.
1308  The template parameters define the kind of neighborhood used (four or eight)
1309  and the underlying image, whereas the required neighborhood restriction is
1310  given by the last constructor argument. This below for typical usage.
1311 
1312  The access functions return the value of the current neighbor pixel. Use <tt>center()</tt> to
1313  access the center pixel of the neighborhood.
1314 
1315  <b>Usage:</b><br>
1316 
1317  <b>\#include</b> <vigra/pixelneighborhood.hxx><br>
1318  Namespace: vigra
1319 
1320  \code
1321  BImage::traverser upperleft(...), lowerright(...);
1322 
1323  int width = lowerright.x - upperleft.x;
1324  int height = lowerright.y - upperleft.y;
1325 
1326  for(int y=0; y<height; ++y, ++upperleft.y)
1327  {
1328  BImage::traverser ix = upperleft;
1329  for(int x=0; x<width; ++x, ++ix.x)
1330  {
1331  // use FourNeighborCode instead of EightNeighborCode for 4-neighborhood
1332  RestrictedNeighborhoodCirculator<BImage::traverser, EightNeighborCode>
1333  circulator(ix, isAtImageBorder(x, y, width, height)),
1334  end(circulator);
1335  do
1336  {
1337  ... // do something with the circulator
1338  }
1339  while(++circulator != end); // out-of-range pixels will be automatically skipped
1340  }
1341  }
1342  \endcode
1343 */
1344 template <class IMAGEITERATOR, class NEIGHBORCODE>
1346 : private NeighborhoodCirculator<IMAGEITERATOR, NEIGHBORCODE>
1347 {
1349 
1350 public:
1351  /** type of the underlying image iterator
1352  */
1353  typedef IMAGEITERATOR base_type;
1354 
1355  /** type of the used neighbor code
1356  */
1357  typedef NEIGHBORCODE NeighborCode;
1358 
1359  /** the circulator's value type
1360  */
1362 
1363  /** type of the direction code
1364  */
1365  typedef typename BaseType::Direction Direction;
1366 
1367  /** the circulator's reference type (return type of <TT>*circ</TT>)
1368  */
1369  typedef typename BaseType::reference reference;
1370 
1371  /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
1372  */
1374 
1375  /** the circulator's pointer type (return type of <TT>operator-></TT>)
1376  */
1377  typedef typename BaseType::pointer pointer;
1378 
1379  /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
1380  */
1382 
1383  /** the circulator tag (random_access_circulator_tag)
1384  */
1386 
1387  /** Construct circulator with given <tt>center</tt> pixel, using the restricted
1388  neighborhood given by \a atBorder.
1389  */
1390  RestrictedNeighborhoodCirculator(IMAGEITERATOR const & center = IMAGEITERATOR(),
1391  AtImageBorder atBorder = NotAtBorder)
1392  : BaseType(center, NEIGHBORCODE::nearBorderDirections(atBorder, 0)),
1393  whichBorder_(atBorder),
1394  count_(NEIGHBORCODE::nearBorderDirectionCount(atBorder)),
1395  current_(0)
1396  {}
1397 
1398  /** pre-increment */
1400  {
1401  return operator+=(1);
1402  }
1403 
1404  /** post-increment */
1406  {
1408  operator++();
1409  return ret;
1410  }
1411 
1412  /** pre-decrement */
1414  {
1415  return operator+=(-1);
1416  }
1417 
1418  /** post-decrement */
1420  {
1422  operator--();
1423  return ret;
1424  }
1425 
1426  /** add-assignment */
1428  {
1429  current_ = static_cast<Direction>((current_ + count_ + d) % count_);
1430  BaseType::turnTo(NEIGHBORCODE::nearBorderDirections(whichBorder_, current_));
1431  return *this;
1432  }
1433 
1434  /** subtract-assignment */
1436  {
1437  return operator+=(-d);
1438  }
1439 
1440  /** addition */
1442  {
1443  RestrictedNeighborhoodCirculator result(*this);
1444  result+= d;
1445  return result;
1446  }
1447 
1448  /** subtraction */
1450  {
1451  RestrictedNeighborhoodCirculator result(*this);
1452  result-= d;
1453  return result;
1454  }
1455 
1456  /** equality */
1458  {
1459  return current_ == rhs.current_;
1460  }
1461 
1462  /** inequality */
1464  {
1465  return current_ != rhs.current_;
1466  }
1467 
1468  /** subtraction */
1470  {
1471  return (current_ - rhs.current_) % count_;
1472  }
1473 
1474  /** dereference */
1476  {
1477  return BaseType::operator*();
1478  }
1479 
1480  /** member access */
1482  {
1483  return BaseType::operator->();
1484  }
1485 
1486  /** Get the base iterator for the current neighbor. */
1487  base_type const & base() const
1488  {
1489  return BaseType::base();
1490  }
1491 
1492  /** Get the base iterator for the center of the circulator. */
1494  {
1495  return BaseType::center();
1496  }
1497 
1498  /** Get the current direction. */
1500  {
1501  return BaseType::direction();
1502  }
1503 
1504  /** Get the current direction bit. */
1505  unsigned int directionBit() const
1506  {
1507  return BaseType::directionBit();
1508  }
1509 
1510  /** Get the difference vector (Diff2D) from the center to the current neighbor. */
1511  typename NeighborCode::difference_type const & diff() const
1512  {
1513  return BaseType::diff();
1514  }
1515 
1516  /** Is the current neighbor a diagonal neighbor? */
1517  bool isDiagonal() const
1518  {
1519  return BaseType::isDiagonal();
1520  }
1521 
1522 private:
1523  AtImageBorder whichBorder_;
1524  signed char count_, current_;
1525 };
1526 
1527 //@}
1528 
1529 } // namespace vigra
1530 
1531 #endif /* VIGRA_PIXELNEIGHBORHOOD_HXX */
static const Direction DirectionCount
Definition: pixelneighborhood.hxx:617
 
Definition: pixelneighborhood.hxx:447
RestrictedNeighborhoodCirculator(IMAGEITERATOR const &center=IMAGEITERATOR(), AtImageBorder atBorder=NotAtBorder)
Definition: pixelneighborhood.hxx:1390
static Diff2D const & southEast()
Definition: pixelneighborhood.hxx:602
base_type center() const
Definition: pixelneighborhood.hxx:1263
bool isDiagonal() const
Definition: pixelneighborhood.hxx:1287
Diff2D const & north()
Definition: pixelneighborhood.hxx:331
static Diff2D const & west()
Definition: pixelneighborhood.hxx:314
 
Definition: pixelneighborhood.hxx:186
NEIGHBORCODE::Direction Direction
Definition: pixelneighborhood.hxx:1057
NeighborhoodCirculator & operator-=(difference_type d)
Definition: pixelneighborhood.hxx:1127
NeighborOffsetCirculator & turnRound()
Definition: pixelneighborhood.hxx:841
RestrictedNeighborhoodCirculator & operator-=(difference_type d)
Definition: pixelneighborhood.hxx:1435
 
Definition: pixelneighborhood.hxx:443
static Diff2D const & top()
Definition: pixelneighborhood.hxx:588
bool operator!=(NeighborhoodCirculator const &rhs) const
Definition: pixelneighborhood.hxx:1226
reference diff() const
Definition: pixelneighborhood.hxx:893
Circulator that walks around a given location in a given image, using a restricted neighborhood...
Definition: pixelneighborhood.hxx:1345
static Diff2D const & north()
Definition: pixelneighborhood.hxx:313
IMAGEITERATOR base_type
Definition: pixelneighborhood.hxx:1045
static int dX(Direction code)
Definition: pixelneighborhood.hxx:257
 
Definition: pixelneighborhood.hxx:437
NeighborhoodCirculator operator--(int)
Definition: pixelneighborhood.hxx:1111
int y
Definition: diff2d.hxx:392
Direction
Definition: pixelneighborhood.hxx:434
BaseType::index_reference index_reference
Definition: pixelneighborhood.hxx:1373
 
Definition: pixelneighborhood.hxx:439
static Diff2D const & top()
Definition: pixelneighborhood.hxx:308
static const Direction SouthWest
Definition: pixelneighborhood.hxx:614
 
Definition: pixelneighborhood.hxx:188
RestrictedNeighborhoodCirculator operator--(int)
Definition: pixelneighborhood.hxx:1419
RestrictedNeighborhoodCirculator & operator--()
Definition: pixelneighborhood.hxx:1413
bool isDiagonal() const
Definition: pixelneighborhood.hxx:1517
NEIGHBORCODE NeighborCode
Definition: pixelneighborhood.hxx:1049
static Diff2D const & diff(Direction code)
Definition: pixelneighborhood.hxx:488
static bool isDiagonal(Direction)
Definition: pixelneighborhood.hxx:305
static const Direction Error
Definition: pixelneighborhood.hxx:323
NeighborOffsetCirculator & turnLeft()
Definition: pixelneighborhood.hxx:831
NeighborOffsetCirculator< FourNeighborCode > FourNeighborOffsetCirculator
Definition: pixelneighborhood.hxx:980
difference_type operator-(RestrictedNeighborhoodCirculator const &rhs) const
Definition: pixelneighborhood.hxx:1469
 
Definition: pixelneighborhood.hxx:189
NeighborOffsetCirculator(Direction dir=NEIGHBORCODE::InitialDirection)
Definition: pixelneighborhood.hxx:752
bool operator==(RestrictedNeighborhoodCirculator const &rhs) const
Definition: pixelneighborhood.hxx:1457
static unsigned int nearBorderDirectionCount(AtImageBorder b)
Definition: pixelneighborhood.hxx:213
AtImageBorder
Encode whether a point is near the image border.
Definition: pixelneighborhood.hxx:68
 
Definition: pixelneighborhood.hxx:75
int x
Definition: diff2d.hxx:385
NeighborOffsetCirculator & operator+=(difference_type d)
Definition: pixelneighborhood.hxx:788
static Diff2D const & northWest()
Definition: pixelneighborhood.hxx:598
RestrictedNeighborhoodCirculator operator-(difference_type d) const
Definition: pixelneighborhood.hxx:1449
static Diff2D const & topRight()
Definition: pixelneighborhood.hxx:587
BaseType::pointer pointer
Definition: pixelneighborhood.hxx:1377
pointer operator->() const
Definition: pixelneighborhood.hxx:1251
unsigned int directionBit() const
Definition: pixelneighborhood.hxx:1275
 
Definition: pixelneighborhood.hxx:444
NEIGHBORCODE::Direction Direction
Definition: pixelneighborhood.hxx:720
Two dimensional difference vector.
Definition: diff2d.hxx:185
IMAGEITERATOR::pointer pointer
Definition: pixelneighborhood.hxx:1070
AtImageBorder isAtImageBorder(int x, int y, int width, int height)
Find out whether a point is at the image border.
Definition: pixelneighborhood.hxx:111
unsigned int directionBit() const
Definition: pixelneighborhood.hxx:1505
static Diff2D const & left()
Definition: pixelneighborhood.hxx:309
NeighborOffsetCirculator operator++(int)
Definition: pixelneighborhood.hxx:772
NeighborOffsetCirculator< EightNeighborCode > EightNeighborOffsetCirculator
Definition: pixelneighborhood.hxx:976
static unsigned int nearBorderDirectionCount(AtImageBorder b)
Definition: pixelneighborhood.hxx:472
NeighborOffsetCirculator operator--(int)
Definition: pixelneighborhood.hxx:780
Diff2D const & west()
Definition: pixelneighborhood.hxx:332
 
Definition: pixelneighborhood.hxx:185
static const Direction South
Definition: pixelneighborhood.hxx:327
pointer operator->() const
Definition: pixelneighborhood.hxx:1481
BaseType::reference reference
Definition: pixelneighborhood.hxx:1369
int difference_type
Definition: pixelneighborhood.hxx:740
Diff2D const & east()
Definition: pixelneighborhood.hxx:330
NeighborhoodCirculator & operator++()
Definition: pixelneighborhood.hxx:1091
index_reference operator[](difference_type d) const
Definition: pixelneighborhood.hxx:880
unsigned int directionBit() const
Definition: pixelneighborhood.hxx:944
NeighborCode::Direction Direction
Definition: pixelneighborhood.hxx:321
static Direction nearBorderDirections(AtImageBorder b, int index)
Definition: pixelneighborhood.hxx:480
Encapsulation of direction management for 4-neighborhood.
Definition: pixelneighborhood.hxx:165
 
Definition: pixelneighborhood.hxx:73
static const Direction South
Definition: pixelneighborhood.hxx:615
IMAGEITERATOR::reference reference
Definition: pixelneighborhood.hxx:1061
 
Definition: pixelneighborhood.hxx:445
NeighborOffsetCirculator operator+(difference_type d) const
Definition: pixelneighborhood.hxx:806
 
Definition: pixelneighborhood.hxx:448
static Diff2D const & south()
Definition: pixelneighborhood.hxx:601
static int dY(int code)
Definition: pixelneighborhood.hxx:522
NeighborhoodCirculator & moveCenterToNeighbor()
Definition: pixelneighborhood.hxx:1201
static Diff2D const & left()
Definition: pixelneighborhood.hxx:590
NeighborhoodCirculator & turnRound()
Definition: pixelneighborhood.hxx:1178
bool operator!=(NeighborOffsetCirculator const &o) const
Definition: pixelneighborhood.hxx:862
static Diff2D const & east()
Definition: pixelneighborhood.hxx:595
NeighborhoodCirculator & turnTo(Direction d)
Definition: pixelneighborhood.hxx:1189
NeighborhoodCirculator & operator+=(difference_type d)
Definition: pixelneighborhood.hxx:1119
static Diff2D const & bottomLeft()
Definition: pixelneighborhood.hxx:591
NeighborOffsetCirculator & operator-=(difference_type d)
Definition: pixelneighborhood.hxx:797
Direction
Definition: pixelneighborhood.hxx:179
NEIGHBOROFFSETCIRCULATOR::difference_type difference_type
Definition: pixelneighborhood.hxx:1074
static Diff2D const & diff(Direction code)
Definition: pixelneighborhood.hxx:229
Circulator that walks around a given location.
Definition: pixelneighborhood.hxx:712
 
Definition: pixelneighborhood.hxx:442
NEIGHBORCODE::difference_type value_type
Definition: pixelneighborhood.hxx:724
RestrictedNeighborhoodCirculator operator++(int)
Definition: pixelneighborhood.hxx:1405
FFTWComplex< R > & operator+=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
add-assignment
Definition: fftw3.hxx:859
static const Direction NorthWest
Definition: pixelneighborhood.hxx:612
static Diff2D const & diff(int code)
Definition: pixelneighborhood.hxx:237
Diff2D const & northWest()
Definition: pixelneighborhood.hxx:622
base_type const & base() const
Definition: pixelneighborhood.hxx:1487
static int dY(Direction code)
Definition: pixelneighborhood.hxx:259
Direction direction(difference_type offset) const
Definition: pixelneighborhood.hxx:965
value_type const * pointer
Definition: pixelneighborhood.hxx:736
static Direction nearBorderDirections(AtImageBorder b, int index)
Definition: pixelneighborhood.hxx:221
NEIGHBORCODE NeighborCode
Definition: pixelneighborhood.hxx:1357
NeighborCode::Direction Direction
Definition: pixelneighborhood.hxx:607
 
Definition: pixelneighborhood.hxx:180
 
Definition: pixelneighborhood.hxx:184
reference operator*() const
Definition: pixelneighborhood.hxx:1475
static Diff2D const & diff(int code)
Definition: pixelneighborhood.hxx:496
NeighborhoodCirculator & turnLeft()
Definition: pixelneighborhood.hxx:1165
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition: fftw3.hxx:841
 
Definition: pixelneighborhood.hxx:446
static const Direction NorthEast
Definition: pixelneighborhood.hxx:610
static int dX(Direction code)
Definition: pixelneighborhood.hxx:516
static Diff2D const & bottomRight()
Definition: pixelneighborhood.hxx:593
static Diff2D const & relativeDiff(int fromCode, int toCode)
Definition: pixelneighborhood.hxx:251
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition: fftw3.hxx:825
BaseType::difference_type difference_type
Definition: pixelneighborhood.hxx:1381
static Direction code(Diff2D const &diff)
Definition: pixelneighborhood.hxx:269
static const Direction West
Definition: pixelneighborhood.hxx:613
RestrictedNeighborhoodCirculator operator+(difference_type d) const
Definition: pixelneighborhood.hxx:1441
Circulator that walks around a given location in a given image.
Definition: pixelneighborhood.hxx:1037
int dY() const
Definition: pixelneighborhood.hxx:923
static Diff2D const & northEast()
Definition: pixelneighborhood.hxx:596
NeighborOffsetCirculator & operator++()
Definition: pixelneighborhood.hxx:758
difference_type operator-(NeighborOffsetCirculator const &o) const
Definition: pixelneighborhood.hxx:868
NeighborhoodCirculator & operator--()
Definition: pixelneighborhood.hxx:1105
index_reference operator[](difference_type d) const
Definition: pixelneighborhood.hxx:1245
static const Direction SouthEast
Definition: pixelneighborhood.hxx:616
static const Direction North
Definition: pixelneighborhood.hxx:611
Direction opposite() const
Definition: pixelneighborhood.hxx:951
NeighborhoodCirculator & swapCenterNeighbor()
Definition: pixelneighborhood.hxx:1211
difference_type operator-(NeighborhoodCirculator const &rhs) const
Definition: pixelneighborhood.hxx:1233
bool isDiagonal() const
Definition: pixelneighborhood.hxx:930
static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
Definition: pixelneighborhood.hxx:243
NeighborhoodCirculator operator++(int)
Definition: pixelneighborhood.hxx:1097
NeighborhoodCirculator operator+(difference_type d) const
Definition: pixelneighborhood.hxx:1133
static Diff2D const & east()
Definition: pixelneighborhood.hxx:312
static Direction code(Diff2D const &diff)
Definition: pixelneighborhood.hxx:533
static int dX(int code)
Definition: pixelneighborhood.hxx:520
BaseType::iterator_category iterator_category
Definition: pixelneighborhood.hxx:1385
Diff2D const & south()
Definition: pixelneighborhood.hxx:333
static Diff2D const & bottom()
Definition: pixelneighborhood.hxx:592
Direction direction() const
Definition: pixelneighborhood.hxx:1499
BaseType::Direction Direction
Definition: pixelneighborhood.hxx:1365
static reference diff(Direction dir)
Definition: pixelneighborhood.hxx:900
Direction direction() const
Definition: pixelneighborhood.hxx:1269
static int dX(int code)
Definition: pixelneighborhood.hxx:261
bool operator!=(RestrictedNeighborhoodCirculator const &rhs) const
Definition: pixelneighborhood.hxx:1463
pointer operator->() const
Definition: pixelneighborhood.hxx:886
static const Direction East
Definition: pixelneighborhood.hxx:324
NeighborOffsetCirculator & operator--()
Definition: pixelneighborhood.hxx:765
Diff2D const & south()
Definition: pixelneighborhood.hxx:625
static const Direction DirectionCount
Definition: pixelneighborhood.hxx:328
static const Direction North
Definition: pixelneighborhood.hxx:325
RestrictedNeighborhoodCirculator & operator++()
Definition: pixelneighborhood.hxx:1399
Diff2D const & southEast()
Definition: pixelneighborhood.hxx:626
NeighborCode::difference_type const & diff() const
Definition: pixelneighborhood.hxx:1511
Direction direction() const
Definition: pixelneighborhood.hxx:937
static int dY(int code)
Definition: pixelneighborhood.hxx:263
static Diff2D const & southWest()
Definition: pixelneighborhood.hxx:600
 
Definition: pixelneighborhood.hxx:74
static Diff2D const & bottom()
Definition: pixelneighborhood.hxx:310
Diff2D const & southWest()
Definition: pixelneighborhood.hxx:624
bool operator==(NeighborOffsetCirculator const &o) const
Definition: pixelneighborhood.hxx:856
static Diff2D const & right()
Definition: pixelneighborhood.hxx:307
 
Definition: pixelneighborhood.hxx:182
base_type const & base() const
Definition: pixelneighborhood.hxx:1257
NeighborhoodCirculator operator-(difference_type d) const
Definition: pixelneighborhood.hxx:1141
 
Definition: pixelneighborhood.hxx:436
static Direction code(FourNeighborhood::Direction d)
Definition: pixelneighborhood.hxx:526
Diff2D const & west()
Definition: pixelneighborhood.hxx:623
int dX() const
Definition: pixelneighborhood.hxx:917
value_type const & index_reference
Definition: pixelneighborhood.hxx:732
FourNeighborhood::NeighborCode FourNeighborCode
Definition: pixelneighborhood.hxx:379
static Diff2D const & north()
Definition: pixelneighborhood.hxx:597
reference operator*() const
Definition: pixelneighborhood.hxx:1239
static const Direction East
Definition: pixelneighborhood.hxx:609
reference index_reference
Definition: pixelneighborhood.hxx:1066
static Diff2D const & relativeDiff(int fromCode, int toCode)
Definition: pixelneighborhood.hxx:510
static const Direction West
Definition: pixelneighborhood.hxx:326
 
Definition: pixelneighborhood.hxx:183
 
Definition: pixelneighborhood.hxx:70
NeighborOffsetCirculator & turnTo(Direction d)
Definition: pixelneighborhood.hxx:849
NeighborOffsetCirculator operator-(difference_type d) const
Definition: pixelneighborhood.hxx:812
 
Definition: pixelneighborhood.hxx:71
 
Definition: pixelneighborhood.hxx:72
 
Definition: pixelneighborhood.hxx:438
RestrictedNeighborhoodCirculator & operator+=(difference_type d)
Definition: pixelneighborhood.hxx:1427
static Diff2D const & south()
Definition: pixelneighborhood.hxx:315
 
Definition: pixelneighborhood.hxx:441
static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
Definition: pixelneighborhood.hxx:502
NeighborhoodCirculator & turnRight()
Definition: pixelneighborhood.hxx:1152
NEIGHBOROFFSETCIRCULATOR::value_type const & diff() const
Definition: pixelneighborhood.hxx:1281
static bool isDiagonal(Direction code)
Definition: pixelneighborhood.hxx:584
static Diff2D const & topLeft()
Definition: pixelneighborhood.hxx:589
NeighborOffsetCirculator & turnRight()
Definition: pixelneighborhood.hxx:821
IMAGEITERATOR base_type
Definition: pixelneighborhood.hxx:1353
IMAGEITERATOR::value_type value_type
Definition: pixelneighborhood.hxx:1053
EightNeighborhood::NeighborCode EightNeighborCode
Definition: pixelneighborhood.hxx:687
BaseType::value_type value_type
Definition: pixelneighborhood.hxx:1361
unsigned int oppositeDirectionBit() const
Definition: pixelneighborhood.hxx:958
Diff2D const & east()
Definition: pixelneighborhood.hxx:619
random_access_circulator_tag iterator_category
Definition: pixelneighborhood.hxx:744
bool operator==(NeighborhoodCirculator const &rhs) const
Definition: pixelneighborhood.hxx:1219
value_type relativeDiff(difference_type offset) const
Definition: pixelneighborhood.hxx:908
Diff2D const & north()
Definition: pixelneighborhood.hxx:621
reference operator*() const
Definition: pixelneighborhood.hxx:874
 
Definition: pixelneighborhood.hxx:181
base_type center() const
Definition: pixelneighborhood.hxx:1493
 
Definition: pixelneighborhood.hxx:440
static Diff2D const & west()
Definition: pixelneighborhood.hxx:599
Diff2D const & northEast()
Definition: pixelneighborhood.hxx:620
NEIGHBOROFFSETCIRCULATOR::iterator_category iterator_category
Definition: pixelneighborhood.hxx:1078
static Diff2D const & right()
Definition: pixelneighborhood.hxx:586
NeighborhoodCirculator(IMAGEITERATOR const &aCenter=IMAGEITERATOR(), Direction d=NEIGHBOROFFSETCIRCULATOR::InitialDirection)
Definition: pixelneighborhood.hxx:1083
 
Definition: pixelneighborhood.hxx:435
 
Definition: pixelneighborhood.hxx:187
value_type const & reference
Definition: pixelneighborhood.hxx:728
Encapsulation of direction management for the 8-neighborhood.
Definition: pixelneighborhood.hxx:420
static int dY(Direction code)
Definition: pixelneighborhood.hxx:518

© 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.11.1 (Fri May 19 2017)