tahoma2d/toonz/sources/image/zcc/tiio_zcc.cpp

342 lines
8.8 KiB
C++
Raw Normal View History

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(), &sectorsPerCluster, &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