Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#pragma warning(disable : 4533)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tiio_std.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tlevel.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "trastercm.h"
Toshihiro Shimizu 890ddd
#include "tnzimage.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "toonz/fill.h"
Toshihiro Shimizu 890ddd
#include "toonz/autoclose.h"
Toshihiro Shimizu 890ddd
#include "tenv.h"
Toshihiro Shimizu 890ddd
#include "convert2tlv.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <map></map>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/toonzfolders.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// gmt, 14/11/2013 removed a commented out blocks of code (void buildInks1(),
Shinya Kitaoka 120a6e
// void buildPalette() )
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
extern TEnv::DoubleVar AutocloseDistance;
Toshihiro Shimizu 890ddd
extern TEnv::DoubleVar AutocloseAngle;
Toshihiro Shimizu 890ddd
extern TEnv::IntVar AutocloseOpacity;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
//----------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline TPixel unmultiply(const TPixel &in) {
Shinya Kitaoka 120a6e
  if (in.r == 255) return in;
Shinya Kitaoka 120a6e
  TPixel out;
Shinya Kitaoka 120a6e
  int val = in.r * 255 / in.m;
Shinya Kitaoka 120a6e
  out.r   = tcrop(val, 0, 255);
Shinya Kitaoka 120a6e
  val     = in.g * 255 / in.m;
Shinya Kitaoka 120a6e
  out.g   = tcrop(val, 0, 255);
Shinya Kitaoka 120a6e
  val     = in.b * 255 / in.m;
Shinya Kitaoka 120a6e
  out.b   = tcrop(val, 0, 255);
Shinya Kitaoka 120a6e
  out.m   = 255;
Shinya Kitaoka 120a6e
  return out;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline int distance(const TPixel &c1, const TPixel &c2) {
Shinya Kitaoka 120a6e
  return (c1.r - c2.r) * (c1.r - c2.r) + (c1.g - c2.g) * (c1.g - c2.g) +
Shinya Kitaoka 120a6e
         (c1.b - c2.b) * (c1.b - c2.b);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int findClosest(const std::map<tpixel, int=""> &colorMap, TPixel &curPixColor) {</tpixel,>
Shinya Kitaoka 120a6e
  std::map<tpixel, int="">::const_iterator it = colorMap.begin();</tpixel,>
shun-iwasawa 1750cb
  int minDistance                          = 1000000000;
shun-iwasawa 1750cb
  int index                                = -1;
Shinya Kitaoka 120a6e
  for (; it != colorMap.end(); ++it) {
Shinya Kitaoka 120a6e
    int dist = distance(it->first, curPixColor);
Shinya Kitaoka 120a6e
    if (dist < minDistance) {
Shinya Kitaoka 120a6e
      minDistance = dist;
Shinya Kitaoka 120a6e
      index       = it->second;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  assert(index != -1);
Shinya Kitaoka 120a6e
  return index;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#define CHECKCOLOR(r, x, y, tone)                                              \
Shinya Kitaoka 120a6e
  {                                                                            \
Shinya Kitaoka 120a6e
    TPixelCM32 color = *((TPixelCM32 *)r->pixels(y) + (x));                    \
Shinya Kitaoka 120a6e
    if (color.getTone() == tone /*&& color.getPaint()!=0*/)                    \
Shinya Kitaoka 120a6e
      return TPoint(x, y);                                                     \
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
// cerca in quadrati concentrici di raggio rad intorno al pixel in  (x, y)
Shinya Kitaoka 120a6e
// il primo pixel di paint puro e ritorna il suo indice di paint
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
TPoint getClosestToneValue(const TRasterCM32P &r, int y, int x, int tone) {
Shinya Kitaoka 120a6e
  int maxRad = std::min({x, r->getLx() - x - 1, y, r->getLy() - y - 1});
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int rad = 1; rad < maxRad; rad++) {
Shinya Kitaoka 120a6e
    CHECKCOLOR(r, x, y - rad, tone)
Shinya Kitaoka 120a6e
    CHECKCOLOR(r, x, y + rad, tone)
Shinya Kitaoka 120a6e
    CHECKCOLOR(r, x - rad, y, tone)
Shinya Kitaoka 120a6e
    CHECKCOLOR(r, x + rad, y, tone)
Shinya Kitaoka 120a6e
    for (int j = 1; j <= rad; j++) {
Shinya Kitaoka 120a6e
      CHECKCOLOR(r, x - j, y - rad, tone)
Shinya Kitaoka 120a6e
      CHECKCOLOR(r, x + j, y - rad, tone)
Shinya Kitaoka 120a6e
      CHECKCOLOR(r, x - j, y + rad, tone)
Shinya Kitaoka 120a6e
      CHECKCOLOR(r, x + j, y + rad, tone)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      CHECKCOLOR(r, x - rad, y - j, tone)
Shinya Kitaoka 120a6e
      CHECKCOLOR(r, x - rad, y + j, tone)
Shinya Kitaoka 120a6e
      CHECKCOLOR(r, x + rad, y - j, tone)
Shinya Kitaoka 120a6e
      CHECKCOLOR(r, x + rad, y + j, tone)
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return TPoint(-1, -1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPoint getClosestPurePaint(const TRasterCM32P &r, int y, int x) {
Shinya Kitaoka 120a6e
  return getClosestToneValue(r, y, x, 255);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPoint getClosestPureInk(const TRasterCM32P &r, int y, int x) {
Shinya Kitaoka 120a6e
  return getClosestToneValue(r, y, x, 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool firstIsUnpainted(const TRaster32P &r1, const TRaster32P &r2) {
Shinya Kitaoka 120a6e
  for (int i = 0; i < r1->getLy(); i++) {
Shinya Kitaoka 120a6e
    TPixel32 *pix1 = r1->pixels(i);
Shinya Kitaoka 120a6e
    TPixel32 *pix2 = r2->pixels(i);
Shinya Kitaoka 120a6e
    for (int j = 0; j < r1->getLx(); j++, pix1++, pix2++) {
Shinya Kitaoka 120a6e
      if (pix1->m == 255 && pix2->m == 0)
Shinya Kitaoka 120a6e
        return false;
Shinya Kitaoka 120a6e
      else if (pix1->m == 0 && pix2->m == 255)
Shinya Kitaoka 120a6e
        return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------
Shinya Kitaoka 120a6e
// ritorna -1 se non ha il canale di matte (tutti i pixel a 255)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
int getMaxMatte(const TRaster32P &r) {
Shinya Kitaoka 120a6e
  int maxMatte   = -1;
Shinya Kitaoka 120a6e
  bool withMatte = false;
Shinya Kitaoka 120a6e
  for (int i = 0; i < r->getLy(); i++) {
Shinya Kitaoka 120a6e
    TPixel32 *pix = r->pixels(i);
Shinya Kitaoka 120a6e
    for (int j = 0; j < r->getLx(); j++, pix++) {
shun-iwasawa 1750cb
      maxMatte = std::max(maxMatte, (int)pix->m);
Shinya Kitaoka 120a6e
      if (pix->m != 255) withMatte = true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return withMatte ? maxMatte : -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void normalize(const TRaster32P &r, int maxMatte) {
Shinya Kitaoka 120a6e
  int val;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = 0; i < r->getLy(); i++) {
Shinya Kitaoka 120a6e
    TPixel32 *pix = r->pixels(i);
Shinya Kitaoka 120a6e
    for (int j = 0; j < r->getLx(); j++, pix++) {
Shinya Kitaoka 120a6e
      val    = pix->r * 255 / maxMatte;
Shinya Kitaoka 120a6e
      pix->r = tcrop(val, 0, 255);
Shinya Kitaoka 120a6e
      val    = pix->g * 255 / maxMatte;
Shinya Kitaoka 120a6e
      pix->g = tcrop(val, 0, 255);
Shinya Kitaoka 120a6e
      val    = pix->b * 255 / maxMatte;
Shinya Kitaoka 120a6e
      pix->b = tcrop(val, 0, 255);
Shinya Kitaoka 120a6e
      val    = pix->m * 255 / maxMatte;
Shinya Kitaoka 120a6e
      pix->m = tcrop(val, 0, 255);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int getFramesCount(const TLevelP &l, int from, int to) {
Shinya Kitaoka 120a6e
  if (from == -1) return l->getFrameCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int count           = 0;
Shinya Kitaoka 120a6e
  TLevel::Iterator it = l->begin();
Shinya Kitaoka 120a6e
  while (it != l->end() && it->first.getNumber() < from) it++;
Shinya Kitaoka 120a6e
  while (it != l->end() && it->first.getNumber() <= to) it++, count++;
Shinya Kitaoka 120a6e
  return count;
Toshihiro Shimizu 890ddd
}
shun-iwasawa 1750cb
}  // namespace
Shinya Kitaoka 120a6e
// namespace
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
std::map<tpixel, int="">::const_iterator Convert2Tlv::findNearestColor(</tpixel,>
Shinya Kitaoka 120a6e
    const TPixel &color) {
Shinya Kitaoka 120a6e
  // assert((int)colorMap.size()>toIndex);
Shinya Kitaoka 120a6e
  // assert((int)colorMap.size()>fromIndex);
Shinya Kitaoka 120a6e
  std::map<tpixel, int="">::const_iterator ret = m_colorMap.end(),</tpixel,>
shun-iwasawa 1750cb
                                        it  = m_colorMap.begin();
Shinya Kitaoka 120a6e
  // std::advance(it, fromIndex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int mindist = 1000;
Shinya Kitaoka 120a6e
  for (; it != m_colorMap.end(); ++it) {
Shinya Kitaoka 120a6e
    const TPixel &curr = it->first;
Shinya Kitaoka 120a6e
    int dr             = abs(curr.r - color.r);
Shinya Kitaoka 120a6e
    if (dr > m_colorTolerance) continue;
Shinya Kitaoka 120a6e
    int dg = abs(curr.g - color.g);
Shinya Kitaoka 120a6e
    if (dg > m_colorTolerance) continue;
Shinya Kitaoka 120a6e
    int db = abs(curr.b - color.b);
Shinya Kitaoka 120a6e
    if (db > m_colorTolerance) continue;
Shinya Kitaoka 120a6e
    int dist = dr + dg + db;
Shinya Kitaoka 120a6e
    if (dist < mindist) {
Shinya Kitaoka 120a6e
      mindist = dist;
Shinya Kitaoka 120a6e
      ret     = it;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Convert2Tlv::buildInks(TRasterCM32P &rout, const TRaster32P &rin) {
Shinya Kitaoka 120a6e
  std::map<tpixel, int="">::const_iterator it;</tpixel,>
Shinya Kitaoka 120a6e
  TPixel curColor = TPixel::Transparent;
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
  int curIndex;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // prima passata: identifico i colori di inchiostro e metto in rout i pixel di
Shinya Kitaoka 120a6e
  // inchiostro puro
Shinya Kitaoka 120a6e
  for (i = 0; i < rin->getLy(); i++) {
Shinya Kitaoka 120a6e
    TPixel *pixin      = rin->pixels(i);
Shinya Kitaoka 120a6e
    TPixelCM32 *pixout = rout->pixels(i);
Shinya Kitaoka 120a6e
    for (j = 0; j < rin->getLx(); j++, pixin++, pixout++) {
Shinya Kitaoka 120a6e
      TPixel colorIn;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (pixin->m != 255) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (curColor != *pixin) {
Shinya Kitaoka 120a6e
        curColor = *pixin;
Shinya Kitaoka 120a6e
        if ((it = m_colorMap.find(curColor)) == m_colorMap.end()) {
Shinya Kitaoka 120a6e
          if (m_colorTolerance > 0) it = findNearestColor(curColor);
Shinya Kitaoka 120a6e
          // if (it==colorMap.end() && (int)colorMap.size()>origColorCount)
Shinya Kitaoka 120a6e
          //	it  = findNearestColor(curColor, colorMap, colorTolerance,
Shinya Kitaoka 38fd86
          // origColorCount, colorMap.size()-1);
Shinya Kitaoka 120a6e
          if (it == m_colorMap.end() && m_lastIndex < 4095) {
Shinya Kitaoka 120a6e
            m_colorMap[curColor] = ++m_lastIndex;
Shinya Kitaoka 120a6e
            curIndex             = m_lastIndex;
Shinya Kitaoka 120a6e
          } else if (it != m_colorMap.end()) {
Shinya Kitaoka 120a6e
            m_colorMap[curColor] = it->second;
Shinya Kitaoka 120a6e
            curIndex             = it->second;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          curIndex = it->second;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      *pixout = TPixelCM32(curIndex, 0, 0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // seconda  passata: metto gli inchiostri di antialiasing
Shinya Kitaoka 120a6e
  curColor = TPixel::Transparent;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < rin->getLy(); i++) {
Shinya Kitaoka 120a6e
    TPixel *pixin      = rin->pixels(i);
Shinya Kitaoka 120a6e
    TPixelCM32 *pixout = rout->pixels(i);
Shinya Kitaoka 120a6e
    for (j = 0; j < rin->getLx(); j++, pixin++, pixout++) {
Shinya Kitaoka 120a6e
      TPixel colorIn;
Shinya Kitaoka 120a6e
      if (pixin->m == 255)  // gia' messo nel ciclo precedente
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      if (pixin->m == 0) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      colorIn = unmultiply(*pixin);  // findClosestOpaque(rin, i, j);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (curColor != colorIn) {
Shinya Kitaoka 120a6e
        curColor = colorIn;
Shinya Kitaoka 120a6e
        if ((it = m_colorMap.find(curColor)) != m_colorMap.end())
Shinya Kitaoka 120a6e
          curIndex = it->second;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          curIndex = findClosest(m_colorMap, curColor);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      *pixout = TPixelCM32(curIndex, 0, 255 - pixin->m);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Convert2Tlv::removeAntialias(TRasterCM32P &r) {
Shinya Kitaoka 120a6e
  int threshold = (int)(m_antialiasValue * 255.0 / 100.0);
Shinya Kitaoka 120a6e
  int tone;
Shinya Kitaoka 120a6e
  for (int i = 0; i < r->getLy(); i++) {
Shinya Kitaoka 120a6e
    TPixelCM32 *pix = r->pixels(i);
Shinya Kitaoka 120a6e
    for (int j = 0; j < r->getLx(); j++, pix++)
Shinya Kitaoka 120a6e
      if ((tone = pix->getTone()) !=
Shinya Kitaoka 120a6e
          0xff)  // tone==ff e tone==0 non vanno toccati mai
Shinya Kitaoka 120a6e
        pix->setTone(tone > threshold ? 0xff : 0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Convert2Tlv::buildInksFromGrayTones(TRasterCM32P &rout,
Shinya Kitaoka 120a6e
                                         const TRasterP &rin) {
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterGR8P r8 = (TRasterGR8P)rin;
Shinya Kitaoka 120a6e
  TRaster32P r32 = (TRaster32P)rin;
Shinya Kitaoka 120a6e
  if (r8)
Shinya Kitaoka 120a6e
    for (i = 0; i < rin->getLy(); i++) {
Shinya Kitaoka 120a6e
      TPixelGR8 *pixin   = r8->pixels(i);
Shinya Kitaoka 120a6e
      TPixelCM32 *pixout = rout->pixels(i);
Shinya Kitaoka 120a6e
      for (j = 0; j < rin->getLx(); j++, pixin++, pixout++)
Shinya Kitaoka 120a6e
        *pixout = TPixelCM32(1, 0, pixin->value);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    for (i = 0; i < rin->getLy(); i++) {
Shinya Kitaoka 120a6e
      TPixel *pixin      = r32->pixels(i);
Shinya Kitaoka 120a6e
      TPixelCM32 *pixout = rout->pixels(i);
Shinya Kitaoka 120a6e
      for (j = 0; j < rin->getLx(); j++, pixin++, pixout++)
Shinya Kitaoka 120a6e
        *pixout = TPixelCM32(1, 0, TPixelGR8::from(*pixin).value);
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Convert2Tlv::buildInksForNAAImage(TRasterCM32P &rout,
Shinya Kitaoka 120a6e
                                       const TRaster32P &rin) {
Shinya Kitaoka 120a6e
  std::map<tpixel, int="">::iterator it;</tpixel,>
Shinya Kitaoka 120a6e
  TPixel curColor = TPixel::Transparent;
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
  int curIndex;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // prima passata: identifico i colori di inchiostro e metto in rout i pixel di
Shinya Kitaoka 120a6e
  // inchiostro puro
Shinya Kitaoka 120a6e
  for (i = 0; i < rin->getLy(); i++) {
Shinya Kitaoka 120a6e
    TPixel *pixin      = rin->pixels(i);
Shinya Kitaoka 120a6e
    TPixelCM32 *pixout = rout->pixels(i);
Shinya Kitaoka 120a6e
    for (j = 0; j < rin->getLx(); j++, pixin++, pixout++) {
Shinya Kitaoka 120a6e
      TPixel colorIn;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- treat white/transparent pixels as transparent -*/
Shinya Kitaoka 120a6e
      if (*pixin == TPixel(255, 255, 255) || *pixin == TPixel::Transparent) {
Shinya Kitaoka 120a6e
        *pixout = TPixelCM32(0, 0, 255);
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (curColor != *pixin) {
Shinya Kitaoka 120a6e
        curColor = *pixin;
Shinya Kitaoka 120a6e
        if ((it = m_colorMap.find(curColor)) == m_colorMap.end()) {
Shinya Kitaoka 120a6e
          if (m_lastIndex < 4095) m_colorMap[curColor] = ++m_lastIndex;
shun-iwasawa 1750cb
          curIndex = m_lastIndex;
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          curIndex = it->second;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      *pixout = TPixelCM32(curIndex, 0, 0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_colorMap.empty()) m_colorMap[TPixel::Black] = ++m_lastIndex;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Convert2Tlv::doFill(TRasterCM32P &rout, const TRaster32P &rin) {
Shinya Kitaoka 120a6e
  // prima passata: si filla  solo partendo da pixel senza inchiostro, senza
Shinya Kitaoka 120a6e
  // antialiasing(tone==255)
Shinya Kitaoka 120a6e
  for (int i = 0; i < rin->getLy(); i++) {
Shinya Kitaoka 120a6e
    TPixel *pixin      = rin->pixels(i);
Shinya Kitaoka 120a6e
    TPixelCM32 *pixout = rout->pixels(i);
Shinya Kitaoka 120a6e
    for (int j = 0; j < rin->getLx(); j++, pixin++, pixout++) {
Shinya Kitaoka 120a6e
      if (!(pixout->getTone() == 255 && pixout->getPaint() == 0 &&
Shinya Kitaoka 120a6e
            pixin->m == 255))
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      std::map<tpixel, int="">::const_iterator it;</tpixel,>
Shinya Kitaoka 120a6e
      int paintIndex;
Shinya Kitaoka 120a6e
      if ((it = m_colorMap.find(*pixin)) == m_colorMap.end()) {
Shinya Kitaoka 120a6e
        if (m_colorTolerance > 0) it = findNearestColor(*pixin);
Shinya Kitaoka 120a6e
        // if (it==colorMap.end() && (int)colorMap.size()>origColorCount) //se
Shinya Kitaoka 120a6e
        // non l'ho trovato tra i colori origari, lo cerco in quelli nuovi, ma
Shinya Kitaoka 120a6e
        // in questo caso deve essere esattamente uguale(tolerance = 0)
Shinya Kitaoka 120a6e
        //	 it  = findNearestColor(*pixin, colorMap, colorTolerance,
Shinya Kitaoka 38fd86
        // origColorCount, colorMap.size()-1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (it == m_colorMap.end() && m_lastIndex < 4096) {
Shinya Kitaoka 120a6e
          m_colorMap[*pixin] = ++m_lastIndex;
Shinya Kitaoka 120a6e
          paintIndex         = m_lastIndex;
Shinya Kitaoka 120a6e
        } else if (it != m_colorMap.end()) {
Shinya Kitaoka 120a6e
          m_colorMap[*pixin] = it->second;
Shinya Kitaoka 120a6e
          paintIndex         = it->second;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        paintIndex = it->second;
Shinya Kitaoka 120a6e
      FillParameters params;
Shinya Kitaoka 120a6e
      params.m_p         = TPoint(j, i);
Shinya Kitaoka 120a6e
      params.m_styleId   = paintIndex;
Shinya Kitaoka 120a6e
      params.m_emptyOnly = true;
Shinya Kitaoka 120a6e
      fill(rout, params);
Shinya Kitaoka 120a6e
      // if (*((ULONG *)rout->getRawData())!=0xff)
Shinya Kitaoka 120a6e
      //  {
Shinya Kitaoka 120a6e
      //  int cavolo=0;
Shinya Kitaoka 120a6e
      //  }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // seconda passata: se son rimasti pixel antialiasati non fillati, si fillano,
Shinya Kitaoka 120a6e
  // cercando nelle vicinanze un pixel di paint puro per capire il colore da
Shinya Kitaoka 120a6e
  // usare
Shinya Kitaoka 120a6e
  for (int i = 0; i < rin->getLy(); i++) {
Shinya Kitaoka 120a6e
    TPixel *pixin      = rin->pixels(i);
Shinya Kitaoka 120a6e
    TPixelCM32 *pixout = rout->pixels(i);
Shinya Kitaoka 120a6e
    for (int j = 0; j < rin->getLx(); j++, pixin++, pixout++) {
Shinya Kitaoka 120a6e
      if (!(pixout->getTone() > 0 && pixout->getTone() < 255 &&
Shinya Kitaoka 120a6e
            pixout->getPaint() == 0 && pixin->m == 255))
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TPoint p = getClosestPurePaint(rout, i, j);
Shinya Kitaoka 120a6e
      if (p.x == -1) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // pixout->setPaint( paintIndex);
Shinya Kitaoka 120a6e
      FillParameters params;
Shinya Kitaoka 120a6e
      params.m_p         = TPoint(j, i);
Shinya Kitaoka 120a6e
      params.m_styleId   = (rout->pixels(p.y) + p.x)->getPaint();
Shinya Kitaoka 120a6e
      params.m_emptyOnly = true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      fill(rout, params);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // infine, si filla di trasparente lo sfondo, percorrendo il bordo, nel caso
Shinya Kitaoka 120a6e
  // di trasbordamenti di colore
Shinya Kitaoka 120a6e
  TPixelCM32 *pixCm;
Shinya Kitaoka 120a6e
  TPixel *pix;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pixCm = rout->pixels(0);
Shinya Kitaoka 120a6e
  pix   = rin->pixels(0);
Shinya Kitaoka 120a6e
  FillParameters params;
Shinya Kitaoka 120a6e
  params.m_styleId = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = 0; i < rout->getLx(); i++, pixCm++, pix++)
Shinya Kitaoka 120a6e
    if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
Shinya Kitaoka 120a6e
      params.m_p = TPoint(i, 0);
Shinya Kitaoka 120a6e
      fill(rout, params);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pixCm = rout->pixels(rout->getLy() - 1);
Shinya Kitaoka 120a6e
  pix   = rin->pixels(rout->getLy() - 1);
Shinya Kitaoka 120a6e
  for (int i = 0; i < rout->getLx(); i++, pixCm++, pix++)
Shinya Kitaoka 120a6e
    if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
Shinya Kitaoka 120a6e
      params.m_p = TPoint(i, rout->getLy() - 1);
Shinya Kitaoka 120a6e
      fill(rout, params);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  int wrapCM = rout->getWrap();
Shinya Kitaoka 120a6e
  int wrap   = rin->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pixCm = rout->pixels(0);
Shinya Kitaoka 120a6e
  pix   = rin->pixels(0);
Shinya Kitaoka 120a6e
  for (int i = 0; i < rin->getLy(); i++, pixCm += wrapCM, pix += wrap)
Shinya Kitaoka 120a6e
    if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
Shinya Kitaoka 120a6e
      params.m_p = TPoint(0, i);
Shinya Kitaoka 120a6e
      fill(rout, params);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  pixCm = rout->pixels(0) + rout->getLx() - 1;
Shinya Kitaoka 120a6e
  pix   = rin->pixels(0) + rin->getLx() - 1;
Shinya Kitaoka 120a6e
  for (int i = 0; i < rin->getLy(); i++, pixCm += wrapCM, pix += wrap)
Shinya Kitaoka 120a6e
    if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
Shinya Kitaoka 120a6e
      params.m_p = TPoint(rout->getLx() - 1, i);
Shinya Kitaoka 120a6e
      fill(rout, params);
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Convert2Tlv::buildToonzRaster(TRasterCM32P &rout, const TRasterP &rin1,
Shinya Kitaoka 120a6e
                                   const TRasterP &rin2) {
Shinya Kitaoka 120a6e
  if (rin2) assert(rin1->getSize() == rin2->getSize());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rout->clear();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::cout << "      computing inks...\n";
Shinya Kitaoka 120a6e
  TRaster32P r1    = (TRaster32P)rin1;
Shinya Kitaoka 120a6e
  TRasterGR8P r1gr = (TRasterGR8P)rin1;
Shinya Kitaoka 120a6e
  TRaster32P r2    = (TRaster32P)rin2;
Shinya Kitaoka 120a6e
  TRasterGR8P r2gr = (TRasterGR8P)rin2;
Shinya Kitaoka 120a6e
  TRasterP rU, rP;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (r1gr) {
Shinya Kitaoka 120a6e
    rU = r1gr;
Shinya Kitaoka 120a6e
    rP = r2;
Shinya Kitaoka 120a6e
  } else if (r2gr) {
Shinya Kitaoka 120a6e
    rU = r2gr;
Shinya Kitaoka 120a6e
    rP = r1;
Shinya Kitaoka 120a6e
  } else if (!r1)
Shinya Kitaoka 120a6e
    rU = r2;
Shinya Kitaoka 120a6e
  else if (!r2)
Shinya Kitaoka 120a6e
    rU = r1;
Shinya Kitaoka 120a6e
  else if (firstIsUnpainted(r1, r2)) {
Shinya Kitaoka 120a6e
    rU = r1;
Shinya Kitaoka 120a6e
    rP = r2;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    rU = r2;
Shinya Kitaoka 120a6e
    rP = r1;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterCM32P r;
Shinya Kitaoka 120a6e
  if (rout->getSize() != rU->getSize()) {
Shinya Kitaoka 120a6e
    int dx = rout->getLx() - rU->getLx();
Shinya Kitaoka 120a6e
    int dy = rout->getLy() - rU->getLy();
Shinya Kitaoka 120a6e
    assert(dx >= 0 && dy >= 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    r = rout->extract(dx / 2, dy / 2, dx / 2 + rU->getLx() - 1,
Shinya Kitaoka 120a6e
                      dy / 2 + rU->getLy() - 1);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    r = rout;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if ((TRasterGR8P)rU)
Shinya Kitaoka 120a6e
    buildInksFromGrayTones(r, rU);
Shinya Kitaoka 120a6e
  else if (m_isUnpaintedFromNAA)
Shinya Kitaoka 120a6e
    buildInksForNAAImage(r, (TRaster32P)rU);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    int maxMatte = getMaxMatte((TRaster32P)rU);
Shinya Kitaoka 120a6e
    if (maxMatte == -1)
Shinya Kitaoka 120a6e
      buildInksFromGrayTones(r, rU);
shun-iwasawa 1750cb
    else if (maxMatte == 0)  // empty frame doesn't need further computation
shun-iwasawa 1750cb
      return;
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      if (maxMatte < 255) normalize(rU, maxMatte);
Shinya Kitaoka 120a6e
      buildInks(r, (TRaster32P)rU /*rP,*/);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_autoclose)
Shinya Kitaoka 120a6e
    TAutocloser(r, AutocloseDistance, AutocloseAngle, 1, AutocloseOpacity)
Shinya Kitaoka 120a6e
        .exec();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (rP) {
Shinya Kitaoka 120a6e
    std::cout << "      computing paints...\n";
Shinya Kitaoka 120a6e
    doFill(r, rP);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_antialiasType == 2)  // remove antialias
Shinya Kitaoka 120a6e
    removeAntialias(r);
Shinya Kitaoka 120a6e
  else if (m_antialiasType == 1)  // add antialias
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    TRasterCM32P raux(r->getSize());
Shinya Kitaoka 120a6e
    TRop::antialias(r, raux, 10, m_antialiasValue);
Shinya Kitaoka 120a6e
    rout = raux;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPalette *Convert2Tlv::buildPalette() {
shun-iwasawa ea9f73
  m_palette->setDirtyFlag(true);  // make sure to be overwritten
shun-iwasawa ea9f73
Shinya Kitaoka 120a6e
  std::map<tpixel, int="">::const_iterator it = m_colorMap.begin();</tpixel,>
shun-iwasawa 1750cb
  TPalette::Page *page                     = m_palette->getPage(0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QList<int> stylesToBeAddedToPage;</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; it != m_colorMap.end(); ++it) {
Shinya Kitaoka 120a6e
    if (it->second >
Shinya Kitaoka 120a6e
        m_maxPaletteIndex)  // colore nuovo da aggiungere alla paletta)
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      if (m_palette->getStyleCount() > it->second)
Shinya Kitaoka 120a6e
        m_palette->setStyle(it->second, it->first);
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        while (m_palette->getStyleCount() < it->second)
Shinya Kitaoka 120a6e
          m_palette->addStyle(TPixel::Transparent);
Shinya Kitaoka 120a6e
        int id = m_palette->addStyle(it->first);
Shinya Kitaoka 120a6e
        assert(id == it->second);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (!m_palette->getStylePage(it->second))
Shinya Kitaoka 120a6e
      stylesToBeAddedToPage.push_back(it->second);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun-iwasawa 443318
  /*- Store on page in index order -*/
Shinya Kitaoka 120a6e
  if (!stylesToBeAddedToPage.isEmpty()) {
Tact Yoshida b8554a
    std::sort(stylesToBeAddedToPage.begin(), stylesToBeAddedToPage.end());
Shinya Kitaoka 120a6e
    for (int s = 0; s < stylesToBeAddedToPage.size(); s++)
Shinya Kitaoka 120a6e
      page->addStyle(stylesToBeAddedToPage.at(s));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun_iwasawa e897af
  /*
shun_iwasawa e897af
    If the palette path is empty, an initial palette with four colors are set in
shun_iwasawa e897af
    the palette here.
shun_iwasawa e897af
    ( see Convert2Tlv::init() ) So here I make the latter three styles in the
shun_iwasawa e897af
    initial palette to set
shun_iwasawa 06bcc2
    "AutoPaint" options.
shun_iwasawa 06bcc2
  */
shun_iwasawa 06bcc2
  if (m_palettePath.isEmpty()) {
shun_iwasawa 06bcc2
    assert(m_palette->getStyleCount() >= 5);
shun_iwasawa e897af
    for (int id = 2; id <= 4; id++) m_palette->getStyle(id)->setFlags(1);
shun_iwasawa 06bcc2
  }
shun_iwasawa 06bcc2
Shinya Kitaoka 120a6e
  if (!m_appendDefaultPalette) return m_palette;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*-- Adding styles in the default palette to the result palette, starts here
Shinya Kitaoka 120a6e
   * --*/
Shinya Kitaoka 120a6e
  TFilePath palettePath =
Shinya Kitaoka 120a6e
      ToonzFolder::getStudioPaletteFolder() + "cleanup_default.tpl";
Shinya Kitaoka 120a6e
  TFileStatus pfs(palettePath);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!pfs.doesExist() || !pfs.isReadable()) return m_palette;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TIStream is(palettePath);
Shinya Kitaoka 120a6e
  if (!is) return m_palette;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string tagName;
Shinya Kitaoka 120a6e
  if (!is.matchTag(tagName) || tagName != "palette") return m_palette;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string gname;
Shinya Kitaoka 120a6e
  is.getTagParam("name", gname);
Shinya Kitaoka 120a6e
  TPalette *defaultPalette = new TPalette();
Shinya Kitaoka 120a6e
  defaultPalette->loadData(is);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_palette->setIsCleanupPalette(false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPalette::Page *dstPage = m_palette->getPage(0);
Shinya Kitaoka 120a6e
  TPalette::Page *srcPage = defaultPalette->getPage(0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int srcIndexInPage = 0; srcIndexInPage < srcPage->getStyleCount();
Shinya Kitaoka 120a6e
       srcIndexInPage++) {
Shinya Kitaoka 120a6e
    int id = srcPage->getStyleId(srcIndexInPage);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    bool isUsedInDstPalette = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int dstIndexInPage = 0; dstIndexInPage < dstPage->getStyleCount();
Shinya Kitaoka 120a6e
         dstIndexInPage++) {
Shinya Kitaoka 120a6e
      if (dstPage->getStyleId(dstIndexInPage) == id) {
Shinya Kitaoka 120a6e
        isUsedInDstPalette = true;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (isUsedInDstPalette)
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      int addedId =
Shinya Kitaoka 120a6e
          m_palette->addStyle(srcPage->getStyle(srcIndexInPage)->clone());
Shinya Kitaoka 120a6e
      dstPage->addStyle(addedId);
shun-iwasawa 443318
      /*--  For StudioPalette-derived DefaultPalettes, clear the GrobalName --*/
Shinya Kitaoka 120a6e
      m_palette->getStyle(addedId)->setGlobalName(L"");
Shinya Kitaoka 120a6e
      m_palette->getStyle(addedId)->setOriginalName(L"");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  delete defaultPalette;
Shinya Kitaoka 120a6e
  /*-- Adding styles in the default palette to the result palette, ends here
Shinya Kitaoka 120a6e
   * --*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return m_palette;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Convert2Tlv::Convert2Tlv(const TFilePath &filepath1, const TFilePath &filepath2,
Shinya Kitaoka 120a6e
                         const TFilePath &outFolder, const QString &outName,
Shinya Kitaoka 120a6e
                         int from, int to, bool doAutoclose,
Shinya Kitaoka 120a6e
                         const TFilePath &palettePath, int colorTolerance,
Shinya Kitaoka 120a6e
                         int antialiasType, int antialiasValue,
shun-iwasawa 1584bb
                         bool isUnpaintedFromNAA, bool appendDefaultPalette,
shun-iwasawa 1584bb
                         double dpi)
Shinya Kitaoka 120a6e
    : m_size(0, 0)
Shinya Kitaoka 120a6e
    , m_level1()
Shinya Kitaoka 120a6e
    , m_levelIn1()
Shinya Kitaoka 120a6e
    , m_levelIn2()
Shinya Kitaoka 120a6e
    , m_levelOut()
Shinya Kitaoka 120a6e
    , m_autoclose(doAutoclose)
Shinya Kitaoka 120a6e
    , m_premultiply(false)
Shinya Kitaoka 120a6e
    , m_count(0)
Shinya Kitaoka 120a6e
    , m_from(from)
Shinya Kitaoka 120a6e
    , m_to(to)
Shinya Kitaoka 120a6e
    , m_palettePath(palettePath)
Shinya Kitaoka 120a6e
    , m_colorTolerance(colorTolerance)
Shinya Kitaoka 120a6e
    , m_palette(0)
Shinya Kitaoka 120a6e
    , m_antialiasType(antialiasType)
Shinya Kitaoka 120a6e
    , m_antialiasValue(antialiasValue)
Shinya Kitaoka 120a6e
    , m_isUnpaintedFromNAA(isUnpaintedFromNAA)
shun-iwasawa 1584bb
    , m_appendDefaultPalette(appendDefaultPalette)
shun-iwasawa 1584bb
    , m_dpi(dpi) {
Shinya Kitaoka 120a6e
  if (filepath1 != TFilePath()) {
Shinya Kitaoka 120a6e
    m_levelIn1 = filepath1.getParentDir() + filepath1.getLevelName();
Shinya Kitaoka 120a6e
    if (outFolder != TFilePath())
Shinya Kitaoka 120a6e
      m_levelOut =
Shinya Kitaoka 120a6e
          m_levelIn1.withParentDir(outFolder).withNoFrame().withType("tlv");
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_levelOut = m_levelIn1.withNoFrame().withType(
Shinya Kitaoka 120a6e
          "tlv");  // filePaths[0].getParentDir() +
Shinya Kitaoka 120a6e
                   // TFilePath(filePaths[0].getWideName() + L".tlv");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (outName != "") m_levelOut = m_levelOut.withName(outName.toStdString());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (filepath2 != TFilePath())
Shinya Kitaoka 120a6e
    m_levelIn2 = filepath2.getParentDir() + filepath2.getLevelName();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int Convert2Tlv::getFramesToConvertCount() {
Shinya Kitaoka 120a6e
  if (m_level1 && m_level1->getFrameCount() > 0)
Shinya Kitaoka 38fd86
    return getFramesCount(m_level1, m_from,
Shinya Kitaoka 38fd86
                          m_to);  // m_level1->getFrameCount();
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      TLevelReaderP lr = TLevelReaderP(m_levelIn1);
Shinya Kitaoka 120a6e
      if (lr) {
Shinya Kitaoka 120a6e
        TLevelP l = lr->loadInfo();
Shinya Kitaoka 120a6e
        if (l) {
Shinya Kitaoka 120a6e
          return getFramesCount(l, m_from, m_to);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } catch (...) {
Shinya Kitaoka 120a6e
      return 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Convert2Tlv::init(std::string &errorMessage) {
Shinya Kitaoka 120a6e
  m_lastIndex = m_maxPaletteIndex = 0;
Shinya Kitaoka 120a6e
  m_colorMap.clear();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  try {
shun-iwasawa 1750cb
    m_lr1 = TLevelReaderP(m_levelIn1);
Shinya Kitaoka 120a6e
    if (m_lr1) m_level1 = m_lr1->loadInfo();
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
    errorMessage =
Shinya Kitaoka 120a6e
        "Error: can't read level " + ::to_string(m_levelIn1.getWideString());
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_level1->getFrameCount() == 0) {
Shinya Kitaoka 120a6e
    errorMessage =
Shinya Kitaoka 120a6e
        "Error: can't find level " + ::to_string(m_levelIn1.getWideString());
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TLevelP level2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_levelIn2 != TFilePath()) {
Shinya Kitaoka 120a6e
    try {
shun-iwasawa 1750cb
      m_lr2 = TLevelReaderP(m_levelIn2);
Shinya Kitaoka 120a6e
      if (m_lr2) level2 = m_lr2->loadInfo();
Shinya Kitaoka 120a6e
    } catch (...) {
Shinya Kitaoka 120a6e
      errorMessage =
Shinya Kitaoka 120a6e
          "Error: can't read level " + ::to_string(m_levelIn2.getWideString());
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (level2->getFrameCount() == 0) {
Shinya Kitaoka 120a6e
      errorMessage =
Shinya Kitaoka 120a6e
          "Error: can't find level " + ::to_string(m_levelIn2.getWideString());
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_level1->getFrameCount() != level2->getFrameCount()) {
Shinya Kitaoka 120a6e
      errorMessage = "Error: the two input levels must have same frame number";
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_size = TDimension();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_lw = TLevelWriterP(m_levelOut);
Shinya Kitaoka 120a6e
  m_it = m_level1->begin();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TLevel::Iterator it2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (level2->getFrameCount() > 0) it2 = level2->begin();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; m_it != m_level1->end(); ++m_it) {
Shinya Kitaoka 120a6e
    TImageReaderP ir1       = m_lr1->getFrameReader(m_it->first);
Shinya Kitaoka 120a6e
    const TImageInfo *info1 = ir1->getImageInfo();
Shinya Kitaoka 120a6e
    if (!info1) {
Shinya Kitaoka 120a6e
      errorMessage = "Error: can't read frame " +
Shinya Kitaoka 120a6e
                     std::to_string(m_it->first.getNumber()) + " of level  " +
Shinya Kitaoka 120a6e
                     ::to_string(m_levelIn1.getWideString());
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (info1->m_bitsPerSample != 8) {
Shinya Kitaoka 120a6e
      errorMessage = "Error: all frames must have 8 bits per channel!\n";
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_size.lx = std::max(m_size.lx, info1->m_lx);
Shinya Kitaoka 120a6e
    m_size.ly = std::max(m_size.ly, info1->m_ly);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_lr2 != TLevelReaderP()) {
Shinya Kitaoka 120a6e
      TImageReaderP ir2 = m_lr2->getFrameReader(it2->first);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (ir2) {
Shinya Kitaoka 120a6e
        const TImageInfo *info2 = ir2->getImageInfo();
Shinya Kitaoka 120a6e
        if (!info1) {
Shinya Kitaoka 120a6e
          errorMessage = "Error: can't read frame " +
Shinya Kitaoka 120a6e
                         std::to_string(it2->first.getNumber()) +
Shinya Kitaoka 120a6e
                         " of level  " +
Shinya Kitaoka 120a6e
                         ::to_string(m_levelIn2.getWideString());
Shinya Kitaoka 120a6e
          ;
Shinya Kitaoka 120a6e
          return false;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (info1->m_lx != info2->m_lx || info1->m_ly != info2->m_ly) {
Shinya Kitaoka 120a6e
          errorMessage =
Shinya Kitaoka 120a6e
              "Error: painted frames must have same resolution of matching "
Shinya Kitaoka 120a6e
              "unpainted frames!\n";
Shinya Kitaoka 120a6e
          return false;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        if (info2->m_bitsPerSample != 8) {
Shinya Kitaoka 120a6e
          errorMessage = "Error: all frames must have 8 bits per channel!\n";
Shinya Kitaoka 120a6e
          return false;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      ++it2;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_palette = new TPalette();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_palettePath != TFilePath()) {
Shinya Kitaoka 120a6e
    TIStream is(m_palettePath);
Shinya Kitaoka 120a6e
    is >> m_palette;
Shinya Kitaoka 120a6e
    if (m_palette->getStyleInPagesCount() == 0) {
Shinya Kitaoka 120a6e
      errorMessage = "Error: invalid palette!\n";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (int i = 0; i < m_palette->getStyleCount(); i++)
Shinya Kitaoka 120a6e
      if (m_palette->getStylePage(i)) {
Shinya Kitaoka 120a6e
        m_colorMap[m_palette->getStyle(i)->getMainColor()] = i;
shun-iwasawa 1750cb
        if (i > m_lastIndex) m_lastIndex = i;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    assert(m_colorMap.size() == m_palette->getStyleInPagesCount());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_maxPaletteIndex = m_lastIndex;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_it = m_level1->begin();
Shinya Kitaoka 120a6e
shun_iwasawa e897af
  /*-
shun_iwasawa e897af
  If the palette is empty, make an initial palette with black, red, blue and
shun_iwasawa e897af
  green styles.
shun_iwasawa 06bcc2
  For the latter three styles the "autopaint" option should be set.
shun_iwasawa 06bcc2
  -*/
shun_iwasawa 06bcc2
  if (m_lastIndex == 0) {
shun_iwasawa 06bcc2
    m_colorMap[TPixel::Black] = ++m_lastIndex;
shun_iwasawa e897af
    m_colorMap[TPixel::Red]   = ++m_lastIndex;
shun_iwasawa e897af
    m_colorMap[TPixel::Blue]  = ++m_lastIndex;
shun_iwasawa 06bcc2
    m_colorMap[TPixel::Green] = ++m_lastIndex;
shun_iwasawa 06bcc2
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Convert2Tlv::convertNext(std::string &errorMessage) {
Shinya Kitaoka 120a6e
  if (m_count == 0 && m_from != -1)
Shinya Kitaoka 120a6e
    while (m_it != m_level1->end() && m_it->first.getNumber() < m_from) m_it++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::cout << "Processing image " << ++m_count << " of "
Shinya Kitaoka 120a6e
            << getFramesCount(m_level1, m_from, m_to) << "...\n";
Shinya Kitaoka 120a6e
  std::cout << "      Loading frame " << m_it->first.getNumber() << "...\n";
Shinya Kitaoka 120a6e
  TImageReaderP ir1    = m_lr1->getFrameReader(m_it->first);
Shinya Kitaoka 120a6e
  TRasterImageP imgIn1 = (TRasterImageP)ir1->load();
Shinya Kitaoka 120a6e
  if (!imgIn1) {
Shinya Kitaoka 120a6e
    errorMessage = "Error: cannot read frame" +
Shinya Kitaoka 120a6e
                   std::to_string(m_it->first.getNumber()) + " of " +
Shinya Kitaoka 120a6e
                   ::to_string(m_levelIn1.getWideString()) + "!";
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TRasterP rin1 = imgIn1->getRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert((TRaster32P)rin1 || (TRasterGR8P)rin1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterP rin2;
Shinya Kitaoka 120a6e
  TRasterImageP imgIn2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_lr2) {
Shinya Kitaoka 120a6e
    TImageReaderP ir2 = m_lr2->getFrameReader(m_it->first);
Shinya Kitaoka 120a6e
    imgIn2            = (TRasterImageP)ir2->load();
Shinya Kitaoka 120a6e
    if (!imgIn2) {
Shinya Kitaoka 120a6e
      errorMessage = "Error: cannot read frame " +
Shinya Kitaoka 120a6e
                     std::to_string(m_it->first.getNumber()) + " of " +
Shinya Kitaoka 120a6e
                     ::to_string(m_levelIn2.getWideString()) + "!";
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    rin2 = imgIn2->getRaster();
Shinya Kitaoka 120a6e
    assert((TRaster32P)rin2 || (TRasterGR8P)rin2);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterCM32P rout(m_size);
Shinya Kitaoka 120a6e
  buildToonzRaster(rout, rin1, rin2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::cout << "      saving frame in level \'" << m_levelOut.getLevelName()
Shinya Kitaoka 120a6e
            << "\'...\n\n";
Shinya Kitaoka 120a6e
  TImageWriterP iw  = m_lw->getFrameWriter(m_it->first);
Shinya Kitaoka 120a6e
  TToonzImageP timg = TToonzImageP(rout, rout->getBounds());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRect bbox;
Shinya Kitaoka 120a6e
  TRop::computeBBox(rout, bbox);
Shinya Kitaoka 120a6e
  timg->setSavebox(bbox);
Shinya Kitaoka 120a6e
shun-iwasawa 1584bb
  if (m_dpi > 0.0)  // specify dpi in the convert popup
shun-iwasawa 1584bb
    timg->setDpi(m_dpi, m_dpi);
shun-iwasawa 1584bb
  else {
shun-iwasawa 1584bb
    double dpix, dpiy;
shun-iwasawa 1584bb
    imgIn1->getDpi(dpix, dpiy);
shun-iwasawa 1584bb
    timg->setDpi(dpix, dpiy);
shun-iwasawa 1584bb
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TLevel::Iterator itaux = m_it;
Shinya Kitaoka 120a6e
  itaux++;
shun-iwasawa 1750cb
  if (itaux == m_level1->end() ||
shun-iwasawa 1750cb
      (m_to != -1 &&
shun-iwasawa 1750cb
       itaux->first.getNumber() > m_to))  // ultimo frame da scrivere.
Shinya Kitaoka 120a6e
    timg->setPalette(buildPalette());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  iw->save(timg);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ++m_it;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Convert2Tlv::abort() {
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    m_lr1    = TLevelReaderP();
Shinya Kitaoka 120a6e
    m_lr2    = TLevelReaderP();
Shinya Kitaoka 120a6e
    m_lw     = TLevelWriterP();
Shinya Kitaoka 120a6e
    m_level1 = TLevelP();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::cout << "No output generated\n";
Shinya Kitaoka 120a6e
    TSystem::deleteFile(m_levelOut);
Shinya Kitaoka 120a6e
    TSystem::deleteFile(m_levelOut.withType("tpl"));
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// RasterToToonzRasterConverter
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
RasterToToonzRasterConverter::RasterToToonzRasterConverter() {
Shinya Kitaoka 120a6e
  m_palette = new TPalette();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
RasterToToonzRasterConverter::~RasterToToonzRasterConverter() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RasterToToonzRasterConverter::setPalette(const TPaletteP &palette) {
Shinya Kitaoka 120a6e
  m_palette = palette;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRasterCM32P RasterToToonzRasterConverter::convert(
Shinya Kitaoka 120a6e
    const TRasterP &inputRaster) {
Shinya Kitaoka 120a6e
  int lx = inputRaster->getLx();
Shinya Kitaoka 120a6e
  int ly = inputRaster->getLy();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P r = inputRaster;
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
TRasterGR8P r1gr = (TRasterGR8P)inputRaster;
Shinya Kitaoka 120a6e
TRasterP rU, rP;
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterCM32P rout(lx, ly);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int y = 0; y < ly; y++) {
Shinya Kitaoka 120a6e
    TPixel32 *pixin    = r->pixels(y);
Shinya Kitaoka 120a6e
    TPixel32 *pixinEnd = pixin + lx;
Shinya Kitaoka 120a6e
    TPixelCM32 *pixout = rout->pixels(y);
Shinya Kitaoka 120a6e
    while (pixin < pixinEnd) {
Shinya Kitaoka 120a6e
      int v = (pixin->r + pixin->g + pixin->b) / 3;
Shinya Kitaoka 120a6e
      ++pixin;
Shinya Kitaoka 120a6e
      *pixout++ = TPixelCM32(1, 0, v);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return rout;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRasterCM32P RasterToToonzRasterConverter::convert(
Shinya Kitaoka 120a6e
    const TRasterP &inksInputRaster, const TRasterP &paintInputRaster) {
Shinya Kitaoka 120a6e
  return TRasterCM32P();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TToonzImageP RasterToToonzRasterConverter::convert(const TRasterImageP &ri) {
Shinya Kitaoka 120a6e
  TRasterCM32P ras = convert(ri->getRaster());
Shinya Kitaoka 120a6e
  if (ras)
Shinya Kitaoka 120a6e
    return TToonzImageP(ras, TRect(ras->getBounds()));
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return TToonzImageP();
Toshihiro Shimizu 890ddd
}