Shinya Kitaoka 810553
#pragma once
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
Shinya Kitaoka 79e39b
#include <memory></memory>
Toshihiro Shimizu 890ddd
#include "STColSelPic.h"
Toshihiro Shimizu 890ddd
#include "SDef.h"
Toshihiro Shimizu 890ddd
#include "toonz4.6/pixel.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class CPattern {
Shinya Kitaoka 120a6e
  int m_lX, m_lY;
Shinya Kitaoka 120a6e
  std::unique_ptr<uc_pixel[]> m_pat;</uc_pixel[]>
Shinya Kitaoka 120a6e
  char m_fn[1024];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void null();
Shinya Kitaoka 120a6e
  bool readPattern(RASTER *imgContour);
Shinya Kitaoka 120a6e
  bool isOK() {
Shinya Kitaoka 120a6e
    if (m_lX > 0 && m_lY > 0 && m_pat) return true;
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  void getMapPixel(const int xx, const int yy, const double invScale,
Shinya Kitaoka 120a6e
                   const double si, const double co, UC_PIXEL *&pucp);
Shinya Kitaoka 120a6e
  void getMapPixel(const int xx, const int yy, const double invScale,
Shinya Kitaoka 120a6e
                   UC_PIXEL *&pucp);
Shinya Kitaoka 120a6e
  bool readTTT(const char *fn);
Shinya Kitaoka 120a6e
  void getBBox(SRECT &bb);
Shinya Kitaoka 120a6e
  void eraseBuffer(const int lX, const int lY, UC_PIXEL *buffer);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  CPattern() : m_lX(0), m_lY(0) { m_fn[0] = '\0'; };
Shinya Kitaoka 120a6e
  CPattern(RASTER *imgContour);
Shinya Kitaoka 120a6e
  virtual ~CPattern();
Shinya Kitaoka 120a6e
  void rotate(const double angle);
Shinya Kitaoka 120a6e
  void optimalizeSize();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <class p=""></class>
Shinya Kitaoka 120a6e
  void test(CSTColSelPic

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

Shinya Kitaoka 120a6e
    for (int y = 0; y < m_lY; y++)
Shinya Kitaoka 120a6e
      for (int x = 0; x < m_lX; x++)
Shinya Kitaoka 120a6e
        if ((x + ox) < pic.m_lX && (y + oy) < pic.m_lY) {
Shinya Kitaoka 120a6e
          P *p         = pic.m_pic + (y + oy) * pic.m_lX + x + ox;
Shinya Kitaoka 120a6e
          UC_PIXEL *pP = m_pat.get() + y * m_lX + x;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (pP->m > (UCHAR)0) {
Shinya Kitaoka 120a6e
            double q = ((double)(pP->m) / 255.0) * ((double)eCol.m / 255.0);
Shinya Kitaoka 120a6e
            double r = (1.0 - q) * (double)p->r + q * (double)eCol.r;
Shinya Kitaoka 120a6e
            double g = (1.0 - q) * (double)p->g + q * (double)eCol.g;
Shinya Kitaoka 120a6e
            double b = (1.0 - q) * (double)p->b + q * (double)eCol.b;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            r = D_CUT_0_255(r);
Shinya Kitaoka 120a6e
            g = D_CUT_0_255(g);
Shinya Kitaoka 120a6e
            b = D_CUT_0_255(b);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            p->r = UC_ROUND(r);
Shinya Kitaoka 120a6e
            p->g = UC_ROUND(g);
Shinya Kitaoka 120a6e
            p->b = UC_ROUND(b);
Shinya Kitaoka 120a6e
            p->m = pP->m;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Maps the pattern. Long and optimalized version.
Shinya Kitaoka 120a6e
  template <class p=""></class>
Shinya Kitaoka 120a6e
  void mapIt(CSTColSelPic

&pic, const CSTColSelPic

&oriPic, const int xx,

Shinya Kitaoka 120a6e
             const int yy, const double scale, const double rot,
Shinya Kitaoka 120a6e
             const bool isUseOriColor, const bool isIncludeAlpha) {
Shinya Kitaoka 120a6e
    if (scale < 0.01) return;
Shinya Kitaoka 120a6e
    if (xx < 0 || yy < 0 || xx >= pic.m_lX || yy >= pic.m_lY) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    double sDiag = scale * sqrt(double(m_lX * m_lX + m_lY * m_lY));
Shinya Kitaoka 120a6e
    int iSDiag   = (int)sDiag + 1;
Shinya Kitaoka 120a6e
    int iSDiag2  = iSDiag / 2 + 1;
Shinya Kitaoka 120a6e
    if (iSDiag <= 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    double invScale  = 1.0 / scale;
Shinya Kitaoka 120a6e
    double co        = cos(-DEG2RAD(rot));
Shinya Kitaoka 120a6e
    double si        = sin(-DEG2RAD(rot));
Shinya Kitaoka 120a6e
    bool isUC        = pic.getType() == ST_RGBM ? true : false;
Shinya Kitaoka 120a6e
    double maxPixVal = isUC ? 255.0 : 65535.0;
Shinya Kitaoka 120a6e
    double ddiv      = 1.0 / (maxPixVal * 255.0);
Shinya Kitaoka 120a6e
    int yBeg         = std::max(yy - iSDiag2, 0);
Shinya Kitaoka 120a6e
    int yEnd         = std::min(yy + iSDiag2, pic.m_lY - 1);
Shinya Kitaoka 120a6e
    int xBeg         = std::max(xx - iSDiag2, 0);
Shinya Kitaoka 120a6e
    int xEnd         = std::min(xx + iSDiag2, pic.m_lX - 1);
Shinya Kitaoka 120a6e
    double lxm105    = (double)(m_lX - 1) * 0.5;
Shinya Kitaoka 120a6e
    double lym105    = (double)(m_lY - 1) * 0.5;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    I_PIXEL eCol;
Shinya Kitaoka 120a6e
    memset(&eCol, 0, sizeof(I_PIXEL));
Shinya Kitaoka 120a6e
    if (isUseOriColor) {
Shinya Kitaoka 120a6e
      P *pOriPic = oriPic.m_pic + yy * oriPic.m_lX + xx;
Shinya Kitaoka 120a6e
      eCol.r     = (int)pOriPic->r;
Shinya Kitaoka 120a6e
      eCol.g     = (int)pOriPic->g;
Shinya Kitaoka 120a6e
      eCol.b     = (int)pOriPic->b;
Shinya Kitaoka 120a6e
      if (isIncludeAlpha)
Shinya Kitaoka 120a6e
        eCol.m = (int)pOriPic->m;
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        if ((int)pOriPic->m != 255)
Shinya Kitaoka 120a6e
          eCol.m = 0;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          eCol.m = 255;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    int oriMatte = (int)((oriPic.m_pic + yy * oriPic.m_lX + xx)->m);
Shinya Kitaoka 120a6e
    for (int y = yBeg; y <= yEnd; y++)
Shinya Kitaoka 120a6e
      for (int x = xBeg; x <= xEnd; x++)
Shinya Kitaoka 120a6e
        if (x >= 0 && x < pic.m_lX && y >= 0 && y < pic.m_lY) {
Shinya Kitaoka 120a6e
          // ----- Calculates the pattern pixel coordinates -----
Shinya Kitaoka 120a6e
          UC_PIXEL *pucp = 0;
Shinya Kitaoka 120a6e
          //					getMapPixel(x-xx,y-yy,invScale,si,co,pucp);
Shinya Kitaoka 120a6e
          double dxx  = (double)(x - xx) * invScale;
Shinya Kitaoka 120a6e
          double dyy  = (double)(y - yy) * invScale;
Shinya Kitaoka 120a6e
          double d2xx = (dxx * co - dyy * si) + lxm105;
Shinya Kitaoka 120a6e
          double d2yy = (dxx * si + dyy * co) + lym105;
Shinya Kitaoka 120a6e
          int x1      = I_ROUND(d2xx);
Shinya Kitaoka 120a6e
          int y1      = I_ROUND(d2yy);
Shinya Kitaoka 120a6e
          if (x1 >= 0 && x1 < m_lX && y1 >= 0 && y1 < m_lY) {
Shinya Kitaoka 120a6e
            pucp = m_pat.get() + y1 * m_lX + x1;
Shinya Kitaoka 120a6e
            pucp = (pucp->m) == (UCHAR)0 ? 0 : pucp;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          // ----------------------------------------------------
Shinya Kitaoka 120a6e
          if (pucp) {
Shinya Kitaoka 120a6e
            int xy  = y * pic.m_lX + x;
Shinya Kitaoka 120a6e
            P *pPic = pic.m_pic + xy;
Shinya Kitaoka 120a6e
            if (!isUseOriColor) {
Shinya Kitaoka 120a6e
              eCol.r = (int)pucp->r;
Shinya Kitaoka 120a6e
              eCol.g = (int)pucp->g;
Shinya Kitaoka 120a6e
              eCol.b = (int)pucp->b;
Shinya Kitaoka 120a6e
              if (isIncludeAlpha)
Shinya Kitaoka 120a6e
                eCol.m = oriMatte;
Shinya Kitaoka 120a6e
              else {
Shinya Kitaoka 120a6e
                if (oriMatte != 255)
Shinya Kitaoka 120a6e
                  eCol.m = 0;
Shinya Kitaoka 120a6e
                else
Shinya Kitaoka 120a6e
                  eCol.m = 255;
Shinya Kitaoka 120a6e
              }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
              if (!isUC) {
Shinya Kitaoka 120a6e
                eCol.r = PIX_USHORT_FROM_BYTE((UCHAR)eCol.r);
Shinya Kitaoka 120a6e
                eCol.g = PIX_USHORT_FROM_BYTE((UCHAR)eCol.g);
Shinya Kitaoka 120a6e
                eCol.b = PIX_USHORT_FROM_BYTE((UCHAR)eCol.b);
Shinya Kitaoka 120a6e
              }
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
            double q  = ((double)pucp->m) * ((double)eCol.m) * ddiv;
Shinya Kitaoka 120a6e
            double qq = 1.0 - q;
Shinya Kitaoka 120a6e
            double r  = qq * (double)pPic->r + q * (double)eCol.r;
Shinya Kitaoka 120a6e
            double g  = qq * (double)pPic->g + q * (double)eCol.g;
Shinya Kitaoka 120a6e
            double b  = qq * (double)pPic->b + q * (double)eCol.b;
Shinya Kitaoka 120a6e
            double m  = qq * (double)pPic->m + q * (double)eCol.m;
Shinya Kitaoka 120a6e
            r         = D_CUT(r, 0.0, maxPixVal);
Shinya Kitaoka 120a6e
            g         = D_CUT(g, 0.0, maxPixVal);
Shinya Kitaoka 120a6e
            b         = D_CUT(b, 0.0, maxPixVal);
Shinya Kitaoka 120a6e
            m         = D_CUT(m, 0.0, maxPixVal);
Shinya Kitaoka 120a6e
            if (isUC) {
Shinya Kitaoka 120a6e
              pPic->r = UC_ROUND(r);
Shinya Kitaoka 120a6e
              pPic->g = UC_ROUND(g);
Shinya Kitaoka 120a6e
              pPic->b = UC_ROUND(b);
Shinya Kitaoka 120a6e
              pPic->m = UC_ROUND(m);
Shinya Kitaoka 120a6e
            } else {
Shinya Kitaoka 120a6e
              pPic->r = (UCHAR)US_ROUND(r);
Shinya Kitaoka 120a6e
              pPic->g = (UCHAR)US_ROUND(g);
Shinya Kitaoka 120a6e
              pPic->b = (UCHAR)US_ROUND(b);
Shinya Kitaoka 120a6e
              pPic->m = (UCHAR)US_ROUND(m);
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // !defined(AFX_PATTERN_H__8E417023_35C0_11D6_B9EA_0040F674BE6A__INCLUDED_)