Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Pattern.h: interface for the CPattern class.
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if !defined(AFX_PATTERN_H__8E417023_35C0_11D6_B9EA_0040F674BE6A__INCLUDED_)
Toshihiro Shimizu 890ddd
#define AFX_PATTERN_H__8E417023_35C0_11D6_B9EA_0040F674BE6A__INCLUDED_
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if _MSC_VER > 1000
Toshihiro Shimizu 890ddd
#pragma once
Toshihiro Shimizu 890ddd
#endif // _MSC_VER > 1000
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "STColSelPic.h"
Toshihiro Shimizu 890ddd
#include "SDef.h"
Toshihiro Shimizu 890ddd
#include "toonz4.6/pixel.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class CPattern
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int m_lX, m_lY;
Toshihiro Shimizu 890ddd
	UC_PIXEL *m_pat;
Toshihiro Shimizu 890ddd
	char m_fn[1024];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void null();
Toshihiro Shimizu 890ddd
	bool readPattern(RASTER *imgContour);
Toshihiro Shimizu 890ddd
	bool isOK()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_lX > 0 && m_lY > 0 && m_pat)
Toshihiro Shimizu 890ddd
			return true;
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	void 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
	void getMapPixel(const int xx, const int yy, const double invScale, UC_PIXEL *&pucp);
Toshihiro Shimizu 890ddd
	bool readTTT(const char *fn);
Toshihiro Shimizu 890ddd
	void getBBox(SRECT &bb);
Toshihiro Shimizu 890ddd
	void eraseBuffer(const int lX, const int lY, UC_PIXEL *buffer);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	CPattern() : m_lX(0), m_lY(0), m_pat(0) { m_fn[0] = '\0'; };
Toshihiro Shimizu 890ddd
	CPattern(RASTER *imgContour);
Toshihiro Shimizu 890ddd
	virtual ~CPattern();
Toshihiro Shimizu 890ddd
	void rotate(const double angle);
Toshihiro Shimizu 890ddd
	void optimalizeSize();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <class p=""></class>
Toshihiro Shimizu 890ddd
	void test(CSTColSelPic

&pic, I_PIXEL &eCol, int ox, int oy)

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
				if ((x + ox) < pic.m_lX && (y + oy) < pic.m_lY) {
Toshihiro Shimizu 890ddd
					P *p = pic.m_pic + (y + oy) * pic.m_lX + x + ox;
Toshihiro Shimizu 890ddd
					UC_PIXEL *pP = m_pat + y * m_lX + x;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					if (pP->m > (UCHAR)0) {
Toshihiro Shimizu 890ddd
						double q = ((double)(pP->m) / 255.0) * ((double)eCol.m / 255.0);
Toshihiro Shimizu 890ddd
						double r = (1.0 - q) * (double)p->r + q * (double)eCol.r;
Toshihiro Shimizu 890ddd
						double g = (1.0 - q) * (double)p->g + q * (double)eCol.g;
Toshihiro Shimizu 890ddd
						double b = (1.0 - q) * (double)p->b + q * (double)eCol.b;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						r = D_CUT_0_255(r);
Toshihiro Shimizu 890ddd
						g = D_CUT_0_255(g);
Toshihiro Shimizu 890ddd
						b = D_CUT_0_255(b);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						p->r = UC_ROUND(r);
Toshihiro Shimizu 890ddd
						p->g = UC_ROUND(g);
Toshihiro Shimizu 890ddd
						p->b = UC_ROUND(b);
Toshihiro Shimizu 890ddd
						p->m = pP->m;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Maps the pattern. Long and optimalized version.
Toshihiro Shimizu 890ddd
	template <class p=""></class>
Toshihiro Shimizu 890ddd
	void mapIt(CSTColSelPic

&pic, const CSTColSelPic

&oriPic,

Toshihiro Shimizu 890ddd
			   const int xx, const int yy,
Toshihiro Shimizu 890ddd
			   const double scale, const double rot, const bool isUseOriColor, const bool isIncludeAlpha)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (scale < 0.01)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		if (xx < 0 || yy < 0 || xx >= pic.m_lX || yy >= pic.m_lY)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double sDiag = scale * sqrt(double(m_lX * m_lX + m_lY * m_lY));
Toshihiro Shimizu 890ddd
		int iSDiag = (int)sDiag + 1;
Toshihiro Shimizu 890ddd
		int iSDiag2 = iSDiag / 2 + 1;
Toshihiro Shimizu 890ddd
		if (iSDiag <= 0)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double invScale = 1.0 / scale;
Toshihiro Shimizu 890ddd
		double co = cos(-DEG2RAD(rot));
Toshihiro Shimizu 890ddd
		double si = sin(-DEG2RAD(rot));
Toshihiro Shimizu 890ddd
		bool isUC = pic.getType() == ST_RGBM ? true : false;
Toshihiro Shimizu 890ddd
		double maxPixVal = isUC ? 255.0 : 65535.0;
Toshihiro Shimizu 890ddd
		double ddiv = 1.0 / (maxPixVal * 255.0);
Toshihiro Shimizu 890ddd
		int yBeg = MAX(yy - iSDiag2, 0);
Toshihiro Shimizu 890ddd
		int yEnd = MIN(yy + iSDiag2, pic.m_lY - 1);
Toshihiro Shimizu 890ddd
		int xBeg = MAX(xx - iSDiag2, 0);
Toshihiro Shimizu 890ddd
		int xEnd = MIN(xx + iSDiag2, pic.m_lX - 1);
Toshihiro Shimizu 890ddd
		double lxm105 = (double)(m_lX - 1) * 0.5;
Toshihiro Shimizu 890ddd
		double lym105 = (double)(m_lY - 1) * 0.5;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		I_PIXEL eCol;
Toshihiro Shimizu 890ddd
		memset(&eCol, 0, sizeof(I_PIXEL));
Toshihiro Shimizu 890ddd
		if (isUseOriColor) {
Toshihiro Shimizu 890ddd
			P *pOriPic = oriPic.m_pic + yy * oriPic.m_lX + xx;
Toshihiro Shimizu 890ddd
			eCol.r = (int)pOriPic->r;
Toshihiro Shimizu 890ddd
			eCol.g = (int)pOriPic->g;
Toshihiro Shimizu 890ddd
			eCol.b = (int)pOriPic->b;
Toshihiro Shimizu 890ddd
			if (isIncludeAlpha)
Toshihiro Shimizu 890ddd
				eCol.m = (int)pOriPic->m;
Toshihiro Shimizu 890ddd
			else {
Toshihiro Shimizu 890ddd
				if ((int)pOriPic->m != 255)
Toshihiro Shimizu 890ddd
					eCol.m = 0;
Toshihiro Shimizu 890ddd
				else
Toshihiro Shimizu 890ddd
					eCol.m = 255;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		int oriMatte = (int)((oriPic.m_pic + yy * oriPic.m_lX + xx)->m);
Toshihiro Shimizu 890ddd
		for (int y = yBeg; y <= yEnd; y++)
Toshihiro Shimizu 890ddd
			for (int x = xBeg; x <= xEnd; x++)
Toshihiro Shimizu 890ddd
				if (x >= 0 && x < pic.m_lX && y >= 0 && y < pic.m_lY) {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					// ----- Calculates the pattern pixel coordinates -----
Toshihiro Shimizu 890ddd
					UC_PIXEL *pucp = 0;
Toshihiro Shimizu 890ddd
					//					getMapPixel(x-xx,y-yy,invScale,si,co,pucp);
Toshihiro Shimizu 890ddd
					double dxx = (double)(x - xx) * invScale;
Toshihiro Shimizu 890ddd
					double dyy = (double)(y - yy) * invScale;
Toshihiro Shimizu 890ddd
					double d2xx = (dxx * co - dyy * si) + lxm105;
Toshihiro Shimizu 890ddd
					double d2yy = (dxx * si + dyy * co) + lym105;
Toshihiro Shimizu 890ddd
					int x1 = I_ROUND(d2xx);
Toshihiro Shimizu 890ddd
					int y1 = I_ROUND(d2yy);
Toshihiro Shimizu 890ddd
					if (x1 >= 0 && x1 < m_lX && y1 >= 0 && y1 < m_lY) {
Toshihiro Shimizu 890ddd
						pucp = m_pat + y1 * m_lX + x1;
Toshihiro Shimizu 890ddd
						pucp = (pucp->m) == (UCHAR)0 ? 0 : pucp;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
					// ----------------------------------------------------
Toshihiro Shimizu 890ddd
					if (pucp) {
Toshihiro Shimizu 890ddd
						int xy = y * pic.m_lX + x;
Toshihiro Shimizu 890ddd
						P *pPic = pic.m_pic + xy;
Toshihiro Shimizu 890ddd
						if (!isUseOriColor) {
Toshihiro Shimizu 890ddd
							eCol.r = (int)pucp->r;
Toshihiro Shimizu 890ddd
							eCol.g = (int)pucp->g;
Toshihiro Shimizu 890ddd
							eCol.b = (int)pucp->b;
Toshihiro Shimizu 890ddd
							if (isIncludeAlpha)
Toshihiro Shimizu 890ddd
								eCol.m = oriMatte;
Toshihiro Shimizu 890ddd
							else {
Toshihiro Shimizu 890ddd
								if (oriMatte != 255)
Toshihiro Shimizu 890ddd
									eCol.m = 0;
Toshihiro Shimizu 890ddd
								else
Toshihiro Shimizu 890ddd
									eCol.m = 255;
Toshihiro Shimizu 890ddd
							}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
							if (!isUC) {
Toshihiro Shimizu 890ddd
								eCol.r = PIX_USHORT_FROM_BYTE((UCHAR)eCol.r);
Toshihiro Shimizu 890ddd
								eCol.g = PIX_USHORT_FROM_BYTE((UCHAR)eCol.g);
Toshihiro Shimizu 890ddd
								eCol.b = PIX_USHORT_FROM_BYTE((UCHAR)eCol.b);
Toshihiro Shimizu 890ddd
							}
Toshihiro Shimizu 890ddd
						}
Toshihiro Shimizu 890ddd
						double q = ((double)pucp->m) * ((double)eCol.m) * ddiv;
Toshihiro Shimizu 890ddd
						double qq = 1.0 - q;
Toshihiro Shimizu 890ddd
						double r = qq * (double)pPic->r + q * (double)eCol.r;
Toshihiro Shimizu 890ddd
						double g = qq * (double)pPic->g + q * (double)eCol.g;
Toshihiro Shimizu 890ddd
						double b = qq * (double)pPic->b + q * (double)eCol.b;
Toshihiro Shimizu 890ddd
						double m = qq * (double)pPic->m + q * (double)eCol.m;
Toshihiro Shimizu 890ddd
						r = D_CUT(r, 0.0, maxPixVal);
Toshihiro Shimizu 890ddd
						g = D_CUT(g, 0.0, maxPixVal);
Toshihiro Shimizu 890ddd
						b = D_CUT(b, 0.0, maxPixVal);
Toshihiro Shimizu 890ddd
						m = D_CUT(m, 0.0, maxPixVal);
Toshihiro Shimizu 890ddd
						if (isUC) {
Toshihiro Shimizu 890ddd
							pPic->r = UC_ROUND(r);
Toshihiro Shimizu 890ddd
							pPic->g = UC_ROUND(g);
Toshihiro Shimizu 890ddd
							pPic->b = UC_ROUND(b);
Toshihiro Shimizu 890ddd
							pPic->m = UC_ROUND(m);
Toshihiro Shimizu 890ddd
						} else {
Toshihiro Shimizu 890ddd
							pPic->r = (UCHAR)US_ROUND(r);
Toshihiro Shimizu 890ddd
							pPic->g = (UCHAR)US_ROUND(g);
Toshihiro Shimizu 890ddd
							pPic->b = (UCHAR)US_ROUND(b);
Toshihiro Shimizu 890ddd
							pPic->m = (UCHAR)US_ROUND(m);
Toshihiro Shimizu 890ddd
						}
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*	Optimized version. Doesn't use the ROTATION parameter. 
Toshihiro Shimizu 890ddd
	!!! Semi-finished version !!!
Toshihiro Shimizu 890ddd
template<class p=""></class>
Toshihiro Shimizu 890ddd
void mapIt(CSTColSelPic

& pic, const CSTColSelPic

& oriPic,

Toshihiro Shimizu 890ddd
		   const int xx, const int yy, 
Toshihiro Shimizu 890ddd
		   const double scale, const bool isUseOriColor)
Toshihiro Shimizu 890ddd
{	
Toshihiro Shimizu 890ddd
	
Toshihiro Shimizu 890ddd
	if ( scale<0.01 ) 
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double scaleInv=1.0/scale;
Toshihiro Shimizu 890ddd
	double sDiag=scale*sqrt(m_lX*m_lX+m_lY*m_lY);
Toshihiro Shimizu 890ddd
	int iSDiag=(int)sDiag+1;
Toshihiro Shimizu 890ddd
	int iSDiag2=iSDiag/2+1;
Toshihiro Shimizu 890ddd
	if ( iSDiag<=0 ) 
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool isUC= pic.getType()==ST_RGBM ? true : false;
Toshihiro Shimizu 890ddd
	double maxPixVal= isUC ? 255.0 : 65535.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int yBeg=MAX(yy-iSDiag2,0);
Toshihiro Shimizu 890ddd
	int yEnd=MIN(yy+iSDiag2,pic.m_lY-1);
Toshihiro Shimizu 890ddd
	int xBeg=MAX(xx-iSDiag2,0);
Toshihiro Shimizu 890ddd
	int xEnd=MIN(xx+iSDiag2,pic.m_lX-1);
Toshihiro Shimizu 890ddd
	I_PIXEL eCol;
Toshihiro Shimizu 890ddd
	for( int y=yBeg; y<=yEnd; y++ )
Toshihiro Shimizu 890ddd
		for( int x=xBeg; x<=xEnd; x++ ) 
Toshihiro Shimizu 890ddd
			if ( x>=0 && x<pic.m_lx &&="" y="">=0 && y</pic.m_lx>
Toshihiro Shimizu 890ddd
// Gets the pointer to the proper pattern pixel		
Toshihiro Shimizu 890ddd
					UC_PIXEL* pPatPixel=0;	
Toshihiro Shimizu 890ddd
					double dxx=(double)(x-xx)*scaleInv+(double)(m_lX-1)*0.5;
Toshihiro Shimizu 890ddd
					double dyy=(double)(y-yy)*scaleInv+(double)(m_lY-1)*0.5;
Toshihiro Shimizu 890ddd
					int x1=I_ROUND(dxx);
Toshihiro Shimizu 890ddd
					int y1=I_ROUND(dyy);
Toshihiro Shimizu 890ddd
					if ( x1>=0 && x1<m_lx &&="" y1="">=0 && y1</m_lx>
Toshihiro Shimizu 890ddd
						pPatPixel=m_pat+y1*m_lX+x1;
Toshihiro Shimizu 890ddd
						pPatPixel= pPatPixel->m>(UCHAR)0 ? pPatPixel : 0;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
						
Toshihiro Shimizu 890ddd
//					getMapPixel(x-xx,y-yy,scale,ucp);
Toshihiro Shimizu 890ddd
					if ( pPatPixel ) {
Toshihiro Shimizu 890ddd
						int xy=y*pic.m_lX+x;
Toshihiro Shimizu 890ddd
						P* pPic=pic.m_pic+xy;
Toshihiro Shimizu 890ddd
						P* pOriPic=oriPic+xy;
Toshihiro Shimizu 890ddd
						if ( isUseOriColor ) {
Toshihiro Shimizu 890ddd
							eCol.r=(int)pOriPic->r;
Toshihiro Shimizu 890ddd
							eCol.g=(int)pOriPic->g;
Toshihiro Shimizu 890ddd
							eCol.b=(int)pOriPic->b;
Toshihiro Shimizu 890ddd
							eCol.m=(int)pOriPic->m;
Toshihiro Shimizu 890ddd
						} else {
Toshihiro Shimizu 890ddd
							eCol.r=(int)pPat->r;
Toshihiro Shimizu 890ddd
							eCol.g=(int)pPat->g;
Toshihiro Shimizu 890ddd
							eCol.b=(int)pPat->b;
Toshihiro Shimizu 890ddd
							eCol.m=(int)pPat->m;						
Toshihiro Shimizu 890ddd
						}
Toshihiro Shimizu 890ddd
						double q= ((double)pPatPixel->m/255.0)*((double)eCol.m/maxPixVal);
Toshihiro Shimizu 890ddd
						double r=(1.0-q)*(double)pPic->r+q*(double)eCol.r;
Toshihiro Shimizu 890ddd
						double g=(1.0-q)*(double)pPic->g+q*(double)eCol.g;
Toshihiro Shimizu 890ddd
						double b=(1.0-q)*(double)pPic->b+q*(double)eCol.b;
Toshihiro Shimizu 890ddd
						double m=(1.0-q)*(double)pPic->m+q*(double)eCol.m;
Toshihiro Shimizu 890ddd
						r=D_CUT(r,0.0,maxPixVal);
Toshihiro Shimizu 890ddd
						g=D_CUT(g,0.0,maxPixVal);
Toshihiro Shimizu 890ddd
						b=D_CUT(b,0.0,maxPixVal);
Toshihiro Shimizu 890ddd
						m=D_CUT(m,0.0,maxPixVal);
Toshihiro Shimizu 890ddd
						if ( isUC ) {
Toshihiro Shimizu 890ddd
							pPic->r=UC_ROUND(r);
Toshihiro Shimizu 890ddd
							pPic->g=UC_ROUND(g);
Toshihiro Shimizu 890ddd
							pPic->b=UC_ROUND(b);
Toshihiro Shimizu 890ddd
							pPic->m=UC_ROUND(m);
Toshihiro Shimizu 890ddd
						} else {
Toshihiro Shimizu 890ddd
							pPic->r=US_ROUND(r);
Toshihiro Shimizu 890ddd
							pPic->g=US_ROUND(g);
Toshihiro Shimizu 890ddd
							pPic->b=US_ROUND(b);
Toshihiro Shimizu 890ddd
							pPic->m=US_ROUND(m);
Toshihiro Shimizu 890ddd
						}
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
}	
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif // !defined(AFX_PATTERN_H__8E417023_35C0_11D6_B9EA_0040F674BE6A__INCLUDED_)