50 virtual void reportError(
const char* error) {
53 const std::string& getErrorString()
const {
return _error; }
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;
172 if (!(
_header.meshtype == mt_triangle ||
_header.meshtype == mt_quad)) {
174 s <<
"Invalid mesh type (" <<
_header.meshtype <<
"): " << pathArg;
184 TempErrorHandler tempErr;
199 pos +=
sizeof(uint64_t);
219 error = tempErr.getErrorString();
230 if (!
readlock.trylock())
return false;
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);
318 for (
int i = 0; i <
_header.nlevels; i++) {
353 if (index < 0 || index >=
int(
_entries.size())) {
399 size_t metaDataMemUsed =
sizeof(
MetaData);
404 _header.metadatazipsize,
_header.metadatamemsize, metaDataMemUsed);
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;
518 if (faceid < 0 ||
size_t(faceid) >=
_header.nfaces)
return;
521 f.flags |= FaceInfo::flag_hasedits;
531 if (!f.isConstant()) {
558 assert(
_fp && size >= 0);
559 if (!
_fp || size < 0)
return false;
560 int result = (int)
_io->read(data, size,
_fp);
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++) {
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);
728 if (!
_ok || faceid < 0 ||
size_t(faceid) >=
_header.nfaces) {
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;
777 if (!
_ok || faceid < 0 ||
size_t(faceid) >=
_header.nfaces) {
782 if (fi.isConstant() || fi.res == 0) {
795 if (!
_ok || faceid < 0 ||
size_t(faceid) >=
_header.nfaces) {
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;
854 else if (
_header.meshtype == mt_triangle)
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;
890 face =
_reductions.tryInsert(key, newface, tableNewMemUsed);
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);
1009 newtileres = newres;
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) {
1047 int dstepv = dstride * tilevres - sstride*(
_ntilesu-1);
1051 for (
int i = 0; i <
_ntiles;) {
1059 tmpptr += (i%
_ntilesu) ? sstride : dstepv;
1085 char* dst = (
char*) newface->
getData();
1086 for (
int i = 0; i <
_ntiles;) {
1093 reducefn(tile->
getData(), sstride, tileures, tilevres,
1096 dst += (i%
_ntilesu) ? dstepu : dstepv;
1117 tile->getPixel(ui - (tileu<<
_tileres.ulog2),
1118 vi - (tilev<<
_tileres.vlog2), result);
1137 int ntilesval = nu*nv;
1139 bool allConstant =
true;
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;
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;) {
1183 dst += (i%nu) ? dstepu : dstepv;
1191 _reader->increaseMemUsed(newMemUsed);
const int EditMetaDataHeaderSize
const int FaceDataHeaderSize
const int EditFaceDataHeaderSize
AutoLock< Mutex > AutoMutex
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.
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.
Smart-pointer for acquiring and releasing API objects.
T * get() const
Get pointer value.
ConstantFace(int pixelsize)
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
PackedFace(Res resArg, int pixelsize, int size)
virtual FaceData * reduce(PtexReader *, Res newres, PtexUtils::ReduceFn, size_t &newMemUsed)
std::vector< FaceData * > _tiles
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
TiledFaceBase * _parentface
virtual PtexFaceData * getTile(int tile)
Access a tile from the data block.
PtexUtils::ReduceFn * _reducefn
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
DefaultInputHandler _defaultIo
volatile size_t _blockReads
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.