Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Pattern.cpp: implementation of the CPattern class.
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
#ifdef WIN32
Toshihiro Shimizu 890ddd
#pragma warning(disable : 4996)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <string.h></string.h>
Toshihiro Shimizu 890ddd
//#include <io.h></io.h>
Toshihiro Shimizu 890ddd
#include <fcntl.h></fcntl.h>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "Pattern.h"
Toshihiro Shimizu 890ddd
#include "toonz4.6/raster.h"
Toshihiro Shimizu 890ddd
//#include "toonz4.6/img.h"
Toshihiro Shimizu 890ddd
#include "toonz4.6/casm.h"
Toshihiro Shimizu 890ddd
//#include "toonz4.6/casm_msg.h"
Toshihiro Shimizu 890ddd
#include "toonz4.6/file.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "toonz4_6staff.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "SDef.h"
Toshihiro Shimizu 890ddd
#include "SError.h"
Toshihiro Shimizu 890ddd
#include "STPic.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
// Construction/Destruction
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#define P(a) tmsg_warning("-- %d --",a)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CPattern::CPattern(RASTER *imgContour) : m_lX(0), m_lY(0), m_pat(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!readPattern(imgContour)) {
Toshihiro Shimizu 890ddd
		throw SFileReadError();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		optimalizeSize();
Toshihiro Shimizu 890ddd
	} catch (SMemAllocError) {
Toshihiro Shimizu 890ddd
		throw;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CPattern::~CPattern()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	null();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPattern::null()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_lX = m_lY = 0;
Toshihiro Shimizu 890ddd
	if (m_pat) {
Toshihiro Shimizu 890ddd
		delete[] m_pat;
Toshihiro Shimizu 890ddd
		m_pat = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	m_fn[0] = '\0';
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool CPattern::readTTT(const char *fn)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
	int fd;
Toshihiro Shimizu 890ddd
		
Toshihiro Shimizu 890ddd
	if ( (fd=_open(fn, _O_RDONLY | _O_BINARY ))==-1 ) 
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	if ( _read(fd,&m_lX,sizeof(int))!=sizeof(int) ) {
Toshihiro Shimizu 890ddd
		_close(fd);
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if ( _read(fd,&m_lY,sizeof(int))!=sizeof(int) ) {
Toshihiro Shimizu 890ddd
		_close(fd);
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if ( m_lX<=0 || m_lY<=0 ) {
Toshihiro Shimizu 890ddd
		_close(fd);
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	
Toshihiro Shimizu 890ddd
	UCHAR *buffer=0;
Toshihiro Shimizu 890ddd
	buffer=new UCHAR[sizeof(UCHAR)*4*m_lX*m_lY];
Toshihiro Shimizu 890ddd
	if ( !buffer ) {
Toshihiro Shimizu 890ddd
		_close(fd);
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_pat=new UC_PIXEL[m_lX*m_lY];
Toshihiro Shimizu 890ddd
	if ( !m_pat ) {
Toshihiro Shimizu 890ddd
		delete [] buffer;
Toshihiro Shimizu 890ddd
		_close(fd);
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int length=4*m_lX*m_lY*sizeof(UCHAR);
Toshihiro Shimizu 890ddd
	if ( _read(fd,buffer,length)!=length ) {
Toshihiro Shimizu 890ddd
		delete [] buffer;
Toshihiro Shimizu 890ddd
		_close(fd);
Toshihiro Shimizu 890ddd
		return false;				
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	
Toshihiro Shimizu 890ddd
	int xy=m_lX*m_lY;
Toshihiro Shimizu 890ddd
	UCHAR* pb=buffer;
Toshihiro Shimizu 890ddd
	UC_PIXEL* pPat=m_pat;
Toshihiro Shimizu 890ddd
	for( int i=0; i
Toshihiro Shimizu 890ddd
		pPat->r=pb[0];
Toshihiro Shimizu 890ddd
		pPat->g=pb[1];
Toshihiro Shimizu 890ddd
		pPat->b=pb[2];
Toshihiro Shimizu 890ddd
		pPat->m=pb[3];
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delete [] buffer;
Toshihiro Shimizu 890ddd
	_close(fd);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool CPattern::readPattern(RASTER *imgContour)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	null();
Toshihiro Shimizu 890ddd
	if (!imgContour) {
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		RASTER *r = imgContour;
Toshihiro Shimizu 890ddd
		if (r) {
Toshihiro Shimizu 890ddd
			CSTPic<uc_pixel> lpic;</uc_pixel>
Toshihiro Shimizu 890ddd
			lpic.read(r);
Toshihiro Shimizu 890ddd
			if (lpic.m_lX > 0 && lpic.m_lY > 0 && lpic.m_pic) {
Toshihiro Shimizu 890ddd
				m_lX = lpic.m_lX;
Toshihiro Shimizu 890ddd
				m_lY = lpic.m_lY;
Toshihiro Shimizu 890ddd
				m_pat = new UC_PIXEL[m_lX * m_lY];
Toshihiro Shimizu 890ddd
				if (!m_pat) {
Toshihiro Shimizu 890ddd
					m_lX = m_lY = 0;
Toshihiro Shimizu 890ddd
					lpic.null();
Toshihiro Shimizu 890ddd
					//			TRop::releaseRaster46(r, true);
Toshihiro Shimizu 890ddd
					return false;
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++) {
Toshihiro Shimizu 890ddd
						UC_PIXEL *plp = lpic.m_pic + y * lpic.m_lX + x;
Toshihiro Shimizu 890ddd
						UC_PIXEL *ucp = m_pat + y * m_lX + x;
Toshihiro Shimizu 890ddd
						ucp->r = plp->r;
Toshihiro Shimizu 890ddd
						ucp->g = plp->g;
Toshihiro Shimizu 890ddd
						ucp->b = plp->b;
Toshihiro Shimizu 890ddd
						ucp->m = plp->m;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				lpic.null();
Toshihiro Shimizu 890ddd
				//	TRop::releaseRaster46(r, true);
Toshihiro Shimizu 890ddd
				return false;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			//TRop::releaseRaster46(r, true);
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPattern::getMapPixel(const int xx, const int yy, const double invScale,
Toshihiro Shimizu 890ddd
						   const double si, const double co, UC_PIXEL *&pucp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	pucp = 0;
Toshihiro Shimizu 890ddd
	double dxx = (double)xx * invScale;
Toshihiro Shimizu 890ddd
	double dyy = (double)yy * invScale;
Toshihiro Shimizu 890ddd
	double d2xx = (dxx * co - dyy * si) + (double)(m_lX - 1) * 0.5;
Toshihiro Shimizu 890ddd
	double d2yy = (dxx * si + dyy * co) + (double)(m_lY - 1) * 0.5;
Toshihiro Shimizu 890ddd
	int x = I_ROUND(d2xx);
Toshihiro Shimizu 890ddd
	int y = I_ROUND(d2yy);
Toshihiro Shimizu 890ddd
	if (x >= 0 && x < m_lX && y >= 0 && y < m_lY) {
Toshihiro Shimizu 890ddd
		pucp = m_pat + y * m_lX + x;
Toshihiro Shimizu 890ddd
		pucp = (pucp->m) == (UCHAR)0 ? 0 : pucp;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPattern::getMapPixel(const int xx, const int yy, const double invScale,
Toshihiro Shimizu 890ddd
						   UC_PIXEL *&pucp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	pucp = 0;
Toshihiro Shimizu 890ddd
	double dxx = (double)xx * invScale + (double)(m_lX - 1) * 0.5;
Toshihiro Shimizu 890ddd
	double dyy = (double)yy * invScale + (double)(m_lY - 1) * 0.5;
Toshihiro Shimizu 890ddd
	int x = I_ROUND(dxx);
Toshihiro Shimizu 890ddd
	int y = I_ROUND(dyy);
Toshihiro Shimizu 890ddd
	if (x >= 0 && x < m_lX && y >= 0 && y < m_lY) {
Toshihiro Shimizu 890ddd
		pucp = m_pat + y * m_lX + x;
Toshihiro Shimizu 890ddd
		pucp = (pucp->m) == (UCHAR)0 ? 0 : pucp;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPattern::getBBox(SRECT &bb)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	bb.x0 = m_lX;
Toshihiro Shimizu 890ddd
	bb.y0 = m_lY;
Toshihiro Shimizu 890ddd
	bb.x1 = -1;
Toshihiro Shimizu 890ddd
	bb.y1 = -1;
Toshihiro Shimizu 890ddd
	UC_PIXEL *pPic = m_pat;
Toshihiro Shimizu 890ddd
	for (int y = 0; y < m_lY; y++)
Toshihiro Shimizu 890ddd
		for (int x = 0; x < m_lX; x++, pPic++)
Toshihiro Shimizu 890ddd
			if (pPic->m > (UCHAR)0) {
Toshihiro Shimizu 890ddd
				bb.x0 = MIN(bb.x0, x);
Toshihiro Shimizu 890ddd
				bb.y0 = MIN(bb.y0, y);
Toshihiro Shimizu 890ddd
				bb.x1 = MAX(bb.x1, x);
Toshihiro Shimizu 890ddd
				bb.y1 = MAX(bb.y1, y);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPattern::optimalizeSize()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	SRECT bb;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	getBBox(bb);
Toshihiro Shimizu 890ddd
	if (bb.x0 <= bb.x1 && bb.y0 <= bb.y1) {
Toshihiro Shimizu 890ddd
		int nLX = bb.x1 - bb.x0 + 1;
Toshihiro Shimizu 890ddd
		int nLY = bb.y1 - bb.y0 + 1;
Toshihiro Shimizu 890ddd
		UC_PIXEL *nPat = new UC_PIXEL[nLX * nLY];
Toshihiro Shimizu 890ddd
		if (!nPat) {
Toshihiro Shimizu 890ddd
			char s[200];
Toshihiro Shimizu 890ddd
			sprintf(s, "in Pattern Optimalization \n");
Toshihiro Shimizu 890ddd
			throw SMemAllocError(s);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		for (int y = bb.y0; y <= bb.y1; y++)
Toshihiro Shimizu 890ddd
			for (int x = bb.x0; x <= bb.x1; x++) {
Toshihiro Shimizu 890ddd
				UC_PIXEL *pPat = m_pat + y * m_lX + x;
Toshihiro Shimizu 890ddd
				UC_PIXEL *pNPat = nPat + (y - bb.y0) * nLX + x - bb.x0;
Toshihiro Shimizu 890ddd
				pNPat->r = pPat->r;
Toshihiro Shimizu 890ddd
				pNPat->g = pPat->g;
Toshihiro Shimizu 890ddd
				pNPat->b = pPat->b;
Toshihiro Shimizu 890ddd
				pNPat->m = pPat->m;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		m_lX = nLX;
Toshihiro Shimizu 890ddd
		m_lY = nLY;
Toshihiro Shimizu 890ddd
		delete[] m_pat;
Toshihiro Shimizu 890ddd
		m_pat = nPat;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPattern::eraseBuffer(const int lX, const int lY, UC_PIXEL *buffer)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int xy = lX * lY;
Toshihiro Shimizu 890ddd
	UC_PIXEL *pb = buffer;
Toshihiro Shimizu 890ddd
	for (int i = 0; i < xy; i++, pb++)
Toshihiro Shimizu 890ddd
		pb->r = pb->g = pb->b = pb->m = (UCHAR)0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CPattern::rotate(const double angle)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_lX <= 0 || m_lY <= 0 || !m_pat)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double sDiag = sqrt(double(m_lX * m_lX + m_lY * m_lY));
Toshihiro Shimizu 890ddd
	int nLXY = (int)sDiag + 5;
Toshihiro Shimizu 890ddd
	int xx = nLXY / 2;
Toshihiro Shimizu 890ddd
	int yy = xx;
Toshihiro Shimizu 890ddd
	double co = cos(-DEG2RAD(angle));
Toshihiro Shimizu 890ddd
	double si = sin(-DEG2RAD(angle));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UC_PIXEL *nPat = new UC_PIXEL[nLXY * nLXY];
Toshihiro Shimizu 890ddd
	if (!nPat) {
Toshihiro Shimizu 890ddd
		char s[200];
Toshihiro Shimizu 890ddd
		sprintf(s, "in Pattern Rotation \n");
Toshihiro Shimizu 890ddd
		throw SMemAllocError(s);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	eraseBuffer(nLXY, nLXY, nPat);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UC_PIXEL *pNPat = nPat;
Toshihiro Shimizu 890ddd
	for (int y = 0; y < nLXY; y++)
Toshihiro Shimizu 890ddd
		for (int x = 0; x < nLXY; x++, pNPat++) {
Toshihiro Shimizu 890ddd
			UC_PIXEL *pucp = 0;
Toshihiro Shimizu 890ddd
			getMapPixel(x - xx, y - yy, 1.0, si, co, pucp);
Toshihiro Shimizu 890ddd
			if (pucp) {
Toshihiro Shimizu 890ddd
				pNPat->r = pucp->r;
Toshihiro Shimizu 890ddd
				pNPat->g = pucp->g;
Toshihiro Shimizu 890ddd
				pNPat->b = pucp->b;
Toshihiro Shimizu 890ddd
				pNPat->m = pucp->m;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	m_lX = m_lY = nLXY;
Toshihiro Shimizu 890ddd
	delete[] m_pat;
Toshihiro Shimizu 890ddd
	m_pat = nPat;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		optimalizeSize();
Toshihiro Shimizu 890ddd
	} catch (SMemAllocError) {
Toshihiro Shimizu 890ddd
		throw;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}