|
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
|