36 #ifndef VIGRA_PIXELNEIGHBORHOOD_HXX
37 #define VIGRA_PIXELNEIGHBORHOOD_HXX
39 #include "utilities.hxx"
132 namespace FourNeighborhood
191 InitialDirection =
East,
192 OppositeDirPrefix = 1,
193 OppositeOffset =
West
199 static unsigned int b[];
200 static unsigned int c[];
206 static unsigned int directionBit(
Direction d)
208 return StaticData<0>::b[d];
215 return StaticData<0>::c[b];
223 return StaticData<0>::bd[b][index];
231 return StaticData<0>::d[
code];
245 return StaticData<0>::rd[fromCode][toCode];
253 return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
287 return (diff.
y == 0) ?
293 return (diff.
y == 0) ?
337 unsigned int NeighborCode::StaticData<DUMMY>::b[] = {1 <<
East,
343 unsigned int NeighborCode::StaticData<DUMMY>::c[] = { 4, 3, 3, 0, 3, 2, 2, 0, 3, 2, 2};
346 Direction NeighborCode::StaticData<DUMMY>::bd[11][4] = {
361 Diff2D NeighborCode::StaticData<DUMMY>::d[] = {
362 Diff2D(1, 0), Diff2D(0, -1), Diff2D(-1, 0), Diff2D(0, 1)
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) }
388 namespace EightNeighborhood
450 InitialDirection =
East,
451 OppositeDirPrefix = 1,
452 OppositeOffset =
West
458 static unsigned int b[];
459 static unsigned int c[];
465 static unsigned int directionBit(
Direction d)
467 return StaticData<0>::b[d];
474 return StaticData<0>::c[b];
482 return StaticData<0>::bd[b][index];
490 return StaticData<0>::d[
code];
504 return StaticData<0>::rd[fromCode][toCode];
512 return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
629 unsigned int NeighborCode::StaticData<DUMMY>::b[] = {
640 unsigned int NeighborCode::StaticData<DUMMY>::c[] = { 8, 5, 5, 0, 5, 3, 3, 0, 5, 3, 3};
643 Direction NeighborCode::StaticData<DUMMY>::bd[11][8] = {
647 {
Error,
Error, Error, Error, Error, Error, Error, Error},
651 {
Error,
Error, Error, Error, Error, Error, Error, Error},
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)
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) }
711 template<
class NEIGHBORCODE>
713 :
public NEIGHBORCODE
716 typedef NEIGHBORCODE NeighborCode;
760 direction_ =
static_cast<Direction>((direction_+1) % NEIGHBORCODE::DirectionCount);
767 direction_ =
static_cast<Direction>((direction_ + NEIGHBORCODE::DirectionCount-1) % NEIGHBORCODE::DirectionCount);
790 direction_ =
static_cast<Direction>((direction_ + d) % NEIGHBORCODE::DirectionCount);
792 direction_ =
static_cast<Direction>(direction_ + NEIGHBORCODE::DirectionCount);
799 direction_ =
static_cast<Direction>((direction_ - d) % NEIGHBORCODE::DirectionCount);
801 direction_ =
static_cast<Direction>(direction_ + NEIGHBORCODE::DirectionCount);
823 direction_ =
static_cast<Direction>((direction_ + NEIGHBORCODE::South) % NEIGHBORCODE::DirectionCount);
833 direction_ =
static_cast<Direction>((direction_ + NEIGHBORCODE::North) % NEIGHBORCODE::DirectionCount);
858 return direction_ == o.direction_;
864 return direction_ != o.direction_;
870 return direction_ - o.direction_;
895 return NEIGHBORCODE::diff(direction_);
902 return NEIGHBORCODE::diff(dir);
910 Direction toDir =
static_cast<Direction>((direction_ + offset) % NEIGHBORCODE::DirectionCount);
912 toDir =
static_cast<Direction>(toDir + NEIGHBORCODE::DirectionCount);
913 return NEIGHBORCODE::relativeDiff(direction_, toDir);
919 return NEIGHBORCODE::dX(direction_);
925 return NEIGHBORCODE::dY(direction_);
932 return NEIGHBORCODE::isDiagonal(direction_);
946 return NEIGHBORCODE::directionBit(direction_);
953 return static_cast<Direction>((NEIGHBORCODE::OppositeDirPrefix*direction_ + NEIGHBORCODE::OppositeOffset) % NEIGHBORCODE::DirectionCount);
960 return NEIGHBORCODE::directionBit(
opposite());
967 int result = (direction_ + offset) % NEIGHBORCODE::DirectionCount;
969 result += NEIGHBORCODE::DirectionCount;
1036 template <
class IMAGEITERATOR,
class NEIGHBORCODE>
1084 Direction d = NEIGHBOROFFSETCIRCULATOR::InitialDirection)
1085 : IMAGEITERATOR(
center), neighborCode_(d)
1157 (oldDirection, neighborCode_.
direction()));
1170 (oldDirection, neighborCode_.
direction()));
1183 (oldDirection, neighborCode_.
direction()));
1194 (oldDirection, neighborCode_.
direction()));
1221 return neighborCode_ == rhs.neighborCode_ &&
1228 return neighborCode_ != rhs.neighborCode_ ||
1235 return neighborCode_ - rhs.neighborCode_;
1241 return IMAGEITERATOR::operator*();
1247 return IMAGEITERATOR::operator[](neighborCode_.
relativeDiff(d));
1253 return IMAGEITERATOR::operator->();
1283 return neighborCode_.
diff();
1293 NEIGHBOROFFSETCIRCULATOR neighborCode_;
1344 template <
class IMAGEITERATOR,
class NEIGHBORCODE>
1392 :
BaseType(
center, NEIGHBORCODE::nearBorderDirections(atBorder, 0)),
1393 whichBorder_(atBorder),
1394 count_(NEIGHBORCODE::nearBorderDirectionCount(atBorder)),
1429 current_ =
static_cast<Direction>((current_ + count_ + d) % count_);
1430 BaseType::turnTo(NEIGHBORCODE::nearBorderDirections(whichBorder_, current_));
1459 return current_ == rhs.current_;
1465 return current_ != rhs.current_;
1471 return (current_ - rhs.current_) % count_;
1511 typename NeighborCode::difference_type
const &
diff()
const
1524 signed char count_, current_;