Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tiio_tzp.h"
shun-iwasawa f6a0e4
// #include "tiio.h"
Toshihiro Shimizu 890ddd
#include "trastercm.h"
Toshihiro Shimizu 890ddd
#include "toonztags.h"
Toshihiro Shimizu 890ddd
#include "texception.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tiffio.h"
Toshihiro Shimizu 890ddd
#include "tiffiop.h"
shun-iwasawa f6a0e4
// #include "tspecialstyleid.h"
Toshihiro Shimizu 890ddd
#include <set></set>
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
//============================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class TzpReader 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_nColor;
Shinya Kitaoka 120a6e
  int m_nPencil;
Shinya Kitaoka 120a6e
  bool m_isBigEndian;
Shinya Kitaoka 120a6e
  bool m_isFirstLineRead;
Toshihiro Shimizu 890ddd
shun-iwasawa f6a0e4
  bool m_isOldCmap13;
shun-iwasawa f6a0e4
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TzpReader();
Shinya Kitaoka 120a6e
  ~TzpReader();
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
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TzpReader::TzpReader()
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)
shun-iwasawa f6a0e4
    , m_isOldCmap13(false)
Shinya Kitaoka 120a6e
    , m_nColor(0)
Shinya Kitaoka 120a6e
    , m_nPencil(0)
Shinya Kitaoka 120a6e
    , m_isBigEndian(false)
Shinya Kitaoka 120a6e
    , m_isFirstLineRead(true) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TzpReader::~TzpReader() { delete m_stripBuffer; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TzpReader::open(FILE *file) {
Shinya Kitaoka 120a6e
  int fd = fileno(file);
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
  if (!m_tiff) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  uint32 w = 0, h = 0, bps = 0, spp = 0, rps = 0;
Shinya Kitaoka 120a6e
  uint32 tileWidth = 0, tileLength = 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
  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
Shinya Kitaoka 120a6e
  m_nColor  = palette[10];
Shinya Kitaoka 120a6e
  m_nPencil = palette[11];
Shinya Kitaoka 120a6e
shun-iwasawa f6a0e4
  // Old 4.1 palette : 4bit paint, 4bit tone, 5bit ink
Shinya Kitaoka 120a6e
  if (m_nColor == 128 && m_nPencil == 32) {
shun-iwasawa f6a0e4
    m_isOldCmap13 = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (bps == 32)
Shinya Kitaoka 120a6e
    m_isCmap24 = true;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_isCmap24 = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  char *data;
Shinya Kitaoka 120a6e
  uint32 count;
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_TOONZHISTORY, &count, &data);
Shinya Kitaoka 120a6e
  std::string history(data);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  uint16 planarconfig;
Shinya Kitaoka 120a6e
  TIFFGetField(m_tiff, TIFFTAG_PLANARCONFIG, &planarconfig);
Shinya Kitaoka 120a6e
  if (planarconfig == PLANARCONFIG_SEPARATE) {
Shinya Kitaoka 120a6e
    // tmsg_error("separate buffer image not supported yet in .tz(up) files");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TzpReader::skipLines(int lineCount) {
Shinya Kitaoka 120a6e
  // m_row += lineCount;
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
extern int ComboInkIndex[];  // a bad patch....
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TzpReader::readLine(char *buffer, int x0, int x1, int shrink) {
Shinya Kitaoka 120a6e
  TPixelCM32 *pix = (TPixelCM32 *)buffer;
Shinya Kitaoka 120a6e
  for (int i = 0; i < m_info.m_lx; i++) pix[i] = TPixelCM32();
shun-iwasawa f6a0e4
  int y = m_row++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const int paintOffset = 0;                 // paint#1 --> 1
Shinya Kitaoka 120a6e
  const int inkOffset   = 1 + m_nColor - 1;  // ink#0 --> nColor-1
Shinya Kitaoka 120a6e
  // (n.b. c'e' un colore in meno visto che il primo colore e' il BG)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_isCmap24) {
Shinya Kitaoka 120a6e
    if (m_y <= y && y < m_y + m_ly) {
Shinya Kitaoka 120a6e
      std::vector<tuint32> line(m_lx);</tuint32>
Shinya Kitaoka 120a6e
      TIFFReadScanline(m_tiff, (char *)&line[0], y - m_y, 0);
Shinya Kitaoka 120a6e
      if (m_isFirstLineRead) {
Shinya Kitaoka 120a6e
        m_isFirstLineRead = false;
Shinya Kitaoka 120a6e
        for (int i = 0; i < m_lx; i++)
Shinya Kitaoka 120a6e
          if ((line[i] >> 24) != 0) {
Shinya Kitaoka 120a6e
            m_isBigEndian = true;
Shinya Kitaoka 120a6e
            break;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      pix += m_x;
Shinya Kitaoka 120a6e
      for (int i = 0; i < m_lx; i++) {
Shinya Kitaoka 120a6e
        TUINT32 inPix = m_isBigEndian ? swapTINT32(line[i]) : line[i];
Shinya Kitaoka 120a6e
        int tone      = inPix & 0xFF;
Shinya Kitaoka 120a6e
        int paint     = ((inPix >> 8) & 0xFF);
Shinya Kitaoka 120a6e
        int ink       = ((inPix >> 16) & 0xFF);
Shinya Kitaoka 120a6e
        if (paint > 0) paint += paintOffset;
Shinya Kitaoka 120a6e
        if (ComboInkIndex[ink] != -1)
Shinya Kitaoka 120a6e
          ink = ComboInkIndex[ink];
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          ink += inkOffset;
Shinya Kitaoka 120a6e
        pix[i] = TPixelCM32(ink, paint, tone);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
shun-iwasawa f6a0e4
  } else if (!m_isOldCmap13) {
Shinya Kitaoka 120a6e
    if (m_y <= y && y < m_y + m_ly) {
Shinya Kitaoka 120a6e
      std::vector<unsigned short=""> line(m_lx);</unsigned>
Shinya Kitaoka 120a6e
      TIFFReadScanline(m_tiff, (char *)&line[0], y - m_y, 0);
Shinya Kitaoka 120a6e
      pix += m_x;
Shinya Kitaoka 120a6e
      static std::set<int> table;</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /// per le tzp che vengono da Irix
Shinya Kitaoka 120a6e
      bool bigEndian =
Shinya Kitaoka 120a6e
          (m_tiff->tif_header.classic.tiff_magic == TIFF_BIGENDIAN);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (int i = 0; i < m_lx; i++) {
Shinya Kitaoka 120a6e
        unsigned short inPix = line[i];
Shinya Kitaoka 120a6e
        if (bigEndian) inPix = swapUshort(inPix);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        int tone  = inPix & 0xF;
Shinya Kitaoka 120a6e
        int paint = ((inPix >> 4) & 0x7F);
Shinya Kitaoka 120a6e
        int ink   = ((inPix >> 11) & 0x1F);
Shinya Kitaoka 120a6e
        tone |= tone << 4;
Shinya Kitaoka 120a6e
        if (paint > 0) paint += paintOffset;
Shinya Kitaoka 120a6e
        ink += inkOffset;
Shinya Kitaoka 120a6e
        pix[i] = TPixelCM32(ink, paint, tone);
Shinya Kitaoka 120a6e
        if (tone < 255) {
Shinya Kitaoka 120a6e
          //           int w = ink;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        if (table.find(ink) == table.end()) {
Shinya Kitaoka 120a6e
          table.insert(ink);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
shun-iwasawa f6a0e4
  } else {
shun-iwasawa f6a0e4
    if (m_y <= y && y < m_y + m_ly) {
shun-iwasawa f6a0e4
      std::vector<unsigned short=""> line(m_lx);</unsigned>
shun-iwasawa f6a0e4
      TIFFReadScanline(m_tiff, (char *)&line[0], y - m_y, 0);
shun-iwasawa f6a0e4
      pix += m_x;
shun-iwasawa f6a0e4
      static std::set<int> table;</int>
shun-iwasawa f6a0e4
shun-iwasawa f6a0e4
      /// per le tzp che vengono da Irix
shun-iwasawa f6a0e4
      bool bigEndian =
shun-iwasawa f6a0e4
          (m_tiff->tif_header.classic.tiff_magic == TIFF_BIGENDIAN);
shun-iwasawa f6a0e4
shun-iwasawa f6a0e4
      for (int i = 0; i < m_lx; i++) {
shun-iwasawa f6a0e4
        unsigned short inPix = line[i];
shun-iwasawa f6a0e4
        if (bigEndian) inPix = swapUshort(inPix);
shun-iwasawa f6a0e4
shun-iwasawa f6a0e4
        int ink   = ((inPix >> 3) & 0x1F);
shun-iwasawa f6a0e4
        int tone  = ((inPix >> 8) & 0xF);
shun-iwasawa f6a0e4
        int paint = ((inPix >> 12) & 0xF);
shun-iwasawa f6a0e4
        tone |= tone << 4;
shun-iwasawa f6a0e4
        if (paint > 0) paint += paintOffset;
shun-iwasawa f6a0e4
        if (ComboInkIndex[ink] != -1)
shun-iwasawa f6a0e4
          ink = ComboInkIndex[ink];
shun-iwasawa f6a0e4
        else
shun-iwasawa f6a0e4
          ink += inkOffset;
shun-iwasawa f6a0e4
        pix[i] = TPixelCM32(ink, paint, tone);
shun-iwasawa f6a0e4
        if (tone < 255) {
shun-iwasawa f6a0e4
          //           int w = ink;
shun-iwasawa f6a0e4
        }
shun-iwasawa f6a0e4
        if (table.find(ink) == table.end()) {
shun-iwasawa f6a0e4
          table.insert(ink);
shun-iwasawa f6a0e4
        }
shun-iwasawa f6a0e4
      }
shun-iwasawa f6a0e4
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//============================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Tiio::Reader *Tiio::makeTzpReader() { return new TzpReader(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Tiio::Writer *Tiio::makeTzpWriter() {
Shinya Kitaoka 120a6e
  assert(0);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------