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