66         error = 
"Ptex library doesn't currently support big-endian cpu's";
 
   72         std::string errstr = 
"Can't open ptex file: ";
 
   74         error = errstr.
c_str();
 
   79         std::string errstr = 
"Not a ptex file: "; errstr += 
path;
 
   80         error = errstr.
c_str();
 
  102                           pos += 
sizeof(uint64_t); 
 
  129       _io(io ? io : &_defaultIo),
 
  130       _premultiply(premultiply),
 
  187     if (faceid >= 0 && uint32_t(faceid) < 
_faceinfo.size())
 
  207         std::vector<uint32_t> faceids_r(nfaces);
 
  213         for (
int i = 0; i < nfaces; i++)
 
  267     MetaMap::iterator iter = 
_map.find(key);
 
  268     if (iter == 
_map.end()) {
 
  273     Entry* e = &iter->second;
 
  341     for (
size_t i = 0, size = 
_metaedits.size(); i < size; i++)
 
  358     for (
size_t i = 0, size = 
_metaedits.size(); i < size; i++)
 
  376     char* buff = useMalloc ? (
char*) malloc(memsize) : (
char*)alloca(memsize);
 
  381         char* end = ptr + memsize;
 
  383             uint8_t keysize = *ptr++;
 
  384             char* key = (
char*)ptr; ptr += keysize;
 
  385             key[keysize-1] = 
'\0';
 
  387             uint32_t datasize; memcpy(&datasize, ptr, 
sizeof(datasize));
 
  388             ptr += 
sizeof(datasize);
 
  389             char* data = ptr; ptr += datasize;
 
  390             metadata->
addEntry((uint8_t)(keysize-1), key, datatype, datasize, data);
 
  393     if (useMalloc) free(buff);
 
  402     char* buff = useMalloc ? (
char*) malloc(memsize) : (
char*)alloca(memsize);
 
  409         char* end = ptr + memsize;
 
  411             uint8_t keysize = *ptr++;
 
  412             char* key = (
char*)ptr; ptr += keysize;
 
  414             uint32_t datasize; memcpy(&datasize, ptr, 
sizeof(datasize));
 
  415             ptr += 
sizeof(datasize);
 
  416             uint32_t zipsize; memcpy(&zipsize, ptr, 
sizeof(zipsize));
 
  417             ptr += 
sizeof(zipsize);
 
  418             metadata->
addLmdEntry((uint8_t)(keysize-1), key, datatype, datasize, pos, zipsize);
 
  422     if (useMalloc) free(buff);
 
  436         endpos = 
FilePos((uint64_t)-1);
 
  439     while (pos < endpos) {
 
  444         if (!
readBlock(&edittype, 
sizeof(edittype),  
false)) 
break;
 
  445         if (!
readBlock(&editsize, 
sizeof(editsize),  
false)) 
break;
 
  446         if (!editsize) 
break;
 
  448         pos = 
tell() + editsize;
 
  506     if (result == size) {
 
  513         setError(
"PtexReader error: read failed (EOF)");
 
  530         int zresult = inflate(&
_zstream, zipsize ? Z_NO_FLUSH : Z_FINISH);
 
  531         if (zresult == Z_STREAM_END) 
break;
 
  532         if (zresult != Z_OK) {
 
  533             setError(
"PtexReader error: unzip failed, file corrupt");
 
  539     int total = (int)
_zstream.total_out;
 
  541     return total == unzipsize;
 
  574         for (
size_t i = 0, size = 
_faceedits.size(); i < size; i++) {
 
  621     int first = faceid, last = faceid;
 
  628         int nfaces = int(level->
fdh.size());
 
  631             if (f < 0 || level->faces[f]) 
break;
 
  641             if (f >= nfaces || level->
faces[f]) 
break;
 
  653     std::vector<FaceData*> extraFaces;
 
  654     extraFaces.reserve(last-first);
 
  656     for (
int i = first; i <= last; i++) {
 
  662             if (i != faceid) extraFaces.push_back(face);
 
  668     for (
size_t i = 0, size = extraFaces.size(); i < size; i++)
 
  669         extraFaces[i]->
unref();
 
  692     _reader->readFaceData(_offsets[tile], _fdh[tile], _tileres, _levelid, data);
 
  722             uint32_t tileheadersize;
 
  723             readBlock(&tileheadersize, 
sizeof(tileheadersize));
 
  733             int uw = res.
u(), vw = res.
v();
 
  734             int npixels = uw * vw;
 
  738             bool useMalloc = unpackedSize > 
AllocaMax;
 
  739             void* tmp = useMalloc ? malloc(unpackedSize) : alloca(unpackedSize);
 
  750             if (useMalloc) free(tmp);
 
  772     int resu = res.
u(), resv = res.
v();
 
  774     if (stride == 0) stride = rowlen;
 
  786         int ntilesu = res.
ntilesu(tileres);
 
  787         int ntilesv = res.
ntilesv(tileres);
 
  788         int tileures = tileres.
u();
 
  789         int tilevres = tileres.
v();
 
  792         char* dsttilerow = (
char*) buffer;
 
  793         for (
int i = 0; i < ntilesv; i++) {
 
  794             char* dsttile = dsttilerow;
 
  795             for (
int j = 0; j < ntilesu; j++) {
 
  797                 if (!t) { i = ntilesv; 
break; }
 
  803                                     tilevres, tilerowlen);
 
  804                 dsttile += tilerowlen;
 
  806             dsttilerow += stride * tilevres;
 
  817     if (faceid < 0 || 
size_t(faceid) >= 
_header.
nfaces) 
return 0;
 
  837     if (faceid < 0 || 
size_t(faceid) >= 
_header.
nfaces) 
return 0;
 
  840     if ((fi.
isConstant() && res >= 0) || res == 0) {
 
  851     if (redu == 0 && redv == 0) {
 
  860     if (redu == redv && !fi.
hasEdits() && res >= 0) {
 
  864         if (
size_t(levelid) < 
_levels.size()) {
 
  872             if (
size_t(rfaceid) < level->
faces.size())
 
  873                 face = 
getFace(levelid, level, rfaceid);
 
  895         std::cerr << 
"PtexReader::getData - reductions below 1 pixel not supported" << std::endl;
 
  898     if (redu < 0 || redv < 0) {
 
  899         std::cerr << 
"PtexReader::getData - enlargements not supported" << std::endl;
 
  905             std::cerr << 
"PtexReader::getData - anisotropic reductions not supported for triangle mesh" << std::endl;
 
  919         blendu = (res.
ulog2 & 1);
 
  921     else blendu = redu > redv;
 
  948         assert(res.
ulog2 < 0); 
 
  949         length = (res.
vlog2 <= 0 ? 1 : res.
v());
 
  954         assert(res.
vlog2 < 0);
 
  955         length = (res.
ulog2 <= 0 ? 1 : res.
u());
 
  965     int r1 = (f.
adjedge(e1)-e1+2)&3;
 
  966     int r2 = (f.
adjedge(e2)-e2+2)&3;
 
  969     Res pres1 = pres, pres2 = pres;
 
  970     if (r1 & 1) pres1.
swapuv();
 
  971     if (r2 & 1) pres2.swapuv();
 
  974     if (nf1 >= 0 && !(
_faceinfo[nf1].res >= pres)) nf1 = -1;
 
  975     if (nf2 >= 0 && !(
_faceinfo[nf2].res >= pres)) nf2 = -1;
 
  981     psrc[0] = 
getData(faceid, pres);
 
  987         flip[nf] = length ? (r1 + blendu) & 1 : 0;
 
  988         psrc[nf++] = 
getData(nf1, pres1);
 
  991         flip[nf] = length ? (r2 + blendu) & 1 : 0;
 
  992         psrc[nf++] = 
getData(nf2, pres2);
 
 1004             for (
int i = 0; i < nf; i++) psrc[i]->
release();
 
 1018         memcpy(data, psrc[0]->
getData(), size);
 
 1021         float weight = 1.0f / (float)nf;
 
 1022         memset(data, 0, size);
 
 1023         for (
int i = 0; i < nf; i++)
 
 1037     for (
int i = 0; i < nf; i++) psrc[i]->
release();
 
 1042                           float* result, 
int firstchan, 
int nchannels)
 
 1044     memset(result, 0, 
sizeof(*result)*nchannels);
 
 1049     if (nchannels <= 0) 
return;
 
 1060         pixel = (
char*) pixel + datasize * firstchan;
 
 1064         memcpy(result, pixel, datasize * nchannels);
 
 1071                           float* result, 
int firstchan, 
int nchannels,
 
 1074     memset(result, 0, nchannels);
 
 1079     if (nchannels <= 0) 
return;
 
 1090         pixel = (
char*) pixel + datasize * firstchan;
 
 1094         memcpy(result, pixel, datasize * nchannels);
 
 1121     reducefn(_data, 
_pixelsize * _res.u(), _res.u(), _res.v(),
 
 1181     if (newres.
ulog2 == 1 || newres.
vlog2 == 1 || isTriangle) {
 
 1182         newtileres = newres;
 
 1186         newtileres = _tileres;
 
 1194     int newntiles = newres.
ntiles(newtileres);
 
 1196     if (newntiles == 1) {
 
 1200         bool allConstant = 
true;
 
 1201         for (
int i = 0; i < _ntiles; i++) {
 
 1203             allConstant = (allConstant && tile->
isConstant() &&
 
 1212         else if (isTriangle) {
 
 1215             int tileures = _tileres.u();
 
 1216             int tilevres = _tileres.v();
 
 1218             int dstride = sstride * _ntilesu;
 
 1219             int dstepv = dstride * tilevres - sstride*(_ntilesu-1);
 
 1221             char* tmp = (
char*) malloc(_ntiles * _tileres.size() * 
_pixelsize);
 
 1223             for (
int i = 0; i < _ntiles;) {
 
 1231                 tmpptr += i%_ntilesu ? sstride : dstepv;
 
 1238             reducefn(tmp, 
_pixelsize * _res.u(), _res.u(), _res.v(),
 
 1248             int tileures = _tileres.u();
 
 1249             int tilevres = _tileres.v();
 
 1252             int dstepu = dstride/_ntilesu;
 
 1253             int dstepv = dstride*newres.
v()/_ntilesv - dstepu*(_ntilesu-1);
 
 1255             char* dst = (
char*) newface->
getData();
 
 1256             for (
int i = 0; i < _ntiles;) {
 
 1260                                     newres.
u()/_ntilesu, newres.
v()/_ntilesv,
 
 1263                     reducefn(tile->
getData(), sstride, tileures, tilevres,
 
 1264                              dst, dstride, _dt, _nchan);
 
 1266                 dst += i%_ntilesu ? dstepu : dstepv;
 
 1270         for (
int i = 0; i < _ntiles; i++) tiles[i]->
release();
 
 1275                                        _dt, _nchan, 
this, reducefn);
 
 1287     int tileu = ui >> _tileres.ulog2;
 
 1288     int tilev = vi >> _tileres.vlog2;
 
 1290     tile->
getPixel(ui - (tileu<<_tileres.ulog2),
 
 1291                    vi - (tilev<<_tileres.vlog2), result);
 
 1308     int pntilesu = _parentface->ntilesu();
 
 1309     int pntilesv = _parentface->ntilesv();
 
 1310     int nu = pntilesu / _ntilesu; 
 
 1311     int nv = pntilesv / _ntilesv; 
 
 1315     bool allConstant = 
true;
 
 1316     int ptile = (tile/_ntilesu) * nv * pntilesu + (tile%_ntilesu) * nu;
 
 1317     for (
int i = 0; i < ntiles;) {
 
 1322         allConstant = (allConstant && tile->
isConstant() &&
 
 1326         ptile += i%nu? 1 : pntilesu - nu + 1;
 
 1334         for (
int i = 0; i < ntiles; i++) tiles[i]->
release();
 
 1349         int ptileures = _parentface->tileres().u();
 
 1350         int ptilevres = _parentface->tileres().v();
 
 1353         int dstepu = dstride/nu;
 
 1354         int dstepv = dstride*_tileres.v()/nv - dstepu*(nu-1);
 
 1356         char* dst = (
char*) face->
getData();
 
 1357         for (
int i = 0; i < ntiles;) {
 
 1361                                 _tileres.u()/nu, _tileres.v()/nv,
 
 1364                 _reducefn(tile->
getData(), sstride, ptileures, ptilevres,
 
 1365                           dst, dstride, _dt, _nchan);
 
 1367             dst += i%nu ? dstepu : dstepv;
 
 1374     for (
int i = 0; i < ntiles; i++) tiles[i]->
release();
 
void handlePendingDelete()
FaceData * getFace(int levelid, Level *level, int faceid)
Left edge, from UV (0,1) to (0,0) 
virtual void reduce(FaceData *&, PtexReader *, Res newres, PtexUtils::ReduceFn)=0
int ntiles(Res tileres) const 
Determine the total number of tiles for the given tile res. 
int ntilesv(Res tileres) const 
Determine the number of tiles in the v direction for the given tile res. 
safevector< LevelInfo > _levelinfo
static void multalpha(void *data, int npixels, DataType dt, int nchannels, int alphachan)
virtual void release()
Release resources held by this pointer (pointer becomes invalid). 
PtexReader(void **parent, PtexCacheImpl *cache, bool premultiply, PtexInputHandler *handler)
bool isConstant() const 
Determine if face is constant (by checking a flag). 
static int DataSize(DataType dt)
Look up size of given data type (in bytes). 
virtual const Ptex::FaceInfo & getFaceInfo(int faceid)
Access resolution and adjacency information about a face. 
Top edge, from UV (1,1) to (0,1) 
static void reduceTri(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
static const int AllocaMax
safevector< FilePos > _levelpos
safevector< FilePos > _offsets
virtual PtexTexture * get(const char *path, Ptex::String &error)=0
Open a texture. 
DataType
Type of data stored in texture file. 
safevector< MetaEdit > _metaedits
static void blend(const void *src, float weight, void *dst, bool flip, int rowlen, DataType dt, int nchannels)
safevector< Level * > _levels
static const int HeaderSize
File-handle and memory cache for reading ptex files. 
bool readBlock(void *data, int size, bool reportError=true)
virtual const char * path()
Path that file was opened with. 
static void copy(const void *src, int sstride, void *dst, int dstride, int nrows, int rowlen)
static const int LevelInfoSize
void readLevel(int levelid, Level *&level)
virtual PtexMetaData * getMetaData()
Access meta data. 
static PtexCache * create(int maxFiles=0, int maxMem=0, bool premultiply=false, PtexInputHandler *handler=0)
Create a cache with the specified limits. 
static const int EditMetaDataHeaderSize
int v() const 
V resolution in texels. 
Bottom edge, from UV (0,0) to (1,0) 
int32_t adjfaces[4]
Adjacent faces (-1 == no adjacent face). 
safevector< FaceEdit > _faceedits
safevector< uint32_t > _rfaceids
static const int ExtHeaderSize
void blendFaces(FaceData *&face, int faceid, Res res, bool blendu)
Per-face texture data accessor. 
int u() const 
U resolution in texels. 
void readMetaDataBlock(MetaData *metadata, FilePos pos, int zipsize, int memsize)
Res getRes(int levelid, int faceid)
virtual void * getData()=0
Access the data from this data block. 
int8_t vlog2
log base 2 of v resolution, in texels 
virtual void reduce(FaceData *&, PtexReader *, Res newres, PtexUtils::ReduceFn)
static void genRfaceids(const FaceInfo *faces, int nfaces, uint32_t *rfaceids, uint32_t *faceids)
int ntilesu(Res tileres) const 
Determine the number of tiles in the u direction for the given tile res. 
virtual PtexFaceData * getTile(int tile)=0
Access a tile from the data block. 
virtual void reduce(FaceData *&, PtexReader *, Res newres, PtexUtils::ReduceFn)
Single-precision (32-bit) floating point. 
safevector< FilePos > offsets
void readTile(int tile, FaceData *&data)
iterator end() const 
Returns an iteraot referencing the location just beyond the table. 
void computeOffsets(FilePos pos, int noffsets, const FaceDataHeader *fdh, FilePos *offsets)
void ReduceFn(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
bool hasEdits() const 
Determine if face has edits in the file (by checking a flag). 
safevector< FaceDataHeader > fdh
virtual void purgeAll()=0
Remove all texture files from the cache. 
T * get()
Get pointer value. 
void setError(const char *error)
static void orphanList(T &list)
bool readZipBlock(void *data, int zipsize, int unzipsize)
DataType datatype() const 
static const uint32_t Magic
virtual void getData(int faceid, void *buffer, int stride)
Access texture data for a face at highest-resolution. 
static void fill(const void *src, void *dst, int dstride, int ures, int vres, int pixelsize)
EdgeId adjedge(int eid) const 
Access an adjacent edge id. The eid value must be 0..3. 
virtual void getPixel(int u, int v, void *result)
Read a single texel from the data block. 
void readLargeMetaDataHeaders(MetaData *metadata, FilePos pos, int zipsize, int memsize)
Level * getLevel(int levelid)
PtexInputHandler::Handle _fp
int size() const 
Total size of specified texture in texels (u * v). 
virtual void getPixel(int faceid, int u, int v, float *result, int firstchan, int nchannels)
Access a single texel from the highest resolution texture . 
static PtexTexture * open(const char *path, Ptex::String &error, bool premultiply=0)
Open a ptex file for reading. 
void swapuv()
Swap the u and v resolution values in place. 
void readFace(int levelid, Level *level, int faceid)
Smart-pointer for acquiring and releasing API objects. 
virtual bool isTiled()=0
True if this data block is tiled. 
void readFaceData(FilePos pos, FaceDataHeader fdh, Res res, int levelid, FaceData *&face)
virtual void * getData()
Access the data from this data block. 
virtual bool isConstant()=0
True if this data block is constant. 
int8_t ulog2
log base 2 of u resolution, in texels 
virtual void getPixel(int u, int v, void *result)=0
Read a single texel from the data block. 
virtual PtexFaceData * getTile(int tile)
Access a tile from the data block. 
Right edge, from UV (1,0) to (1,1) 
Interface for reading data from a ptex file. 
static const int BlockSize
safevector< FaceData * > faces
Pixel resolution of a given texture. 
virtual void reduce(FaceData *&, PtexReader *, Res newres, PtexUtils::ReduceFn)
safevector< FaceDataHeader > _fdh
Cache entry for open file handle. 
safevector< FaceInfo > _faceinfo
static void reduceu(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
static void interleave(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
static const int FaceDataHeaderSize
bool open(const char *path, Ptex::String &error)
Ptex cache implementation. 
static void reducev(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
Res res
Resolution of face. 
Automatically acquire and release lock within enclosing scope. 
Information about a face, as stored in the Ptex file header. 
iterator begin() const 
Returns an iterator referencing the beginning of the table. 
static void decodeDifference(void *data, int size, DataType dt)
static void ConvertToFloat(float *dst, const void *src, Ptex::DataType dt, int numChannels)
Convert a number of data values from the given data type to float. 
static bool LittleEndian()
static const int EditFaceDataHeaderSize
const char * c_str() const 
Public API classes for reading, writing, caching, and filtering Ptex files. 
int unpackedSize(FaceDataHeader fdh, int levelid, int faceid)
virtual Ptex::Res tileRes()=0
Resolution of each tile in this data block.