Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// EraseContour.cpp: implementation of the CEraseContour class.
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <stdlib.h></stdlib.h>
Toshihiro Shimizu 890ddd
#include <search.h></search.h>
Toshihiro Shimizu 890ddd
#include <math.h></math.h>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#include "myetc.h"
Toshihiro Shimizu 890ddd
#include "EraseContour.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
// Construction/Destruction
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CEraseContour::~CEraseContour()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	null();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CEraseContour::null()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_lX = m_lY = 0;
Toshihiro Shimizu 890ddd
	m_picUC = 0;
Toshihiro Shimizu 890ddd
	m_picUS = 0;
Toshihiro Shimizu 890ddd
	m_sel = 0;
Toshihiro Shimizu 890ddd
	m_ras = 0;
Toshihiro Shimizu 890ddd
	m_cil.m_nb = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int CEraseContour::makeSelectionCMAP32()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UCHAR *pSel = m_sel;
Toshihiro Shimizu 890ddd
	int xy = 0, nbSel = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int y = 0; y < m_lY; y++)
Toshihiro Shimizu 890ddd
		for (int x = 0; x < m_lX; x++, xy++, pSel++) {
Toshihiro Shimizu 890ddd
			int xyRas = y * m_ras->wrap + x;
Toshihiro Shimizu 890ddd
			UD44_CMAPINDEX32 ci32 = *((UD44_CMAPINDEX32 *)(m_ras->buffer) + xyRas);
Toshihiro Shimizu 890ddd
			if ((ci32 & 0x000000ff) == 0xff) {
Toshihiro Shimizu 890ddd
				// Paint color, if transparent 0
Toshihiro Shimizu 890ddd
				*pSel = (UCHAR)3;
Toshihiro Shimizu 890ddd
			} else if ((ci32 & 0x000000ff) == 0x0) {
Toshihiro Shimizu 890ddd
				// Ink color
Toshihiro Shimizu 890ddd
				if (m_cil.isIn((int)((ci32 >> 20) & 0x00000fff))) {
Toshihiro Shimizu 890ddd
					*pSel = (UCHAR)1;
Toshihiro Shimizu 890ddd
					nbSel++;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				// Tone color ( antialiasing pixel )
Toshihiro Shimizu 890ddd
				if (m_cil.isIn((int)((ci32 >> 20) & 0x00000fff))) {
Toshihiro Shimizu 890ddd
					*pSel = (UCHAR)1;
Toshihiro Shimizu 890ddd
					nbSel++;
Toshihiro Shimizu 890ddd
					//					*pSel=(UCHAR)2;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return nbSel;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//  Makes the selection of ink and antialiasing pixels.
Toshihiro Shimizu 890ddd
//	0 - 0 matte (transparent) OR ink color which is not in m_cil
Toshihiro Shimizu 890ddd
//  1 - ink pixel, which is in the m_cil
Toshihiro Shimizu 890ddd
//  1 - antialiasing pixel
Toshihiro Shimizu 890ddd
//  3 - paint color
Toshihiro Shimizu 890ddd
int CEraseContour::makeSelection(const CCIL &iil)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int nb = 0;
Toshihiro Shimizu 890ddd
	m_cil = iil;
Toshihiro Shimizu 890ddd
	if (m_cil.m_nb <= 0)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	if (m_lX <= 0 || m_lY <= 0 || !m_sel || !m_ras || !(m_picUC || m_picUS))
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	memset(m_sel, 0, m_lX * m_lY);
Toshihiro Shimizu 890ddd
	if (m_ras->type == RAS_CM32)
Toshihiro Shimizu 890ddd
		nb = makeSelectionCMAP32();
Toshihiro Shimizu 890ddd
	if (nb > 0)
Toshihiro Shimizu 890ddd
		sel0123To01();
Toshihiro Shimizu 890ddd
	return nb;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//  Makes the selection of ink and antialiasing pixels.
Toshihiro Shimizu 890ddd
//  m_cil has been prepared!!
Toshihiro Shimizu 890ddd
//  0 - 0 matte (transparent) OR ink color which is not in m_cil
Toshihiro Shimizu 890ddd
//  1 - ink pixel, which is in the m_cil
Toshihiro Shimizu 890ddd
//  1 - antialiasing pixel
Toshihiro Shimizu 890ddd
//  3 - paint color
Toshihiro Shimizu 890ddd
int CEraseContour::makeSelection()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	memset(m_sel, 0, m_lX * m_lY);
Toshihiro Shimizu 890ddd
	if (m_ras->type == RAS_CM32)
Toshihiro Shimizu 890ddd
		return makeSelectionCMAP32();
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int CEraseContour::doIt(const CCIL &iil)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int nb = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_cil = iil;
Toshihiro Shimizu 890ddd
	if (m_cil.m_nb <= 0)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	if (m_lX <= 0 || m_lY <= 0 || !m_sel || !m_ras || !(m_picUC || m_picUS))
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	nb = makeSelection();
Toshihiro Shimizu 890ddd
	if (nb > 0) {
Toshihiro Shimizu 890ddd
		eraseInkColors();
Toshihiro Shimizu 890ddd
		sel0123To01();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return nb;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CEraseContour::sel0123To01()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int xy = m_lX * m_lY;
Toshihiro Shimizu 890ddd
	UCHAR *pSel = m_sel;
Toshihiro Shimizu 890ddd
	for (int i = 0; i < xy; i++, pSel++)
Toshihiro Shimizu 890ddd
		*pSel = *(pSel) == (UCHAR)1 ? (UCHAR)1 : (UCHAR)0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CEraseContour::eraseInkColors()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UCHAR *pSel = m_sel;
Toshihiro Shimizu 890ddd
	prepareNeighbours();
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)1 || *pSel == (UCHAR)2) {
Toshihiro Shimizu 890ddd
				I_PIXEL ip = {0, 0, 0, 0};
Toshihiro Shimizu 890ddd
				if (findClosestPaint(x, y, ip)) {
Toshihiro Shimizu 890ddd
					if (m_picUC) {
Toshihiro Shimizu 890ddd
						UC_PIXEL *uc = m_picUC + y * m_lX + x;
Toshihiro Shimizu 890ddd
						uc->r = (UCHAR)ip.r;
Toshihiro Shimizu 890ddd
						uc->g = (UCHAR)ip.g;
Toshihiro Shimizu 890ddd
						uc->b = (UCHAR)ip.b;
Toshihiro Shimizu 890ddd
						uc->m = (UCHAR)ip.m;
Toshihiro Shimizu 890ddd
					} else {
Toshihiro Shimizu 890ddd
						US_PIXEL *us = m_picUS + y * m_lX + x;
Toshihiro Shimizu 890ddd
						us->r = (USHORT)ip.r;
Toshihiro Shimizu 890ddd
						us->g = (USHORT)ip.g;
Toshihiro Shimizu 890ddd
						us->b = (USHORT)ip.b;
Toshihiro Shimizu 890ddd
						us->m = (USHORT)ip.m;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int erasecontour_xydwCompare(const void *a, const void *b)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	SXYDW *aa = (SXYDW *)a;
Toshihiro Shimizu 890ddd
	SXYDW *bb = (SXYDW *)b;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (aa->w < bb->w)
Toshihiro Shimizu 890ddd
		return -1;
Toshihiro Shimizu 890ddd
	if (aa->w > bb->w)
Toshihiro Shimizu 890ddd
		return 1;
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CEraseContour::prepareNeighbours()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int q = ((int)sqrt((double)MAXNB_NEIGHBOURS) - 1) / 2;
Toshihiro Shimizu 890ddd
	m_nbNeighbours = 0;
Toshihiro Shimizu 890ddd
	for (int y = -q; y <= q; y++)
Toshihiro Shimizu 890ddd
		for (int x = -q; x <= q; x++) {
Toshihiro Shimizu 890ddd
			m_neighbours[m_nbNeighbours].x = x;
Toshihiro Shimizu 890ddd
			m_neighbours[m_nbNeighbours].y = y;
Toshihiro Shimizu 890ddd
			m_neighbours[m_nbNeighbours].w = sqrt((double)(x * x + y * y));
Toshihiro Shimizu 890ddd
			m_nbNeighbours++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	qsort(m_neighbours, m_nbNeighbours, sizeof(SXYDW), erasecontour_xydwCompare);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool CEraseContour::findClosestPaint(const int xx, const int yy, I_PIXEL &ip)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int i = 0; i < m_nbNeighbours; i++) {
Toshihiro Shimizu 890ddd
		int x = xx + m_neighbours[i].x;
Toshihiro Shimizu 890ddd
		int y = yy + m_neighbours[i].y;
Toshihiro Shimizu 890ddd
		if (x >= 0 && y >= 0 && x < m_lX && y < m_lY)
Toshihiro Shimizu 890ddd
			if (*(m_sel + y * m_lX + x) == (UCHAR)3) {
Toshihiro Shimizu 890ddd
				if (m_picUC) {
Toshihiro Shimizu 890ddd
					UC_PIXEL *uc = m_picUC + y * m_lX + x;
Toshihiro Shimizu 890ddd
					ip.r = (int)uc->r;
Toshihiro Shimizu 890ddd
					ip.g = (int)uc->g;
Toshihiro Shimizu 890ddd
					ip.b = (int)uc->b;
Toshihiro Shimizu 890ddd
					ip.m = (int)uc->m;
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					US_PIXEL *us = m_picUS + y * m_lX + x;
Toshihiro Shimizu 890ddd
					ip.r = (int)us->r;
Toshihiro Shimizu 890ddd
					ip.g = (int)us->g;
Toshihiro Shimizu 890ddd
					ip.b = (int)us->b;
Toshihiro Shimizu 890ddd
					ip.m = (int)us->m;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				return true;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	ip.r = ip.g = ip.b = ip.m = 0;
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}