#include "tiio_zcc.h"
//#include "tparam.h"
#include "tsystem.h"
#ifdef DOPO_LO_FACCIAMO
#define PID_TAG(X) \
(((X) >> 24) | ((X >> 8) & 0x0000FF00) | ((X << 8) & 0x00FF0000) | \
((X) << 24))
/*
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 >
0 |
<RAWDATA
<FRAMEDATA
*/
/*
class ZCCParser {
TFile &m_file;
public:
ZCCParser(TFile&file) : m_file(file)
{
m_file.seek(0);
string tag = readTag();
}
private:
string readTag()
{
}
};
*/
//-----------------------------------------------------------
TReaderWriterInfo *TReaderWriterInfoZCC::create(const string &) {
return new TReaderWriterInfoZCC();
}
//-----------------------------------------------------------
TReaderWriterInfoZCC::TReaderWriterInfoZCC() {
int c = 0;
TIntEnumParamP type = new TIntEnumParam();
type->addItem(c++, "RGBM Uncompressed");
type->addItem(c++, "YUV Uncompressed");
addParam("codec", type.getPointer());
}
//-----------------------------------------------------------
TReaderWriterInfo *TReaderWriterInfoZCC::clone() const {
return new TReaderWriterInfoZCC(*this);
}
//-----------------------------------------------------------
TReaderWriterInfoZCC::~TReaderWriterInfoZCC() {}
//-----------------------------------------------------------
TReaderWriterInfoZCC::TReaderWriterInfoZCC(const TReaderWriterInfoZCC &src)
: TReaderWriterInfo(src) {}
//===========================================================
class TImageReaderWriterZCC : public TImageReaderWriter {
public:
TImageReaderWriterZCC(const TFilePath &fp, int index,
TLevelReaderWriterZCC *lrw);
private:
// not implemented
TImageReaderWriterZCC(const TImageReaderWriterZCC &);
TImageReaderWriterZCC &operator=(const TImageReaderWriterZCC &src);
public:
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;
private:
TLevelReaderWriterZCC *m_lrw;
};
//------------------------------------------------------------------------------
using namespace TFileConsts;
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);
}
//-----------------------------------------------------------
void TLevelReaderWriterZCC::saveSoundTrack(TSoundTrack *st) {}
//-----------------------------------------------------------
TLevelP TLevelReaderWriterZCC::loadInfo() {
TLevelP level;
if (!m_file.size()) return level;
m_file.seek(0);
UCHAR *buffer = new UCHAR[m_blockSize];
m_file.read(buffer, m_blockSize);
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];
delete[] buffer;
TINT64 offset = m_blockSize;
TINT64 fs = m_file.size();
while (offset < fs) {
m_file.seek(offset);
m_file.read(buffer, m_blockSize);
ULONG frameId = *(ULONG *)&buffer[0];
ULONG width = *(ULONG *)&buffer[4];
ULONG height = *(ULONG *)&buffer[8];
ULONG rawDataSize = *(ULONG *)&buffer[12];
TINT64 d = rawDataSize + 16;
int headerSize = 16;
int dataSize = rawDataSize + headerSize;
long bufferSize = tceil(dataSize / (double)m_blockSize) * m_blockSize;
m_map[frameId] = C(offset, bufferSize, width, height);
level->setFrame(TFrameId(frameId), TImageP());
offset += bufferSize;
}
return level;
}
//-----------------------------------------------------------
TImageReaderWriterP TLevelReaderWriterZCC::getFrameReaderWriter(TFrameId id) {
TImageReaderWriterZCC *iwm =
new TImageReaderWriterZCC(m_path, id.getNumber(), this);
return TImageReaderWriterP(iwm);
}
//-----------------------------------------------------------
TLevelReaderWriterZCC::~TLevelReaderWriterZCC() {
m_file.seek(0);
UCHAR *buffer = new UCHAR[m_blockSize];
memset(buffer, 0, m_blockSize);
ULONG *magicNumber = (ULONG *)&buffer[0];
*magicNumber = PID_TAG('ZCC ');
ULONG *majorRevision = (ULONG *)&buffer[4];
*majorRevision = 0x0001;
ULONG *minorRevision = (ULONG *)&buffer[8];
*minorRevision = 0x0000;
ULONG *frameRateNum = (ULONG *)&buffer[12];
*frameRateNum = 25;
ULONG *frameRateDen = (ULONG *)&buffer[16];
*frameRateDen = 1;
ULONG *frameCount = (ULONG *)&buffer[20];
*frameCount = 0xffff;
ULONG *compressorType = (ULONG *)&buffer[24];
*compressorType = PID_TAG('RGBM');
m_file.write(buffer, m_blockSize);
delete[] buffer;
}
//-----------------------------------------------------------
TImageReaderWriterZCC::TImageReaderWriterZCC(const TFilePath &fp, int index,
TLevelReaderWriterZCC *lrw)
: TImageReaderWriter(fp), m_lrw(lrw), m_index(index) {}
//-----------------------------------------------------------
void TImageReaderWriterZCC::save(const TImageP &img) {
TFile &file = m_lrw->m_file;
TRaster32P ras = TRasterImageP(img)->getRaster();
int rasDataSize = ras->getRowSize() * ras->getLy();
int headerSize = 16;
int dataSize = rasDataSize + headerSize;
int bufferSize =
tceil(dataSize / (double)m_lrw->m_blockSize) * m_lrw->m_blockSize;
TINT64 offset = bufferSize * m_index + m_lrw->m_blockSize;
m_lrw->m_map[m_index] = C(offset, bufferSize, ras->getLx(), ras->getLy());
if (!file.seek(offset /*per l'header*/))
throw TImageException(m_path, file.getLastError());
TRasterImageP rasImage = img;
UCHAR *buffer = new UCHAR[bufferSize];
ULONG *frameId = (ULONG *)&buffer[0];
*frameId = m_index;
ULONG *width = (ULONG *)&buffer[4];
*width = ras->getLx();
ULONG *height = (ULONG *)&buffer[8];
*height = ras->getLy();
bwww ULONG *rawDataSize = (ULONG *)&buffer[12];
*rawDataSize = rasDataSize;
memcpy(&buffer[16], ras->getRawData(), rasDataSize);
if (!file.write(buffer, bufferSize))
throw TImageException(m_path, file.getLastError());
delete[] buffer;
}
//-----------------------------------------------------------
TImageP TImageReaderWriterZCC::load() {
C c = m_lrw->m_map[m_index];
TRaster32P ras(c.m_lx, c.m_ly);
load(ras);
return TImageP(TRasterImageP(ras));
}
//-----------------------------------------------------------
void TImageReaderWriterZCC::load(const TRasterP &ras, const TPoint &pos,
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);
if (it == m_lrw->m_map.end())
return;
*/
C c = m_lrw->m_map[m_index];
if (!file.seek(c.m_offset))
throw TImageException(m_path, file.getLastError());
UCHAR *buffer = new UCHAR[c.m_size];
if (!file.read(buffer, c.m_size))
throw TImageException(m_path, file.getLastError());
ULONG *frameId = (ULONG *)&buffer[0];
assert(*frameId == (ULONG)m_index);
ULONG *width = (ULONG *)&buffer[4];
ULONG *height = (ULONG *)&buffer[8];
ULONG *rawDataSize = (ULONG *)&buffer[12];
assert((ULONG)ras->getLx() == *width);
assert((ULONG)ras->getLy() == *height);
memcpy(ras->getRawData(), &buffer[16], *rawDataSize);
delete[] buffer;
}
#endif