Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#include "tiio_tzl.h"
Toshihiro Shimizu 890ddd
#include "tmachine.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "tfilepath_io.h"
Toshihiro Shimizu 890ddd
#include "tpixelcm.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tcodec.h"
Toshihiro Shimizu 890ddd
#include <stdio.h>
</stdio.h>
Toshihiro Shimizu 890ddd
#include "trastercm.h"
Toshihiro Shimizu 890ddd
#include "timageinfo.h"
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "tcontenthistory.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#include "tenv.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd

Campbell Barton d0e335
#include <qbytearray>
</qbytearray>
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !defined(TNZ_LITTLE_ENDIAN)
Toshihiro Shimizu 890ddd
TNZ_LITTLE_ENDIAN undefined !!
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
    const int CURRENT_VERSION = 14;
Shinya Kitaoka 120a6e
const int CREATOR_LENGTH      = 40;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
char *reverse(char *buffer, int size) {
Shinya Kitaoka 120a6e
  char *start = buffer;
Shinya Kitaoka 120a6e
  char *end   = start + size;
Shinya Kitaoka 120a6e
  while (start < --end) {
Shinya Kitaoka 120a6e
    char tmp = *start;
Shinya Kitaoka 120a6e
    *start++ = *end;
Shinya Kitaoka 120a6e
    *end     = tmp;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return buffer;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Campbell Barton 8c6c57
static int tfwrite(const char *data, const unsigned int count, FILE *f) {
Shinya Kitaoka 120a6e
  return fwrite(data, sizeof(char), count, f);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Campbell Barton 8c6c57
static int tfwrite(UCHAR *data, const unsigned int count, FILE *f) {
Shinya Kitaoka 120a6e
  return fwrite(data, sizeof(char), count, f);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Campbell Barton 8c6c57
static int tfwrite(TINT32 *data, const unsigned int count, FILE *f) {
Shinya Kitaoka 120a6e
  if (count == 1) {
Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
    TUINT32 dataToWrite = swapTINT32(*data);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    TUINT32 dataToWrite = *data;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    return fwrite(&dataToWrite, sizeof(TINT32), 1, f);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  assert(0);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Campbell Barton 8c6c57
static int tfwrite(TUINT32 *data, const unsigned int count, FILE *f) {
Shinya Kitaoka 120a6e
  if (count == 1) {
Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
    TUINT32 dataToWrite = swapTINT32(*data);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    TUINT32 dataToWrite = *data;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    return fwrite(&dataToWrite, sizeof(TINT32), 1, f);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  assert(0);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Campbell Barton 8c6c57
static int tfwrite(double *data, unsigned int count, FILE *f) {
Shinya Kitaoka 120a6e
  if (count == 1) {
Shinya Kitaoka 120a6e
    double v  = *data;
Shinya Kitaoka 120a6e
    char *ptr = (char *)&v;
Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
    ptr = reverse((char *)&v, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    return fwrite(ptr, sizeof(double), 1, f);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  assert(0);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TImageReaderTzl
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
bool erasedFrame;  // Vera se รจ stato rimosso almeno un frame.
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
bool writeVersionAndCreator(FILE *chan, const char *version, QString creator) {
Shinya Kitaoka 120a6e
  if (!chan) return false;
Shinya Kitaoka 120a6e
  tfwrite(version, strlen(version), chan);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // creator : CREATOR_LENGTH characater
Shinya Kitaoka 120a6e
  char s[CREATOR_LENGTH];
Shinya Kitaoka 120a6e
  if (creator.length() == 0) creator = "UNKNOWN";
Shinya Kitaoka 120a6e
  memset(s, 0, sizeof s);
Shinya Kitaoka 120a6e
  if (creator.length() > CREATOR_LENGTH - 1)
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Shinya Kitaoka 120a6e
    memcpy(s, creator.toLatin1(), CREATOR_LENGTH - 1);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    memcpy(s, creator.toAscii(), CREATOR_LENGTH - 1);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  else
Toshihiro Shimizu 890ddd
#if QT_VERSION >= 0x050000
Shinya Kitaoka 120a6e
    memcpy(s, creator.toLatin1(), creator.length());
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    memcpy(s, creator.toAscii(), creator.length());
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  tfwrite(s, CREATOR_LENGTH, chan);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
bool readVersion(FILE *chan, int &version) {
Shinya Kitaoka 120a6e
  char magic[8];
Shinya Kitaoka 120a6e
  memset(magic, 0, sizeof(magic));
Shinya Kitaoka 120a6e
  fread(&magic, sizeof(char), 8, chan);
Campbell Barton 4e9ecf
  if (memcmp(magic, "TLV10", 5) == 0) {
Shinya Kitaoka 120a6e
    version = 10;
shun-iwasawa 27b0cf
  } else if (memcmp(magic, "TLV11", 5) == 0) {
Shinya Kitaoka 120a6e
    version = 11;
shun-iwasawa 27b0cf
  } else if (memcmp(magic, "TLV12", 5) == 0) {
Shinya Kitaoka 120a6e
    version = 12;
shun-iwasawa 27b0cf
  } else if (memcmp(magic, "TLV13", 5) == 0) {
Shinya Kitaoka 120a6e
    version = 13;
shun-iwasawa 27b0cf
  } else if (memcmp(magic, "TLV14", 5) == 0) {
Shinya Kitaoka 120a6e
    version = 14;
shun-iwasawa 27b0cf
  } else {
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
bool readHeaderAndOffsets(FILE *chan, TzlOffsetMap &frameOffsTable,
Shinya Kitaoka 120a6e
                          TzlOffsetMap &iconOffsTable, TDimension &res,
Shinya Kitaoka 120a6e
                          int &version, QString &creator, TINT32 *_frameCount,
Shinya Kitaoka 120a6e
                          TINT32 *_offsetTablePos, TINT32 *_iconOffsetTablePos,
Shinya Kitaoka 120a6e
                          TLevelP level) {
Shinya Kitaoka 120a6e
  TINT32 hdrSize;
Shinya Kitaoka 120a6e
  TINT32 lx = 0, ly = 0, frameCount = 0;
Shinya Kitaoka 120a6e
  char codec[4];
Shinya Kitaoka 120a6e
  TINT32 offsetTablePos;
Shinya Kitaoka 120a6e
  TINT32 iconOffsetTablePos;
Shinya Kitaoka 120a6e
  // char magic[8];
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  assert(frameOffsTable.empty());
Shinya Kitaoka 120a6e
  assert(iconOffsTable.empty());
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (!readVersion(chan, version)) return false;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // read creator
Shinya Kitaoka 120a6e
  if (version == 14) {
Shinya Kitaoka 120a6e
    char buffer[CREATOR_LENGTH + 1];
Shinya Kitaoka 120a6e
    memset(buffer, 0, sizeof buffer);
Shinya Kitaoka 120a6e
    fread(&buffer, sizeof(char), CREATOR_LENGTH, chan);
Shinya Kitaoka 120a6e
    creator = buffer;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  fread(&hdrSize, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&lx, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&ly, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&frameCount, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (version > 10) {
Shinya Kitaoka 120a6e
    fread(&offsetTablePos, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    fread(&iconOffsetTablePos, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
    offsetTablePos     = swapTINT32(offsetTablePos);
Shinya Kitaoka 120a6e
    iconOffsetTablePos = swapTINT32(iconOffsetTablePos);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  fread(&codec, 4, 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
  hdrSize    = swapTINT32(hdrSize);
Shinya Kitaoka 120a6e
  lx         = swapTINT32(lx);
Shinya Kitaoka 120a6e
  ly         = swapTINT32(ly);
Shinya Kitaoka 120a6e
  frameCount = swapTINT32(frameCount);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  assert(0 < frameCount && frameCount < 60000);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (version > 10 && offsetTablePos != 0 && iconOffsetTablePos != 0) {
Shinya Kitaoka 120a6e
    // assert(offsetTablePos>0);
Shinya Kitaoka 120a6e
    assert(frameCount > 0);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    fseek(chan, offsetTablePos, SEEK_SET);
Shinya Kitaoka 120a6e
    TFrameId oldFid(TFrameId::EMPTY_FRAME);
Shinya Kitaoka 120a6e
    for (int i = 0; i < (int)frameCount; i++) {
Shinya Kitaoka 120a6e
      TINT32 number, offs, length;
Shinya Kitaoka 120a6e
      char letter;
Shinya Kitaoka 120a6e
      fread(&number, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
      fread(&letter, sizeof(char), 1, chan);
Shinya Kitaoka 120a6e
      fread(&offs, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
      if (version >= 12) fread(&length, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
      number                    = swapTINT32(number);
Shinya Kitaoka 120a6e
      offs                      = swapTINT32(offs);
Shinya Kitaoka 120a6e
      if (version == 12) length = swapTINT32(length);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
      //		std::cout << "#" << i << std::hex << " n 0x" << number
Shinya Kitaoka 120a6e
      //<< " l 0x" << letter << " o 0x" << offs << std::dec << std::endl;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
      TFrameId fid(number, letter);
Shinya Kitaoka 120a6e
      // assert(i==0 || oldFid
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
      if (version >= 12) {
Shinya Kitaoka 120a6e
        frameOffsTable[fid] = TzlChunk(offs, length);
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        frameOffsTable[fid] = TzlChunk(offs, 0);
Shinya Kitaoka 120a6e
        if (i > 0) {
Shinya Kitaoka 120a6e
          frameOffsTable[oldFid].m_length =
Shinya Kitaoka 120a6e
              offs - frameOffsTable[oldFid].m_offs;
Shinya Kitaoka 120a6e
          assert(frameOffsTable[oldFid].m_length > 0);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        if (i == frameCount - 1) {
Shinya Kitaoka 120a6e
          frameOffsTable[fid].m_length = offsetTablePos - offs;
Shinya Kitaoka 120a6e
          assert(frameOffsTable[fid].m_length > 0);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      oldFid = fid;
Shinya Kitaoka 120a6e
      if (level) level->setFrame(fid, TImageP());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (version >= 13) {
Shinya Kitaoka 120a6e
      // Build IconOffsetTable
Shinya Kitaoka 120a6e
      fseek(chan, iconOffsetTablePos, SEEK_SET);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
      for (int i = 0; i < (int)frameCount; i++) {
Shinya Kitaoka 120a6e
        TINT32 number, thumbnailOffs, thumbnailLength;
Shinya Kitaoka 120a6e
        char letter;
Shinya Kitaoka 120a6e
        fread(&number, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
        fread(&letter, sizeof(char), 1, chan);
Shinya Kitaoka 120a6e
        fread(&thumbnailOffs, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
        fread(&thumbnailLength, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
        number          = swapTINT32(number);
Shinya Kitaoka 120a6e
        thumbnailOffs   = swapTINT32(thumbnailOffs);
Shinya Kitaoka 120a6e
        thumbnailLength = swapTINT32(thumbnailLength);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
        TFrameId fid(number, letter);
Shinya Kitaoka 120a6e
        iconOffsTable[fid] = TzlChunk(thumbnailOffs, thumbnailLength);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    // m_frameOffsTable.resize(frameCount);
Shinya Kitaoka 120a6e
    frameOffsTable[TFrameId(1)] = TzlChunk(ftell(chan), 0);
Shinya Kitaoka 120a6e
    iconOffsTable[TFrameId(1)]  = TzlChunk(ftell(chan), 0);
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 2; i <= (int)frameCount; i++) {
Shinya Kitaoka 120a6e
      frameOffsTable[TFrameId(i)] = TzlChunk(0, 0);
Shinya Kitaoka 120a6e
      iconOffsTable[TFrameId(i)]  = TzlChunk(0, 0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (level)
Shinya Kitaoka 120a6e
      for (i = 1; i <= (int)frameCount; i++)
Shinya Kitaoka 120a6e
        level->setFrame(TFrameId(i), TImageP());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  res.lx                                        = lx;
Shinya Kitaoka 120a6e
  res.ly                                        = ly;
Shinya Kitaoka 120a6e
  if (_offsetTablePos) *_offsetTablePos         = offsetTablePos;
Shinya Kitaoka 120a6e
  if (_iconOffsetTablePos) *_iconOffsetTablePos = iconOffsetTablePos;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (_frameCount) *_frameCount = frameCount;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

shun-iwasawa 27b0cf
static bool adjustIconAspectRatio(TDimension &outDimension,
shun-iwasawa 27b0cf
                                  TDimension inDimension, TDimension imageRes) {
Shinya Kitaoka 120a6e
  TINT32 iconLx = inDimension.lx, iconLy = inDimension.ly;
Shinya Kitaoka 120a6e
  assert(iconLx > 0 && iconLy > 0);
Shinya Kitaoka 120a6e
  assert(imageRes.lx > 0 && imageRes.ly > 0);
Shinya Kitaoka 120a6e
  if (iconLx <= 0 || iconLy <= 0 || imageRes.lx <= 0 || imageRes.ly <= 0)
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  int lx = imageRes.lx;
Shinya Kitaoka 120a6e
  int ly = imageRes.ly;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (std::max(double(lx) / inDimension.lx, double(ly) / inDimension.ly) ==
Shinya Kitaoka 120a6e
      double(ly) / inDimension.ly)
Shinya Kitaoka 120a6e
    iconLx = tround((double(lx) * inDimension.ly) / ly);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    iconLy     = tround((double(ly) * inDimension.lx) / lx);
Shinya Kitaoka 120a6e
  outDimension = TDimension(iconLx, iconLy);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Campbell Barton 8c6c57
static void getThumbnail(TRasterP ras, int shrink, TRasterP &thumbnail) {
Shinya Kitaoka 120a6e
  int j          = 0;
Shinya Kitaoka 120a6e
  int y          = 0;
Shinya Kitaoka 120a6e
  TPixel32 *pix2 = (TPixel32 *)thumbnail->getRawData();
Shinya Kitaoka 120a6e
  for (j = 0; j < thumbnail->getLy(); j++) {
Shinya Kitaoka 120a6e
    ras->lock();
Shinya Kitaoka 120a6e
    TPixel32 *pix    = (TPixel32 *)ras->getRawData() + y * ras->getLx();
Shinya Kitaoka 120a6e
    TPixel32 *endPix = pix2 + thumbnail->getLx();
Shinya Kitaoka 120a6e
    while (pix2 < endPix) {
Shinya Kitaoka 120a6e
      *pix2++ = *pix;
Shinya Kitaoka 120a6e
      pix += shrink;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    y += shrink;
Shinya Kitaoka 120a6e
    ras->unlock();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka d1f6c4
class TImageReaderTzl final : public TImageReader {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TImageReaderTzl(const TFilePath &f, const TFrameId &fid, TLevelReaderTzl *);
Shinya Kitaoka 120a6e
  ~TImageReaderTzl() {}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  // not implemented
Shinya Kitaoka 120a6e
  TImageReaderTzl(const TImageReaderTzl &);
Shinya Kitaoka 120a6e
  TImageReaderTzl &operator=(const TImageReaderTzl &src);
Shinya Kitaoka 120a6e
  TImageP load10();
Shinya Kitaoka 120a6e
  TImageP load11();
Shinya Kitaoka 120a6e
  TImageP load13();  // Aggiunta iconcine
Shinya Kitaoka 120a6e
  TImageP load14();  //	Aggiunto creator con lunghezza fissa
Shinya Kitaoka 120a6e
  const TImageInfo *getImageInfo10() const;
Shinya Kitaoka 120a6e
  const TImageInfo *getImageInfo11() const;  // vale anche le versioni > di 11
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  //! Indice del frame del livello
Shinya Kitaoka 120a6e
  TFrameId m_fid;
Shinya Kitaoka 473e70
  TImageP load() override;
Shinya Kitaoka 473e70
  TImageP loadIcon() override {
Shinya Kitaoka 120a6e
    m_isIcon = true;
Shinya Kitaoka 120a6e
    return load();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  const TImageInfo *getImageInfo() const override;
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  // TImageP doLoad();
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  TDimension getSize() const;
Shinya Kitaoka 120a6e
  TRect getBBox() const;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  //! Size of image
Shinya Kitaoka 120a6e
  int m_lx, m_ly;
Shinya Kitaoka 120a6e
  bool m_isIcon;
Shinya Kitaoka 120a6e
  //! Reference to level reader
Shinya Kitaoka 120a6e
  TLevelReaderTzl *m_lrp;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TImageWriterTzl
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka d1f6c4
class TImageWriterTzl final : public TImageWriter {
Shinya Kitaoka 120a6e
  //! Reference to level writer
Shinya Kitaoka 120a6e
  TLevelWriterTzl *m_lwp;
Shinya Kitaoka 120a6e
  TFrameId m_fid;
Shinya Kitaoka 120a6e
  TDimension
Shinya Kitaoka 120a6e
      m_iconSize;  // Dimensioni dell'iconcina salvata all'interno del file tlv
Shinya Kitaoka 120a6e
  //	In genere questo parametro viene settato come quello impostato
Shinya Kitaoka 38fd86
  // dall'utente
Shinya Kitaoka 120a6e
  // nelle preferenze.
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TImageWriterTzl(TLevelWriterTzl *lw, TFrameId fid)
Shinya Kitaoka 120a6e
      : TImageWriter(TFilePath())
Shinya Kitaoka 120a6e
      , m_lwp(lw)
Shinya Kitaoka 120a6e
      , m_fid(fid)
Shinya Kitaoka 120a6e
      , m_iconSize(TDimension(80, 60)) {}
Shinya Kitaoka 120a6e
  ~TImageWriterTzl() {}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  // not implemented
Shinya Kitaoka 120a6e
  TImageWriterTzl(const TImageWriterTzl &);
Shinya Kitaoka 120a6e
  TImageWriterTzl &operator=(const TImageWriterTzl &src);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 473e70
  void save(const TImageP &img) override { m_lwp->save(img, m_fid); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TWriterInfo
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TWriterInfo *TWriterInfoTzl::create(const std::string &ext)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
  return new TWriterInfoTzl();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TWriterInfo *TWriterInfoTzl::clone() const
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  return new TWriterInfoTzl(*this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
class Header {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  enum RasType {
Shinya Kitaoka 120a6e
    Raster32RGBM,
Shinya Kitaoka 120a6e
    Raster64RGBM,
Shinya Kitaoka 120a6e
    Raster32CM,
Shinya Kitaoka 120a6e
    RasterGR8,
Shinya Kitaoka 120a6e
    RasterUnknown
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  int m_lx;
Shinya Kitaoka 120a6e
  int m_ly;
Shinya Kitaoka 120a6e
  RasType m_rasType;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
void TLevelWriterTzl::buildFreeChunksTable() {
Shinya Kitaoka 120a6e
  std::set<tzlchunk> occupiedChunks;
</tzlchunk>
Shinya Kitaoka 120a6e
  TzlOffsetMap::const_iterator it1 = m_frameOffsTable.begin();
Shinya Kitaoka 120a6e
  TINT32 lastOccupiedPos = 0;  // ultima posizione all'interno del file occupata
Shinya Kitaoka 120a6e
                               // dall'ultima immagine(grande o icona)
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  while (it1 != m_frameOffsTable.end()) {
Shinya Kitaoka 120a6e
    occupiedChunks.insert(TzlChunk(it1->second.m_offs, it1->second.m_length));
Shinya Kitaoka 120a6e
    if (it1->second.m_offs + it1->second.m_length > lastOccupiedPos)
Shinya Kitaoka 120a6e
      lastOccupiedPos = it1->second.m_offs + it1->second.m_length - 1;
Shinya Kitaoka 120a6e
    it1++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TzlOffsetMap::const_iterator iconIt1 = m_iconOffsTable.begin();
Shinya Kitaoka 120a6e
  while (iconIt1 != m_iconOffsTable.end()) {
Shinya Kitaoka 120a6e
    occupiedChunks.insert(
Shinya Kitaoka 120a6e
        TzlChunk(iconIt1->second.m_offs, iconIt1->second.m_length));
Shinya Kitaoka 120a6e
    if (iconIt1->second.m_offs + iconIt1->second.m_length > lastOccupiedPos)
Shinya Kitaoka 120a6e
      lastOccupiedPos = iconIt1->second.m_offs + iconIt1->second.m_length - 1;
Shinya Kitaoka 120a6e
    iconIt1++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  std::set<tzlchunk>::const_iterator it2 = occupiedChunks.begin();
</tzlchunk>
Shinya Kitaoka 120a6e
  TINT32 curPos;  // prima posizione utile nel file in cui vengono memorizzati i
Shinya Kitaoka 120a6e
                  // dati relativi alle immagini
Shinya Kitaoka 120a6e
  if (m_version == 13)
Shinya Kitaoka 120a6e
    curPos = 6 * sizeof(TINT32) + 4 * sizeof(char) + 8 * sizeof(char);
Shinya Kitaoka 120a6e
  else if (m_version == 14)
Shinya Kitaoka 120a6e
    curPos = 6 * sizeof(TINT32) + 4 * sizeof(char) + 8 * sizeof(char) +
Shinya Kitaoka 120a6e
             CREATOR_LENGTH * sizeof(char);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    curPos = it2->m_offs;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  while (it2 != occupiedChunks.end()) {
Shinya Kitaoka 120a6e
    assert(it2->m_offs >= curPos);
Shinya Kitaoka 120a6e
    if (it2->m_offs > curPos)
Shinya Kitaoka 120a6e
      m_freeChunks.insert(TzlChunk(curPos, it2->m_offs - curPos));
Shinya Kitaoka 120a6e
    curPos = it2->m_offs + it2->m_length;
Shinya Kitaoka 120a6e
    it2++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  assert(lastOccupiedPos < m_offsetTablePos);
Shinya Kitaoka 120a6e
  if (lastOccupiedPos + 1 < m_offsetTablePos)
Shinya Kitaoka 120a6e
    m_freeChunks.insert(
Shinya Kitaoka 120a6e
        TzlChunk(lastOccupiedPos + 1, m_offsetTablePos - lastOccupiedPos));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TLevelWriterTzl
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TLevelWriterTzl::TLevelWriterTzl(const TFilePath &path, TPropertyGroup *info)
Shinya Kitaoka 120a6e
    : TLevelWriter(path, info)
Shinya Kitaoka 120a6e
    , m_headerWritten(false)
Shinya Kitaoka 120a6e
    , m_creatorWritten(false)
Shinya Kitaoka 120a6e
    , m_chan(0)
Shinya Kitaoka 120a6e
    , m_frameCountPos(0)
Shinya Kitaoka 120a6e
    , m_frameCount(0)
Shinya Kitaoka 120a6e
    , m_palette(0)
Shinya Kitaoka 120a6e
    , m_res(0, 0)
Shinya Kitaoka 120a6e
    , m_exists(false)
Shinya Kitaoka 120a6e
    , m_version(CURRENT_VERSION)
Shinya Kitaoka 120a6e
    , m_updatedIconsSize(false)
Shinya Kitaoka 120a6e
    , m_currentIconSize(0, 0)
Shinya Kitaoka 120a6e
    , m_iconSize(TDimension(80, 60))
Shinya Kitaoka 120a6e
    , m_userIconSize(TDimension(80, 60))
Shinya Kitaoka 120a6e
    , m_adjustRatio(false)
Shinya Kitaoka 120a6e
    , m_codec(new TRasterCodecLZO("LZO", true))
Shinya Kitaoka 120a6e
    , m_overwritePaletteFlag(true) {
Shinya Kitaoka 120a6e
  m_path        = path;
Shinya Kitaoka 120a6e
  m_palettePath = path.withNoFrame().withType("tpl");
Shinya Kitaoka 120a6e
  TFileStatus fs(path);
Shinya Kitaoka 120a6e
  m_magic     = "TLV14B1a";  // actual version
Shinya Kitaoka 120a6e
  erasedFrame = false;
Shinya Kitaoka 120a6e
  // version TLV10B1a: first version
Shinya Kitaoka 120a6e
  // version TLV11B1a: added frameIds
Shinya Kitaoka 120a6e
  // version TLV12B1a: incremental writings
Shinya Kitaoka 120a6e
  // version TLV13B1a: added thumbnails
Shinya Kitaoka 120a6e
  // version TLV15B1a: add creator string (fixed size = CREATOR_LENGTH char)
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (fs.doesExist()) {
Shinya Kitaoka 120a6e
    // if (!fs.isWritable())
Shinya Kitaoka 120a6e
    m_chan = fopen(path, "rb+");
Shinya Kitaoka 120a6e
    /*--- ่ชฐใ‹ใŒ้–‹ใ„ใฆใ„ใ‚‹ใ€ใพใŸใฏๆจฉ้™ใŒ็„กใ„ใจใ ---*/
Shinya Kitaoka 120a6e
    if (!m_chan) {
Shinya Kitaoka 120a6e
      throw TSystemException(path, "can't fopen.");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    /*--- TLVใƒ•ใ‚กใ‚คใƒซใฎใƒ˜ใƒƒใƒ€ใŒๆญฃใ—ใ่ชญใ‚ใชใ‹ใฃใŸๅ ดๅˆ ---*/
Shinya Kitaoka 120a6e
    if (!readHeaderAndOffsets(m_chan, m_frameOffsTable, m_iconOffsTable, m_res,
Shinya Kitaoka 120a6e
                              m_version, m_creator, &m_frameCount,
Shinya Kitaoka 120a6e
                              &m_offsetTablePos, &m_iconOffsetTablePos, 0)) {
Shinya Kitaoka 120a6e
      throw TSystemException(path, "can't readHeaderAndOffsets.");
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      if (m_version >= 12) buildFreeChunksTable();
Shinya Kitaoka 120a6e
      m_headerWritten = true;
Shinya Kitaoka 120a6e
      m_exists        = true;
Shinya Kitaoka 120a6e
      if (m_version == 14)
Shinya Kitaoka 120a6e
        m_frameCountPos = 8 + CREATOR_LENGTH + 3 * sizeof(TINT32);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        m_frameCountPos = 8 + 3 * sizeof(TINT32);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!m_exists) {
Shinya Kitaoka 120a6e
    TFilePath parentDir = path.getParentDir();
Shinya Kitaoka 120a6e
    if (!TFileStatus(parentDir).doesExist()) {
Shinya Kitaoka 120a6e
      try {
Shinya Kitaoka 120a6e
        TSystem::mkDir(parentDir);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
      } catch (...) {
Shinya Kitaoka 120a6e
        return;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_chan = fopen(path, "wb");
Shinya Kitaoka 120a6e
    if (!m_chan) return;
Shinya Kitaoka 120a6e
    if (!writeVersionAndCreator(m_chan, m_magic, m_creator)) return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TLevelWriterTzl::~TLevelWriterTzl() {
Shinya Kitaoka 120a6e
  if (m_version < CURRENT_VERSION) {
Shinya Kitaoka 120a6e
    if (!convertToLatestVersion()) return;
Shinya Kitaoka 120a6e
    assert(m_version == CURRENT_VERSION);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  delete m_codec;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TINT32 offsetMapPos     = 0;
Shinya Kitaoka 120a6e
  TINT32 iconOffsetMapPos = 0;
Shinya Kitaoka 120a6e
  if (!m_chan) return;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  assert(m_frameCount == (int)m_frameOffsTable.size());
Shinya Kitaoka 120a6e
  assert(m_frameCount == (int)m_iconOffsTable.size());
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  offsetMapPos = (m_exists ? m_offsetTablePos : ftell(m_chan));
Shinya Kitaoka 120a6e
  fseek(m_chan, offsetMapPos, SEEK_SET);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator it = m_frameOffsTable.begin();
Shinya Kitaoka 120a6e
  for (; it != m_frameOffsTable.end(); ++it) {
Shinya Kitaoka 120a6e
    TFrameId fid  = it->first;
Shinya Kitaoka 120a6e
    TINT32 num    = fid.getNumber();
Shinya Kitaoka 120a6e
    char letter   = fid.getLetter();
Shinya Kitaoka 120a6e
    TINT32 offs   = it->second.m_offs;
Shinya Kitaoka 120a6e
    TINT32 length = it->second.m_length;
Shinya Kitaoka 120a6e
    tfwrite(&num, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&letter, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&offs, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&length, 1, m_chan);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // Write Icon Offset Table after frameOffsTable
Shinya Kitaoka 120a6e
  iconOffsetMapPos =
Shinya Kitaoka 120a6e
      ftell(m_chan);  //(m_exists?m_iconOffsetTablePos: ftell(m_chan));
Shinya Kitaoka 120a6e
  fseek(m_chan, iconOffsetMapPos, SEEK_SET);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator iconIt = m_iconOffsTable.begin();
Shinya Kitaoka 120a6e
  for (; iconIt != m_iconOffsTable.end(); ++iconIt) {
Shinya Kitaoka 120a6e
    TFrameId fid           = iconIt->first;
Shinya Kitaoka 120a6e
    TINT32 num             = fid.getNumber();
Shinya Kitaoka 120a6e
    char letter            = fid.getLetter();
Shinya Kitaoka 120a6e
    TINT32 thumbnailOffs   = iconIt->second.m_offs;
Shinya Kitaoka 120a6e
    TINT32 thumbnailLength = iconIt->second.m_length;
Shinya Kitaoka 120a6e
    tfwrite(&num, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&letter, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&thumbnailOffs, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&thumbnailLength, 1, m_chan);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  fseek(m_chan, m_frameCountPos, SEEK_SET);
Shinya Kitaoka 120a6e
  TINT32 frameCount = m_frameCount;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  tfwrite(&frameCount, 1, m_chan);
Shinya Kitaoka 120a6e
  tfwrite(&offsetMapPos, 1, m_chan);
Shinya Kitaoka 120a6e
  tfwrite(&iconOffsetMapPos, 1, m_chan);
Shinya Kitaoka 120a6e
  fclose(m_chan);
Shinya Kitaoka 120a6e
  m_chan = 0;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (m_palette && m_overwritePaletteFlag &&
Shinya Kitaoka 120a6e
      (m_palette->getDirtyFlag() ||
Shinya Kitaoka 120a6e
       !TSystem::doesExistFileOrLevel(m_palettePath))) {
Shinya Kitaoka 120a6e
    TOStream os(m_palettePath);
Shinya Kitaoka 120a6e
    os << m_palette;
Shinya Kitaoka 120a6e
    m_palette->release();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (m_contentHistory) {
Shinya Kitaoka 120a6e
    TFilePath historyFp = m_path.withNoFrame().withType("hst");
Shinya Kitaoka 120a6e
    FILE *historyChan   = fopen(historyFp, "w");
Shinya Kitaoka 120a6e
    if (historyChan) {
Shinya Kitaoka 120a6e
      std::string historyData = m_contentHistory->serialize().toStdString();
Shinya Kitaoka 120a6e
      fwrite(&historyData[0], 1, historyData.length(), historyChan);
Shinya Kitaoka 120a6e
      fclose(historyChan);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // Se lo spazio libero (cioรจ la somma di tutti i buchi che si sono creati tra
Shinya Kitaoka 120a6e
  // i frame)
Shinya Kitaoka 120a6e
  // รจ maggiore di una certa soglia oppure รจ stato rimosso almeno un frame
Shinya Kitaoka 120a6e
  // allora ottimizzo il file
Shinya Kitaoka 120a6e
  // (in pratica risalvo il file da capo senza buchi).
Shinya Kitaoka 120a6e
  if (getFreeSpace() > 0.3 || erasedFrame) optimize();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TImageWriterP TLevelWriterTzl::getFrameWriter(TFrameId fid) {
Shinya Kitaoka 120a6e
  return new TImageWriterTzl(this, fid);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
void TLevelWriterTzl::writeHeader(const TDimension &size) {
Shinya Kitaoka 120a6e
  m_headerWritten   = true;
Shinya Kitaoka 120a6e
  const char *codec = "LZO ";
Shinya Kitaoka 120a6e
  int codecLen      = strlen(codec);
Shinya Kitaoka 120a6e
  TINT32 hdrSize    = 3 * sizeof(TINT32) + codecLen;
Shinya Kitaoka 120a6e
  TINT32 lx = size.lx, ly = size.ly, intval = 1;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  tfwrite(&hdrSize, 1, m_chan);
Shinya Kitaoka 120a6e
  tfwrite(&lx, 1, m_chan);
Shinya Kitaoka 120a6e
  tfwrite(&ly, 1, m_chan);
Shinya Kitaoka 120a6e
  m_frameCountPos = ftell(m_chan);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  assert(m_frameCountPos == 8 + CREATOR_LENGTH + 3 * sizeof(TINT32));
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // I put the place for the frameCount, which I will write in this position at
Shinya Kitaoka 120a6e
  // the end  (see in the distructor)
Shinya Kitaoka 120a6e
  tfwrite(&intval, 1, m_chan);
Shinya Kitaoka 120a6e
  // I put the place for the offsetTableOffset, which I will write in this
Shinya Kitaoka 120a6e
  // position at the end  (see in the distructor)
Shinya Kitaoka 120a6e
  intval = 0;
Shinya Kitaoka 120a6e
  tfwrite(&intval, 1, m_chan);
Shinya Kitaoka 120a6e
  // I put the place for the iconOffsetTableOffset, which I will write in this
Shinya Kitaoka 120a6e
  // position at the end  (see in the distructor)
Shinya Kitaoka 120a6e
  tfwrite(&intval, 1, m_chan);
Shinya Kitaoka 120a6e
  tfwrite(codec, codecLen, m_chan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
void TLevelWriterTzl::addFreeChunk(TINT32 offs, TINT32 length) {
Shinya Kitaoka 120a6e
  std::set<tzlchunk>::iterator it = m_freeChunks.begin();
</tzlchunk>
Shinya Kitaoka 120a6e
  while (it != m_freeChunks.end()) {
Shinya Kitaoka 120a6e
    // if (it->m_offs>offs+length+1)
Shinya Kitaoka 120a6e
    //  break;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    if (it->m_offs + it->m_length == offs)  // accorpo due chunks in uno
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      TzlChunk chunk(it->m_offs, it->m_length + length);
Shinya Kitaoka 120a6e
      m_freeChunks.erase(it);
Shinya Kitaoka 120a6e
      m_freeChunks.insert(chunk);
Shinya Kitaoka 120a6e
      // it->m_length += length;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (offs + length == it->m_offs) {
Shinya Kitaoka 120a6e
      TzlChunk chunk(offs, it->m_length + length);
Shinya Kitaoka 120a6e
      m_freeChunks.erase(it);
Shinya Kitaoka 120a6e
      m_freeChunks.insert(chunk);
Shinya Kitaoka 120a6e
      // it->m_offs = offs;
Shinya Kitaoka 120a6e
      // it->m_length += length;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    it++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (it == m_freeChunks.end()) m_freeChunks.insert(TzlChunk(offs, length));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TINT32 TLevelWriterTzl::findSavingChunk(const TFrameId &fid, TINT32 length,
Shinya Kitaoka 120a6e
                                        bool isIcon) {
Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator it;
Shinya Kitaoka 120a6e
  // prima libero il chunk del fid, se c'e'. accorpo con altro chunk se trovo
Shinya Kitaoka 120a6e
  // uno contiguo.
Shinya Kitaoka 120a6e
  if (!isIcon) {
Shinya Kitaoka 120a6e
    if ((it = m_frameOffsTable.find(fid)) != m_frameOffsTable.end()) {
Shinya Kitaoka 120a6e
      addFreeChunk(it->second.m_offs, it->second.m_length);
Shinya Kitaoka 120a6e
      m_frameOffsTable.erase(it);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      m_frameCount++;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if ((it = m_iconOffsTable.find(fid)) != m_iconOffsTable.end()) {
Shinya Kitaoka 120a6e
      addFreeChunk(it->second.m_offs, it->second.m_length);
Shinya Kitaoka 120a6e
      m_iconOffsTable.erase(it);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // ora cerco un cioncone libero con la piu' piccola memoria sufficiente
Shinya Kitaoka 120a6e
  std::set<tzlchunk>::iterator it1   = m_freeChunks.begin(),
</tzlchunk>
Shinya Kitaoka 120a6e
                               found = m_freeChunks.end();
Shinya Kitaoka 120a6e
  for (; it1 != m_freeChunks.end(); it1++) {
Shinya Kitaoka 120a6e
    //   TINT32 _length = it1->m_length;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    if (it1->m_length >= length &&
Shinya Kitaoka 120a6e
        (found == m_freeChunks.end() || found->m_length > it1->m_length))
Shinya Kitaoka 120a6e
      found = it1;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (found != m_freeChunks.end()) {
Shinya Kitaoka 120a6e
    //  TINT32 _length = found->m_length;
Shinya Kitaoka 120a6e
    TINT32 _offset = found->m_offs;
Shinya Kitaoka 120a6e
    if (found->m_length > length) {
Shinya Kitaoka 120a6e
      TzlChunk chunk(found->m_offs + length, found->m_length - length);
Shinya Kitaoka 120a6e
      m_freeChunks.insert(chunk);
Shinya Kitaoka 120a6e
      // found->m_offs+=length;
Shinya Kitaoka 120a6e
      // found->m_length-=length;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      assert(found->m_length == length);
Shinya Kitaoka 120a6e
    m_freeChunks.erase(found);
Shinya Kitaoka 120a6e
    return _offset;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    m_offsetTablePos += length;
Shinya Kitaoka 120a6e
    return m_offsetTablePos - length;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Shinya Kitaoka 120a6e
bool TLevelWriterTzl::convertToLatestVersion() {
Shinya Kitaoka 120a6e
  TFileStatus fs(m_path);
Shinya Kitaoka 120a6e
  // se il file รจ di una versione precedente deve necessariamente giร  esistere
Shinya Kitaoka 120a6e
  // su disco
Shinya Kitaoka 120a6e
  assert(fs.doesExist());
Shinya Kitaoka 120a6e
  if (!fs.doesExist()) return false;
Shinya Kitaoka 120a6e
  m_exists         = false;
Shinya Kitaoka 120a6e
  m_frameCount     = 0;
Shinya Kitaoka 120a6e
  m_frameOffsTable = TzlOffsetMap();
Shinya Kitaoka 120a6e
  m_iconOffsTable  = TzlOffsetMap();
Shinya Kitaoka 120a6e
  m_headerWritten  = false;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  fclose(m_chan);
Shinya Kitaoka 120a6e
  m_chan = 0;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  std::string tempName = "~" + m_path.getName() + "tmp&.tlv";
Shinya Kitaoka 120a6e
  TFilePath tempPath   = TSystem::getTempDir() + tempName;
Shinya Kitaoka 120a6e
  if (TSystem::doesExistFileOrLevel(m_path)) {
Shinya Kitaoka 120a6e
    assert(m_path != tempPath);
Shinya Kitaoka 120a6e
    if (TSystem::doesExistFileOrLevel(tempPath)) TSystem::deleteFile(tempPath);
Shinya Kitaoka 120a6e
    TSystem::copyFile(tempPath, m_path);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  m_chan = fopen(m_path, "rb+");
Shinya Kitaoka 120a6e
  if (!m_chan) return false;
Shinya Kitaoka 120a6e
  if (!writeVersionAndCreator(m_chan, m_magic, m_creator)) return false;
Shinya Kitaoka 120a6e
  m_creatorWritten = true;
Shinya Kitaoka 120a6e
  m_version        = CURRENT_VERSION;
Shinya Kitaoka 120a6e
  TLevelReaderP lr(tempPath);
Shinya Kitaoka 120a6e
  if (!lr) return false;
Shinya Kitaoka 120a6e
  TLevelP level = lr->loadInfo();
Shinya Kitaoka 120a6e
  for (TLevel::Iterator it = level->begin(); it != level->end(); ++it) {
Shinya Kitaoka 120a6e
    save(lr->getFrameReader(it->first)->load(), it->first);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  lr = TLevelReaderP();
Shinya Kitaoka 120a6e
  if (TSystem::doesExistFileOrLevel(tempPath)) {
Shinya Kitaoka 120a6e
    TSystem::deleteFile(tempPath);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TINT32 offsetMapPos     = 0;
Shinya Kitaoka 120a6e
  TINT32 iconOffsetMapPos = 0;
Shinya Kitaoka 120a6e
  if (!m_chan) return false;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  assert(m_frameCount == (int)m_frameOffsTable.size());
Shinya Kitaoka 120a6e
  assert(m_frameCount == (int)m_iconOffsTable.size());
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  offsetMapPos = (m_exists ? m_offsetTablePos : ftell(m_chan));
Shinya Kitaoka 120a6e
  fseek(m_chan, offsetMapPos, SEEK_SET);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator it2 = m_frameOffsTable.begin();
Shinya Kitaoka 120a6e
  for (; it2 != m_frameOffsTable.end(); ++it2) {
Shinya Kitaoka 120a6e
    TFrameId fid  = it2->first;
Shinya Kitaoka 120a6e
    TINT32 num    = fid.getNumber();
Shinya Kitaoka 120a6e
    char letter   = fid.getLetter();
Shinya Kitaoka 120a6e
    TINT32 offs   = it2->second.m_offs;
Shinya Kitaoka 120a6e
    TINT32 length = it2->second.m_length;
Shinya Kitaoka 120a6e
    tfwrite(&num, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&letter, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&offs, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&length, 1, m_chan);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  iconOffsetMapPos = ftell(m_chan);
Shinya Kitaoka 120a6e
  fseek(m_chan, iconOffsetMapPos, SEEK_SET);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator iconIt = m_iconOffsTable.begin();
Shinya Kitaoka 120a6e
  for (; iconIt != m_iconOffsTable.end(); ++iconIt) {
Shinya Kitaoka 120a6e
    TFrameId fid           = iconIt->first;
Shinya Kitaoka 120a6e
    TINT32 num             = fid.getNumber();
Shinya Kitaoka 120a6e
    char letter            = fid.getLetter();
Shinya Kitaoka 120a6e
    TINT32 thumbnailOffs   = iconIt->second.m_offs;
Shinya Kitaoka 120a6e
    TINT32 thumbnailLength = iconIt->second.m_length;
Shinya Kitaoka 120a6e
    tfwrite(&num, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&letter, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&thumbnailOffs, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&thumbnailLength, 1, m_chan);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  fseek(m_chan, m_frameCountPos, SEEK_SET);
Shinya Kitaoka 120a6e
  TINT32 frameCount = m_frameCount;
Shinya Kitaoka 120a6e
  tfwrite(&frameCount, 1, m_chan);
Shinya Kitaoka 120a6e
  tfwrite(&offsetMapPos, 1, m_chan);
Shinya Kitaoka 120a6e
  tfwrite(&iconOffsetMapPos, 1, m_chan);
Shinya Kitaoka 120a6e
  m_frameOffsTable = TzlOffsetMap();
Shinya Kitaoka 120a6e
  m_iconOffsTable  = TzlOffsetMap();
Shinya Kitaoka 120a6e
  m_frameCount     = 0;
Shinya Kitaoka 120a6e
  m_res            = TDimension();
Shinya Kitaoka 120a6e
  fclose(m_chan);
Shinya Kitaoka 120a6e
  m_chan = 0;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (m_palette && (m_palette->getDirtyFlag() ||
Shinya Kitaoka 120a6e
                    !TSystem::doesExistFileOrLevel(m_palettePath))) {
Shinya Kitaoka 120a6e
    TOStream os(m_palettePath);
Shinya Kitaoka 120a6e
    os << m_palette;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // else
Shinya Kitaoka 120a6e
  //	m_palette = 0;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  m_chan = fopen(m_path, "rb+");
Shinya Kitaoka 120a6e
  if (!m_chan) return false;
Shinya Kitaoka 120a6e
  if (!readHeaderAndOffsets(m_chan, m_frameOffsTable, m_iconOffsTable, m_res,
Shinya Kitaoka 120a6e
                            m_version, m_creator, &m_frameCount,
Shinya Kitaoka 120a6e
                            &m_offsetTablePos, &m_iconOffsetTablePos, 0))
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  m_freeChunks.clear();
Shinya Kitaoka 120a6e
  buildFreeChunksTable();
Shinya Kitaoka 120a6e
  m_headerWritten = true;
Shinya Kitaoka 120a6e
  m_exists        = true;
Shinya Kitaoka 120a6e
  m_frameCountPos = 8 + CREATOR_LENGTH + 3 * sizeof(TINT32);
Shinya Kitaoka 120a6e
  assert(m_version == CURRENT_VERSION);
Shinya Kitaoka 120a6e
  if (!m_renumberTable.empty()) renumberFids(m_renumberTable);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Shinya Kitaoka 120a6e
void TLevelWriterTzl::saveImage(const TImageP &img, const TFrameId &_fid,
Shinya Kitaoka 120a6e
                                bool isIcon) {
Shinya Kitaoka 120a6e
  TFrameId fid = _fid;
Shinya Kitaoka 120a6e
  if (!m_chan) return;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // se il file รจ di una versione precedente allora lo converto prima
Shinya Kitaoka 120a6e
  if (m_version < CURRENT_VERSION) {
Shinya Kitaoka 120a6e
    if (!convertToLatestVersion()) return;
Shinya Kitaoka 120a6e
    assert(m_version == CURRENT_VERSION);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (!m_updatedIconsSize && m_exists)
Shinya Kitaoka 120a6e
    m_updatedIconsSize = checkIconSize(getIconSize());
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TToonzImageP ti = img;
Shinya Kitaoka 120a6e
  if (!ti) return;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (!m_palette) {
Shinya Kitaoka 120a6e
    m_palette = ti->getPalette();
Shinya Kitaoka 120a6e
    if (m_palette) m_palette->addRef();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (!m_creatorWritten) {
Shinya Kitaoka 120a6e
    fseek(m_chan, 0, SEEK_SET);
Shinya Kitaoka 120a6e
    writeVersionAndCreator(m_chan, m_magic, m_creator);
Shinya Kitaoka 120a6e
    m_creatorWritten = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!m_headerWritten) writeHeader(ti->getSize());
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (m_res != TDimension())
Shinya Kitaoka 120a6e
    if (!isIcon)
Shinya Kitaoka 120a6e
      assert(m_res == ti->getSize());
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      assert(getIconSize() == ti->getSize());
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_res = ti->getSize();
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TRect sb = ti->getSavebox();
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TINT32 sbx0 = sb.x0, sby0 = sb.y0, sblx = sb.getLx(), sbly = sb.getLy();
Shinya Kitaoka 120a6e
  TINT32 buffSize = 0;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  UCHAR *buff = 0;  //  = ti->getCompressedBuffer(buffSize);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TRasterP cmras = ti->getRaster();
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  assert(cmras);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (cmras->getBounds() != sb) {
Shinya Kitaoka 120a6e
    TRect rectToExtract = sb;
Shinya Kitaoka 120a6e
    if (!rectToExtract.isEmpty()) {
Shinya Kitaoka 120a6e
      TRasterP smallRaster = cmras->extract(rectToExtract)->clone();
Shinya Kitaoka 120a6e
      assert(rectToExtract == sb);
Shinya Kitaoka 120a6e
      cmras = smallRaster;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      cmras = cmras->create(1, 1);
Shinya Kitaoka 120a6e
      cmras->clear();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TRasterGR8P rCompressed = m_codec->compress(cmras, 1, buffSize);
Shinya Kitaoka 120a6e
  if (rCompressed == TRasterGR8P()) {
Shinya Kitaoka 120a6e
    static bool firstTime = true;
Shinya Kitaoka 120a6e
    if (firstTime) {
Shinya Kitaoka 120a6e
      firstTime = false;
Shinya Kitaoka 120a6e
      // MessageBox( NULL, "Cannot save level, out of memory!", "Warning!",
Shinya Kitaoka 120a6e
      // MB_OK);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  rCompressed->lock();
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  buffSize = rCompressed->getLx();
Shinya Kitaoka 120a6e
  buff     = rCompressed->getRawData();
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  assert(buffSize);
Shinya Kitaoka 120a6e
  assert(buff);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  Header *header = (Header *)buff;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TRasterP ras;
Shinya Kitaoka 120a6e
  m_codec->decompress(buff, buffSize, ras);
Shinya Kitaoka 120a6e
  delete[] buff;
Shinya Kitaoka 120a6e
  assert((TRasterCM32P)ras);
Shinya Kitaoka 120a6e
  assert(ras->getLx() == header->m_lx);
Shinya Kitaoka 120a6e
  assert(ras->getLy() == header->m_ly);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  for (int y = 0; y < ras->getLy(); ++y) {
Shinya Kitaoka 120a6e
    ras->lock();
Shinya Kitaoka 120a6e
    TINT32 *pix    = ((TINT32 *)ras->getRawData()) + y * ras->getLx();
Shinya Kitaoka 120a6e
    TINT32 *endPix = pix + ras->getLx();
Shinya Kitaoka 120a6e
    while (pix < endPix) {
Shinya Kitaoka 120a6e
      *pix = swapTINT32(*pix);
Shinya Kitaoka 120a6e
      pix++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    ras->unlock();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  rCompressed = m_codec->compress(ras, 1, buffSize);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  header = (Header *)buff;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  header->m_lx      = swapTINT32(header->m_lx);
Shinya Kitaoka 120a6e
  header->m_ly      = swapTINT32(header->m_ly);
Shinya Kitaoka 120a6e
  header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  double xdpi = 1, ydpi = 1;
Shinya Kitaoka 120a6e
  ti->getDpi(xdpi, ydpi);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TINT32 theBuffSize = buffSize;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TINT32 length = 0;
Shinya Kitaoka 120a6e
  if (!isIcon)
Shinya Kitaoka 120a6e
    length = 5 * sizeof(TINT32) + 2 * sizeof(double) + theBuffSize;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    length = 3 * sizeof(TINT32) + theBuffSize;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (fid == TFrameId()) {
Shinya Kitaoka 120a6e
    assert(!m_exists);
Shinya Kitaoka 120a6e
    if (m_frameOffsTable.empty())
Shinya Kitaoka 120a6e
      fid = (m_frameOffsTable.empty())
Shinya Kitaoka 120a6e
                ? TFrameId(1, 0)
Shinya Kitaoka 120a6e
                : TFrameId(m_frameOffsTable.rbegin()->first.getNumber() + 1, 0);
Shinya Kitaoka 120a6e
    if (m_iconOffsTable.empty())
Shinya Kitaoka 120a6e
      fid = (m_iconOffsTable.empty())
Shinya Kitaoka 120a6e
                ? TFrameId(1, 0)
Shinya Kitaoka 120a6e
                : TFrameId(m_iconOffsTable.rbegin()->first.getNumber() + 1, 0);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (!m_exists) {
Shinya Kitaoka 120a6e
    long offs = ftell(m_chan);
Shinya Kitaoka 120a6e
    if (!isIcon) {
Shinya Kitaoka 120a6e
      m_frameOffsTable[fid] = TzlChunk(offs, length);
Shinya Kitaoka 120a6e
      m_frameCount++;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      m_iconOffsTable[fid] = TzlChunk(offs, length);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    long frameOffset = findSavingChunk(fid, length, isIcon);
Shinya Kitaoka 120a6e
    if (!isIcon)
Shinya Kitaoka 120a6e
      m_frameOffsTable[fid] = TzlChunk(frameOffset, length);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_iconOffsTable[fid] = TzlChunk(frameOffset, length);
Shinya Kitaoka 120a6e
    fseek(m_chan, frameOffset, SEEK_SET);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!isIcon) {
Shinya Kitaoka 120a6e
    tfwrite(&sbx0, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&sby0, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&sblx, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&sbly, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&buffSize, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&xdpi, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&ydpi, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(buff, theBuffSize, m_chan);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    TINT32 iconLx = getIconSize().lx;
Shinya Kitaoka 120a6e
    TINT32 iconLy = getIconSize().ly;
Shinya Kitaoka 120a6e
    tfwrite(&iconLx, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&iconLy, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(&buffSize, 1, m_chan);
Shinya Kitaoka 120a6e
    tfwrite(buff, theBuffSize, m_chan);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  rCompressed->unlock();
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  //#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
  // delete [] buff;
Shinya Kitaoka 120a6e
  //#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
void TLevelWriterTzl::doSave(const TImageP &img, const TFrameId &_fid) {
Shinya Kitaoka 120a6e
  // salvo l'immagine grande
Shinya Kitaoka 120a6e
  saveImage(img, _fid);
Shinya Kitaoka 120a6e
  if (!img)
Shinya Kitaoka 120a6e
    throw(TException(
Shinya Kitaoka 120a6e
        "Saving tlv: it is not possible to create the image frame."));
Shinya Kitaoka 120a6e
  // creo l'iconcina
Shinya Kitaoka 120a6e
  TImageP icon = TImageP();
Shinya Kitaoka 120a6e
  createIcon(img, icon);
Shinya Kitaoka 120a6e
  assert(icon);
Shinya Kitaoka 120a6e
  if (!icon)
Shinya Kitaoka 120a6e
    throw(
Shinya Kitaoka 120a6e
        TException("Saving tlv: it is not possible to create the image icon."));
Shinya Kitaoka 120a6e
  // salvo l'iconcina
Shinya Kitaoka 120a6e
  saveImage(icon, _fid, true);
Shinya Kitaoka 120a6e
  return;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Shinya Kitaoka 120a6e
void TLevelWriterTzl::save(const TImageP &img, const TFrameId &fid) {
Shinya Kitaoka 120a6e
  doSave(img, fid);
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
void TLevelWriterTzl::save(const TImageP &img) { doSave(img, TFrameId()); }
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Shinya Kitaoka 120a6e
void TLevelWriterTzl::saveIcon(const TImageP &img, const TFrameId &fid) {
Shinya Kitaoka 120a6e
  // salvo su file come icona
Shinya Kitaoka 120a6e
  saveImage(img, fid, true);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
void TLevelWriterTzl::setPalette(TPalette *palette) {
Shinya Kitaoka 120a6e
  if (!m_palette) {
Shinya Kitaoka 120a6e
    m_palette = palette;
Shinya Kitaoka 120a6e
    m_palette->addRef();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Shinya Kitaoka 120a6e
void TLevelWriterTzl::renumberFids(
Shinya Kitaoka 120a6e
    const std::map<tframeid, tframeid=""> &renumberTable) {
</tframeid,>
Shinya Kitaoka 120a6e
  m_renumberTable = renumberTable;
Shinya Kitaoka 120a6e
  if (m_version < 13) return;
Shinya Kitaoka 120a6e
  if (m_frameOffsTable.empty() || !m_exists) return;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // Rimozione dei frame non presenti nella prima colonna di renumberTable
Shinya Kitaoka 120a6e
  std::map<tframeid, tzlchunk=""> frameOffsTableTemp;
</tframeid,>
Shinya Kitaoka 120a6e
  frameOffsTableTemp        = m_frameOffsTable;
Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator it = frameOffsTableTemp.begin();
Shinya Kitaoka 120a6e
  while (it != frameOffsTableTemp.end()) {
Shinya Kitaoka 120a6e
    TFrameId fid = it->first;
Shinya Kitaoka 120a6e
    std::map<tframeid, tframeid="">::const_iterator it2 = renumberTable.find(fid);
</tframeid,>
Shinya Kitaoka 120a6e
    if (it2 == renumberTable.end()) remove(fid);
Shinya Kitaoka 120a6e
    it++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  std::map<tframeid, tzlchunk=""> frameOffsTable, iconOffsTable;
</tframeid,>
Shinya Kitaoka 120a6e
  // Renumber Frame
Shinya Kitaoka 120a6e
  std::map<tframeid, tframeid="">::const_iterator it3 = renumberTable.begin();
</tframeid,>
Shinya Kitaoka 120a6e
  while (it3 != renumberTable.end()) {
Shinya Kitaoka 120a6e
    TFrameId fidToRenumber        = it3->first;
Shinya Kitaoka 120a6e
    TzlOffsetMap::iterator it     = m_frameOffsTable.find(fidToRenumber);
Shinya Kitaoka 120a6e
    TzlOffsetMap::iterator iconIt = m_iconOffsTable.find(fidToRenumber);
Shinya Kitaoka 120a6e
    if (it != m_frameOffsTable.end()) frameOffsTable[it3->second] = it->second;
Shinya Kitaoka 120a6e
    if (m_iconOffsTable.size() > 0 && iconIt != m_iconOffsTable.end())
Shinya Kitaoka 120a6e
      iconOffsTable[it3->second] = iconIt->second;
Shinya Kitaoka 120a6e
    it3++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  m_frameOffsTable.clear();
Shinya Kitaoka 120a6e
  m_frameOffsTable = frameOffsTable;
Shinya Kitaoka 120a6e
  m_iconOffsTable.clear();
Shinya Kitaoka 120a6e
  m_iconOffsTable = iconOffsTable;
Shinya Kitaoka 120a6e
  m_frameCount    = m_frameOffsTable.size();
Shinya Kitaoka 120a6e
  // buildFreeChunksTable();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
void TLevelWriterTzl::createIcon(const TImageP &imgIn, TImageP &imgOut) {
Shinya Kitaoka 120a6e
  // Creo iconcina e poi la salvo
Shinya Kitaoka 120a6e
  TToonzImageP ti = imgIn;
Shinya Kitaoka 120a6e
  if (!ti) return;
Shinya Kitaoka 120a6e
  TRect sb    = ti->getSavebox();
Shinya Kitaoka 120a6e
  TINT32 sbx0 = sb.x0, sby0 = sb.y0, sblx = sb.getLx(), sbly = sb.getLy();
Shinya Kitaoka 120a6e
  TRasterP cmras = ti->getRaster();
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  assert(m_iconSize.lx > 0 && m_iconSize.ly > 0);
Shinya Kitaoka 120a6e
  if (m_iconSize.lx <= 0 || m_iconSize.ly <= 0) return;
Shinya Kitaoka 120a6e
  TINT32 iconLx = m_iconSize.lx, iconLy = m_iconSize.ly;
Shinya Kitaoka 120a6e
  if (cmras->getLx() <= iconLx && cmras->getLy() <= iconLy) {
Shinya Kitaoka 120a6e
    iconLx     = cmras->getLx();
Shinya Kitaoka 120a6e
    iconLy     = cmras->getLy();
Shinya Kitaoka 120a6e
    m_iconSize = TDimension(iconLx, iconLy);
Shinya Kitaoka 120a6e
    imgOut     = imgIn;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TRasterCM32P thumbnailRas(iconLx, iconLy);
Shinya Kitaoka 120a6e
  if (iconLx > 0 && iconLy > 0) {
Shinya Kitaoka 120a6e
    // Do thumbnail
Shinya Kitaoka 120a6e
    TRop::makeIcon(thumbnailRas, TRasterCM32P(cmras));
Shinya Kitaoka 120a6e
    assert(thumbnailRas);
Shinya Kitaoka 120a6e
    if (!thumbnailRas) return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // Compute savebox
Shinya Kitaoka 120a6e
  if (ti->getSize().lx <= 0 || ti->getSize().ly <= 0) return;
Shinya Kitaoka 120a6e
  TRect tmp_savebox;
Shinya Kitaoka 120a6e
  TRect savebox;
Shinya Kitaoka 120a6e
  TRop::computeBBox(thumbnailRas, tmp_savebox);
Shinya Kitaoka 120a6e
  if (tmp_savebox.isEmpty()) {
Shinya Kitaoka 120a6e
    TINT32 iconsbx0 = tround((double)iconLx * sbx0 / ti->getSize().lx);
Shinya Kitaoka 120a6e
    TINT32 iconsby0 = tround((double)iconLy * sby0 / ti->getSize().ly);
Shinya Kitaoka 120a6e
    TINT32 iconsblx =
Shinya Kitaoka 120a6e
        std::max(tround((double)iconLx * sblx / ti->getSize().lx), 1);
Shinya Kitaoka 120a6e
    TINT32 iconsbly =
Shinya Kitaoka 120a6e
        std::max(tround((double)iconLy * sbly / ti->getSize().ly), 1);
Shinya Kitaoka 120a6e
    savebox = TRect(TPoint(iconsbx0, iconsby0), TDimension(iconsblx, iconsbly));
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    savebox = tmp_savebox;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (!TRect(m_iconSize).contains(savebox))  // it should be better to use
Shinya Kitaoka 120a6e
                                             // tfloor instead of tround in the
Shinya Kitaoka 120a6e
                                             // previous lines:
Shinya Kitaoka 120a6e
    // sometimes, for rounding problems, the savebox is outside 1 pixel the
Shinya Kitaoka 120a6e
    // raster size.
Shinya Kitaoka 120a6e
    // the best solution should be to replace tround with tfloor here
Shinya Kitaoka 120a6e
    // and in the icon reading of tzl 1.4 (method load14),
Shinya Kitaoka 120a6e
    // but this way the old 1.4 tzl are not readed correctly (crash!)
Shinya Kitaoka 120a6e
    // so, this 'if' is a patch. vinz
Shinya Kitaoka 120a6e
    savebox = savebox * TRect(m_iconSize);
Shinya Kitaoka 120a6e
  thumbnailRas->clearOutside(savebox);
Shinya Kitaoka 120a6e
  TToonzImageP ticon(thumbnailRas, savebox);
Shinya Kitaoka 120a6e
  double xdpi = 1, ydpi = 1;
Shinya Kitaoka 120a6e
  ti->getDpi(xdpi, ydpi);
Shinya Kitaoka 120a6e
  ticon->setDpi(xdpi, ydpi);
Shinya Kitaoka 120a6e
  ticon->setPalette(ti->getPalette());
Shinya Kitaoka 120a6e
  imgOut = TImageP(ticon);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
void TLevelWriterTzl::remove(const TFrameId &fid) {
Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator it = m_frameOffsTable.find(fid);
Shinya Kitaoka 120a6e
  // se il fid non esiste non faccio nulla
Shinya Kitaoka 120a6e
  if (it == m_frameOffsTable.end()) return;
Shinya Kitaoka 120a6e
  // aggiungo spazio vuoto
Shinya Kitaoka 120a6e
  // m_freeChunks.insert(TzlChunk(it->second.m_offs, it->second.m_length));
Shinya Kitaoka 120a6e
  addFreeChunk(it->second.m_offs, it->second.m_length);
Shinya Kitaoka 120a6e
  // cancello l'immagine dalla tabella
Shinya Kitaoka 120a6e
  m_frameOffsTable.erase(it);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (m_iconOffsTable.size() > 0) {
Shinya Kitaoka 120a6e
    TzlOffsetMap::iterator iconIt = m_iconOffsTable.find(fid);
Shinya Kitaoka 120a6e
    // deve necessariamente esserci anche l'iconcina
Shinya Kitaoka 120a6e
    assert(iconIt != m_iconOffsTable.end());
Shinya Kitaoka 120a6e
    if (iconIt == m_iconOffsTable.end()) return;
Shinya Kitaoka 120a6e
    // aggiungo spazio vuoto
Shinya Kitaoka 120a6e
    // m_freeChunks.insert(TzlChunk(iconIt->second.m_offs,
Shinya Kitaoka 120a6e
    // iconIt->second.m_length));
Shinya Kitaoka 120a6e
    addFreeChunk(iconIt->second.m_offs, iconIt->second.m_length);
Shinya Kitaoka 120a6e
    // Cancello la relativa icona
Shinya Kitaoka 120a6e
    m_iconOffsTable.erase(iconIt);
Shinya Kitaoka 120a6e
    erasedFrame = true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
void TLevelWriterTzl::setIconSize(TDimension iconSize) {
Shinya Kitaoka 120a6e
  assert(iconSize.lx > 0 && iconSize.ly > 0);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  m_iconSize     = TDimension(iconSize.lx, iconSize.ly);
Shinya Kitaoka 120a6e
  m_userIconSize = TDimension(
Shinya Kitaoka 120a6e
      iconSize.lx, iconSize.ly);  // Used in TLevelWriterTzl::optimize().
Shinya Kitaoka 120a6e
                                  // Observe that m_iconSize may change below.
Shinya Kitaoka 120a6e
  if (m_version >= 13 && m_exists) {
Shinya Kitaoka 120a6e
    // A supported level file already exists at the specified path
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    // Check whether icons stored in the file already
Shinya Kitaoka 120a6e
    // have the required size
Shinya Kitaoka 120a6e
    if (!m_updatedIconsSize)  // m_updatedIconsSize tells whether
Shinya Kitaoka 120a6e
      m_updatedIconsSize =
Shinya Kitaoka 120a6e
          checkIconSize(m_iconSize);  // icon sizes in the file match m_iconSize
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    if (!m_updatedIconsSize) {
Shinya Kitaoka 120a6e
      // Icons in the stored file mismatch with the
Shinya Kitaoka 120a6e
      // required size. They need to be resized.
Shinya Kitaoka 120a6e
      m_updatedIconsSize = resizeIcons(m_iconSize);
Shinya Kitaoka 120a6e
      assert(m_updatedIconsSize);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief    Checks the icons size stored inside an already existing level
Toshihiro Shimizu 890ddd
            file, and compares it with the specified newSize.
Toshihiro Shimizu 890ddd
  \return   Whether the specified newSize \a matches the icons size in
Toshihiro Shimizu 890ddd
            the level file.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
bool TLevelWriterTzl::checkIconSize(const TDimension &newSize) {
Shinya Kitaoka 120a6e
  assert(m_version >= 13);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  if (!m_exists || m_iconOffsTable.empty() || !m_chan || m_version < 13)
Shinya Kitaoka 120a6e
    return false;
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  // Read the size of icons in the file
Shinya Kitaoka 120a6e
  TINT32 iconLx = 0, iconLy = 0;
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  long currentPos =
Shinya Kitaoka 120a6e
      ftell(m_chan);  // Backup current reading position in the file
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator it = m_iconOffsTable.begin();
Shinya Kitaoka 120a6e
  long offs                 = it->second.m_offs;
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  fseek(m_chan, offs, SEEK_SET);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  fread(&iconLx, sizeof(TINT32), 1, m_chan);
Shinya Kitaoka 120a6e
  fread(&iconLy, sizeof(TINT32), 1, m_chan);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  fseek(m_chan, currentPos,
Shinya Kitaoka 120a6e
        SEEK_SET);  // Reset to the original position in the file
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  assert(iconLx > 0 && iconLy > 0);
Shinya Kitaoka 120a6e
  if (iconLx <= 0 || iconLy <= 0 || iconLx > m_res.lx || iconLy > m_res.ly)
Shinya Kitaoka 120a6e
    return false;
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  m_currentIconSize = TDimension(
Shinya Kitaoka 120a6e
      iconLx, iconLy);  // This is not performed if the above pre-emptive
Shinya Kitaoka 120a6e
                        // bailout kicks in. BTW, m_currentIconSize
Shinya Kitaoka 120a6e
                        // is currently UNUSED! Should be cleaned up...
Shinya Kitaoka 120a6e
  // Compare newSize against read icon size in the file
Shinya Kitaoka 120a6e
  return (m_currentIconSize == newSize);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
bool TLevelWriterTzl::resizeIcons(const TDimension &newSize) {
Shinya Kitaoka 120a6e
  if (!m_exists) return false;
Shinya Kitaoka 120a6e
  if (m_iconOffsTable.empty()) return false;
Shinya Kitaoka 120a6e
  if (!m_chan) return false;
Shinya Kitaoka 120a6e
  assert(m_version >= 13);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // faccio una copia di m_path per poi usarla per la resizeIcons()
Shinya Kitaoka 120a6e
  fclose(m_chan);
Shinya Kitaoka 120a6e
  m_chan = 0;
Shinya Kitaoka 120a6e
  TFileStatus fs(m_path);
Shinya Kitaoka 120a6e
  assert(fs.doesExist());
Shinya Kitaoka 120a6e
  if (!fs.doesExist()) return false;
Shinya Kitaoka 120a6e
  std::string tempName = "~" + m_path.getName() + "tmpIcon&.tlv";
Shinya Kitaoka 120a6e
  TFilePath tempPath   = TSystem::getTempDir() + tempName;
Shinya Kitaoka 120a6e
  if (TSystem::doesExistFileOrLevel(m_path)) {
Shinya Kitaoka 120a6e
    assert(m_path != tempPath);
Shinya Kitaoka 120a6e
    if (TSystem::doesExistFileOrLevel(tempPath)) TSystem::deleteFile(tempPath);
Shinya Kitaoka 120a6e
    TSystem::copyFile(tempPath, m_path);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  m_chan = fopen(m_path, "rb+");
Shinya Kitaoka 120a6e
  assert(m_chan);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  assert(TSystem::doesExistFileOrLevel(tempPath));
Shinya Kitaoka 120a6e
  if (!TSystem::doesExistFileOrLevel(tempPath)) return false;
Shinya Kitaoka 120a6e
  TLevelReaderP lr(tempPath);
Shinya Kitaoka 120a6e
  TLevelP level = lr->loadInfo();
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
  if(m_currentIconSize.lx>newSize.lx && m_currentIconSize.ly>newSize.ly)
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
          for(TLevel::Iterator it=level->begin(); it != level->end(); ++it)
Shinya Kitaoka 120a6e
          {
Shinya Kitaoka 120a6e
                  TImageReaderP ir = lr->getFrameReader(it->first);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
                  // carico l'iconcina
Shinya Kitaoka 120a6e
            TImageP img = ir->loadIcon();
Shinya Kitaoka 120a6e
                  TImageP icon;
Shinya Kitaoka 120a6e
                  createIcon(img,icon);
Shinya Kitaoka 120a6e
                  saveIcon(icon,it->first);
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
  {				 */
Shinya Kitaoka 120a6e
  // leggo tutte le immagini da file e creo le iconcine da da zero
Shinya Kitaoka 120a6e
  for (TLevel::Iterator it = level->begin(); it != level->end(); ++it) {
Shinya Kitaoka 120a6e
    // carico l'iconcina
Shinya Kitaoka 120a6e
    TImageP img = lr->getFrameReader(it->first)->load();
Shinya Kitaoka 120a6e
    // creo e salvo
Shinya Kitaoka 120a6e
    TImageP icon;
Shinya Kitaoka 120a6e
    createIcon(img, icon);
Shinya Kitaoka 120a6e
    saveIcon(icon, it->first);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  //}
Shinya Kitaoka 120a6e
  lr = TLevelReaderP();
Shinya Kitaoka 120a6e
  // delete m_tempPath
Shinya Kitaoka 120a6e
  if (TSystem::doesExistFileOrLevel(tempPath)) {
Shinya Kitaoka 120a6e
    TSystem::deleteFile(tempPath);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
float TLevelWriterTzl::getFreeSpace() {
Shinya Kitaoka 120a6e
  if (m_exists && m_version >= 13) {
Shinya Kitaoka 120a6e
    TINT32 freeSpace                = 0;
Shinya Kitaoka 120a6e
    std::set<tzlchunk>::iterator it = m_freeChunks.begin();
</tzlchunk>
Shinya Kitaoka 120a6e
    for (; it != m_freeChunks.end(); ++it) freeSpace += it->m_length;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    TINT32 totalSpace = 0;
Shinya Kitaoka 120a6e
    if (m_version == 13)
Shinya Kitaoka 120a6e
      totalSpace = m_offsetTablePos - 6 * sizeof(TINT32) - 4 * sizeof(char) -
Shinya Kitaoka 120a6e
                   8 * sizeof(char);
Shinya Kitaoka 120a6e
    else if (m_version == 14)
Shinya Kitaoka 120a6e
      totalSpace = m_offsetTablePos - 6 * sizeof(TINT32) - 4 * sizeof(char) -
Shinya Kitaoka 120a6e
                   8 * sizeof(char) - CREATOR_LENGTH * sizeof(char);
Shinya Kitaoka 120a6e
    assert(totalSpace > 0);
Shinya Kitaoka 120a6e
    return (float)freeSpace / totalSpace;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
// creo il file ottimizzato, cioรจ senza spazi liberi
Shinya Kitaoka 120a6e
bool TLevelWriterTzl::optimize() {
Shinya Kitaoka 120a6e
  TFileStatus fs(m_path);
Shinya Kitaoka 120a6e
  assert(fs.doesExist());
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  std::string tempName = "~" + m_path.getName() + "tmp&.tlv";
Shinya Kitaoka 120a6e
  TFilePath tempPath =
Shinya Kitaoka 120a6e
      TSystem::getTempDir() + tempName;  // Path temporaneo del file ottimizzato
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (TSystem::doesExistFileOrLevel(tempPath)) TSystem::deleteFile(tempPath);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TLevelWriterP lw(tempPath);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TLevelReaderP lr(m_path);
Shinya Kitaoka 120a6e
  lw->setIconSize(m_userIconSize);
Shinya Kitaoka 120a6e
  TLevelP level = lr->loadInfo();
Shinya Kitaoka 120a6e
  if (!level || level->getFrameCount() == 0) return false;
Shinya Kitaoka 120a6e
  TLevel::Iterator levelIt = level->begin();
Shinya Kitaoka 120a6e
  for (levelIt; levelIt != level->end(); ++levelIt) {
Shinya Kitaoka 120a6e
    TToonzImageP img = lr->getFrameReader(levelIt->first)->load();
Shinya Kitaoka 120a6e
    assert(img);
Shinya Kitaoka 120a6e
    lw->getFrameWriter(levelIt->first)->save(img);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  lr = TLevelReaderP();
Shinya Kitaoka 120a6e
  lw = TLevelWriterP();
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // Se il file tempPath (ottimizzato) รจ stato creato
Shinya Kitaoka 120a6e
  // lo copio sostituendolo ad m_path
Shinya Kitaoka 120a6e
  if (TSystem::doesExistFileOrLevel(tempPath)) {
Shinya Kitaoka 120a6e
    assert(m_path != tempPath);
Shinya Kitaoka 120a6e
    if (TSystem::doesExistFileOrLevel(m_path))
Shinya Kitaoka 120a6e
      TSystem::deleteFile(m_path);  // Cancello il file non ottimizzato
Shinya Kitaoka 120a6e
    TSystem::copyFile(m_path, tempPath);
Shinya Kitaoka 120a6e
    TSystem::deleteFile(tempPath);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TLevelReaderTzl
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
void TLevelReaderTzl::readPalette() {
Shinya Kitaoka 120a6e
  TFilePath pltfp = m_path.withNoFrame().withType("tpl");
Shinya Kitaoka 120a6e
  TFileStatus fs(pltfp);
Shinya Kitaoka 120a6e
  TPersist *p = 0;
Shinya Kitaoka 120a6e
  TIStream is(pltfp);
Shinya Kitaoka 120a6e
  TPalette *palette = 0;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (is && fs.doesExist()) {
shun-iwasawa 995cf6
    std::string tagName;
shun-iwasawa 995cf6
    if (is.matchTag(tagName) && tagName == "palette") {
shun-iwasawa 995cf6
      std::string gname;
shun-iwasawa 995cf6
      is.getTagParam("name", gname);
shun-iwasawa 995cf6
      palette = new TPalette();
shun-iwasawa 995cf6
      palette->loadData(is);
shun-iwasawa 995cf6
      palette->setGlobalName(::to_wstring(gname));
shun-iwasawa 995cf6
      is.matchEndTag();
shun-iwasawa 995cf6
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (!palette) {
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    palette = new TPalette();
Shinya Kitaoka 120a6e
    for (i = 1; i < 128 + 32; i++) palette->addStyle(TPixel32(127, 150, 255));
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    for (i = 0; i < 10; i++) palette->getPage(0)->addStyle(i + 1);
Shinya Kitaoka 120a6e
    for (i = 0; i < 10; i++) palette->getPage(0)->addStyle(128 + i);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_level) m_level->setPalette(palette);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//---------------------------------------------------
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
TLevelReaderTzl::TLevelReaderTzl(const TFilePath &path)
Shinya Kitaoka 120a6e
    : TLevelReader(path)
Shinya Kitaoka 120a6e
    , m_chan(0)
Shinya Kitaoka 120a6e
    , m_res(0, 0)
Shinya Kitaoka 120a6e
    , m_xDpi(0)
Shinya Kitaoka 120a6e
    , m_yDpi(0)
Shinya Kitaoka 120a6e
    , m_version(0)
Shinya Kitaoka 120a6e
    , m_frameOffsTable()
Shinya Kitaoka 120a6e
    , m_iconOffsTable()
Shinya Kitaoka 120a6e
    , m_level()
Shinya Kitaoka 120a6e
    , m_readPalette(true) {
Shinya Kitaoka 120a6e
  m_chan = fopen(path, "rb");
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (!m_chan) return;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (!readHeaderAndOffsets(m_chan, m_frameOffsTable, m_iconOffsTable, m_res,
Shinya Kitaoka 120a6e
                            m_version, m_creator, 0, 0, 0, m_level))
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TFilePath historyFp = path.withNoFrame().withType("hst");
Shinya Kitaoka 120a6e
  FILE *historyChan   = fopen(historyFp, "r");
Shinya Kitaoka 120a6e
  if (historyChan) {
Shinya Kitaoka 120a6e
    // read the whole file into historyData string
Shinya Kitaoka 120a6e
    fseek(historyChan, 0, SEEK_END);
Shinya Kitaoka 120a6e
    long lSize = ftell(historyChan);
Shinya Kitaoka 120a6e
    rewind(historyChan);
Shinya Kitaoka 120a6e
    std::string historyData(lSize, '\0');
Shinya Kitaoka 120a6e
    fread(&historyData[0], 1, lSize, historyChan);
Shinya Kitaoka 120a6e
    fclose(historyChan);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    if (!m_contentHistory) m_contentHistory = new TContentHistory(true);
Shinya Kitaoka 120a6e
    m_contentHistory->deserialize(QString::fromStdString(historyData));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // UCHAR *imgBuff = new UCHAR[imgBuffSize];
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // fclose(m_chan);
Shinya Kitaoka 120a6e
  // m_chan = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
void TLevelReaderTzl::doReadPalette(bool doReadIt) { m_readPalette = doReadIt; }
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TLevelReaderTzl::~TLevelReaderTzl() {
Shinya Kitaoka 120a6e
  if (m_chan) fclose(m_chan);
Shinya Kitaoka 120a6e
  m_chan = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TLevelP TLevelReaderTzl::loadInfo() {
Shinya Kitaoka 120a6e
  if (m_level && m_level->getPalette() == 0 && m_readPalette) readPalette();
Shinya Kitaoka 120a6e
  return m_level;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TImageReaderP TLevelReaderTzl::getFrameReader(TFrameId fid) {
Shinya Kitaoka 120a6e
  if (m_level && m_level->getPalette() == 0 && m_readPalette) readPalette();
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  return new TImageReaderTzl(getFilePath(), fid, this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Shinya Kitaoka 120a6e
QString TLevelReaderTzl::getCreator() {
Shinya Kitaoka 120a6e
  if (m_version < 14) return "";
Shinya Kitaoka 120a6e
  return m_creator;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Shinya Kitaoka 120a6e
bool TLevelReaderTzl::getIconSize(TDimension &iconSize) {
Shinya Kitaoka 120a6e
  if (m_iconOffsTable.empty()) return false;
Shinya Kitaoka 120a6e
  if (m_version < 13) return false;
Shinya Kitaoka 120a6e
  assert(m_chan);
Shinya Kitaoka 120a6e
  TINT32 currentPos         = ftell(m_chan);
Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator it = m_iconOffsTable.begin();
Shinya Kitaoka 120a6e
  TINT32 offs               = it->second.m_offs;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  fseek(m_chan, offs, SEEK_SET);
Shinya Kitaoka 120a6e
  TINT32 iconLx = 0, iconLy = 0;
Shinya Kitaoka 120a6e
  // leggo la dimensione delle iconcine nel file
Shinya Kitaoka 120a6e
  fread(&iconLx, sizeof(TINT32), 1, m_chan);
Shinya Kitaoka 120a6e
  fread(&iconLy, sizeof(TINT32), 1, m_chan);
Shinya Kitaoka 120a6e
  assert(iconLx > 0 && iconLy > 0);
Shinya Kitaoka 120a6e
  // ritorno alla posizione corrente
Shinya Kitaoka 120a6e
  fseek(m_chan, currentPos, SEEK_SET);
Shinya Kitaoka 120a6e
  iconSize = TDimension(iconLx, iconLy);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TImageReaderTzl
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TImageReaderTzl::TImageReaderTzl(const TFilePath &f, const TFrameId &fid,
Shinya Kitaoka 120a6e
                                 TLevelReaderTzl *lr)
Shinya Kitaoka 120a6e
    : TImageReader(f)
Shinya Kitaoka 120a6e
    , m_fid(fid)
Shinya Kitaoka 120a6e
    , m_lrp(lr)
Shinya Kitaoka 120a6e
    , m_lx(lr->m_res.lx)
Shinya Kitaoka 120a6e
    , m_ly(lr->m_res.ly)
Shinya Kitaoka 120a6e
    , m_isIcon(false) {}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TImageP TImageReaderTzl::load10() {
Shinya Kitaoka 120a6e
  FILE *chan = m_lrp->m_chan;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (!chan) return TImageP();
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // SAVEBOX_X0 SAVEBOX_Y0 SAVEBOX_LX SAVEBOX_LY BUFFER_SIZE
Shinya Kitaoka 120a6e
  TINT32 sbx0, sby0, sblx, sbly;
Shinya Kitaoka 120a6e
  TINT32 actualBuffSize;
Shinya Kitaoka 120a6e
  double xdpi = 1, ydpi = 1;
Shinya Kitaoka 120a6e
  TINT32 imgBuffSize = 0;
Shinya Kitaoka 120a6e
  UCHAR *imgBuff     = 0;
Shinya Kitaoka 120a6e
  int frameIndex     = m_fid.getNumber();
Shinya Kitaoka 120a6e
  // int pos = ftell(chan);
Shinya Kitaoka 120a6e
  /*if(m_lrp->m_frameIndex>=m_frameIndex)
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
fseek(chan, m_lrp->m_framesOffset, SEEK_SET);
Shinya Kitaoka 120a6e
m_lrp->m_frameIndex = 0;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
int k = m_lrp->m_frameIndex + 1;
Shinya Kitaoka 120a6e
m_lrp->m_frameIndex = m_frameIndex;*/
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  int k;
Shinya Kitaoka 120a6e
  if (m_lrp->m_frameOffsTable[TFrameId(frameIndex)].m_offs == 0) {
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 2; m_lrp->m_frameOffsTable[TFrameId(i)].m_offs != 0 &&
Shinya Kitaoka 120a6e
                i <= m_fid.getNumber();
Shinya Kitaoka 120a6e
         i++)
Shinya Kitaoka 120a6e
      ;
Shinya Kitaoka 120a6e
    if (i == frameIndex) i = 2;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    fseek(chan, m_lrp->m_frameOffsTable[TFrameId(i - 1)].m_offs, SEEK_SET);
Shinya Kitaoka 120a6e
    k = i - 1;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    fseek(chan, m_lrp->m_frameOffsTable[TFrameId(frameIndex)].m_offs, SEEK_SET);
Shinya Kitaoka 120a6e
    k = frameIndex;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  for (; k <= frameIndex; k++) {
Shinya Kitaoka 120a6e
    m_lrp->m_frameOffsTable[TFrameId(k)] = TzlChunk(ftell(chan), 0);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    fread(&sbx0, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    fread(&sby0, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    fread(&sblx, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    fread(&sbly, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    fread(&xdpi, sizeof(double), 1, chan);
Shinya Kitaoka 120a6e
    fread(&ydpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
    sbx0           = swapTINT32(sbx0);
Shinya Kitaoka 120a6e
    sby0           = swapTINT32(sby0);
Shinya Kitaoka 120a6e
    sblx           = swapTINT32(sblx);
Shinya Kitaoka 120a6e
    sbly           = swapTINT32(sbly);
Shinya Kitaoka 120a6e
    actualBuffSize = swapTINT32(actualBuffSize);
Shinya Kitaoka 120a6e
    reverse((char *)&xdpi, sizeof(double));
Shinya Kitaoka 120a6e
    reverse((char *)&ydpi, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
    imgBuffSize = m_lx * m_ly * sizeof(TPixelCM32);
Shinya Kitaoka 120a6e
    assert(actualBuffSize <= imgBuffSize);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
    delete[] imgBuff;
Shinya Kitaoka 120a6e
    imgBuff = new UCHAR[imgBuffSize];
Shinya Kitaoka 120a6e
    // int ret =
Shinya Kitaoka 120a6e
    fread(imgBuff, actualBuffSize, 1, chan);
Shinya Kitaoka 120a6e
    // assert(ret==1);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  Header *header = (Header *)imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
  header->m_lx      = swapTINT32(header->m_lx);
Shinya Kitaoka 120a6e
  header->m_ly      = swapTINT32(header->m_ly);
Shinya Kitaoka 120a6e
  header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  TRasterCodecLZO codec("LZO", false);
Shinya Kitaoka 120a6e
  TRasterP ras;
Shinya Kitaoka 120a6e
  if (!codec.decompress(imgBuff, actualBuffSize, ras, m_safeMode))
Shinya Kitaoka 120a6e
    return TImageP();
Shinya Kitaoka 120a6e
  assert((TRasterCM32P)ras);
Shinya Kitaoka 120a6e
  assert(ras->getLx() == header->m_lx);
Shinya Kitaoka 120a6e
  assert(ras->getLy() == header->m_ly);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
  ras->lock();
Shinya Kitaoka 120a6e
  for (int y = 0; y < ras->getLy(); ++y) {
Shinya Kitaoka 120a6e
    TINT32 *pix    = ((TINT32 *)ras->getRawData(0, y));
Shinya Kitaoka 120a6e
    TINT32 *endPix = pix + ras->getLx();
Shinya Kitaoka 120a6e
    while (pix < endPix) {
Shinya Kitaoka 120a6e
      *pix = swapTINT32(*pix);
Shinya Kitaoka 120a6e
      pix++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  ras->unlock();
Toshihiro Shimizu 890ddd
// codec.compress(ras, 1, &imgBuff, actualBuffSize);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  TRect savebox(TPoint(sbx0, sby0), TDimension(sblx, sbly));
Shinya Kitaoka 120a6e
  TDimension imgSize(m_lrp->m_res.lx, m_lrp->m_res.ly);
Shinya Kitaoka 120a6e
  assert(TRect(imgSize).contains(savebox));
Shinya Kitaoka 120a6e
  if (imgSize != savebox.getSize() && !savebox.isEmpty()) {
Shinya Kitaoka 120a6e
    assert(TRect(imgSize).contains(savebox));
Shinya Kitaoka 120a6e
    TRasterCM32P fullRas(imgSize);
Shinya Kitaoka 120a6e
    TPixelCM32 bgColor;
Shinya Kitaoka 120a6e
    fullRas->fillOutside(savebox, bgColor);
Shinya Kitaoka 120a6e
    assert(savebox.getSize() == ras->getSize());
Shinya Kitaoka 120a6e
    fullRas->extractT(savebox)->copy(ras);
Shinya Kitaoka 120a6e
    ras = fullRas;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  delete[] imgBuff;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // codec.decompress(m_compressedBuffer, m_compressedBufferSize, ras);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // assert(0);
Shinya Kitaoka 120a6e
  // TToonzImageP ti; //  = new
Shinya Kitaoka 120a6e
  // TToonzImage(m_lx,m_ly,savebox,imgBuff,actualBuffSize);
Shinya Kitaoka 120a6e
  TToonzImageP ti(ras, savebox);
Shinya Kitaoka 120a6e
  // if(dpiflag)
Shinya Kitaoka 120a6e
  ti->setDpi(xdpi, ydpi);
Shinya Kitaoka 120a6e
  // m_lrp->m_level->setFrame(TFrameId(m_frameIndex+1), ti);
Shinya Kitaoka 120a6e
  ti->setPalette(m_lrp->m_level->getPalette());
Shinya Kitaoka 120a6e
  // delete [] imgBuff;
Shinya Kitaoka 120a6e
  // imgBuff = 0;
Shinya Kitaoka 120a6e
  return ti;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // ToonzImageUtils::updateRas32(ti);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TImageP TImageReaderTzl::load11() {
Shinya Kitaoka 120a6e
  FILE *chan = m_lrp->m_chan;
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  if (!chan) return TImageP();
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  // SAVEBOX_X0 SAVEBOX_Y0 SAVEBOX_LX SAVEBOX_LY BUFFER_SIZE
Shinya Kitaoka 120a6e
  TINT32 sbx0, sby0, sblx, sbly;
Shinya Kitaoka 120a6e
  TINT32 actualBuffSize;
Shinya Kitaoka 120a6e
  double xdpi = 1, ydpi = 1;
Shinya Kitaoka 120a6e
  TINT32 imgBuffSize = 0;
Shinya Kitaoka 120a6e
  UCHAR *imgBuff     = 0;
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  assert(!m_lrp->m_frameOffsTable.empty());
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  // int pos = ftell(chan);
Shinya Kitaoka 120a6e
  /*if(m_lrp->m_frameIndex>=m_frameIndex)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
fseek(chan, m_lrp->m_framesOffset, SEEK_SET);
Shinya Kitaoka 120a6e
m_lrp->m_frameIndex = 0;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
int k = m_lrp->m_frameIndex + 1;
Shinya Kitaoka 120a6e
m_lrp->m_frameIndex = m_frameIndex;*/
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator it = m_lrp->m_frameOffsTable.find(m_fid);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  if (it == m_lrp->m_frameOffsTable.end()) return 0;
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  fseek(chan, it->second.m_offs, SEEK_SET);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  fread(&sbx0, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&sby0, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&sblx, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&sbly, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  fread(&xdpi, sizeof(double), 1, chan);
Shinya Kitaoka 120a6e
  fread(&ydpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
  sbx0           = swapTINT32(sbx0);
Shinya Kitaoka 120a6e
  sby0           = swapTINT32(sby0);
Shinya Kitaoka 120a6e
  sblx           = swapTINT32(sblx);
Shinya Kitaoka 120a6e
  sbly           = swapTINT32(sbly);
Shinya Kitaoka 120a6e
  actualBuffSize = swapTINT32(actualBuffSize);
Shinya Kitaoka 120a6e
  reverse((char *)&xdpi, sizeof(double));
Shinya Kitaoka 120a6e
  reverse((char *)&ydpi, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  imgBuffSize = m_lx * m_ly * sizeof(TPixelCM32);
Shinya Kitaoka 120a6e
  assert(actualBuffSize <= imgBuffSize);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  imgBuff = new UCHAR[imgBuffSize];
Shinya Kitaoka 120a6e
  // int ret =
Shinya Kitaoka 120a6e
  fread(imgBuff, actualBuffSize, 1, chan);
Shinya Kitaoka 120a6e
  // assert(ret==1);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  Header *header = (Header *)imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
  header->m_lx      = swapTINT32(header->m_lx);
Shinya Kitaoka 120a6e
  header->m_ly      = swapTINT32(header->m_ly);
Shinya Kitaoka 120a6e
  header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  TRasterCodecLZO codec("LZO", false);
Shinya Kitaoka 120a6e
  TRasterP ras;
Shinya Kitaoka 120a6e
  if (!codec.decompress(imgBuff, actualBuffSize, ras, m_safeMode))
Shinya Kitaoka 120a6e
    return TImageP();
Shinya Kitaoka 120a6e
  assert((TRasterCM32P)ras);
Shinya Kitaoka 120a6e
  assert(ras->getLx() == header->m_lx);
Shinya Kitaoka 120a6e
  assert(ras->getLy() == header->m_ly);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  for (int y = 0; y < ras->getLy(); ++y) {
Shinya Kitaoka 120a6e
    ras->lock();
Shinya Kitaoka 120a6e
    TINT32 *pix    = ((TINT32 *)ras->getRawData(0, y));
Shinya Kitaoka 120a6e
    TINT32 *endPix = pix + ras->getLx();
Shinya Kitaoka 120a6e
    while (pix < endPix) {
Shinya Kitaoka 120a6e
      *pix = swapTINT32(*pix);
Shinya Kitaoka 120a6e
      pix++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    ras->unlock();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
// codec.compress(ras, 1, &imgBuff, actualBuffSize);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  TRect savebox(TPoint(sbx0, sby0), TDimension(sblx, sbly));
Shinya Kitaoka 120a6e
  TDimension imgSize(m_lrp->m_res.lx, m_lrp->m_res.ly);
Shinya Kitaoka 120a6e
  assert(TRect(imgSize).contains(savebox));
Shinya Kitaoka 120a6e
  if (imgSize != savebox.getSize() && !savebox.isEmpty()) {
Shinya Kitaoka 120a6e
    assert(TRect(imgSize).contains(savebox));
Shinya Kitaoka 120a6e
    TRasterCM32P fullRas(imgSize);
Shinya Kitaoka 120a6e
    TPixelCM32 bgColor;
Shinya Kitaoka 120a6e
    fullRas->fillOutside(savebox, bgColor);
Shinya Kitaoka 120a6e
    assert(savebox.getSize() == ras->getSize());
Shinya Kitaoka 120a6e
    fullRas->extractT(savebox)->copy(ras);
Shinya Kitaoka 120a6e
    ras = fullRas;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  delete[] imgBuff;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // codec.decompress(m_compressedBuffer, m_compressedBufferSize, ras);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // assert(0);
Shinya Kitaoka 120a6e
  // TToonzImageP ti; //  = new
Shinya Kitaoka 120a6e
  // TToonzImage(m_lx,m_ly,savebox,imgBuff,actualBuffSize);
Shinya Kitaoka 120a6e
  TToonzImageP ti(ras, savebox);
Shinya Kitaoka 120a6e
  // if(dpiflag)
Shinya Kitaoka 120a6e
  ti->setDpi(xdpi, ydpi);
Shinya Kitaoka 120a6e
  // m_lrp->m_level->setFrame(TFrameId(m_frameIndex+1), ti);
Shinya Kitaoka 120a6e
  ti->setPalette(m_lrp->m_level->getPalette());
Shinya Kitaoka 120a6e
  // delete [] imgBuff;
Shinya Kitaoka 120a6e
  // imgBuff = 0;
Shinya Kitaoka 120a6e
  return ti;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // ToonzImageUtils::updateRas32(ti);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TImageP TImageReaderTzl::load13() {
Shinya Kitaoka 120a6e
  FILE *chan = m_lrp->m_chan;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (!chan) return TImageP();
Shinya Kitaoka 120a6e
  // SAVEBOX_X0 SAVEBOX_Y0 SAVEBOX_LX SAVEBOX_LY BUFFER_SIZE
Shinya Kitaoka 120a6e
  TINT32 sbx0, sby0, sblx, sbly;
Shinya Kitaoka 120a6e
  TINT32 actualBuffSize;
Shinya Kitaoka 120a6e
  double xdpi = 1, ydpi = 1;
Shinya Kitaoka 120a6e
  TINT32 imgBuffSize = 0;
Shinya Kitaoka 120a6e
  UCHAR *imgBuff     = 0;
Shinya Kitaoka 120a6e
  TINT32 iconLx = 0, iconLy = 0;
Shinya Kitaoka 120a6e
  assert(!m_lrp->m_frameOffsTable.empty());
Shinya Kitaoka 120a6e
  assert(!m_lrp->m_iconOffsTable.empty());
Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator it     = m_lrp->m_frameOffsTable.find(m_fid);
Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator iconIt = m_lrp->m_iconOffsTable.find(m_fid);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (it == m_lrp->m_frameOffsTable.end() ||
Shinya Kitaoka 120a6e
      iconIt == m_lrp->m_iconOffsTable.end())
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  fseek(chan, it->second.m_offs, SEEK_SET);
Shinya Kitaoka 120a6e
  fread(&sbx0, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&sby0, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&sblx, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&sbly, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&xdpi, sizeof(double), 1, chan);
Shinya Kitaoka 120a6e
  fread(&ydpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
  sbx0           = swapTINT32(sbx0);
Shinya Kitaoka 120a6e
  sby0           = swapTINT32(sby0);
Shinya Kitaoka 120a6e
  sblx           = swapTINT32(sblx);
Shinya Kitaoka 120a6e
  sbly           = swapTINT32(sbly);
Shinya Kitaoka 120a6e
  actualBuffSize = swapTINT32(actualBuffSize);
Shinya Kitaoka 120a6e
  reverse((char *)&xdpi, sizeof(double));
Shinya Kitaoka 120a6e
  reverse((char *)&ydpi, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  // Carico l'icona dal file
Shinya Kitaoka 120a6e
  if (m_isIcon) {
Shinya Kitaoka 120a6e
    fseek(chan, iconIt->second.m_offs, SEEK_SET);
Shinya Kitaoka 120a6e
    fread(&iconLx, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    fread(&iconLy, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    assert(iconLx > 0 && iconLy > 0);
Shinya Kitaoka 120a6e
    if (iconLx <= 0 || iconLy <= 0) throw TException();
Shinya Kitaoka 120a6e
    fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    imgBuffSize = (iconLx * iconLy * sizeof(TPixelCM32));
Shinya Kitaoka 120a6e
    imgBuff     = new UCHAR[imgBuffSize];
Shinya Kitaoka 120a6e
    fread(imgBuff, actualBuffSize, 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
    Header *header    = (Header *)imgBuff;
Shinya Kitaoka 120a6e
    header->m_lx      = swapTINT32(header->m_lx);
Shinya Kitaoka 120a6e
    header->m_ly      = swapTINT32(header->m_ly);
Shinya Kitaoka 120a6e
    header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    TRasterCodecLZO codec("LZO", false);
Shinya Kitaoka 120a6e
    TRasterP ras;
Shinya Kitaoka 120a6e
    if (!codec.decompress(imgBuff, actualBuffSize, ras, m_safeMode))
Shinya Kitaoka 120a6e
      return TImageP();
Shinya Kitaoka 120a6e
    assert((TRasterCM32P)ras);
Shinya Kitaoka 120a6e
    delete[] imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
    for (int y = 0; y < ras->getLy(); ++y) {
Shinya Kitaoka 120a6e
      ras->lock();
Shinya Kitaoka 120a6e
      TINT32 *pix    = ((TINT32 *)ras->getRawData(0, y));
Shinya Kitaoka 120a6e
      TINT32 *endPix = pix + ras->getLx();
Shinya Kitaoka 120a6e
      while (pix < endPix) {
Shinya Kitaoka 120a6e
        *pix = swapTINT32(*pix);
Shinya Kitaoka 120a6e
        pix++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      ras->unlock();
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
    /*
Shinya Kitaoka 120a6e
            TINT32 iconsbx0 = tround((double)iconLx*sbx0/m_lrp->m_res.lx);
Shinya Kitaoka 120a6e
            TINT32 iconsby0 = tround((double)iconLy*sby0/m_lrp->m_res.ly);
Shinya Kitaoka 120a6e
            TRect savebox(TPoint(iconsbx0,iconsby0),
Shinya Kitaoka 120a6e
       TDimension(ras->getLx(),ras->getLy()));
Shinya Kitaoka 120a6e
             */
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    // Compute savebox
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    TINT32 iconsbx0 = tround((double)iconLx * sbx0 / m_lrp->m_res.lx);
Shinya Kitaoka 120a6e
    TINT32 iconsby0 =
Shinya Kitaoka 120a6e
        tround((double)iconLy * sby0 /
Shinya Kitaoka 120a6e
               m_lrp->m_res.ly);  //+tround((double)(iconLy-ly)/2);
Shinya Kitaoka 120a6e
    TINT32 iconsblx = tround((double)iconLx * sblx / m_lrp->m_res.lx);
Shinya Kitaoka 120a6e
    TINT32 iconsbly = tround((double)iconLy * sbly / m_lrp->m_res.ly);
Shinya Kitaoka 120a6e
    TRect savebox(TPoint(iconsbx0, iconsby0), TDimension(iconsblx, iconsbly));
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    // int ly = tround((double)m_lrp->m_res.ly*iconLx/m_lrp->m_res.lx);
Shinya Kitaoka 120a6e
    // TRect
Shinya Kitaoka 120a6e
    // rect(TPoint(0,tround((double)(iconLy-ly)/2)),TDimension(iconLx,ly));
Shinya Kitaoka 120a6e
    // TPixelCM32 bgColorRect(1,0,100);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    TDimension imgSize(iconLx, iconLy);
Shinya Kitaoka 120a6e
    assert(TRect(imgSize).contains(savebox));
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    if (imgSize != savebox.getSize() && !savebox.isEmpty()) {
Shinya Kitaoka 120a6e
      assert(TRect(imgSize).contains(savebox));
Shinya Kitaoka 120a6e
      TRasterCM32P fullRas(imgSize);
Shinya Kitaoka 120a6e
      TPixelCM32 bgColor;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
      fullRas->fillOutside(savebox, bgColor);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
      // fullRas->extractT(rect)->fill(bgColorRect);
Shinya Kitaoka 120a6e
      assert(savebox.getSize() == ras->getSize());
Shinya Kitaoka 120a6e
      fullRas->extractT(savebox)->copy(ras);
Shinya Kitaoka 120a6e
      ras = fullRas;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
    TToonzImageP ti(ras, savebox);
Shinya Kitaoka 120a6e
    ti->setDpi(xdpi, ydpi);
Shinya Kitaoka 120a6e
    ti->setPalette(m_lrp->m_level->getPalette());
Shinya Kitaoka 120a6e
    return ti;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  TRasterCM32P raux = TRasterCM32P(m_lx, m_ly);
Shinya Kitaoka 120a6e
  raux->lock();
Shinya Kitaoka 120a6e
  imgBuff = (UCHAR *)raux->getRawData();  // new UCHAR[imgBuffSize];
Shinya Kitaoka 120a6e
  // imgBuff = new UCHAR[imgBuffSize];
Shinya Kitaoka 120a6e
  // imgBuffSize = m_lx*m_ly*sizeof(TPixelCM32);
Shinya Kitaoka 120a6e
  // assert(actualBuffSize <= imgBuffSize);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  // imgBuff = new UCHAR[imgBuffSize];
Shinya Kitaoka 120a6e
  // int ret =
Shinya Kitaoka 120a6e
  fread(imgBuff, actualBuffSize, 1, chan);
Shinya Kitaoka 120a6e
  // assert(ret==1);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  Header *header = (Header *)imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
  header->m_lx      = swapTINT32(header->m_lx);
Shinya Kitaoka 120a6e
  header->m_ly      = swapTINT32(header->m_ly);
Shinya Kitaoka 120a6e
  header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  TRasterCodecLZO codec("LZO", false);
Shinya Kitaoka 120a6e
  TRasterP ras;
Shinya Kitaoka 120a6e
  if (!codec.decompress(imgBuff, actualBuffSize, ras, m_safeMode))
Shinya Kitaoka 120a6e
    return TImageP();
Shinya Kitaoka 120a6e
  assert((TRasterCM32P)ras);
Shinya Kitaoka 120a6e
  assert(ras->getLx() == header->m_lx);
Shinya Kitaoka 120a6e
  assert(ras->getLy() == header->m_ly);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  for (int y = 0; y < ras->getLy(); ++y) {
Shinya Kitaoka 120a6e
    ras->lock();
Shinya Kitaoka 120a6e
    TINT32 *pix    = ((TINT32 *)ras->getRawData(0, y));
Shinya Kitaoka 120a6e
    TINT32 *endPix = pix + ras->getLx();
Shinya Kitaoka 120a6e
    while (pix < endPix) {
Shinya Kitaoka 120a6e
      *pix = swapTINT32(*pix);
Shinya Kitaoka 120a6e
      pix++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    ras->unlock();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
// codec.compress(ras, 1, &imgBuff, actualBuffSize);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  TRect savebox(TPoint(sbx0, sby0), TDimension(sblx, sbly));
Shinya Kitaoka 120a6e
  TDimension imgSize(m_lrp->m_res.lx, m_lrp->m_res.ly);
Shinya Kitaoka 120a6e
  assert(TRect(imgSize).contains(savebox));
Shinya Kitaoka 120a6e
  if (imgSize != savebox.getSize() && !savebox.isEmpty()) {
Shinya Kitaoka 120a6e
    assert(TRect(imgSize).contains(savebox));
Shinya Kitaoka 120a6e
    TRasterCM32P fullRas(imgSize);
Shinya Kitaoka 120a6e
    TPixelCM32 bgColor;
Shinya Kitaoka 120a6e
    fullRas->fillOutside(savebox, bgColor);
Shinya Kitaoka 120a6e
    assert(savebox.getSize() == ras->getSize());
Shinya Kitaoka 120a6e
    fullRas->extractT(savebox)->copy(ras);
Shinya Kitaoka 120a6e
    ras = fullRas;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  raux->unlock();
Shinya Kitaoka 120a6e
  raux = TRasterCM32P();
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // delete [] imgBuff;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // codec.decompress(m_compressedBuffer, m_compressedBufferSize, ras);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // assert(0);
Shinya Kitaoka 120a6e
  // TToonzImageP ti; //  = new
Shinya Kitaoka 120a6e
  // TToonzImage(m_lx,m_ly,savebox,imgBuff,actualBuffSize);
Shinya Kitaoka 120a6e
  TToonzImageP ti(ras, savebox);
Shinya Kitaoka 120a6e
  // if(dpiflag)
Shinya Kitaoka 120a6e
  ti->setDpi(xdpi, ydpi);
Shinya Kitaoka 120a6e
  // m_lrp->m_level->setFrame(TFrameId(m_frameIndex+1), ti);
Shinya Kitaoka 120a6e
  ti->setPalette(m_lrp->m_level->getPalette());
Shinya Kitaoka 120a6e
  // delete [] imgBuff;
Shinya Kitaoka 120a6e
  // imgBuff = 0;
Shinya Kitaoka 120a6e
  return ti;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // ToonzImageUtils::updateRas32(ti);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
// Restituisce la regione del raster shrinkata e la relativa savebox.
Campbell Barton 8c6c57
static TRect applyShrinkAndRegion(TRasterP &ras, int shrink, TRect region,
Campbell Barton 8c6c57
                                  TRect savebox) {
Shinya Kitaoka 120a6e
  // estraggo la regione solo se essa ha coordinate valide.
Shinya Kitaoka 120a6e
  if (!region.isEmpty() && region != TRect() && region.getLx() > 0 &&
Shinya Kitaoka 120a6e
      region.getLy() > 0)
Shinya Kitaoka 120a6e
    ras = ras->extract(region);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    region = TRect(0, 0, ras->getLx() - 1, ras->getLy() - 1);
Shinya Kitaoka 120a6e
  if (shrink > 1) {
Shinya Kitaoka 120a6e
    ras = TRop::shrink(ras, shrink);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // calcolo la nuova savebox
Shinya Kitaoka 120a6e
  savebox *= region;
Shinya Kitaoka 120a6e
  if (savebox == TRect() || savebox.getLx() <= 0 || savebox.getLy() <= 0)
Shinya Kitaoka 120a6e
    return TRect();
Shinya Kitaoka 120a6e
  int firstColIndexOfLayer = (savebox.x0 - region.x0) - 1 + shrink -
Shinya Kitaoka 120a6e
                             (abs(savebox.x0 - region.x0 - 1) % shrink);
Shinya Kitaoka 120a6e
  int firstRowIndexOfLayer = (savebox.y0 - region.y0) - 1 + shrink -
Shinya Kitaoka 120a6e
                             (abs(savebox.y0 - region.y0 - 1) % shrink);
Shinya Kitaoka 120a6e
  savebox.x0 = (firstColIndexOfLayer) / shrink;
Shinya Kitaoka 120a6e
  savebox.y0 = (firstRowIndexOfLayer) / shrink;
Shinya Kitaoka 120a6e
  savebox.x1 = savebox.x0 + (savebox.getLx()) / shrink - 1;
Shinya Kitaoka 120a6e
  savebox.y1 = savebox.y0 + (savebox.getLy()) / shrink - 1;
Shinya Kitaoka 120a6e
  return savebox;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TImageP TImageReaderTzl::load14() {
Shinya Kitaoka 120a6e
  FILE *chan = m_lrp->m_chan;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (!chan) return TImageP();
Shinya Kitaoka 120a6e
  // SAVEBOX_X0 SAVEBOX_Y0 SAVEBOX_LX SAVEBOX_LY BUFFER_SIZE
Shinya Kitaoka 120a6e
  TINT32 sbx0 = 0, sby0 = 0, sblx, sbly;
Shinya Kitaoka 120a6e
  TINT32 actualBuffSize;
Shinya Kitaoka 120a6e
  double xdpi = 1, ydpi = 1;
Shinya Kitaoka 120a6e
  // TINT32 imgBuffSize = 0;
Shinya Kitaoka 120a6e
  UCHAR *imgBuff = 0;
Shinya Kitaoka 120a6e
  TINT32 iconLx = 0, iconLy = 0;
Shinya Kitaoka 120a6e
  assert(!m_lrp->m_frameOffsTable.empty());
Shinya Kitaoka 120a6e
  assert(!m_lrp->m_iconOffsTable.empty());
Shinya Kitaoka 120a6e
  if (m_lrp->m_frameOffsTable.empty())
Shinya Kitaoka 120a6e
    throw TException("Loading tlv: the frames table is empty.");
Shinya Kitaoka 120a6e
  if (m_lrp->m_iconOffsTable.empty())
Shinya Kitaoka 120a6e
    throw TException("Loading tlv: the frames icons table is empty.");
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator it     = m_lrp->m_frameOffsTable.find(m_fid);
Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator iconIt = m_lrp->m_iconOffsTable.find(m_fid);
Shinya Kitaoka 120a6e
  if (it == m_lrp->m_frameOffsTable.end() ||
Shinya Kitaoka 120a6e
      iconIt == m_lrp->m_iconOffsTable.end())
Shinya Kitaoka 120a6e
    throw TException("Loading tlv: frame ID not found.");
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  fseek(chan, it->second.m_offs, SEEK_SET);
Shinya Kitaoka 120a6e
  fread(&sbx0, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&sby0, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&sblx, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&sbly, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&xdpi, sizeof(double), 1, chan);
Shinya Kitaoka 120a6e
  fread(&ydpi, sizeof(double), 1, chan);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (sbx0 < 0 || sby0 < 0 || sblx < 0 || sbly < 0 || sblx > m_lx ||
Shinya Kitaoka 120a6e
      sbly > m_ly)
Shinya Kitaoka 120a6e
    throw TException("Loading tlv: savebox dimension error.");
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
  sbx0           = swapTINT32(sbx0);
Shinya Kitaoka 120a6e
  sby0           = swapTINT32(sby0);
Shinya Kitaoka 120a6e
  sblx           = swapTINT32(sblx);
Shinya Kitaoka 120a6e
  sbly           = swapTINT32(sbly);
Shinya Kitaoka 120a6e
  actualBuffSize = swapTINT32(actualBuffSize);
Shinya Kitaoka 120a6e
  reverse((char *)&xdpi, sizeof(double));
Shinya Kitaoka 120a6e
  reverse((char *)&ydpi, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  // Carico l'icona dal file
Shinya Kitaoka 120a6e
  if (m_isIcon) {
Shinya Kitaoka 120a6e
    fseek(chan, iconIt->second.m_offs, SEEK_SET);
Shinya Kitaoka 120a6e
    fread(&iconLx, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    fread(&iconLy, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    assert(iconLx > 0 && iconLy > 0);
Shinya Kitaoka 120a6e
    if (iconLx < 0 || iconLy < 0 || iconLx > m_lx || iconLy > m_ly)
Shinya Kitaoka 120a6e
      throw TException("Loading tlv: bad icon size.");
Shinya Kitaoka 120a6e
    fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    if (actualBuffSize <= 0 ||
Shinya Kitaoka 120a6e
        actualBuffSize > (int)(iconLx * iconLx * sizeof(TPixelCM32)))
Shinya Kitaoka 120a6e
      throw TException("Loading tlv: icon buffer size error.");
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    TRasterCM32P raux = TRasterCM32P(iconLx, iconLy);
Shinya Kitaoka 120a6e
    if (!raux) return TImageP();
Shinya Kitaoka 120a6e
    raux->lock();
Shinya Kitaoka 120a6e
    imgBuff = (UCHAR *)raux->getRawData();  // new UCHAR[imgBuffSize];
Shinya Kitaoka 120a6e
    fread(imgBuff, actualBuffSize, 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
    Header *header    = (Header *)imgBuff;
Shinya Kitaoka 120a6e
    header->m_lx      = swapTINT32(header->m_lx);
Shinya Kitaoka 120a6e
    header->m_ly      = swapTINT32(header->m_ly);
Shinya Kitaoka 120a6e
    header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
    TRasterCodecLZO codec("LZO", false);
Shinya Kitaoka 120a6e
    TRasterP ras;
Shinya Kitaoka 120a6e
    if (!codec.decompress(imgBuff, actualBuffSize, ras, m_safeMode))
Shinya Kitaoka 120a6e
      return TImageP();
Shinya Kitaoka 120a6e
    assert((TRasterCM32P)ras);
Shinya Kitaoka 120a6e
    raux->unlock();
Shinya Kitaoka 120a6e
    raux = TRasterCM32P();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
    for (int y = 0; y < ras->getLy(); ++y) {
Shinya Kitaoka 120a6e
      ras->lock();
Shinya Kitaoka 120a6e
      TINT32 *pix    = ((TINT32 *)ras->getRawData(0, y));
Shinya Kitaoka 120a6e
      TINT32 *endPix = pix + ras->getLx();
Shinya Kitaoka 120a6e
      while (pix < endPix) {
Shinya Kitaoka 120a6e
        *pix = swapTINT32(*pix);
Shinya Kitaoka 120a6e
        pix++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      ras->unlock();
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
    /*
Shinya Kitaoka 120a6e
            TINT32 iconsbx0 = tround((double)iconLx*sbx0/m_lrp->m_res.lx);
Shinya Kitaoka 120a6e
            TINT32 iconsby0 = tround((double)iconLy*sby0/m_lrp->m_res.ly);
Shinya Kitaoka 120a6e
            TRect savebox(TPoint(iconsbx0,iconsby0),
Shinya Kitaoka 120a6e
       TDimension(ras->getLx(),ras->getLy()));
Shinya Kitaoka 120a6e
             */
Shinya Kitaoka 120a6e
    if (m_lrp->m_res.lx == 0 || m_lrp->m_res.ly == 0) return TImageP();
Shinya Kitaoka 120a6e
    // Compute savebox
Shinya Kitaoka 120a6e
    if (m_lrp->m_res.lx < 0 || m_lrp->m_res.ly < 0)
Shinya Kitaoka 120a6e
      throw TException("Loading tlv: icon resolution error");
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    TRect tmp_savebox;
Shinya Kitaoka 120a6e
    TRect savebox;
Shinya Kitaoka 120a6e
    TRop::computeBBox(ras, tmp_savebox);
Shinya Kitaoka 120a6e
    if (tmp_savebox.isEmpty()) {
Shinya Kitaoka 120a6e
      TINT32 iconsbx0 = tround((double)iconLx * sbx0 / m_lrp->m_res.lx);
Shinya Kitaoka 120a6e
      TINT32 iconsby0 = tround((double)iconLy * sby0 / m_lrp->m_res.ly);
Shinya Kitaoka 120a6e
      TINT32 iconsblx =
Shinya Kitaoka 120a6e
          std::max(tround((double)iconLx * sblx / m_lrp->m_res.lx), 1);
Shinya Kitaoka 120a6e
      TINT32 iconsbly =
Shinya Kitaoka 120a6e
          std::max(tround((double)iconLy * sbly / m_lrp->m_res.ly), 1);
Shinya Kitaoka 120a6e
      savebox =
Shinya Kitaoka 120a6e
          TRect(TPoint(iconsbx0, iconsby0), TDimension(iconsblx, iconsbly));
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      TINT32 iconsbx0 = tfloor((double)iconLx * sbx0 / m_lrp->m_res.lx);
Shinya Kitaoka 120a6e
      TINT32 iconsby0 = tfloor((double)iconLy * sby0 / m_lrp->m_res.ly);
Shinya Kitaoka 120a6e
      savebox         = TRect(TPoint(iconsbx0, iconsby0),
Shinya Kitaoka 120a6e
                      TDimension(tmp_savebox.getLx(), tmp_savebox.getLy()));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    // int ly = tround((double)m_lrp->m_res.ly*iconLx/m_lrp->m_res.lx);
Shinya Kitaoka 120a6e
    // TRect
Shinya Kitaoka 120a6e
    // rect(TPoint(0,tround((double)(iconLy-ly)/2)),TDimension(iconLx,ly));
Shinya Kitaoka 120a6e
    // TPixelCM32 bgColorRect(1,0,100);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    TDimension imgSize(iconLx, iconLy);
Shinya Kitaoka 120a6e
    if (!TRect(imgSize).contains(
Shinya Kitaoka 120a6e
            savebox))  // for this 'if', see comment in createIcon method. vinz
Shinya Kitaoka 120a6e
      savebox = savebox * TRect(imgSize);
Shinya Kitaoka 120a6e
    // if(!TRect(imgSize).contains(savebox)) throw TException("Loading tlv: bad
Shinya Kitaoka 120a6e
    // icon savebox size.");
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    if (imgSize != savebox.getSize()) {
Shinya Kitaoka 120a6e
      TRasterCM32P fullRas(imgSize);
Shinya Kitaoka 120a6e
      TPixelCM32 bgColor;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
      fullRas->fillOutside(savebox, bgColor);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
      // fullRas->extractT(rect)->fill(bgColorRect);
Shinya Kitaoka 120a6e
      // assert(savebox.getSize() == ras->getSize());
Shinya Kitaoka 120a6e
      if (savebox.getSize() != ras->getSize())
Shinya Kitaoka 120a6e
        throw TException("Loading tlv: bad icon savebox size.");
Shinya Kitaoka 120a6e
      fullRas->extractT(savebox)->copy(ras);
Shinya Kitaoka 120a6e
      ras = fullRas;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    TToonzImageP ti(ras, savebox);
Shinya Kitaoka 120a6e
    ti->setDpi(xdpi, ydpi);
Shinya Kitaoka 120a6e
    ti->setPalette(m_lrp->m_level->getPalette());
Shinya Kitaoka 120a6e
    return ti;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (actualBuffSize <= 0 ||
Shinya Kitaoka 120a6e
      actualBuffSize > (int)(m_lx * m_ly * sizeof(TPixelCM32)))
Shinya Kitaoka 120a6e
    throw TException("Loading tlv: buffer size error");
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TRasterCM32P raux = TRasterCM32P(m_lx, m_ly);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // imgBuffSize = m_lx*m_ly*sizeof(TPixelCM32);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  raux->lock();
Shinya Kitaoka 120a6e
  imgBuff = (UCHAR *)raux->getRawData();  // new UCHAR[imgBuffSize];
Shinya Kitaoka 120a6e
  // int ret =
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  fread(imgBuff, actualBuffSize, 1, chan);
Shinya Kitaoka 120a6e
  // assert(ret==1);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  Header *header = (Header *)imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
  header->m_lx      = swapTINT32(header->m_lx);
Shinya Kitaoka 120a6e
  header->m_ly      = swapTINT32(header->m_ly);
Shinya Kitaoka 120a6e
  header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  TRasterCodecLZO codec("LZO", false);
Shinya Kitaoka 120a6e
  TRasterP ras;
Shinya Kitaoka 120a6e
  if (!codec.decompress(imgBuff, actualBuffSize, ras, m_safeMode))
Shinya Kitaoka 120a6e
    return TImageP();
Shinya Kitaoka 120a6e
  assert((TRasterCM32P)ras);
Shinya Kitaoka 120a6e
  assert(ras->getLx() == header->m_lx);
Shinya Kitaoka 120a6e
  assert(ras->getLy() == header->m_ly);
Shinya Kitaoka 120a6e
  if (ras->getLx() != header->m_lx)
Shinya Kitaoka 120a6e
    throw TException("Loading tlv: lx dimension error.");
Shinya Kitaoka 120a6e
  if (ras->getLy() != header->m_ly)
Shinya Kitaoka 120a6e
    throw TException("Loading tlv: ly dimension error.");
Shinya Kitaoka 120a6e
  raux->unlock();
Shinya Kitaoka 120a6e
  raux = TRasterCM32P();
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  for (int y = 0; y < ras->getLy(); ++y) {
Shinya Kitaoka 120a6e
    ras->lock();
Shinya Kitaoka 120a6e
    TINT32 *pix    = ((TINT32 *)ras->getRawData(0, y));
Shinya Kitaoka 120a6e
    TINT32 *endPix = pix + ras->getLx();
Shinya Kitaoka 120a6e
    while (pix < endPix) {
Shinya Kitaoka 120a6e
      *pix = swapTINT32(*pix);
Shinya Kitaoka 120a6e
      pix++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    ras->unlock();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
// codec.compress(ras, 1, &imgBuff, actualBuffSize);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  TRect savebox(TPoint(sbx0, sby0), TDimension(sblx, sbly));
Shinya Kitaoka 120a6e
  TDimension imgSize(m_lrp->m_res.lx, m_lrp->m_res.ly);
Shinya Kitaoka 120a6e
  assert(TRect(imgSize).contains(savebox));
Shinya Kitaoka 120a6e
  if (!TRect(imgSize).contains(savebox))
Shinya Kitaoka 120a6e
    throw TException("Loading tlv: bad savebox size.");
Shinya Kitaoka 120a6e
  if (imgSize != savebox.getSize()) {
Shinya Kitaoka 120a6e
    TRasterCM32P fullRas(imgSize);
Shinya Kitaoka 120a6e
    TPixelCM32 bgColor;
Shinya Kitaoka 120a6e
    if (!savebox.isEmpty()) {
Shinya Kitaoka 120a6e
      fullRas->fillOutside(savebox, bgColor);
Shinya Kitaoka 120a6e
      assert(savebox.getSize() == ras->getSize());
Shinya Kitaoka 120a6e
      if (savebox.getSize() != ras->getSize())
Shinya Kitaoka 120a6e
        throw TException("Loading tlv: bad icon savebox size.");
Shinya Kitaoka 120a6e
      fullRas->extractT(savebox)->copy(ras);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      fullRas->clear();
Shinya Kitaoka 120a6e
    ras = fullRas;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  TToonzImageP ti(ras, savebox);
Shinya Kitaoka 120a6e
  // if(dpiflag)
Shinya Kitaoka 120a6e
  ti->setDpi(xdpi, ydpi);
Shinya Kitaoka 120a6e
  // m_lrp->m_level->setFrame(TFrameId(m_frameIndex+1), ti);
Shinya Kitaoka 120a6e
  ti->setPalette(m_lrp->m_level->getPalette());
Shinya Kitaoka 120a6e
  // delete [] imgBuff;
Shinya Kitaoka 120a6e
  // imgBuff = 0;
Shinya Kitaoka 120a6e
  return ti;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // ToonzImageUtils::updateRas32(ti);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TImageP TImageReaderTzl::load() {
Shinya Kitaoka 120a6e
  int version   = m_lrp->m_version;
Shinya Kitaoka 120a6e
  TImageP image = TImageP();
Shinya Kitaoka 120a6e
  switch (version) {
Shinya Kitaoka 120a6e
  case 11:
Shinya Kitaoka 120a6e
    if (!m_lrp->m_frameOffsTable.empty()) image = load11();
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 12:
Shinya Kitaoka 120a6e
    if (!m_lrp->m_frameOffsTable.empty()) image = load11();
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 13:
Shinya Kitaoka 120a6e
    if (!m_lrp->m_frameOffsTable.empty() && !m_lrp->m_iconOffsTable.empty())
Shinya Kitaoka 120a6e
      image = load13();
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 14:
Shinya Kitaoka 120a6e
    if (!m_lrp->m_frameOffsTable.empty() && !m_lrp->m_iconOffsTable.empty())
Shinya Kitaoka 120a6e
      image = load14();
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    image = load10();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (image == TImageP()) return TImageP();
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  if (!m_isIcon) {
Shinya Kitaoka 120a6e
    TToonzImageP ti = image;
Shinya Kitaoka 120a6e
    if (!ti) return TImageP();
Shinya Kitaoka 120a6e
    TRasterP ras  = ti->getRaster();
Shinya Kitaoka 120a6e
    TRect savebox = ti->getSavebox();
Shinya Kitaoka 120a6e
    if (m_region != TRect() && m_region.getLx() > 0 && m_region.getLy() > 0) {
Shinya Kitaoka 120a6e
      m_region *= TRect(0, 0, ti->getSize().lx, ti->getSize().ly);
Shinya Kitaoka 120a6e
      if (m_region.isEmpty() || m_region == TRect() || m_region.getLx() <= 0 ||
Shinya Kitaoka 120a6e
          m_region.getLy() <= 0)
Shinya Kitaoka 120a6e
        return TImageP();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    savebox = applyShrinkAndRegion(ras, m_shrink, m_region, savebox);
Shinya Kitaoka 120a6e
    if (savebox == TRect()) {
Shinya Kitaoka 120a6e
      if (m_region != TRect()) {
Shinya Kitaoka 120a6e
        ras = ras->create(m_region.getLx(), m_region.getLy());
Shinya Kitaoka 120a6e
        ras->clear();
Shinya Kitaoka 120a6e
        savebox = m_region;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        // se sia la savebox che la regione sono vuote non faccio nulla
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    ti->setCMapped(ras);
Shinya Kitaoka 120a6e
    ti->setSavebox(savebox);
Shinya Kitaoka 120a6e
    return ti;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return image;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
const TImageInfo *TImageReaderTzl::getImageInfo11() const {
Shinya Kitaoka 120a6e
  assert(!m_lrp->m_frameOffsTable.empty());
Shinya Kitaoka 120a6e
  FILE *chan = m_lrp->m_chan;
Shinya Kitaoka 120a6e
  if (!chan) return 0;
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  TzlOffsetMap::iterator it = m_lrp->m_frameOffsTable.find(m_fid);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  if (it == m_lrp->m_frameOffsTable.end()) return 0;
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  fseek(chan, it->second.m_offs, SEEK_SET);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  // SAVEBOX_X0 SAVEBOX_Y0 SAVEBOX_LX SAVEBOX_LY BUFFER_SIZE
Shinya Kitaoka 120a6e
  TINT32 sbx0, sby0, sblx, sbly;
Shinya Kitaoka 120a6e
  TINT32 actualBuffSize;
Shinya Kitaoka 120a6e
  double xdpi = 1, ydpi = 1;
Shinya Kitaoka 120a6e
  //  TINT32 imgBuffSize = 0;
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  // int pos = ftell(chan);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  fread(&sbx0, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&sby0, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&sblx, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&sbly, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
  fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  fread(&xdpi, sizeof(double), 1, chan);
Shinya Kitaoka 120a6e
  fread(&ydpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
  sbx0           = swapTINT32(sbx0);
Shinya Kitaoka 120a6e
  sby0           = swapTINT32(sby0);
Shinya Kitaoka 120a6e
  sblx           = swapTINT32(sblx);
Shinya Kitaoka 120a6e
  sbly           = swapTINT32(sbly);
Shinya Kitaoka 120a6e
  actualBuffSize = swapTINT32(actualBuffSize);
Shinya Kitaoka 120a6e
  reverse((char *)&xdpi, sizeof(double));
Shinya Kitaoka 120a6e
  reverse((char *)&ydpi, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  static TImageInfo info;
Shinya Kitaoka 120a6e
  info.m_x0   = sbx0;
Shinya Kitaoka 120a6e
  info.m_y0   = sby0;
Shinya Kitaoka 120a6e
  info.m_x1   = sbx0 + sblx - 1;
Shinya Kitaoka 120a6e
  info.m_y1   = sby0 + sbly - 1;
Shinya Kitaoka 120a6e
  info.m_lx   = m_lx;
Shinya Kitaoka 120a6e
  info.m_ly   = m_ly;
Shinya Kitaoka 120a6e
  info.m_dpix = xdpi;
Shinya Kitaoka 120a6e
  info.m_dpiy = ydpi;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // m_lrp->m_frameIndex = m_frameIndex;
Shinya Kitaoka 120a6e
  return &info;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
const TImageInfo *TImageReaderTzl::getImageInfo10() const {
Shinya Kitaoka 120a6e
  FILE *chan = m_lrp->m_chan;
Shinya Kitaoka 120a6e
  if (!chan) return 0;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // SAVEBOX_X0 SAVEBOX_Y0 SAVEBOX_LX SAVEBOX_LY BUFFER_SIZE
Shinya Kitaoka 120a6e
  TINT32 sbx0, sby0, sblx, sbly;
Shinya Kitaoka 120a6e
  TINT32 actualBuffSize;
Shinya Kitaoka 120a6e
  double xdpi = 1, ydpi = 1;
Shinya Kitaoka 120a6e
  TINT32 imgBuffSize = 0;
Shinya Kitaoka 120a6e
  UCHAR *imgBuff     = 0;
Shinya Kitaoka 120a6e
  int frameIndex     = m_fid.getNumber();
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  // int pos = ftell(chan);
Shinya Kitaoka 120a6e
  assert(m_lrp->m_frameOffsTable[TFrameId(1)].m_offs > 0);
Shinya Kitaoka 120a6e
  int k;
Shinya Kitaoka 120a6e
  if (m_lrp->m_frameOffsTable[TFrameId(frameIndex)].m_offs == 0) {
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 2;
Shinya Kitaoka 120a6e
         m_lrp->m_frameOffsTable[TFrameId(i)].m_offs != 0 && i <= frameIndex;
Shinya Kitaoka 120a6e
         i++)
Shinya Kitaoka 120a6e
      ;
Shinya Kitaoka 120a6e
    if (i == frameIndex) i = 2;
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    fseek(chan, m_lrp->m_frameOffsTable[TFrameId(i - 1)].m_offs, SEEK_SET);
Shinya Kitaoka 120a6e
    k = i - 1;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    fseek(chan, m_lrp->m_frameOffsTable[TFrameId(frameIndex)].m_offs, SEEK_SET);
Shinya Kitaoka 120a6e
    k = frameIndex;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
  for (; k <= frameIndex; k++) {
Shinya Kitaoka 120a6e
    m_lrp->m_frameOffsTable[TFrameId(k)] = TzlChunk(ftell(chan), 0);
Shinya Kitaoka 120a6e
    fread(&sbx0, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    fread(&sby0, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    fread(&sblx, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    fread(&sbly, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e
    fread(&actualBuffSize, sizeof(TINT32), 1, chan);
Shinya Kitaoka 120a6e

Shinya Kitaoka 120a6e
    fread(&xdpi, sizeof(double), 1, chan);
Shinya Kitaoka 120a6e
    fread(&ydpi, sizeof(double), 1, chan);
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
    sbx0           = swapTINT32(sbx0);
Shinya Kitaoka 120a6e
    sby0           = swapTINT32(sby0);
Shinya Kitaoka 120a6e
    sblx           = swapTINT32(sblx);
Shinya Kitaoka 120a6e
    sbly           = swapTINT32(sbly);
Shinya Kitaoka 120a6e
    actualBuffSize = swapTINT32(actualBuffSize);
Shinya Kitaoka 120a6e
    reverse((char *)&xdpi, sizeof(double));
Shinya Kitaoka 120a6e
    reverse((char *)&ydpi, sizeof(double));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
    imgBuffSize = m_lx * m_ly * sizeof(TPixelCM32);
Shinya Kitaoka 120a6e
    assert(actualBuffSize <= imgBuffSize);
Shinya Kitaoka 120a6e
    delete[] imgBuff;
Shinya Kitaoka 120a6e
    imgBuff = new UCHAR[imgBuffSize];
Shinya Kitaoka 120a6e
    fread(imgBuff, actualBuffSize, 1, chan);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  Header *header = (Header *)imgBuff;
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
#if !TNZ_LITTLE_ENDIAN
Shinya Kitaoka 120a6e
  header->m_lx      = swapTINT32(header->m_lx);
Shinya Kitaoka 120a6e
  header->m_ly      = swapTINT32(header->m_ly);
Shinya Kitaoka 120a6e
  header->m_rasType = (Header::RasType)swapTINT32(header->m_rasType);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  delete[] imgBuff;
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  static TImageInfo info;
Shinya Kitaoka 120a6e
  info.m_x0   = sbx0;
Shinya Kitaoka 120a6e
  info.m_y0   = sby0;
Shinya Kitaoka 120a6e
  info.m_x1   = sbx0 + sblx - 1;
Shinya Kitaoka 120a6e
  info.m_y1   = sby0 + sbly - 1;
Shinya Kitaoka 120a6e
  info.m_lx   = m_lx;
Shinya Kitaoka 120a6e
  info.m_ly   = m_ly;
Shinya Kitaoka 120a6e
  info.m_dpix = xdpi;
Shinya Kitaoka 120a6e
  info.m_dpiy = ydpi;
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
  // m_lrp->m_frameIndex = m_frameIndex;
Shinya Kitaoka 120a6e
  return &info;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
const TImageInfo *TImageReaderTzl::getImageInfo() const {
Shinya Kitaoka 120a6e
  if (m_lrp->m_version > 10 && !m_lrp->m_frameOffsTable.empty())
Shinya Kitaoka 120a6e
    return getImageInfo11();
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return getImageInfo10();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TDimension TImageReaderTzl::getSize() const { return TDimension(m_lx, m_ly); }
Toshihiro Shimizu 890ddd

Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd

Shinya Kitaoka 120a6e
TRect TImageReaderTzl::getBBox() const { return TRect(getSize()); }