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