Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tiio_plt.h"
Toshihiro Shimizu 890ddd
//#include "tiio.h"
Toshihiro Shimizu 890ddd
#include "trastercm.h"
Toshihiro Shimizu 890ddd
#include "toonztags.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tiffio.h"
Toshihiro Shimizu 890ddd
e280ae
#ifdef _MSC_VER
Toshihiro Shimizu 890ddd
#pragma warning(disable : 4996)
e280ae
#endif
e280ae
e280ae
#ifdef _WIN32
Toshihiro Shimizu 890ddd
#include "windows.h"
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
extern "C" {
Toshihiro Shimizu 890ddd
#include "avl.h"
Toshihiro Shimizu 890ddd
#include "tcm.h"
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//============================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class PltReader final : public Tiio::Reader {
Shinya Kitaoka 120a6e
  TIFF *m_tiff;
Shinya Kitaoka 120a6e
  int m_row;
Shinya Kitaoka 120a6e
  bool m_tiled, m_stripped;
Shinya Kitaoka 120a6e
  int m_rowsPerStrip;
Shinya Kitaoka 120a6e
  int m_stripIndex;
Shinya Kitaoka 120a6e
  int m_rowLength;
Shinya Kitaoka 120a6e
  UCHAR *m_stripBuffer;
Shinya Kitaoka 120a6e
  int m_x, m_y, m_lx, m_ly;
Shinya Kitaoka 120a6e
  bool m_isCmap24;
Shinya Kitaoka 120a6e
  std::string m_history;
Shinya Kitaoka 120a6e
  int m_pltType;  //[1..4]
Shinya Kitaoka 120a6e
  int m_nColor;
Shinya Kitaoka 120a6e
  int m_nPencil;
Shinya Kitaoka 120a6e
  std::vector<tpixel32> m_infoRow;</tpixel32>
Shinya Kitaoka 120a6e
  std::map<int, std::pair<std::string,="" std::string="">></int,>
Shinya Kitaoka 120a6e
      m_pltNames;  // colorIndex(<256: paint) , pageName, colorName
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  PltReader();
Shinya Kitaoka 120a6e
  ~PltReader();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void open(FILE *file) override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  Tiio::RowOrder getRowOrder() const override { return Tiio::BOTTOM2TOP; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  int skipLines(int lineCount) override;
Shinya Kitaoka 473e70
  void readLine(char *buffer, int x0, int x1, int shrink) override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void getTzpPaletteColorNames(
Shinya Kitaoka 38fd86
      std::map<int, std::pair<std::string,="" std::string="">> &pltColorNames)</int,>
Shinya Kitaoka 38fd86
      const override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PltReader::PltReader()
Shinya Kitaoka 120a6e
    : m_tiff(0)
Shinya Kitaoka 120a6e
    , m_row(0)
Shinya Kitaoka 120a6e
    , m_rowsPerStrip(0)
Shinya Kitaoka 120a6e
    , m_stripIndex(-1)
Shinya Kitaoka 120a6e
    , m_stripBuffer(0)
Shinya Kitaoka 120a6e
    , m_rowLength(0)
Shinya Kitaoka 120a6e
    , m_x(0)
Shinya Kitaoka 120a6e
    , m_y(0)
Shinya Kitaoka 120a6e
    , m_lx(0)
Shinya Kitaoka 120a6e
    , m_ly(0)
Shinya Kitaoka 120a6e
    , m_isCmap24(false)
Shinya Kitaoka 120a6e
    , m_pltType(-1)
Shinya Kitaoka 120a6e
    , m_nColor(0)
Shinya Kitaoka 120a6e
    , m_nPencil(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
PltReader::~PltReader() { delete m_stripBuffer; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Campbell Barton 8c6c57
static int decode_group_name(char group_name[], char **name, int *key,
Campbell Barton 8c6c57
                             int *sister_index) {
Shinya Kitaoka 120a6e
  char *s, *t;
Shinya Kitaoka 120a6e
  *key          = 0;
Shinya Kitaoka 120a6e
  *sister_index = -1;
Shinya Kitaoka 120a6e
  s             = group_name;
Shinya Kitaoka 120a6e
  while (1) {
Shinya Kitaoka 120a6e
    t = strchr(s, '!');
Shinya Kitaoka 120a6e
    if (!t) break;
Shinya Kitaoka 120a6e
    *t = '\0';
Shinya Kitaoka 120a6e
    if (s[0] == 'C' && s[1] >= '0' && s[1] <= '9')
Shinya Kitaoka 120a6e
      *sister_index = atoi(s + 1);
Shinya Kitaoka 120a6e
    else if (s[0] >= '0' && s[0] <= '9')
Shinya Kitaoka 120a6e
      *key = atoi(s);
Shinya Kitaoka 120a6e
    *t     = '!';
Shinya Kitaoka 120a6e
    s      = t + 1;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  *name = s;
Shinya Kitaoka 120a6e
  return 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PltReader::getTzpPaletteColorNames(
Shinya Kitaoka 120a6e
    std::map<int, std::pair<std::string,="" std::string="">> &pltColorNames) const {</int,>
Shinya Kitaoka 120a6e
  pltColorNames = m_pltNames;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
bool isDefaultName(const std::string &_name) {
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  QString name = QString::fromStdString(_name);
Shinya Kitaoka 120a6e
  if (name.startsWith("Ink_")) {
Shinya Kitaoka 120a6e
    for (i = 4; i < name.size(); i++)
Shinya Kitaoka 120a6e
      if (!name.at(i).isDigit()) return false;
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  } else if (name.startsWith("Paint_")) {
Shinya Kitaoka 120a6e
    for (i = 6; i < name.size(); i++)
Shinya Kitaoka 120a6e
      if (!name.at(i).isDigit()) return false;
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool PaletteRead = false;
Shinya Kitaoka 120a6e
int ComboInkIndex[256];  // a bad patch....
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void PltReader::open(FILE *file) {
Shinya Kitaoka 120a6e
  char *data;
Shinya Kitaoka 120a6e
  uint32 count;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < 256; i++) ComboInkIndex[i] = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int fd = fileno(file);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TIFFErrorHandler oldhandler;
Shinya Kitaoka 120a6e
  oldhandler = TIFFSetWarningHandler(NULL);
Shinya Kitaoka 120a6e
  m_tiff     = TIFFFdOpen(fd, "", "rb");
Shinya Kitaoka 120a6e
  TIFFSetWarningHandler(oldhandler);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_tiff) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  uint32 w = 0, h = 0, rps = 0;
Shinya Kitaoka 120a6e
  uint32 tileWidth = 0, tileLength = 0;
Shinya Kitaoka 120a6e
  uint16 bps = 0, spp = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_IMAGEWIDTH, &w);
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_IMAGELENGTH, &h);
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_BITSPERSAMPLE, &bps);
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_SAMPLESPERPIXEL, &spp);
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_ROWSPERSTRIP, &rps);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  float xdpi, ydpi;
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_XRESOLUTION, &xdpi);
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_YRESOLUTION, &ydpi);
Shinya Kitaoka 120a6e
  m_info.m_dpix = xdpi;
Shinya Kitaoka 120a6e
  m_info.m_dpiy = ydpi;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_TILEWIDTH, &tileWidth);
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_TILELENGTH, &tileLength);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  uint32 risCount  = 0;
Shinya Kitaoka 120a6e
  USHORT *risArray = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_info.m_lx = w;
Shinya Kitaoka 120a6e
  m_info.m_ly = h;
Shinya Kitaoka 120a6e
  m_x         = 0;
Shinya Kitaoka 120a6e
  m_y         = 0;
Shinya Kitaoka 120a6e
  m_lx        = w;
Shinya Kitaoka 120a6e
  m_ly        = h;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(h == 1);
Shinya Kitaoka 120a6e
  m_ly = m_info.m_ly = 2;  // per l'infoRow
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (TIFFGetField(m_tiff, TIFFTAG_TOONZWINDOW, &risCount, &risArray)) {
Shinya Kitaoka 120a6e
    m_info.m_x0 = m_x = risArray[0];
Shinya Kitaoka 120a6e
    m_info.m_y0 = m_y = risArray[1];
Shinya Kitaoka 120a6e
    m_info.m_lx       = risArray[2];
Shinya Kitaoka 120a6e
    m_info.m_ly       = risArray[3];
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    m_info.m_x0 = 0;
Shinya Kitaoka 120a6e
    m_info.m_y0 = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_info.m_x1 = m_info.m_x0 + w;
Shinya Kitaoka 120a6e
  m_info.m_y1 = m_info.m_y0 + h;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (TIFFIsTiled(m_tiff)) {
Shinya Kitaoka 120a6e
    m_rowsPerStrip  = tileLength;
Shinya Kitaoka 120a6e
    int tilesPerRow = (w + tileWidth - 1) / tileWidth;
Shinya Kitaoka 120a6e
    m_rowLength     = tileWidth * tilesPerRow;
Shinya Kitaoka 120a6e
    int stripSize   = m_rowsPerStrip * m_rowLength * 4;
Shinya Kitaoka 120a6e
    m_stripBuffer   = new UCHAR[stripSize];
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    m_rowsPerStrip = rps;
Shinya Kitaoka 120a6e
    int stripSize  = rps * w * 4 + 4096;  // TIFFStripSize(m_tiff);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_stripBuffer = new UCHAR[stripSize];
Shinya Kitaoka 120a6e
    m_rowLength   = w;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  uint32 paletteCount;
Shinya Kitaoka 120a6e
  USHORT *palette;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_TOONZPALETTE, &paletteCount, &palette);
Shinya Kitaoka 120a6e
  assert(paletteCount);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_pltType = palette[0];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_nColor  = palette[10];
Shinya Kitaoka 120a6e
  m_nPencil = palette[11];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string colorNames;
Shinya Kitaoka 120a6e
  if (TIFFGetField(m_tiff, TIFFTAG_TOONZCOLORNAMES, &count, &data))
Shinya Kitaoka 120a6e
    colorNames = data;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TREE *names = cdb_decode_all(data, Tcm_24_default_info);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  CDB_TREE_ITEM *item;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  char *pageName;
Shinya Kitaoka 120a6e
  int key, sisterIndex;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int maxCount = m_nColor + m_nPencil;
Shinya Kitaoka 120a6e
  m_infoRow.resize(maxCount, TPixel32(0, 0, 0, 0));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < maxCount; i++) {
Shinya Kitaoka 120a6e
    item = (CDB_TREE_ITEM *)avl_locate(names, i);
Shinya Kitaoka 120a6e
    if (!item) continue;
Shinya Kitaoka 120a6e
    decode_group_name(item->group, &pageName, &key, &sisterIndex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (strcmp(pageName, "_UNUSED_PAGE") == 0) continue;
Shinya Kitaoka 120a6e
    if (sisterIndex == -1 || i < m_nColor) m_infoRow[i].r = 255;
Shinya Kitaoka 120a6e
    if (i < m_nColor) m_infoRow[i].g                      = 255;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (isdigit(item->name[0]))  // in toonz colors cannot begin with digits
Shinya Kitaoka 120a6e
      item->name++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::map<int, std::pair<std::string,="" std::string="">>::iterator it;</int,>
Shinya Kitaoka 120a6e
    if ((it = m_pltNames.find(i)) == m_pltNames.end() ||
Shinya Kitaoka 120a6e
        isDefaultName(it->second.second))
Shinya Kitaoka 120a6e
      m_pltNames[i] = std::pair<std::string, std::string="">(pageName, item->name);</std::string,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (sisterIndex != -1) {
Shinya Kitaoka 120a6e
      int comboindex = (i < 256) ? (sisterIndex >> 16) + 256 : sisterIndex >> 8;
Shinya Kitaoka 120a6e
      if (i >= 256) ComboInkIndex[i - 256] = comboindex;
Shinya Kitaoka 120a6e
      std::map<int, std::pair<std::string,="" std::string="">>::iterator it;</int,>
Shinya Kitaoka 120a6e
      if ((it = m_pltNames.find(comboindex)) == m_pltNames.end() ||
Shinya Kitaoka 120a6e
          isDefaultName(it->second.second)) {
Shinya Kitaoka 120a6e
        m_pltNames[comboindex] =
Shinya Kitaoka 120a6e
            std::pair<std::string, std::string="">(pageName, item->name);</std::string,>
Shinya Kitaoka 120a6e
        if (comboindex < m_nColor)
Shinya Kitaoka 120a6e
          m_infoRow[comboindex].r = m_infoRow[comboindex].g = 255;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (TIFFGetField(m_tiff, TIFFTAG_TOONZHISTORY, &count, &data))
Shinya Kitaoka 120a6e
    m_history = data;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  uint16 photometric, planarconfig;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_PHOTOMETRIC, &photometric);
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_PLANARCONFIG, &planarconfig);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (photometric != PHOTOMETRIC_RGB || planarconfig != PLANARCONFIG_CONTIG) {
Shinya Kitaoka 120a6e
    // tmsg_error("bad !");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int PltReader::skipLines(int lineCount) {
Shinya Kitaoka 120a6e
  // m_row+=lineCount;
Shinya Kitaoka 120a6e
  return lineCount;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PltReader::readLine(char *buffer, int x0, int x1, int shrink) {
Shinya Kitaoka 120a6e
  TPixelRGBM32 *pix = (TPixelRGBM32 *)buffer;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < m_info.m_lx; i++) pix[i] = TPixelRGBM32();
Shinya Kitaoka 120a6e
  int y                                    = m_row++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (y == 1) {
Shinya Kitaoka 120a6e
    for (i = 0; i < m_info.m_lx; i++) pix[i] = m_infoRow[i];
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  } else if (y > 1)
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  unsigned char line[4096 * 4];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TIFFReadScanline(m_tiff, (char *)line, y - m_y, 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (m_pltType) {
Shinya Kitaoka 120a6e
  case 1:
Shinya Kitaoka 120a6e
    throw "Unsupported palette type";
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case 2:
Shinya Kitaoka 120a6e
  case 4:
Shinya Kitaoka 120a6e
    for (i = 0; i < (m_nColor + m_nPencil) * 4;
Shinya Kitaoka 120a6e
         i += 4)  // prima i color, poi i pencil
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      pix->r = line[i + 0];
Shinya Kitaoka 120a6e
      pix->g = line[i + 1];
Shinya Kitaoka 120a6e
      pix->b = line[i + 2];
Shinya Kitaoka 120a6e
      pix->m = line[i + 3];
Shinya Kitaoka 120a6e
      ++pix;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case 3:
Shinya Kitaoka 120a6e
    for (i = 0; i < (m_nColor + m_nPencil) * 4;
Shinya Kitaoka 120a6e
         i += 4)  // prima i color, poi i pencil
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      pix->m = line[i + 0]; /* different from type 2 */
Shinya Kitaoka 120a6e
      pix->b = line[i + 1];
Shinya Kitaoka 120a6e
      pix->g = line[i + 2];
Shinya Kitaoka 120a6e
      pix->r = line[i + 3];
Shinya Kitaoka 120a6e
      ++pix;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    throw "Unknown palette type";
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//============================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Tiio::Reader *Tiio::makePltReader() { return new PltReader(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Tiio::Writer *Tiio::makePltWriter() {
Shinya Kitaoka 120a6e
  assert(0);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------