|
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 |
|
|
Shinya Kitaoka |
120a6e |
CEraseContour::~CEraseContour() { null(); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void CEraseContour::null() {
|
|
Shinya Kitaoka |
120a6e |
m_lX = m_lY = 0;
|
|
Shinya Kitaoka |
120a6e |
m_picUC = 0;
|
|
Shinya Kitaoka |
120a6e |
m_picUS = 0;
|
|
Shinya Kitaoka |
120a6e |
m_sel.reset();
|
|
Shinya Kitaoka |
120a6e |
m_ras = 0;
|
|
Shinya Kitaoka |
120a6e |
m_cil.m_nb = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int CEraseContour::makeSelectionCMAP32() {
|
|
Shinya Kitaoka |
120a6e |
UCHAR *pSel = m_sel.get();
|
|
Shinya Kitaoka |
120a6e |
int xy = 0, nbSel = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int y = 0; y < m_lY; y++)
|
|
Shinya Kitaoka |
120a6e |
for (int x = 0; x < m_lX; x++, xy++, pSel++) {
|
|
Shinya Kitaoka |
120a6e |
int xyRas = y * m_ras->wrap + x;
|
|
Shinya Kitaoka |
120a6e |
UD44_CMAPINDEX32 ci32 = *((UD44_CMAPINDEX32 *)(m_ras->buffer) + xyRas);
|
|
Shinya Kitaoka |
120a6e |
if ((ci32 & 0x000000ff) == 0xff) {
|
|
Shinya Kitaoka |
120a6e |
// Paint color, if transparent 0
|
|
Shinya Kitaoka |
120a6e |
*pSel = (UCHAR)3;
|
|
Shinya Kitaoka |
120a6e |
} else if ((ci32 & 0x000000ff) == 0x0) {
|
|
Shinya Kitaoka |
120a6e |
// Ink color
|
|
Shinya Kitaoka |
120a6e |
if (m_cil.isIn((int)((ci32 >> 20) & 0x00000fff))) {
|
|
Shinya Kitaoka |
120a6e |
*pSel = (UCHAR)1;
|
|
Shinya Kitaoka |
120a6e |
nbSel++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// Tone color ( antialiasing pixel )
|
|
Shinya Kitaoka |
120a6e |
if (m_cil.isIn((int)((ci32 >> 20) & 0x00000fff))) {
|
|
Shinya Kitaoka |
120a6e |
*pSel = (UCHAR)1;
|
|
Shinya Kitaoka |
120a6e |
nbSel++;
|
|
Shinya Kitaoka |
120a6e |
// *pSel=(UCHAR)2;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
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
|
|
Shinya Kitaoka |
120a6e |
int CEraseContour::makeSelection(const CCIL &iil) {
|
|
Shinya Kitaoka |
120a6e |
int nb = 0;
|
|
Shinya Kitaoka |
120a6e |
m_cil = iil;
|
|
Shinya Kitaoka |
120a6e |
if (m_cil.m_nb <= 0) return 0;
|
|
Shinya Kitaoka |
120a6e |
if (m_lX <= 0 || m_lY <= 0 || !m_sel || !m_ras || !(m_picUC || m_picUS))
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
memset(m_sel.get(), 0, m_lX * m_lY);
|
|
Shinya Kitaoka |
120a6e |
if (m_ras->type == RAS_CM32) nb = makeSelectionCMAP32();
|
|
Shinya Kitaoka |
120a6e |
if (nb > 0) sel0123To01();
|
|
Shinya Kitaoka |
120a6e |
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
|
|
Shinya Kitaoka |
120a6e |
int CEraseContour::makeSelection() {
|
|
Shinya Kitaoka |
120a6e |
memset(m_sel.get(), 0, m_lX * m_lY);
|
|
Shinya Kitaoka |
120a6e |
if (m_ras->type == RAS_CM32) return makeSelectionCMAP32();
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int CEraseContour::doIt(const CCIL &iil) {
|
|
Shinya Kitaoka |
120a6e |
int nb = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_cil = iil;
|
|
Shinya Kitaoka |
120a6e |
if (m_cil.m_nb <= 0) return 0;
|
|
Shinya Kitaoka |
120a6e |
if (m_lX <= 0 || m_lY <= 0 || !m_sel || !m_ras || !(m_picUC || m_picUS))
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
nb = makeSelection();
|
|
Shinya Kitaoka |
120a6e |
if (nb > 0) {
|
|
Shinya Kitaoka |
120a6e |
eraseInkColors();
|
|
Shinya Kitaoka |
120a6e |
sel0123To01();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return nb;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void CEraseContour::sel0123To01() {
|
|
Shinya Kitaoka |
120a6e |
int xy = m_lX * m_lY;
|
|
Shinya Kitaoka |
120a6e |
UCHAR *pSel = m_sel.get();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < xy; i++, pSel++)
|
|
Shinya Kitaoka |
120a6e |
*pSel = *(pSel) == (UCHAR)1 ? (UCHAR)1 : (UCHAR)0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void CEraseContour::eraseInkColors() {
|
|
Shinya Kitaoka |
120a6e |
UCHAR *pSel = m_sel.get();
|
|
Shinya Kitaoka |
120a6e |
prepareNeighbours();
|
|
Shinya Kitaoka |
120a6e |
for (int y = 0; y < m_lY; y++)
|
|
Shinya Kitaoka |
120a6e |
for (int x = 0; x < m_lX; x++, pSel++)
|
|
Shinya Kitaoka |
120a6e |
if (*pSel == (UCHAR)1 || *pSel == (UCHAR)2) {
|
|
Shinya Kitaoka |
120a6e |
I_PIXEL ip = {0, 0, 0, 0};
|
|
Shinya Kitaoka |
120a6e |
if (findClosestPaint(x, y, ip)) {
|
|
Shinya Kitaoka |
120a6e |
if (m_picUC) {
|
|
Shinya Kitaoka |
120a6e |
UC_PIXEL *uc = m_picUC + y * m_lX + x;
|
|
Shinya Kitaoka |
120a6e |
uc->r = (UCHAR)ip.r;
|
|
Shinya Kitaoka |
120a6e |
uc->g = (UCHAR)ip.g;
|
|
Shinya Kitaoka |
120a6e |
uc->b = (UCHAR)ip.b;
|
|
Shinya Kitaoka |
120a6e |
uc->m = (UCHAR)ip.m;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
US_PIXEL *us = m_picUS + y * m_lX + x;
|
|
Shinya Kitaoka |
120a6e |
us->r = (USHORT)ip.r;
|
|
Shinya Kitaoka |
120a6e |
us->g = (USHORT)ip.g;
|
|
Shinya Kitaoka |
120a6e |
us->b = (USHORT)ip.b;
|
|
Shinya Kitaoka |
120a6e |
us->m = (USHORT)ip.m;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
b3bd84 |
static int erasecontour_xydwCompare(const void *a, const void *b) {
|
|
Shinya Kitaoka |
120a6e |
SXYDW *aa = (SXYDW *)a;
|
|
Shinya Kitaoka |
120a6e |
SXYDW *bb = (SXYDW *)b;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (aa->w < bb->w) return -1;
|
|
Shinya Kitaoka |
120a6e |
if (aa->w > bb->w) return 1;
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void CEraseContour::prepareNeighbours() {
|
|
Shinya Kitaoka |
120a6e |
int q = ((int)sqrt((double)MAXNB_NEIGHBOURS) - 1) / 2;
|
|
Shinya Kitaoka |
120a6e |
m_nbNeighbours = 0;
|
|
Shinya Kitaoka |
120a6e |
for (int y = -q; y <= q; y++)
|
|
Shinya Kitaoka |
120a6e |
for (int x = -q; x <= q; x++) {
|
|
Shinya Kitaoka |
120a6e |
m_neighbours[m_nbNeighbours].x = x;
|
|
Shinya Kitaoka |
120a6e |
m_neighbours[m_nbNeighbours].y = y;
|
|
Shinya Kitaoka |
120a6e |
m_neighbours[m_nbNeighbours].w = sqrt((double)(x * x + y * y));
|
|
Shinya Kitaoka |
120a6e |
m_nbNeighbours++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
qsort(m_neighbours.data(), m_nbNeighbours, sizeof(SXYDW),
|
|
Shinya Kitaoka |
120a6e |
erasecontour_xydwCompare);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool CEraseContour::findClosestPaint(const int xx, const int yy, I_PIXEL &ip) {
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < m_nbNeighbours; i++) {
|
|
Shinya Kitaoka |
120a6e |
int x = xx + m_neighbours[i].x;
|
|
Shinya Kitaoka |
120a6e |
int y = yy + m_neighbours[i].y;
|
|
Shinya Kitaoka |
120a6e |
if (x >= 0 && y >= 0 && x < m_lX && y < m_lY)
|
|
Shinya Kitaoka |
120a6e |
if (*(m_sel.get() + y * m_lX + x) == (UCHAR)3) {
|
|
Shinya Kitaoka |
120a6e |
if (m_picUC) {
|
|
Shinya Kitaoka |
120a6e |
UC_PIXEL *uc = m_picUC + y * m_lX + x;
|
|
Shinya Kitaoka |
120a6e |
ip.r = (int)uc->r;
|
|
Shinya Kitaoka |
120a6e |
ip.g = (int)uc->g;
|
|
Shinya Kitaoka |
120a6e |
ip.b = (int)uc->b;
|
|
Shinya Kitaoka |
120a6e |
ip.m = (int)uc->m;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
US_PIXEL *us = m_picUS + y * m_lX + x;
|
|
Shinya Kitaoka |
120a6e |
ip.r = (int)us->r;
|
|
Shinya Kitaoka |
120a6e |
ip.g = (int)us->g;
|
|
Shinya Kitaoka |
120a6e |
ip.b = (int)us->b;
|
|
Shinya Kitaoka |
120a6e |
ip.m = (int)us->m;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
ip.r = ip.g = ip.b = ip.m = 0;
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|