50 virtual void reportError(
const char* error) {
53 const std::string& getErrorString()
const {
return _error; }
72 : _io(io ? io : &_defaultIo),
74 _premultiply(premultiply),
84 _baseMemUsed(sizeof(*this)),
85 _memUsed(_baseMemUsed),
99 for (std::vector<Level*>::iterator i =
_levels.begin(); i !=
_levels.end(); ++i) {
107 for (std::vector<Level*>::iterator i =
_levels.begin(); i !=
_levels.end(); ++i) {
108 if (*i) {
delete *i; *i = 0; }
124 std::vector<Level*>().swap(
_levels);
143 error =
"Ptex library doesn't currently support big-endian cpu's";
149 std::string errstr =
"Can't open ptex file: ";
150 errstr += pathArg; errstr +=
"\n"; errstr +=
_io->
lastError();
151 error = errstr.c_str();
158 std::string errstr =
"Not a ptex file: "; errstr += pathArg;
159 error = errstr.c_str();
166 s <<
"Unsupported ptex file version ("<<
_header.
version <<
"): " << pathArg;
184 TempErrorHandler tempErr;
199 pos +=
sizeof(uint64_t);
219 error = tempErr.getErrorString();
250 if (
_fp)
return true;
262 memset(&extheaderval, 0,
sizeof(extheaderval));
264 if (0 != memcmp(&headerval, &
_header,
sizeof(headerval)) ||
265 0 != memcmp(&extheaderval, &
_extheader,
sizeof(extheaderval)))
267 setError(
"Header mismatch on reopen of");
277 if (faceid >= 0 && uint32_t(faceid) <
_faceinfo.size())
293 (
int)(
sizeof(FaceInfo)*nfaces));
297 std::vector<uint32_t> faceids_r(nfaces);
353 if (index < 0 || index >=
int(
_entries.size())) {
399 size_t metaDataMemUsed =
sizeof(
MetaData);
412 for (
size_t i = 0, size =
_metaedits.size(); i < size; i++)
427 char* buff = useNew ?
new char[memsize] : (
char*)alloca(memsize);
432 char* end = ptr + memsize;
434 uint8_t keysize = *ptr++;
435 char* key = (
char*)ptr; ptr += keysize;
436 key[keysize-1] =
'\0';
437 uint8_t datatypeval = *ptr++;
438 uint32_t datasize; memcpy(&datasize, ptr,
sizeof(datasize));
439 ptr +=
sizeof(datasize);
440 char* data = ptr; ptr += datasize;
441 metadata->
addEntry((uint8_t)(keysize-1), key, datatypeval, datasize, data, metaDataMemUsed);
444 if (useNew)
delete [] buff;
453 char* buff = useNew ?
new char [memsize] : (
char*)alloca(memsize);
460 char* end = ptr + memsize;
462 uint8_t keysize = *ptr++;
463 char* key = (
char*)ptr; ptr += keysize;
464 uint8_t datatypeval = *ptr++;
465 uint32_t datasize; memcpy(&datasize, ptr,
sizeof(datasize));
466 ptr +=
sizeof(datasize);
467 uint32_t zipsizeval; memcpy(&zipsizeval, ptr,
sizeof(zipsizeval));
468 ptr +=
sizeof(zipsizeval);
469 metadata->
addLmdEntry((uint8_t)(keysize-1), key, datatypeval, datasize, pos, zipsizeval, metaDataMemUsed);
473 if (useNew)
delete [] buff;
487 endpos =
FilePos((uint64_t)-1);
490 while (pos < endpos) {
495 if (!
readBlock(&edittype,
sizeof(edittype),
false))
break;
496 if (!
readBlock(&editsize,
sizeof(editsize),
false))
break;
497 if (!editsize)
break;
499 pos =
tell() + editsize;
521 f.flags |= FaceInfo::flag_hasedits;
531 if (!f.isConstant()) {
558 assert(
_fp && size >= 0);
559 if (!
_fp || size < 0)
return false;
561 if (result == size) {
566 setError(
"PtexReader error: read failed (EOF)");
573 if (zipsize < 0 || unzipsize < 0)
return false;
588 int zresult = inflate(&
_zstream, zipsize ? Z_NO_FLUSH : Z_FINISH);
589 if (zresult == Z_STREAM_END)
break;
590 if (zresult != Z_OK) {
591 setError(
"PtexReader error: unzip failed, file corrupt");
597 int total = (int)
_zstream.total_out;
599 return total == unzipsize;
622 for (
size_t i = 0, size =
_faceedits.size(); i < size; i++) {
645 _reader->readFaceData(_offsets[tile], _fdh[tile], _tileres, _levelid, data);
659 size_t newMemUsed = 0;
678 uint32_t tileheadersize;
679 readBlock(&tileheadersize,
sizeof(tileheadersize));
690 int uw = res.u(), vw = res.v();
691 int npixels = uw * vw;
695 newMemUsed =
sizeof(
PackedFace) + unpackedSize;
697 char* tmp = useNew ?
new char [unpackedSize] : (
char*) alloca(unpackedSize);
707 if (useNew)
delete [] tmp;
722 getData(faceid, buffer, stride, f.res);
734 int resu = res.u(), resv = res.v();
736 if (stride == 0) stride = rowlen;
739 if (d->isConstant()) {
744 else if (d->isTiled()) {
746 Res tileres = d->tileRes();
747 int ntilesu = res.ntilesu(tileres);
748 int ntilesv = res.ntilesv(tileres);
749 int tileures = tileres.u();
750 int tilevres = tileres.v();
753 char* dsttilerow = (
char*) buffer;
754 for (
int i = 0; i < ntilesv; i++) {
755 char* dsttile = dsttilerow;
756 for (
int j = 0; j < ntilesu; j++) {
763 tilevres, tilerowlen);
764 dsttile += tilerowlen;
766 dsttilerow += stride * tilevres;
782 if (fi.isConstant() || fi.res == 0) {
800 if (fi.isConstant() || res == 0) {
805 int redu = fi.res.ulog2 - res.ulog2, redv = fi.res.vlog2 - res.vlog2;
807 if (redu == 0 && redv == 0) {
814 if (redu == redv && !fi.hasEdits()) {
818 if (
size_t(levelid) <
_levels.size()) {
826 if (
size_t(rfaceid) < level->
faces.size()) {
827 face =
getFace(levelid, level, rfaceid, res);
844 size_t newMemUsed = 0;
846 if (res.ulog2 < 0 || res.vlog2 < 0) {
847 std::cerr <<
"PtexReader::getData - reductions below 1 pixel not supported" << std::endl;
850 else if (redu < 0 || redv < 0) {
851 std::cerr <<
"PtexReader::getData - enlargements not supported" << std::endl;
857 std::cerr <<
"PtexReader::getData - anisotropic reductions not supported for triangle mesh" << std::endl;
871 blendu = (res.ulog2 & 1);
873 else blendu = redu > redv;
889 size_t tableNewMemUsed = 0;
891 if (face != newface) {
902 float* result,
int firstchan,
int nchannelsArg)
904 memset(result, 0,
sizeof(*result)*nchannelsArg);
908 if (nchannelsArg <= 0)
return;
913 data->getPixel(u, v, pixel);
916 int datasize = DataSize(
datatype());
918 pixel = (
char*) pixel + datasize * firstchan;
922 memcpy(result, pixel, datasize * nchannelsArg);
929 float* result,
int firstchan,
int nchannelsArg,
932 memset(result, 0, nchannelsArg);
936 if (nchannelsArg <= 0)
return;
941 data->getPixel(u, v, pixel);
944 int datasize = DataSize(
datatype());
946 pixel = (
char*) pixel + datasize * firstchan;
950 memcpy(result, pixel, datasize * nchannelsArg);
967 reducefn(_data,
_pixelsize * _res.u(), _res.u(), _res.v(),
1009 newtileres = newres;
1013 newtileres = _tileres;
1015 if (newtileres.ulog2 > newres.ulog2) newtileres.ulog2 = newres.ulog2;
1016 if (newtileres.vlog2 > newres.vlog2) newtileres.vlog2 = newres.vlog2;
1021 int newntiles = newres.ntiles(newtileres);
1023 if (newntiles == 1) {
1027 bool allConstant =
true;
1028 for (
int i = 0; i < _ntiles; i++) {
1030 allConstant = (allConstant && tile->
isConstant() &&
1040 else if (isTriangle) {
1043 int tileures = _tileres.u();
1044 int tilevres = _tileres.v();
1046 int dstride = sstride * _ntilesu;
1047 int dstepv = dstride * tilevres - sstride*(_ntilesu-1);
1049 char* tmp =
new char [_ntiles * _tileres.size() *
_pixelsize];
1051 for (
int i = 0; i < _ntiles;) {
1059 tmpptr += (i%_ntilesu) ? sstride : dstepv;
1067 reducefn(tmp,
_pixelsize * _res.u(), _res.u(), _res.v(),
1078 int tileures = _tileres.u();
1079 int tilevres = _tileres.v();
1082 int dstepu = dstride/_ntilesu;
1083 int dstepv = dstride*newres.v()/_ntilesv - dstepu*(_ntilesu-1);
1085 char* dst = (
char*) newface->
getData();
1086 for (
int i = 0; i < _ntiles;) {
1090 newres.u()/_ntilesu, newres.v()/_ntilesv,
1093 reducefn(tile->
getData(), sstride, tileures, tilevres,
1094 dst, dstride, _dt, _nchan);
1096 dst += (i%_ntilesu) ? dstepu : dstepv;
1100 for (
int i = 0; i < _ntiles; i++) tiles[i]->
release();
1114 int tileu = ui >> _tileres.ulog2;
1115 int tilev = vi >> _tileres.vlog2;
1117 tile->getPixel(ui - (tileu<<_tileres.ulog2),
1118 vi - (tilev<<_tileres.vlog2), result);
1132 int pntilesu = _parentface->ntilesu();
1133 int pntilesv = _parentface->ntilesv();
1134 int nu = pntilesu / _ntilesu;
1135 int nv = pntilesv / _ntilesv;
1137 int ntilesval = nu*nv;
1139 bool allConstant =
true;
1140 int ptile = (tile/_ntilesu) * nv * pntilesu + (tile%_ntilesu) * nu;
1141 for (
int i = 0; i < ntilesval;) {
1143 allConstant = (allConstant && tileval->
isConstant() &&
1147 ptile += (i%nu)? 1 : pntilesu - nu + 1;
1151 size_t newMemUsed = 0;
1165 int ptileures = _parentface->tileres().u();
1166 int ptilevres = _parentface->tileres().v();
1169 int dstepu = dstride/nu;
1170 int dstepv = dstride*_tileres.v()/nv - dstepu*(nu-1);
1172 char* dst = (
char*) newface->
getData();
1173 for (
int i = 0; i < ntilesval;) {
1177 _tileres.u()/nu, _tileres.v()/nv,
1180 _reducefn(tileval->
getData(), sstride, ptileures, ptilevres,
1181 dst, dstride, _dt, _nchan);
1183 dst += (i%nu) ? dstepu : dstepv;
1191 _reader->increaseMemUsed(newMemUsed);
const int EditMetaDataHeaderSize
const int FaceDataHeaderSize
const int EditFaceDataHeaderSize
void ConvertToFloat(float *dst, const void *src, DataType dt, int numChannels)
#define PTEX_NAMESPACE_END
Public API classes for reading, writing, caching, and filtering Ptex files.
Automatically acquire and release lock within enclosing scope.
Custom handler interface redirecting Ptex error messages.
Per-face texture data accessor.
virtual PtexFaceData * getTile(int tile)=0
Access a tile from the data block.
virtual bool isConstant()=0
True if this data block is constant.
virtual void * getData()=0
Access the data from this data block.
Value tryInsert(Key &key, Value value, size_t &newMemUsed)
Smart-pointer for acquiring and releasing API objects.
T * get() const
Get pointer value.
virtual FaceData * reduce(PtexReader *, Res newres, PtexUtils::ReduceFn, size_t &newMemUsed)
virtual FaceData * reduce(PtexReader *, Res newres, PtexUtils::ReduceFn, size_t &newMemUsed)=0
std::vector< FilePos > offsets
std::vector< FaceDataHeader > fdh
std::vector< FaceData * > faces
virtual FaceData * reduce(PtexReader *, Res newres, PtexUtils::ReduceFn, size_t &newMemUsed)
virtual FaceData * reduce(PtexReader *, Res newres, PtexUtils::ReduceFn, size_t &newMemUsed)
virtual void getPixel(int u, int v, void *result)
Read a single texel from the data block.
std::vector< FaceDataHeader > _fdh
void readTile(int tile, FaceData *&data)
std::vector< FilePos > _offsets
virtual PtexFaceData * getTile(int tile)
Access a tile from the data block.
DataType datatype() const
void readMetaDataBlock(MetaData *metadata, FilePos pos, int zipsize, int memsize, size_t &metaDataMemUsed)
std::vector< FilePos > _levelpos
virtual void getPixel(int faceid, int u, int v, float *result, int firstchan, int nchannels)
Access a single texel from the highest resolution texture .
std::vector< FaceEdit > _faceedits
virtual void release()
Release resources held by this pointer (pointer becomes invalid).
void increaseMemUsed(size_t amount)
FaceData * getFace(int levelid, Level *level, int faceid, Res res)
Level * getLevel(int levelid)
FaceData * errorData(bool deleteOnRelease=false)
void computeOffsets(FilePos pos, int noffsets, const FaceDataHeader *fdh, FilePos *offsets)
virtual PtexMetaData * getMetaData()
Access meta data.
virtual void getData(int faceid, void *buffer, int stride)
Access texture data for a face at highest-resolution.
std::vector< LevelInfo > _levelinfo
PtexReader(bool premultiply, PtexInputHandler *inputHandler, PtexErrorHandler *errorHandler)
virtual const Ptex::FaceInfo & getFaceInfo(int faceid)
Access resolution and adjacency information about a face.
void readLargeMetaDataHeaders(MetaData *metadata, FilePos pos, int zipsize, int memsize, size_t &metaDataMemUsed)
void readFace(int levelid, Level *level, int faceid, Res res)
std::vector< uint32_t > _rfaceids
std::vector< MetaEdit > _metaedits
void readFaceData(FilePos pos, FaceDataHeader fdh, Res res, int levelid, FaceData *&face)
bool readBlock(void *data, int size, bool reportError=true)
std::vector< Level * > _levels
std::vector< FaceInfo > _faceinfo
PtexInputHandler::Handle _fp
bool readZipBlock(void *data, int zipsize, int unzipsize)
void readLevel(int levelid, Level *&level)
std::vector< char > _errorPixel
bool open(const char *path, Ptex::String &error)
void setError(const char *error)
Interface for reading data from a ptex file.
virtual const char * path()=0
Path that file was opened with.
static PtexTexture * open(const char *path, Ptex::String &error, bool premultiply=0)
Open a ptex file for reading.
void genRfaceids(const FaceInfo *faces, int nfaces, uint32_t *rfaceids, uint32_t *faceids)
void reduceu(const void *src, int sstride, int uw, int vw, void *dst, int dstride, DataType dt, int nchan)
void decodeDifference(void *data, int size, DataType dt)
void reducev(const void *src, int sstride, int uw, int vw, void *dst, int dstride, DataType dt, int nchan)
void fill(const void *src, void *dst, int dstride, int ures, int vres, int pixelsize)
void reduceTri(const void *src, int sstride, int w, int, void *dst, int dstride, DataType dt, int nchan)
void copy(const void *src, int sstride, void *dst, int dstride, int vres, int rowlen)
void ReduceFn(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
void multalpha(void *data, int npixels, DataType dt, int nchannels, int alphachan)
void interleave(const void *src, int sstride, int uw, int vw, void *dst, int dstride, DataType dt, int nchan)
Information about a face, as stored in the Ptex file header.
Pixel resolution of a given texture.