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;
176 TempErrorHandler tempErr;
191 pos +=
sizeof(uint64_t);
211 error = tempErr.getErrorString();
242 if (
_fp)
return true;
254 memset(&extheaderval, 0,
sizeof(extheaderval));
256 if (0 != memcmp(&headerval, &
_header,
sizeof(headerval)) ||
257 0 != memcmp(&extheaderval, &
_extheader,
sizeof(extheaderval)))
259 setError(
"Header mismatch on reopen of");
269 if (faceid >= 0 && uint32_t(faceid) <
_faceinfo.size())
285 (
int)(
sizeof(FaceInfo)*nfaces));
289 std::vector<uint32_t> faceids_r(nfaces);
345 if (index < 0 || index >=
int(
_entries.size())) {
391 size_t metaDataMemUsed =
sizeof(
MetaData);
404 for (
size_t i = 0, size =
_metaedits.size(); i < size; i++)
419 char* buff = useNew ?
new char[memsize] : (
char*)alloca(memsize);
424 char* end = ptr + memsize;
426 uint8_t keysize = *ptr++;
427 char* key = (
char*)ptr; ptr += keysize;
428 key[keysize-1] =
'\0';
429 uint8_t datatypeval = *ptr++;
430 uint32_t datasize; memcpy(&datasize, ptr,
sizeof(datasize));
431 ptr +=
sizeof(datasize);
432 char* data = ptr; ptr += datasize;
433 metadata->
addEntry((uint8_t)(keysize-1), key, datatypeval, datasize, data, metaDataMemUsed);
436 if (useNew)
delete [] buff;
445 char* buff = useNew ?
new char [memsize] : (
char*)alloca(memsize);
452 char* end = ptr + memsize;
454 uint8_t keysize = *ptr++;
455 char* key = (
char*)ptr; ptr += keysize;
456 uint8_t datatypeval = *ptr++;
457 uint32_t datasize; memcpy(&datasize, ptr,
sizeof(datasize));
458 ptr +=
sizeof(datasize);
459 uint32_t zipsizeval; memcpy(&zipsizeval, ptr,
sizeof(zipsizeval));
460 ptr +=
sizeof(zipsizeval);
461 metadata->
addLmdEntry((uint8_t)(keysize-1), key, datatypeval, datasize, pos, zipsizeval, metaDataMemUsed);
465 if (useNew)
delete [] buff;
479 endpos =
FilePos((uint64_t)-1);
482 while (pos < endpos) {
487 if (!
readBlock(&edittype,
sizeof(edittype),
false))
break;
488 if (!
readBlock(&editsize,
sizeof(editsize),
false))
break;
489 if (!editsize)
break;
491 pos =
tell() + editsize;
513 f.flags |= FaceInfo::flag_hasedits;
523 if (!f.isConstant()) {
550 assert(
_fp && size >= 0);
551 if (!
_fp || size < 0)
return false;
553 if (result == size) {
558 setError(
"PtexReader error: read failed (EOF)");
565 if (zipsize < 0 || unzipsize < 0)
return false;
580 int zresult = inflate(&
_zstream, zipsize ? Z_NO_FLUSH : Z_FINISH);
581 if (zresult == Z_STREAM_END)
break;
582 if (zresult != Z_OK) {
583 setError(
"PtexReader error: unzip failed, file corrupt");
589 int total = (int)
_zstream.total_out;
591 return total == unzipsize;
614 for (
size_t i = 0, size =
_faceedits.size(); i < size; i++) {
637 _reader->readFaceData(_offsets[tile], _fdh[tile], _tileres, _levelid, data);
651 size_t newMemUsed = 0;
670 uint32_t tileheadersize;
671 readBlock(&tileheadersize,
sizeof(tileheadersize));
682 int uw = res.u(), vw = res.v();
683 int npixels = uw * vw;
687 newMemUsed =
sizeof(
PackedFace) + unpackedSize;
689 char* tmp = useNew ?
new char [unpackedSize] : (
char*) alloca(unpackedSize);
699 if (useNew)
delete [] tmp;
714 getData(faceid, buffer, stride, f.res);
726 int resu = res.u(), resv = res.v();
728 if (stride == 0) stride = rowlen;
739 int ntilesu = res.
ntilesu(tileres);
740 int ntilesv = res.ntilesv(tileres);
741 int tileures = tileres.u();
742 int tilevres = tileres.v();
745 char* dsttilerow = (
char*) buffer;
746 for (
int i = 0; i < ntilesv; i++) {
747 char* dsttile = dsttilerow;
748 for (
int j = 0; j < ntilesu; j++) {
755 tilevres, tilerowlen);
756 dsttile += tilerowlen;
758 dsttilerow += stride * tilevres;
774 if (fi.isConstant() || fi.res == 0) {
792 if (fi.isConstant() || res == 0) {
797 int redu = fi.res.ulog2 - res.ulog2, redv = fi.res.vlog2 - res.vlog2;
799 if (redu == 0 && redv == 0) {
806 if (redu == redv && !fi.hasEdits()) {
810 if (
size_t(levelid) <
_levels.size()) {
818 if (
size_t(rfaceid) < level->
faces.size()) {
819 face =
getFace(levelid, level, rfaceid, res);
836 size_t newMemUsed = 0;
838 if (res.ulog2 < 0 || res.vlog2 < 0) {
839 std::cerr <<
"PtexReader::getData - reductions below 1 pixel not supported" << std::endl;
842 else if (redu < 0 || redv < 0) {
843 std::cerr <<
"PtexReader::getData - enlargements not supported" << std::endl;
849 std::cerr <<
"PtexReader::getData - anisotropic reductions not supported for triangle mesh" << std::endl;
863 blendu = (res.ulog2 & 1);
865 else blendu = redu > redv;
881 size_t tableNewMemUsed = 0;
883 if (face != newface) {
894 float* result,
int firstchan,
int nchannelsArg)
896 memset(result, 0,
sizeof(*result)*nchannelsArg);
900 if (nchannelsArg <= 0)
return;
910 pixel = (
char*) pixel + datasize * firstchan;
914 memcpy(result, pixel, datasize * nchannelsArg);
921 float* result,
int firstchan,
int nchannelsArg,
924 memset(result, 0, nchannelsArg);
928 if (nchannelsArg <= 0)
return;
938 pixel = (
char*) pixel + datasize * firstchan;
942 memcpy(result, pixel, datasize * nchannelsArg);
959 reducefn(_data,
_pixelsize * _res.u(), _res.u(), _res.v(),
1001 newtileres = newres;
1005 newtileres = _tileres;
1007 if (newtileres.ulog2 > newres.ulog2) newtileres.ulog2 = newres.ulog2;
1008 if (newtileres.vlog2 > newres.vlog2) newtileres.vlog2 = newres.vlog2;
1013 int newntiles = newres.ntiles(newtileres);
1015 if (newntiles == 1) {
1019 bool allConstant =
true;
1020 for (
int i = 0; i < _ntiles; i++) {
1022 allConstant = (allConstant && tile->
isConstant() &&
1032 else if (isTriangle) {
1035 int tileures = _tileres.u();
1036 int tilevres = _tileres.v();
1038 int dstride = sstride * _ntilesu;
1039 int dstepv = dstride * tilevres - sstride*(_ntilesu-1);
1041 char* tmp =
new char [_ntiles * _tileres.size() *
_pixelsize];
1043 for (
int i = 0; i < _ntiles;) {
1051 tmpptr += (i%_ntilesu) ? sstride : dstepv;
1059 reducefn(tmp,
_pixelsize * _res.u(), _res.u(), _res.v(),
1070 int tileures = _tileres.u();
1071 int tilevres = _tileres.v();
1074 int dstepu = dstride/_ntilesu;
1075 int dstepv = dstride*newres.v()/_ntilesv - dstepu*(_ntilesu-1);
1077 char* dst = (
char*) newface->
getData();
1078 for (
int i = 0; i < _ntiles;) {
1082 newres.u()/_ntilesu, newres.v()/_ntilesv,
1085 reducefn(tile->
getData(), sstride, tileures, tilevres,
1086 dst, dstride, _dt, _nchan);
1088 dst += (i%_ntilesu) ? dstepu : dstepv;
1092 for (
int i = 0; i < _ntiles; i++) tiles[i]->
release();
1106 int tileu = ui >> _tileres.ulog2;
1107 int tilev = vi >> _tileres.vlog2;
1109 tile->
getPixel(ui - (tileu<<_tileres.ulog2),
1110 vi - (tilev<<_tileres.vlog2), result);
1124 int pntilesu = _parentface->ntilesu();
1125 int pntilesv = _parentface->ntilesv();
1126 int nu = pntilesu / _ntilesu;
1127 int nv = pntilesv / _ntilesv;
1129 int ntilesval = nu*nv;
1131 bool allConstant =
true;
1132 int ptile = (tile/_ntilesu) * nv * pntilesu + (tile%_ntilesu) * nu;
1133 for (
int i = 0; i < ntilesval;) {
1135 allConstant = (allConstant && tileval->
isConstant() &&
1139 ptile += (i%nu)? 1 : pntilesu - nu + 1;
1143 size_t newMemUsed = 0;
1157 int ptileures = _parentface->tileres().u();
1158 int ptilevres = _parentface->tileres().v();
1161 int dstepu = dstride/nu;
1162 int dstepv = dstride*_tileres.v()/nv - dstepu*(nu-1);
1164 char* dst = (
char*) newface->
getData();
1165 for (
int i = 0; i < ntilesval;) {
1169 _tileres.u()/nu, _tileres.v()/nv,
1172 _reducefn(tileval->
getData(), sstride, ptileures, ptilevres,
1173 dst, dstride, _dt, _nchan);
1175 dst += (i%nu) ? dstepu : dstepv;
1183 _reader->increaseMemUsed(newMemUsed);