Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tiio_zcc.h"
Toshihiro Shimizu 890ddd
//#include "tparam.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DOPO_LO_FACCIAMO
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#define PID_TAG(X)                                                             \
Shinya Kitaoka 120a6e
  (((X) >> 24) | ((X >> 8) & 0x0000FF00) | ((X << 8) & 0x00FF0000) |           \
Shinya Kitaoka 120a6e
   ((X) << 24))
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
HEADER 'HDR '  32 bytes >
Toshihiro Shimizu 890ddd
  0 |  4  |  Magic number 'ZCC '
Toshihiro Shimizu 890ddd
  4 |  4  |  Major revision
Toshihiro Shimizu 890ddd
  8 |  4  |  Minor revision
Toshihiro Shimizu 890ddd
 12 |  4  |  Frame rate num
Toshihiro Shimizu 890ddd
 16 |  4  |  Frame rate den
Toshihiro Shimizu 890ddd
 20 |  4  |  Frame count
Toshihiro Shimizu 890ddd
 24 |  4  |  Compressor type ( 'YUV2', 'RGBM' )
Toshihiro Shimizu 890ddd
 28 |  4  |  Padding (future use)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FRAMEDATA 'FRME' >
Toshihiro Shimizu 890ddd
  0 FRAMEDESCRIPTOR 'DSCR' 16 bytes >
Toshihiro Shimizu 890ddd
     0 |  4  |  Frame ID
Toshihiro Shimizu 890ddd
     4 |  4  |  Width
Toshihiro Shimizu 890ddd
     8 |  4  |  Height
Toshihiro Shimizu 890ddd
    12 |  4  |  RawData size
Toshihiro Shimizu 890ddd
   
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  16 RAWDATA 'DATA' RawDataSize >
Shinya Kitaoka 120a6e
     0 |
Toshihiro Shimizu 890ddd
   
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
class ZCCParser {
Toshihiro Shimizu 890ddd
TFile &m_file;
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
  ZCCParser(TFile&file) : m_file(file)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    m_file.seek(0);
Toshihiro Shimizu 890ddd
    string tag = readTag();
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
  string readTag()
Toshihiro Shimizu 890ddd
    {
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TReaderWriterInfo *TReaderWriterInfoZCC::create(const string &) {
Shinya Kitaoka 120a6e
  return new TReaderWriterInfoZCC();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TReaderWriterInfoZCC::TReaderWriterInfoZCC() {
Shinya Kitaoka 120a6e
  int c               = 0;
Shinya Kitaoka 120a6e
  TIntEnumParamP type = new TIntEnumParam();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  type->addItem(c++, "RGBM Uncompressed");
Shinya Kitaoka 120a6e
  type->addItem(c++, "YUV  Uncompressed");
Shinya Kitaoka 120a6e
  addParam("codec", type.getPointer());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TReaderWriterInfo *TReaderWriterInfoZCC::clone() const {
Shinya Kitaoka 120a6e
  return new TReaderWriterInfoZCC(*this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TReaderWriterInfoZCC::~TReaderWriterInfoZCC() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TReaderWriterInfoZCC::TReaderWriterInfoZCC(const TReaderWriterInfoZCC &src)
Shinya Kitaoka 120a6e
    : TReaderWriterInfo(src) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===========================================================
Shinya Kitaoka 120a6e
class TImageReaderWriterZCC : public TImageReaderWriter {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TImageReaderWriterZCC(const TFilePath &fp, int index,
Shinya Kitaoka 120a6e
                        TLevelReaderWriterZCC *lrw);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  // not implemented
Shinya Kitaoka 120a6e
  TImageReaderWriterZCC(const TImageReaderWriterZCC &);
Shinya Kitaoka 120a6e
  TImageReaderWriterZCC &operator=(const TImageReaderWriterZCC &src);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  void save(const TImageP &);
Shinya Kitaoka 120a6e
  TImageP load();
Shinya Kitaoka 120a6e
  void load(const TRasterP &ras, const TPoint &pos = TPoint(0, 0),
Shinya Kitaoka 120a6e
            int shrinkX = 1, int shrinkY = 1);
Shinya Kitaoka 120a6e
  int m_index;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  TLevelReaderWriterZCC *m_lrw;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace TFileConsts;
Shinya Kitaoka 120a6e
TLevelReaderWriterZCC::TLevelReaderWriterZCC(const TFilePath &path,
Shinya Kitaoka 120a6e
                                             TReaderWriterInfo *winfo)
Shinya Kitaoka 120a6e
    : TLevelReaderWriter(path, winfo)
Shinya Kitaoka 120a6e
    , m_file(path, kReadWrite | kUnbuffered | kOpenAlways)
Shinya Kitaoka 120a6e
    , m_indexFile(path.withType("ndx"), kReadWrite | kOpenAlways)
Shinya Kitaoka 120a6e
    , m_initDone(false)
Shinya Kitaoka 120a6e
    , m_blockSize(0) {
Shinya Kitaoka 120a6e
  if (!m_file.isOpen()) throw TImageException(path, m_file.getLastError());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFilePathSet fps = TSystem::getDisks();
Shinya Kitaoka 120a6e
  TFilePath disk;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (TFilePathSet::iterator it = fps.begin(); it != fps.end(); it++) {
Shinya Kitaoka 120a6e
    disk = *it;
Shinya Kitaoka 120a6e
    if (disk.isAncestorOf(m_path)) {
Shinya Kitaoka 120a6e
      DWORD sectorsPerCluster;
Shinya Kitaoka 120a6e
      // DWORD bytesPerSector;
Shinya Kitaoka 120a6e
      DWORD numberOfFreeClusters;
Shinya Kitaoka 120a6e
      DWORD totalNumberOfClusters;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      BOOL rc = GetDiskFreeSpaceW(
Shinya Kitaoka 120a6e
          disk.getWideString().c_str(), §orsPerCluster, &m_blockSize,
Shinya Kitaoka 120a6e
          &numberOfFreeClusters, &totalNumberOfClusters);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  assert(m_blockSize);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TLevelReaderWriterZCC::saveSoundTrack(TSoundTrack *st) {}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TLevelP TLevelReaderWriterZCC::loadInfo() {
Shinya Kitaoka 120a6e
  TLevelP level;
Shinya Kitaoka 120a6e
  if (!m_file.size()) return level;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_file.seek(0);
Shinya Kitaoka 120a6e
  UCHAR *buffer = new UCHAR[m_blockSize];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_file.read(buffer, m_blockSize);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG magicNumber = *(ULONG *)&buffer[0];
Shinya Kitaoka 120a6e
  assert(magicNumber == PID_TAG('ZCC '));
Shinya Kitaoka 120a6e
  ULONG majorRevision  = *(ULONG *)&buffer[4];
Shinya Kitaoka 120a6e
  ULONG minorRevision  = *(ULONG *)&buffer[8];
Shinya Kitaoka 120a6e
  ULONG frameRateNum   = *(ULONG *)&buffer[12];
Shinya Kitaoka 120a6e
  ULONG frameRateDen   = *(ULONG *)&buffer[16];
Shinya Kitaoka 120a6e
  ULONG frameCount     = *(ULONG *)&buffer[20];
Shinya Kitaoka 120a6e
  ULONG compressorType = *(ULONG *)&buffer[24];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  delete[] buffer;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TINT64 offset = m_blockSize;
Shinya Kitaoka 120a6e
  TINT64 fs     = m_file.size();
Shinya Kitaoka 120a6e
  while (offset < fs) {
Shinya Kitaoka 120a6e
    m_file.seek(offset);
Shinya Kitaoka 120a6e
    m_file.read(buffer, m_blockSize);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ULONG frameId     = *(ULONG *)&buffer[0];
Shinya Kitaoka 120a6e
    ULONG width       = *(ULONG *)&buffer[4];
Shinya Kitaoka 120a6e
    ULONG height      = *(ULONG *)&buffer[8];
Shinya Kitaoka 120a6e
    ULONG rawDataSize = *(ULONG *)&buffer[12];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TINT64 d = rawDataSize + 16;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int headerSize = 16;
Shinya Kitaoka 120a6e
    int dataSize   = rawDataSize + headerSize;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    long bufferSize = tceil(dataSize / (double)m_blockSize) * m_blockSize;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_map[frameId] = C(offset, bufferSize, width, height);
Shinya Kitaoka 120a6e
    level->setFrame(TFrameId(frameId), TImageP());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    offset += bufferSize;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return level;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageReaderWriterP TLevelReaderWriterZCC::getFrameReaderWriter(TFrameId id) {
Shinya Kitaoka 120a6e
  TImageReaderWriterZCC *iwm =
Shinya Kitaoka 120a6e
      new TImageReaderWriterZCC(m_path, id.getNumber(), this);
Shinya Kitaoka 120a6e
  return TImageReaderWriterP(iwm);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TLevelReaderWriterZCC::~TLevelReaderWriterZCC() {
Shinya Kitaoka 120a6e
  m_file.seek(0);
Shinya Kitaoka 120a6e
  UCHAR *buffer = new UCHAR[m_blockSize];
Shinya Kitaoka 120a6e
  memset(buffer, 0, m_blockSize);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *magicNumber = (ULONG *)&buffer[0];
Shinya Kitaoka 120a6e
  *magicNumber       = PID_TAG('ZCC ');
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *majorRevision = (ULONG *)&buffer[4];
Shinya Kitaoka 120a6e
  *majorRevision       = 0x0001;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *minorRevision = (ULONG *)&buffer[8];
Shinya Kitaoka 120a6e
  *minorRevision       = 0x0000;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *frameRateNum = (ULONG *)&buffer[12];
Shinya Kitaoka 120a6e
  *frameRateNum       = 25;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *frameRateDen = (ULONG *)&buffer[16];
Shinya Kitaoka 120a6e
  *frameRateDen       = 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *frameCount = (ULONG *)&buffer[20];
Shinya Kitaoka 120a6e
  *frameCount       = 0xffff;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *compressorType = (ULONG *)&buffer[24];
Shinya Kitaoka 120a6e
  *compressorType       = PID_TAG('RGBM');
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_file.write(buffer, m_blockSize);
Shinya Kitaoka 120a6e
  delete[] buffer;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageReaderWriterZCC::TImageReaderWriterZCC(const TFilePath &fp, int index,
Shinya Kitaoka 120a6e
                                             TLevelReaderWriterZCC *lrw)
Shinya Kitaoka 120a6e
    : TImageReaderWriter(fp), m_lrw(lrw), m_index(index) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TImageReaderWriterZCC::save(const TImageP &img) {
Shinya Kitaoka 120a6e
  TFile &file = m_lrw->m_file;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRaster32P ras = TRasterImageP(img)->getRaster();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int rasDataSize = ras->getRowSize() * ras->getLy();
Shinya Kitaoka 120a6e
  int headerSize  = 16;
Shinya Kitaoka 120a6e
  int dataSize    = rasDataSize + headerSize;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int bufferSize =
Shinya Kitaoka 120a6e
      tceil(dataSize / (double)m_lrw->m_blockSize) * m_lrw->m_blockSize;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TINT64 offset         = bufferSize * m_index + m_lrw->m_blockSize;
Shinya Kitaoka 120a6e
  m_lrw->m_map[m_index] = C(offset, bufferSize, ras->getLx(), ras->getLy());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!file.seek(offset /*per l'header*/))
Shinya Kitaoka 120a6e
    throw TImageException(m_path, file.getLastError());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterImageP rasImage = img;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UCHAR *buffer = new UCHAR[bufferSize];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *frameId = (ULONG *)&buffer[0];
Shinya Kitaoka 120a6e
  *frameId       = m_index;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *width = (ULONG *)&buffer[4];
Shinya Kitaoka 120a6e
  *width       = ras->getLx();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *height           = (ULONG *)&buffer[8];
Shinya Kitaoka 120a6e
  *height                 = ras->getLy();
Shinya Kitaoka 120a6e
  bwww ULONG *rawDataSize = (ULONG *)&buffer[12];
Shinya Kitaoka 120a6e
  *rawDataSize            = rasDataSize;
Shinya Kitaoka 120a6e
  memcpy(&buffer[16], ras->getRawData(), rasDataSize);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!file.write(buffer, bufferSize))
Shinya Kitaoka 120a6e
    throw TImageException(m_path, file.getLastError());
Shinya Kitaoka 120a6e
  delete[] buffer;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TImageP TImageReaderWriterZCC::load() {
Shinya Kitaoka 120a6e
  C c = m_lrw->m_map[m_index];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRaster32P ras(c.m_lx, c.m_ly);
Shinya Kitaoka 120a6e
  load(ras);
Shinya Kitaoka 120a6e
  return TImageP(TRasterImageP(ras));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TImageReaderWriterZCC::load(const TRasterP &ras, const TPoint &pos,
Shinya Kitaoka 120a6e
                                 int shrinkX, int shrinkY) {
Shinya Kitaoka 120a6e
  if (!m_lrw->m_initDone) {
Shinya Kitaoka 120a6e
    //
Shinya Kitaoka 120a6e
    // write header
Shinya Kitaoka 120a6e
    //
Shinya Kitaoka 120a6e
    m_lrw->m_initDone = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TFile &file = m_lrw->m_file;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
std::map<int, c="">::iterator it = std::find(m_lrw->m_map.begin(),</int,>
Shinya Kitaoka 120a6e
m_lrw->m_map.end(), m_index);
Toshihiro Shimizu 890ddd
if (it == m_lrw->m_map.end())
Shinya Kitaoka 120a6e
return;
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  C c = m_lrw->m_map[m_index];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!file.seek(c.m_offset))
Shinya Kitaoka 120a6e
    throw TImageException(m_path, file.getLastError());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UCHAR *buffer = new UCHAR[c.m_size];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!file.read(buffer, c.m_size))
Shinya Kitaoka 120a6e
    throw TImageException(m_path, file.getLastError());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *frameId = (ULONG *)&buffer[0];
Shinya Kitaoka 120a6e
  assert(*frameId == (ULONG)m_index);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *width = (ULONG *)&buffer[4];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *height = (ULONG *)&buffer[8];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ULONG *rawDataSize = (ULONG *)&buffer[12];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert((ULONG)ras->getLx() == *width);
Shinya Kitaoka 120a6e
  assert((ULONG)ras->getLy() == *height);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  memcpy(ras->getRawData(), &buffer[16], *rawDataSize);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  delete[] buffer;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif