Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_IMAGE_ITERATOR_H
Toshihiro Shimizu 890ddd
#define TCG_IMAGE_ITERATOR_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "tcg_ptr.h"
Toshihiro Shimizu 890ddd
#include "tcg_image_ops.h"
Toshihiro Shimizu 890ddd
#include "tcg_point.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STD includes
Toshihiro Shimizu 890ddd
#include <iterator></iterator>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace tcg {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*********************************************************************************************************
Toshihiro Shimizu 890ddd
//    Image Iterator  class
Toshihiro Shimizu 890ddd
//*********************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
  The image_iterator class models an iterator accessing pixels of an image along
Shinya Kitaoka 120a6e
  its rows.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename it=""></typename>
Shinya Kitaoka 120a6e
class image_iterator : public iterator_traits<it>::inheritable_iterator_type {</it>
Shinya Kitaoka 120a6e
  typedef typename iterator_traits<it>::inheritable_iterator_type iter;</it>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  typedef typename iter::iterator_category iterator_category;
Shinya Kitaoka 120a6e
  typedef typename iter::value_type value_type;
Shinya Kitaoka 120a6e
  typedef typename iter::difference_type difference_type;
Shinya Kitaoka 120a6e
  typedef typename iter::pointer pointer;
Shinya Kitaoka 120a6e
  typedef typename iter::reference reference;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  image_iterator() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename img=""></typename>
Shinya Kitaoka 120a6e
  image_iterator(const Img &img, int x, int y)
Shinya Kitaoka 120a6e
      : iter(image_traits::pixel(img, x, y))
Shinya Kitaoka 120a6e
      , m_base(image_traits::pixel(img, 0, 0))
Shinya Kitaoka 120a6e
      , m_lx(image_traits::width(img))
Shinya Kitaoka 120a6e
      , m_ly(image_traits::height(img))
Shinya Kitaoka 120a6e
      , m_wrap(image_traits::wrap(img))
Shinya Kitaoka 120a6e
      , m_skew(m_wrap - lx) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int x() const { return (iter::operator-(m_base)) % m_wrap; }
Shinya Kitaoka 120a6e
  int y() const { return (iter::operator-(m_base)) / m_wrap; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  image_iterator &operator++() {
Shinya Kitaoka 120a6e
    iter::operator++();
Shinya Kitaoka 120a6e
    if (x() >= m_lx) iter::operator+=(m_skew);
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  image_iterator operator++(int) {
Shinya Kitaoka 120a6e
    image_iterator it(*this);
Shinya Kitaoka 120a6e
    operator++();
Shinya Kitaoka 120a6e
    return it;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  image_iterator &operator--() {
Shinya Kitaoka 120a6e
    iter::operator--();
Shinya Kitaoka 120a6e
    if (x() < 0) iter::operator-=(m_skew);
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  image_iterator operator--(int) {
Shinya Kitaoka 120a6e
    image_iterator it(*this);
Shinya Kitaoka 120a6e
    operator--();
Shinya Kitaoka 120a6e
    return it;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  image_iterator &operator+=(difference_type d) {
Shinya Kitaoka 120a6e
    int yCount = (x() + d) / m_lx;
Shinya Kitaoka 120a6e
    iter::operator+=((d - yCount * m_lx) + yCount * m_wrap);
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  image_iterator operator+(difference_type d) const {
Shinya Kitaoka 120a6e
    image_iterator it(*this);
Shinya Kitaoka 120a6e
    it += d;
Shinya Kitaoka 120a6e
    return it;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  image_iterator operator-(difference_type d) const { return operator+(-d); }
Shinya Kitaoka 120a6e
  image_iterator &operator-=(difference_type d) { return operator+=(-d); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  difference_type operator-(const image_iterator &other) const {
Shinya Kitaoka 120a6e
    return (x() - other.x()) + m_lx * (y() - other.y());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  reference operator[](difference_type d) const {
Shinya Kitaoka 120a6e
    const image_iterator &it = operator+(d);
Shinya Kitaoka 120a6e
    return *it;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  iter m_base;
Shinya Kitaoka 120a6e
  int m_lx, m_ly, m_wrap, m_skew;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*********************************************************************************************************
Toshihiro Shimizu 890ddd
//    image_edge_iterator class
Toshihiro Shimizu 890ddd
//*********************************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
enum _iei_adherence_policy { LEFT_ADHERENCE, RIGHT_ADHERENCE };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
  The image_edge_iterator class models a forward iterator following the contour
Shinya Kitaoka 120a6e
  of
Toshihiro Shimizu 890ddd
  an image area of uniform color.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename _adherence="RIGHT_ADHERENCE" _iei_adherence_policy="" it,=""></typename>
Shinya Kitaoka 120a6e
class image_edge_iterator {
Shinya Kitaoka 120a6e
  typedef typename iterator_traits<it>::inheritable_iterator_type iter;</it>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  typedef std::forward_iterator_tag iterator_category;
Shinya Kitaoka 120a6e
  typedef typename iter::value_type value_type;
Shinya Kitaoka 120a6e
  typedef typename iter::difference_type difference_type;
Shinya Kitaoka 120a6e
  typedef typename iter::pointer pointer;
Shinya Kitaoka 120a6e
  typedef typename iter::reference reference;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  enum { adherence = _adherence };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  enum Direction {
Shinya Kitaoka 120a6e
    STRAIGHT        = 0x0,
Shinya Kitaoka 120a6e
    LEFT            = 0x1,
Shinya Kitaoka 120a6e
    RIGHT           = 0x2,
Shinya Kitaoka 120a6e
    AMBIGUOUS       = 0x4,
Shinya Kitaoka 120a6e
    UNKNOWN         = 0x8,
Shinya Kitaoka 120a6e
    AMBIGUOUS_LEFT  = LEFT | AMBIGUOUS,
Shinya Kitaoka 120a6e
    AMBIGUOUS_RIGHT = RIGHT | AMBIGUOUS
Shinya Kitaoka 120a6e
  };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  image_edge_iterator() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  template <typename img=""></typename>
Shinya Kitaoka 120a6e
  image_edge_iterator(const Img &img, int x, int y, int dirX, int dirY);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const Point &pos() const { return m_pos; }
Shinya Kitaoka 120a6e
  const Point &dir() const { return m_dir; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const value_type &leftColor() const { return m_leftColor; }
Shinya Kitaoka 120a6e
  const value_type &rightColor() const { return m_rightColor; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const value_type &color() const { return color(policy<_adherence>()); }
Shinya Kitaoka 120a6e
  const value_type &oppositeColor() const {
Shinya Kitaoka 120a6e
    return oppositeColor(policy<_adherence>());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  const value_type &elbowColor() const { return m_elbowColor; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  iter leftPixel() const { return m_leftPix; }
Shinya Kitaoka 120a6e
  iter rightPixel() const { return m_rightPix; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  iter pixel() const { return pixel(policy<_adherence>()); }
Shinya Kitaoka 120a6e
  iter oppositePixel() const { return oppositePixel(policy<_adherence>()); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Direction turn() const { return Direction(m_turn); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  // Iterator functions
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator==(const image_edge_iterator &it) const {
Shinya Kitaoka 120a6e
    return (m_pos == it.m_pos) && (m_dir == it.m_dir);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool operator!=(const image_edge_iterator &it) const {
Shinya Kitaoka 120a6e
    return !operator==(it);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  image_edge_iterator &operator++() {
Shinya Kitaoka 120a6e
    advance(policy<_adherence>());
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  image_edge_iterator operator++(int) {
Shinya Kitaoka 120a6e
    image_edge_iterator temp(*this);
Shinya Kitaoka 120a6e
    operator++();
Shinya Kitaoka 120a6e
    return temp;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  void pixels(iter pixLeft, iter pixRight);
Shinya Kitaoka 120a6e
  void colors(value_type &leftColor, value_type &rightColor);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void turnLeft() {
Shinya Kitaoka 120a6e
    int temp = m_dir.x;
Shinya Kitaoka 120a6e
    m_dir.x  = -m_dir.y;
Shinya Kitaoka 120a6e
    m_dir.y  = temp;
Shinya Kitaoka 120a6e
    m_turn   = LEFT;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  void turnRight() {
Shinya Kitaoka 120a6e
    int temp = m_dir.x;
Shinya Kitaoka 120a6e
    m_dir.x  = m_dir.y;
Shinya Kitaoka 120a6e
    m_dir.y  = -temp;
Shinya Kitaoka 120a6e
    m_turn   = RIGHT;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void turn(const value_type &newLeftColor, const value_type &newRightColor) {
Shinya Kitaoka 120a6e
    turn(newLeftColor, newRightColor, policy<_adherence>());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  void turnAmbiguous(const value_type &newLeftColor,
Shinya Kitaoka 120a6e
                     const value_type &newRightColor);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  template <_iei_adherence_policy>
Shinya Kitaoka 120a6e
  struct policy {};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const value_type &color(policy<left_adherence>) const { return m_leftColor; }</left_adherence>
Shinya Kitaoka 120a6e
  const value_type &color(policy<right_adherence>) const {</right_adherence>
Shinya Kitaoka 120a6e
    return m_rightColor;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const value_type &oppositeColor(policy<left_adherence>) const {</left_adherence>
Shinya Kitaoka 120a6e
    return m_rightColor;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  const value_type &oppositeColor(policy<right_adherence>) const {</right_adherence>
Shinya Kitaoka 120a6e
    return m_leftColor;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  iter pixel(policy<left_adherence>) const { return m_leftPix; }</left_adherence>
Shinya Kitaoka 120a6e
  iter pixel(policy<right_adherence>) const { return m_rightPix; }</right_adherence>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  iter oppositePixel(policy<left_adherence>) const { return m_rightPix; }</left_adherence>
Shinya Kitaoka 120a6e
  iter oppositePixel(policy<right_adherence>) const { return m_leftPix; }</right_adherence>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void turn(const value_type &newLeftColor, const value_type &newRightColor,
Shinya Kitaoka 120a6e
            policy<left_adherence>);</left_adherence>
Shinya Kitaoka 120a6e
  void turn(const value_type &newLeftColor, const value_type &newRightColor,
Shinya Kitaoka 120a6e
            policy<right_adherence>);</right_adherence>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void advance(policy<left_adherence>);</left_adherence>
Shinya Kitaoka 120a6e
  void advance(policy<right_adherence>);</right_adherence>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  int m_lx_1, m_ly_1, m_wrap;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Point m_pos, m_dir;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  value_type m_leftColor, m_rightColor, m_outsideColor, m_elbowColor;
Shinya Kitaoka 120a6e
  iter m_pix, m_leftPix, m_rightPix;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int m_turn;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace tcg
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // TCG_IMAGE_ITERATOR_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=====================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef INCLUDE_HPP
Toshihiro Shimizu 890ddd
#include "hpp/image_iterator.hpp"
Shinya Kitaoka 120a6e
#endif  // INCLUDE_HPP