|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef TCG_IMAGE_ITERATOR_HPP
|
|
Toshihiro Shimizu |
890ddd |
#define TCG_IMAGE_ITERATOR_HPP
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// tcg includes
|
|
Toshihiro Shimizu |
890ddd |
#include "../image_iterator.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "../pixel_ops.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace tcg
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// image_edge_iterator implementation
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename _adherence="" _iei_adherence_policy="" it,=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
template <typename img=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
image_edge_iterator<it, _adherence="">::image_edge_iterator(</it,>
|
|
Toshihiro Shimizu |
890ddd |
const Img &img, int x, int y, int dirX, int dirY)
|
|
Toshihiro Shimizu |
890ddd |
: m_lx_1(image_traits::width(img) - 1), m_ly_1(image_traits::height(img) - 1), m_wrap(image_traits::wrap(img)), m_pos(x, y), m_dir(dirX, dirY), m_outsideColor(image_traits::outsideColor(img)), m_elbowColor(m_outsideColor), m_pix(image_traits::pixel(img, x, y)), m_turn(UNKNOWN)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
pixels(m_leftPix, m_rightPix);
|
|
Toshihiro Shimizu |
890ddd |
colors(m_leftColor, m_rightColor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename _adherence="" _iei_adherence_policy="" it,=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
inline void image_edge_iterator<it, _adherence="">::pixels(</it,>
|
|
Toshihiro Shimizu |
890ddd |
iter pixLeft, iter pixRight)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_dir.y)
|
|
Toshihiro Shimizu |
890ddd |
if (m_dir.y > 0)
|
|
Toshihiro Shimizu |
890ddd |
pixLeft = m_pix - 1, pixRight = m_pix;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
pixLeft = m_pix - m_wrap, pixRight = pixLeft - 1;
|
|
Toshihiro Shimizu |
890ddd |
else if (m_dir.x > 0)
|
|
Toshihiro Shimizu |
890ddd |
pixLeft = m_pix, pixRight = m_pix - m_wrap;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
pixRight = m_pix - 1, pixLeft = pixRight - m_wrap;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename _adherence="" _iei_adherence_policy="" it,=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
inline void image_edge_iterator<it, _adherence="">::colors(</it,>
|
|
Toshihiro Shimizu |
890ddd |
value_type &leftColor, value_type &rightColor)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_dir.y)
|
|
Toshihiro Shimizu |
890ddd |
if (m_dir.y > 0) {
|
|
Toshihiro Shimizu |
890ddd |
if (m_pos.y > m_ly_1)
|
|
Toshihiro Shimizu |
890ddd |
leftColor = rightColor = m_outsideColor;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
leftColor = (m_pos.x > 0) ? *m_leftPix : m_outsideColor;
|
|
Toshihiro Shimizu |
890ddd |
rightColor = (m_pos.x <= m_lx_1) ? *m_rightPix : m_outsideColor;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
if (m_pos.y < 1)
|
|
Toshihiro Shimizu |
890ddd |
leftColor = rightColor = m_outsideColor;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
leftColor = (m_pos.x <= m_lx_1) ? *m_leftPix : m_outsideColor;
|
|
Toshihiro Shimizu |
890ddd |
rightColor = (m_pos.x > 0) ? *m_rightPix : m_outsideColor;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
else if (m_dir.x > 0) {
|
|
Toshihiro Shimizu |
890ddd |
if (m_pos.x > m_lx_1)
|
|
Toshihiro Shimizu |
890ddd |
leftColor = rightColor = m_outsideColor;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
leftColor = (m_pos.y <= m_ly_1) ? *m_leftPix : m_outsideColor;
|
|
Toshihiro Shimizu |
890ddd |
rightColor = (m_pos.y > 0) ? *m_rightPix : m_outsideColor;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
if (m_pos.x < 1)
|
|
Toshihiro Shimizu |
890ddd |
leftColor = rightColor = m_outsideColor;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
leftColor = (m_pos.y > 0) ? *m_leftPix : m_outsideColor;
|
|
Toshihiro Shimizu |
890ddd |
rightColor = (m_pos.y <= m_ly_1) ? *m_rightPix : m_outsideColor;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename _adherence="" _iei_adherence_policy="" it,=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
inline void image_edge_iterator<it, _adherence="">::turn(</it,>
|
|
Toshihiro Shimizu |
890ddd |
const value_type &newLeftColor, const value_type &newRightColor,
|
|
Toshihiro Shimizu |
890ddd |
policy<right_adherence>)</right_adherence>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (newLeftColor == m_rightColor) {
|
|
Toshihiro Shimizu |
890ddd |
if (newRightColor == m_leftColor)
|
|
Toshihiro Shimizu |
890ddd |
turnAmbiguous(newLeftColor, newRightColor);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
turnLeft();
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
if (newRightColor != m_rightColor)
|
|
Toshihiro Shimizu |
890ddd |
turnRight();
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_turn = STRAIGHT;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_elbowColor = newLeftColor;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
pixels(m_leftPix, m_rightPix);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename _adherence="" _iei_adherence_policy="" it,=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
inline void image_edge_iterator<it, _adherence="">::turn(</it,>
|
|
Toshihiro Shimizu |
890ddd |
const value_type &newLeftColor, const value_type &newRightColor,
|
|
Toshihiro Shimizu |
890ddd |
policy<left_adherence>)</left_adherence>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (newRightColor == m_leftColor) {
|
|
Toshihiro Shimizu |
890ddd |
if (newLeftColor == m_rightColor)
|
|
Toshihiro Shimizu |
890ddd |
turnAmbiguous(newLeftColor, newRightColor);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
turnRight();
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
if (newLeftColor != m_leftColor)
|
|
Toshihiro Shimizu |
890ddd |
turnLeft();
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_turn = STRAIGHT;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_elbowColor = newRightColor;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
pixels(m_leftPix, m_rightPix);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename _adherence="" _iei_adherence_policy="" it,=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
inline void image_edge_iterator<it, _adherence="">::turnAmbiguous(</it,>
|
|
Toshihiro Shimizu |
890ddd |
const value_type &newLeftColor, const value_type &newRightColor)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
UCHAR count1 = 0, count2 = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
value_type val;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Check the 4x4 neighbourhood and connect the minority color
|
|
Toshihiro Shimizu |
890ddd |
if (m_pos.x > 2) {
|
|
Toshihiro Shimizu |
890ddd |
val = *(m_pix - 2);
|
|
Toshihiro Shimizu |
890ddd |
if (val == m_leftColor)
|
|
Toshihiro Shimizu |
890ddd |
++count1;
|
|
Toshihiro Shimizu |
890ddd |
else if (val == m_rightColor)
|
|
Toshihiro Shimizu |
890ddd |
++count2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
val = *(m_pix - 2 - m_wrap);
|
|
Toshihiro Shimizu |
890ddd |
if (val == m_leftColor)
|
|
Toshihiro Shimizu |
890ddd |
++count1;
|
|
Toshihiro Shimizu |
890ddd |
else if (val == m_rightColor)
|
|
Toshihiro Shimizu |
890ddd |
++count2;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_pos.x < m_lx_1) {
|
|
Toshihiro Shimizu |
890ddd |
val = *(m_pix + 1);
|
|
Toshihiro Shimizu |
890ddd |
if (val == m_leftColor)
|
|
Toshihiro Shimizu |
890ddd |
++count1;
|
|
Toshihiro Shimizu |
890ddd |
else if (val == m_rightColor)
|
|
Toshihiro Shimizu |
890ddd |
++count2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
val = *(m_pix + 1 - m_wrap);
|
|
Toshihiro Shimizu |
890ddd |
if (val == m_leftColor)
|
|
Toshihiro Shimizu |
890ddd |
++count1;
|
|
Toshihiro Shimizu |
890ddd |
else if (val == m_rightColor)
|
|
Toshihiro Shimizu |
890ddd |
++count2;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_pos.y > 2) {
|
|
Toshihiro Shimizu |
890ddd |
int wrap2 = m_wrap << 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
val = *(m_pix - wrap2);
|
|
Toshihiro Shimizu |
890ddd |
if (val == m_leftColor)
|
|
Toshihiro Shimizu |
890ddd |
++count1;
|
|
Toshihiro Shimizu |
890ddd |
else if (val == m_rightColor)
|
|
Toshihiro Shimizu |
890ddd |
++count2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
val = *(m_pix - wrap2 - 1);
|
|
Toshihiro Shimizu |
890ddd |
if (val == m_leftColor)
|
|
Toshihiro Shimizu |
890ddd |
++count1;
|
|
Toshihiro Shimizu |
890ddd |
else if (val == m_rightColor)
|
|
Toshihiro Shimizu |
890ddd |
++count2;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_pos.y < m_ly_1) {
|
|
Toshihiro Shimizu |
890ddd |
val = *(m_pix + m_wrap);
|
|
Toshihiro Shimizu |
890ddd |
if (val == m_leftColor)
|
|
Toshihiro Shimizu |
890ddd |
++count1;
|
|
Toshihiro Shimizu |
890ddd |
else if (val == m_rightColor)
|
|
Toshihiro Shimizu |
890ddd |
++count2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
val = *(m_pix + m_wrap - 1);
|
|
Toshihiro Shimizu |
890ddd |
if (val == m_leftColor)
|
|
Toshihiro Shimizu |
890ddd |
++count1;
|
|
Toshihiro Shimizu |
890ddd |
else if (val == m_rightColor)
|
|
Toshihiro Shimizu |
890ddd |
++count2;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Minority connection - join the one with less count
|
|
Toshihiro Shimizu |
890ddd |
if (count1 <= count2)
|
|
Toshihiro Shimizu |
890ddd |
turnRight(); // Join m_leftColor == newRightColor
|
|
Toshihiro Shimizu |
890ddd |
else if (count1 > count2)
|
|
Toshihiro Shimizu |
890ddd |
turnLeft(); // Join m_rightColor == newLeftColor
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_turn |= AMBIGUOUS;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename _adherence="" _iei_adherence_policy="" it,=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
void image_edge_iterator<it, _adherence="">::advance(policy<right_adherence>)</right_adherence></it,>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
value_type newLeftColor = m_leftColor, newRightColor = m_rightColor;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int pixAdd = m_dir.y * m_wrap + m_dir.x;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_pos.x += m_dir.x, m_pos.y += m_dir.y;
|
|
Toshihiro Shimizu |
890ddd |
m_pix += pixAdd, m_leftPix += pixAdd, m_rightPix += pixAdd;
|
|
Toshihiro Shimizu |
890ddd |
m_leftColor = newLeftColor;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
colors(newLeftColor, newRightColor);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
turn(newLeftColor, newRightColor);
|
|
Toshihiro Shimizu |
890ddd |
colors(m_leftColor, m_rightColor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename _adherence="" _iei_adherence_policy="" it,=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
void image_edge_iterator<it, _adherence="">::advance(policy<left_adherence>)</left_adherence></it,>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
value_type newLeftColor = m_leftColor, newRightColor = m_rightColor;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int pixAdd = m_dir.y * m_wrap + m_dir.x;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_pos.x += m_dir.x, m_pos.y += m_dir.y;
|
|
Toshihiro Shimizu |
890ddd |
m_pix += pixAdd, m_leftPix += pixAdd, m_rightPix += pixAdd;
|
|
Toshihiro Shimizu |
890ddd |
m_rightColor = newRightColor;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
colors(newLeftColor, newRightColor);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
turn(newLeftColor, newRightColor);
|
|
Toshihiro Shimizu |
890ddd |
colors(m_leftColor, m_rightColor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
} // namespace tcg
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif // TCG_IMAGE_ITERATOR_HPP
|