Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// SDirection.cpp: implementation of the CSDirection class.
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
#include <stdlib.h></stdlib.h>
Toshihiro Shimizu 890ddd
#include <memory.h></memory.h>
Toshihiro Shimizu 890ddd
#include "SDirection.h"
Toshihiro Shimizu 890ddd
#include "SError.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
// Construction/Destruction
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CSDirection::CSDirection() : m_lX(0), m_lY(0), m_dir(0), m_lDf(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int i = 0; i < NBDIR; i++)
Toshihiro Shimizu 890ddd
		m_df[i] = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CSDirection::CSDirection(const int lX, const int lY, const UCHAR *sel,
Toshihiro Shimizu 890ddd
						 const int sens)
Toshihiro Shimizu 890ddd
	: m_lX(lX), m_lY(lY), m_dir(0), m_lDf(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int i = 0; i < NBDIR; i++)
Toshihiro Shimizu 890ddd
		m_df[i] = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		if (m_lX > 0 && m_lY > 0) {
Toshihiro Shimizu 890ddd
			m_dir = new UCHAR[m_lX * m_lY];
Toshihiro Shimizu 890ddd
			if (!m_dir) {
Toshihiro Shimizu 890ddd
				null();
Toshihiro Shimizu 890ddd
				throw SMemAllocError("in directionMap");
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			memcpy(m_dir, sel, sizeof(UCHAR) * m_lX * m_lY);
Toshihiro Shimizu 890ddd
			setDir01();
Toshihiro Shimizu 890ddd
			//			For optimalization purpose.
Toshihiro Shimizu 890ddd
			//			The quality is better, if it is removed.
Toshihiro Shimizu 890ddd
			//			setContourBorder(2);
Toshihiro Shimizu 890ddd
			makeDirFilter(sens);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} catch (SMemAllocError) {
Toshihiro Shimizu 890ddd
		throw;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CSDirection::CSDirection(const int lX, const int lY, const UCHAR *sel,
Toshihiro Shimizu 890ddd
						 const int sens, const int border)
Toshihiro Shimizu 890ddd
	: m_lX(lX), m_lY(lY), m_dir(0), m_lDf(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int i = 0; i < NBDIR; i++)
Toshihiro Shimizu 890ddd
		m_df[i] = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		if (m_lX > 0 && m_lY > 0) {
Toshihiro Shimizu 890ddd
			m_dir = new UCHAR[m_lX * m_lY];
Toshihiro Shimizu 890ddd
			if (!m_dir) {
Toshihiro Shimizu 890ddd
				null();
Toshihiro Shimizu 890ddd
				throw SMemAllocError("in directionMap");
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			memcpy(m_dir, sel, sizeof(UCHAR) * m_lX * m_lY);
Toshihiro Shimizu 890ddd
			setDir01();
Toshihiro Shimizu 890ddd
			if (border > 0)
Toshihiro Shimizu 890ddd
				setContourBorder(border);
Toshihiro Shimizu 890ddd
			makeDirFilter(sens);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} catch (SMemAllocError) {
Toshihiro Shimizu 890ddd
		throw;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool CSDirection::isContourBorder(const int xx, const int yy,
Toshihiro Shimizu 890ddd
								  const int border)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int y = yy - border; y <= (yy + border); y++)
Toshihiro Shimizu 890ddd
		for (int x = xx - border; x <= (xx + border); x++)
Toshihiro Shimizu 890ddd
			if (x >= 0 && y >= 0 && x < m_lX && y < m_lY)
Toshihiro Shimizu 890ddd
				if (*(m_dir + y * m_lX + x) == (UCHAR)0)
Toshihiro Shimizu 890ddd
					return true;
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CSDirection::setContourBorder(const int border)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UCHAR *pDir = m_dir;
Toshihiro Shimizu 890ddd
	int y = 0;
Toshihiro Shimizu 890ddd
	for (y = 0; y < m_lY; y++)
Toshihiro Shimizu 890ddd
		for (int x = 0; x < m_lX; x++, pDir++)
Toshihiro Shimizu 890ddd
			if (*pDir == (UCHAR)1)
Toshihiro Shimizu 890ddd
				if (!isContourBorder(x, y, border))
Toshihiro Shimizu 890ddd
					*pDir = (UCHAR)2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int xy = m_lX * m_lY;
Toshihiro Shimizu 890ddd
	pDir = m_dir;
Toshihiro Shimizu 890ddd
	for (y = 0; y < xy; y++, pDir++)
Toshihiro Shimizu 890ddd
		*pDir = *pDir == (UCHAR)2 ? (UCHAR)0 : *pDir;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CSDirection::null()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_dir) {
Toshihiro Shimizu 890ddd
		delete[] m_dir;
Toshihiro Shimizu 890ddd
		m_dir = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	for (int i = 0; i < NBDIR; i++)
Toshihiro Shimizu 890ddd
		if (m_df[i]) {
Toshihiro Shimizu 890ddd
			delete[] m_df[i];
Toshihiro Shimizu 890ddd
			m_df[i] = 0;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	m_lX = m_lY = 0;
Toshihiro Shimizu 890ddd
	m_lDf = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CSDirection::~CSDirection()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	null();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double CSDirection::adjustAngle(const short sum[4], const int Ima,
Toshihiro Shimizu 890ddd
								const int Im45, const int Ip45)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	short ma = MAX(sum[Im45], sum[Ip45]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (ma < 0)
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
	if ((double)ma < (double)sum[Ima] / 10.0)
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
	if (((double)abs(sum[Im45] - sum[Ip45]) / (double)ma) < 0.5)
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double d = 45.0 * (double)ma / (double)(sum[Ima] + ma);
Toshihiro Shimizu 890ddd
	if (ma == sum[Im45])
Toshihiro Shimizu 890ddd
		return -d;
Toshihiro Shimizu 890ddd
	return d;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double CSDirection::getAngle(const short sum[4], short ma)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int nbMax = ma == sum[0] ? 1 : 0;
Toshihiro Shimizu 890ddd
	nbMax = ma == sum[1] ? nbMax + 1 : nbMax;
Toshihiro Shimizu 890ddd
	nbMax = ma == sum[2] ? nbMax + 1 : nbMax;
Toshihiro Shimizu 890ddd
	nbMax = ma == sum[3] ? nbMax + 1 : nbMax;
Toshihiro Shimizu 890ddd
	double diff = 50.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (nbMax == 1) {
Toshihiro Shimizu 890ddd
		double angle, corrAngle;
Toshihiro Shimizu 890ddd
		if (ma == sum[0]) {
Toshihiro Shimizu 890ddd
			angle = 0.0;
Toshihiro Shimizu 890ddd
			corrAngle = adjustAngle(sum, 0, 3, 1);
Toshihiro Shimizu 890ddd
			if (corrAngle < 0.0)
Toshihiro Shimizu 890ddd
				angle = 180.0;
Toshihiro Shimizu 890ddd
		} else if (ma == sum[1]) {
Toshihiro Shimizu 890ddd
			angle = 45.0;
Toshihiro Shimizu 890ddd
			corrAngle = adjustAngle(sum, 1, 0, 2);
Toshihiro Shimizu 890ddd
		} else if (ma == sum[2]) {
Toshihiro Shimizu 890ddd
			angle = 90.0;
Toshihiro Shimizu 890ddd
			corrAngle = adjustAngle(sum, 2, 1, 3);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			angle = 135.0;
Toshihiro Shimizu 890ddd
			corrAngle = adjustAngle(sum, 3, 2, 0);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		return angle + corrAngle + diff;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	///* ?????????????????????? kiprobalni
Toshihiro Shimizu 890ddd
	if (nbMax == 2) {
Toshihiro Shimizu 890ddd
		if (ma == sum[0] && ma == sum[1])
Toshihiro Shimizu 890ddd
			return 22.5 + diff;
Toshihiro Shimizu 890ddd
		if (ma == sum[0] && ma == sum[3])
Toshihiro Shimizu 890ddd
			return 157.5 + diff;
Toshihiro Shimizu 890ddd
		if (ma == sum[1] && ma == sum[2])
Toshihiro Shimizu 890ddd
			return 67.5 + diff;
Toshihiro Shimizu 890ddd
		if (ma == sum[2] && ma == sum[3])
Toshihiro Shimizu 890ddd
			return 112.5 + diff;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//*/
Toshihiro Shimizu 890ddd
	return 1.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
UCHAR CSDirection::getDir(const int xx, const int yy, UCHAR *sel)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	short sum[4] = {0, 0, 0, 0};
Toshihiro Shimizu 890ddd
	short w = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int i = 0; i < m_lDf; i++) {
Toshihiro Shimizu 890ddd
		int x = xx + m_df[0][i].x;
Toshihiro Shimizu 890ddd
		int y = yy + m_df[0][i].y;
Toshihiro Shimizu 890ddd
		if (y >= 0 && y < m_lY && x >= 0 && x < m_lX) {
Toshihiro Shimizu 890ddd
			UCHAR *pSel = sel + y * m_lX + x;
Toshihiro Shimizu 890ddd
			for (int j = 0; j < NBDIR; j++)
Toshihiro Shimizu 890ddd
				sum[j] += (short)(*pSel) * m_df[j][i].w;
Toshihiro Shimizu 890ddd
			w += (short)(*pSel);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (w == 0)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	short ma = MAX(MAX(MAX(sum[0], sum[1]), sum[2]), sum[3]);
Toshihiro Shimizu 890ddd
	double angle = getAngle(sum, ma);
Toshihiro Shimizu 890ddd
	//tmsg_info(" - dir - %d, %d, %d, %d angle=%f", sum[0],sum[1],sum[2],sum[3],
Toshihiro Shimizu 890ddd
	//		                                          angle-50.0);
Toshihiro Shimizu 890ddd
	return UC_ROUND(angle);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CSDirection::makeDir(UCHAR *sel)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UCHAR *pSel = sel;
Toshihiro Shimizu 890ddd
	UCHAR *pDir = m_dir;
Toshihiro Shimizu 890ddd
	for (int y = 0; y < m_lY; y++)
Toshihiro Shimizu 890ddd
		for (int x = 0; x < m_lX; x++, pSel++, pDir++) {
Toshihiro Shimizu 890ddd
			*pDir = 0;
Toshihiro Shimizu 890ddd
			if (*pSel > 0)
Toshihiro Shimizu 890ddd
				*pDir = getDir(x, y, sel);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
UCHAR CSDirection::equalizeDir_GTE50(UCHAR *sel,
Toshihiro Shimizu 890ddd
									 const int xx, const int yy, const int d)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int sum = 0;
Toshihiro Shimizu 890ddd
	int w = 0;
Toshihiro Shimizu 890ddd
	int aa;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	aa = (int)*(sel + yy * m_lX + xx) - 50;
Toshihiro Shimizu 890ddd
	for (int y = yy - d; y <= (yy + d); y++)
Toshihiro Shimizu 890ddd
		for (int x = xx - d; x <= (xx + d); x++)
Toshihiro Shimizu 890ddd
			if (x >= 0 && y >= 0 && x < m_lX && y < m_lY) {
Toshihiro Shimizu 890ddd
				UCHAR *pSel = sel + y * m_lX + x;
Toshihiro Shimizu 890ddd
				int a = (int)*pSel;
Toshihiro Shimizu 890ddd
				if (a >= 50) {
Toshihiro Shimizu 890ddd
					a -= 50;
Toshihiro Shimizu 890ddd
					if (aa < 90 && a > 135) {
Toshihiro Shimizu 890ddd
						a = -(180 - a);
Toshihiro Shimizu 890ddd
					} else if (aa > 90 && a < 45) {
Toshihiro Shimizu 890ddd
						a = 180 + a;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
					sum += a;
Toshihiro Shimizu 890ddd
					w++;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
	if (w > 0) {
Toshihiro Shimizu 890ddd
		double q = (double)sum / (double)w;
Toshihiro Shimizu 890ddd
		int a = I_ROUND(q);
Toshihiro Shimizu 890ddd
		if (a >= 180) {
Toshihiro Shimizu 890ddd
			a -= 180;
Toshihiro Shimizu 890ddd
		} else if (a < 0) {
Toshihiro Shimizu 890ddd
			a = 180 + a;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		return (UCHAR)(a + 50);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return *(sel + yy * m_lX + xx);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
UCHAR CSDirection::equalizeDir_LT50(UCHAR *sel,
Toshihiro Shimizu 890ddd
									const int xx, const int yy, const int d)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int sum = 0;
Toshihiro Shimizu 890ddd
	int w = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int y = yy - d; y <= (yy + d); y++)
Toshihiro Shimizu 890ddd
		for (int x = xx - d; x <= (xx + d); x++)
Toshihiro Shimizu 890ddd
			if (x >= 0 && y >= 0 && x < m_lX && y < m_lY) {
Toshihiro Shimizu 890ddd
				int a = (int)*(sel + y * m_lX + x);
Toshihiro Shimizu 890ddd
				if (a >= 50) {
Toshihiro Shimizu 890ddd
					a -= 50;
Toshihiro Shimizu 890ddd
					sum += a;
Toshihiro Shimizu 890ddd
					w++;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
	if (w > 0) {
Toshihiro Shimizu 890ddd
		double q = (double)sum / (double)w;
Toshihiro Shimizu 890ddd
		int a = I_ROUND(q);
Toshihiro Shimizu 890ddd
		if (a >= 180) {
Toshihiro Shimizu 890ddd
			a -= 180;
Toshihiro Shimizu 890ddd
		} else if (a < 0) {
Toshihiro Shimizu 890ddd
			a = 180 + a;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		return (UCHAR)(a + 50);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return *(sel + yy * m_lX + xx);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CSDirection::equalizeDir(UCHAR *sel, const int d)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UCHAR *pSel = sel;
Toshihiro Shimizu 890ddd
	UCHAR *pDir = m_dir;
Toshihiro Shimizu 890ddd
	for (int y = 0; y < m_lY; y++)
Toshihiro Shimizu 890ddd
		for (int x = 0; x < m_lX; x++, pSel++) {
Toshihiro Shimizu 890ddd
			if (*pSel > (UCHAR)0) {
Toshihiro Shimizu 890ddd
				if (*pSel >= (UCHAR)50)
Toshihiro Shimizu 890ddd
					*pDir = equalizeDir_GTE50(sel, x, y, d);
Toshihiro Shimizu 890ddd
				else
Toshihiro Shimizu 890ddd
					*pDir = equalizeDir_LT50(sel, x, y, d);
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				*pDir = (UCHAR)0;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
UCHAR getRadius(const double angle, const double r[4])
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double p, q;
Toshihiro Shimizu 890ddd
	if (angle >= 0.0 && angle < 45.0) {
Toshihiro Shimizu 890ddd
		q = angle / 45.0;
Toshihiro Shimizu 890ddd
		p = r[0] * (1.0 - q) + r[1] * q;
Toshihiro Shimizu 890ddd
	} else if (angle >= 45.0 && angle < 90.0) {
Toshihiro Shimizu 890ddd
		q = (angle - 45.0) / 45.0;
Toshihiro Shimizu 890ddd
		p = r[1] * (1.0 - q) + r[2] * q;
Toshihiro Shimizu 890ddd
	} else if (angle >= 90.0 && angle < 135.0) {
Toshihiro Shimizu 890ddd
		q = (angle - 90.0) / 45.0;
Toshihiro Shimizu 890ddd
		p = r[2] * (1.0 - q) + r[3] * q;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		q = (angle - 135.0) / 45.0;
Toshihiro Shimizu 890ddd
		p = r[3] * (1.0 - q) + r[0] * q;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return (UCHAR)(1 + I_ROUND(p * 254.0));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CSDirection::makeDirFilter(const int sens)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const int size = 2 * sens + 1;
Toshihiro Shimizu 890ddd
	const int middle = size / 2;
Toshihiro Shimizu 890ddd
	const int maxVal = size - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_lDf = size * size;
Toshihiro Shimizu 890ddd
	for (int i = 0; i < NBDIR; i++) {
Toshihiro Shimizu 890ddd
		m_df[i] = new SXYW[m_lDf];
Toshihiro Shimizu 890ddd
		if (!m_df[i]) {
Toshihiro Shimizu 890ddd
			null();
Toshihiro Shimizu 890ddd
			throw SMemAllocError("in directionMap");
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		for (int y = 0; y < size; y++)
Toshihiro Shimizu 890ddd
			for (int x = 0; x < size; x++) {
Toshihiro Shimizu 890ddd
				int xy = y * size + x;
Toshihiro Shimizu 890ddd
				m_df[i][xy].x = x - middle;
Toshihiro Shimizu 890ddd
				m_df[i][xy].y = y - middle;
Toshihiro Shimizu 890ddd
				switch (i) {
Toshihiro Shimizu 890ddd
				case 0:
Toshihiro Shimizu 890ddd
					// Horizontal
Toshihiro Shimizu 890ddd
					m_df[i][xy].w = y == middle ? maxVal : -1;
Toshihiro Shimizu 890ddd
					break;
Toshihiro Shimizu 890ddd
				case 1:
Toshihiro Shimizu 890ddd
					// Left - Right
Toshihiro Shimizu 890ddd
					m_df[i][xy].w = x == y ? maxVal : -1;
Toshihiro Shimizu 890ddd
					break;
Toshihiro Shimizu 890ddd
				case 2:
Toshihiro Shimizu 890ddd
					// Vertical
Toshihiro Shimizu 890ddd
					m_df[i][xy].w = x == middle ? maxVal : -1;
Toshihiro Shimizu 890ddd
					break;
Toshihiro Shimizu 890ddd
				case 3:
Toshihiro Shimizu 890ddd
					// Right - Left
Toshihiro Shimizu 890ddd
					m_df[i][xy].w = (x + y) == (size - 1) ? maxVal : -1;
Toshihiro Shimizu 890ddd
					break;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
UCHAR CSDirection::blurRadius(UCHAR *sel, const int xx, const int yy, const int dBlur)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int sum, w;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	sum = w = 0;
Toshihiro Shimizu 890ddd
	for (int y = yy - dBlur; y <= (yy + dBlur); y++)
Toshihiro Shimizu 890ddd
		for (int x = xx - dBlur; x <= (xx + dBlur); x++)
Toshihiro Shimizu 890ddd
			if (x >= 0 && y >= 0 && x < m_lX && y < m_lY) {
Toshihiro Shimizu 890ddd
				UCHAR *pSel = sel + y * m_lX + x;
Toshihiro Shimizu 890ddd
				if (*pSel > (UCHAR)0) {
Toshihiro Shimizu 890ddd
					sum += (int)(*pSel);
Toshihiro Shimizu 890ddd
					w++;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
	if (w > 0) {
Toshihiro Shimizu 890ddd
		double d = (double)sum / (double)w;
Toshihiro Shimizu 890ddd
		d = D_CUT_0_255(d);
Toshihiro Shimizu 890ddd
		return UC_ROUND(d);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return *(sel + yy * m_lX + xx);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CSDirection::blurRadius(const int dBlur)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_lX > 0 && m_lY > 0 && m_dir) {
Toshihiro Shimizu 890ddd
		UCHAR *sel = new UCHAR[m_lX * m_lY];
Toshihiro Shimizu 890ddd
		if (!sel)
Toshihiro Shimizu 890ddd
			throw SMemAllocError("in directionMap");
Toshihiro Shimizu 890ddd
		memcpy(sel, m_dir, m_lX * m_lY * sizeof(UCHAR));
Toshihiro Shimizu 890ddd
		UCHAR *pSel = sel;
Toshihiro Shimizu 890ddd
		UCHAR *pDir = m_dir;
Toshihiro Shimizu 890ddd
		for (int y = 0; y < m_lY; y++)
Toshihiro Shimizu 890ddd
			for (int x = 0; x < m_lX; x++, pSel++, pDir++)
Toshihiro Shimizu 890ddd
				if (*pSel > (UCHAR)0)
Toshihiro Shimizu 890ddd
					*pDir = blurRadius(sel, x, y, dBlur);
Toshihiro Shimizu 890ddd
		delete[] sel;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CSDirection::setDir01()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int xy = m_lX * m_lY;
Toshihiro Shimizu 890ddd
	UCHAR *pDir = m_dir;
Toshihiro Shimizu 890ddd
	for (int i = 0; i < xy; i++, pDir++)
Toshihiro Shimizu 890ddd
		*pDir = *pDir > (UCHAR)0 ? (UCHAR)1 : (UCHAR)0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CSDirection::doDir()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UCHAR *sel = 0;
Toshihiro Shimizu 890ddd
	if (m_lX > 0 && m_lY > 0 && m_dir) {
Toshihiro Shimizu 890ddd
		sel = new UCHAR[m_lX * m_lY];
Toshihiro Shimizu 890ddd
		if (!sel)
Toshihiro Shimizu 890ddd
			throw SMemAllocError("in directionMap");
Toshihiro Shimizu 890ddd
		size_t length = (size_t)(m_lX * m_lY * sizeof(UCHAR));
Toshihiro Shimizu 890ddd
		memcpy(sel, m_dir, length);
Toshihiro Shimizu 890ddd
		makeDir(sel);
Toshihiro Shimizu 890ddd
		memcpy(sel, m_dir, length);
Toshihiro Shimizu 890ddd
		equalizeDir(sel, 3);
Toshihiro Shimizu 890ddd
		delete[] sel;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CSDirection::doRadius(const double rH, const double rLR,
Toshihiro Shimizu 890ddd
						   const double rV, const double rRL, const int dBlur)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		int xy = m_lX * m_lY;
Toshihiro Shimizu 890ddd
		UCHAR *pDir = m_dir;
Toshihiro Shimizu 890ddd
		double r[4] = {D_CUT_0_1(rH), D_CUT_0_1(rLR), D_CUT_0_1(rV), D_CUT_0_1(rRL)};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (int i = 0; i < xy; i++, pDir++)
Toshihiro Shimizu 890ddd
			if (*pDir < (UCHAR)50) {
Toshihiro Shimizu 890ddd
				*pDir = (UCHAR)0;
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				*pDir = getRadius((double)(*pDir - 50), r);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (dBlur > 0)
Toshihiro Shimizu 890ddd
			blurRadius(dBlur);
Toshihiro Shimizu 890ddd
	} catch (SMemAllocError) {
Toshihiro Shimizu 890ddd
		throw;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CSDirection::getResult(UCHAR *sel)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	memcpy(sel, m_dir, (size_t)(m_lX * m_lY * sizeof(UCHAR)));
Toshihiro Shimizu 890ddd
}