#ifndef PtexWriter_h
#define PtexWriter_h
#include "PtexPlatform.h"
#include "zlib/zlib.h"
#include <map>
#include <vector>
#include <stdio.h>
#include "Ptexture.h"
#include "PtexIO.h"
#include "PtexReader.h"
class PtexWriterBase : public PtexWriter, public PtexIO {
public:
virtual void setBorderModes(Ptex::BorderMode uBorderMode, Ptex::BorderMode vBorderMode)
{
_extheader.ubordermode = uBorderMode;
_extheader.vbordermode = vBorderMode;
}
virtual void writeMeta(
const char* key,
const char*
value);
virtual void writeMeta(
const char* key,
const int8_t* value,
int count);
virtual void writeMeta(const char* key, const int16_t* value, int count);
virtual void writeMeta(const char* key, const int32_t* value, int count);
virtual void writeMeta(const char* key, const float* value, int count);
virtual void writeMeta(const char* key, const double* value, int count);
virtual void writeMeta(PtexMetaData*
data);
virtual bool close(Ptex::String& error);
virtual void release();
bool ok(Ptex::String& error) {
if (!_ok) getError(error);
return _ok;
}
void getError(Ptex::String& error) {
error = (_error + "\nPtex file: " + _path).c_str();
}
protected:
struct MetaEntry {
MetaDataType datatype;
std::vector<uint8_t>
data;
MetaEntry() : datatype(MetaDataType(0)),
data() {}
};
virtual void finish() = 0;
PtexWriterBase(const char* path,
Ptex::MeshType mt, Ptex::DataType dt,
int nchannels, int alphachan, int nfaces,
bool compress);
virtual ~PtexWriterBase();
int writeBlank(FILE* fp,
int size);
int writeBlock(FILE* fp, const void* data, int size);
int writeZipBlock(FILE* fp, const void* data, int size, bool finish=true);
int readBlock(FILE* fp, void* data, int size);
int copyBlock(FILE*
dst, FILE*
src, FilePos pos,
int size);
Res calcTileRes(Res faceres);
virtual void addMetaData(
const char* key, MetaDataType
t,
const void* value,
int size);
void writeConstFaceBlock(FILE* fp, const void* data, FaceDataHeader& fdh);
void writeFaceBlock(FILE* fp,
const void* data,
int stride, Res
res,
FaceDataHeader& fdh);
void writeFaceData(FILE* fp, const void* data, int stride, Res res,
FaceDataHeader& fdh);
void writeReduction(FILE* fp, const void* data, int stride, Res res);
int writeMetaDataBlock(FILE* fp, MetaEntry& val);
void setError(
const std::string& error) { _error = error; _ok =
false; }
bool storeFaceInfo(int faceid, FaceInfo& dest, const FaceInfo& src, int flags=0);
bool _ok;
FILE* _tilefp;
Header _header;
ExtHeader _extheader;
int _pixelSize;
std::vector<MetaEntry> _metadata;
std::map<std::string,int> _metamap;
z_stream_s _zstream;
PtexUtils::ReduceFn* _reduceFn;
};
class PtexMainWriter : public PtexWriterBase {
public:
PtexMainWriter(const char* path, PtexTexture* tex,
Ptex::MeshType mt, Ptex::DataType dt,
int nchannels, int alphachan, int nfaces, bool genmipmaps);
virtual bool close(Ptex::String& error);
virtual bool writeFace(
int faceid,
const FaceInfo&
f,
const void*
data,
int stride);
virtual bool writeConstantFace(
int faceid,
const FaceInfo&
f,
const void*
data);
protected:
virtual ~PtexMainWriter();
virtual void addMetaData(
const char* key, MetaDataType
t,
const void*
value,
int size)
{
PtexWriterBase::addMetaData(key, t, value, size);
_hasNewData = true;
}
private:
virtual void finish();
void generateReductions();
void flagConstantNeighorhoods();
void storeConstValue(
int faceid,
const void*
data,
int stride, Res
res);
void writeMetaData(FILE* fp);
FILE* _tmpfp;
bool _hasNewData;
bool _genmipmaps;
std::vector<FaceInfo> _faceinfo;
std::vector<uint8_t> _constdata;
std::vector<uint32_t> _rfaceids;
std::vector<uint32_t> _faceids_r;
static const int MinReductionLog2 =2;
struct LevelRec {
std::vector<FilePos> pos;
std::vector<FaceDataHeader> fdh;
};
std::vector<LevelRec> _levels;
std::vector<FilePos> _rpos;
PtexReader* _reader;
};
class PtexIncrWriter : public PtexWriterBase {
public:
PtexIncrWriter(const char* path, FILE* fp,
Ptex::MeshType mt, Ptex::DataType dt,
int nchannels, int alphachan, int nfaces);
virtual bool close(Ptex::String& error);
virtual bool writeFace(
int faceid,
const FaceInfo&
f,
const void*
data,
int stride);
virtual bool writeConstantFace(
int faceid,
const FaceInfo&
f,
const void*
data);
protected:
void writeMetaDataEdit();
virtual void finish();
virtual ~PtexIncrWriter();
private:
FILE* _fp;
};
#endif