void PtexWriterBase::writeFaceData(FILE* fp, const void* data, int stride, Res res, FaceDataHeader& fdh) { // determine whether to break into tiles Res tileres = calcTileRes(res); int ntilesu = res.ntilesu(tileres); int ntilesv = res.ntilesv(tileres); int ntiles = ntilesu * ntilesv; if (ntiles == 1) { // write single block writeFaceBlock(fp, data, stride, res, fdh); } else { // write tiles to tilefp temp file rewind(_tilefp); // alloc tile header std::vector<FaceDataHeader> tileHeader(ntiles); int tileures = tileres.u(); int tilevres = tileres.v(); int tileustride = tileures*_pixelSize; int tilevstride = tilevres*stride; // output tiles FaceDataHeader* tdh = &tileHeader[0]; int datasize = 0; const char* rowp = (const char*) data; const char* rowpend = rowp + ntilesv * tilevstride; for (; rowp != rowpend; rowp += tilevstride) { const char* p = rowp; const char* pend = p + ntilesu * tileustride; for (; p != pend; tdh++, p += tileustride) { // determine if tile is constant if (PtexUtils::isConstant(p, stride, tileures, tilevres, _pixelSize)) writeConstFaceBlock(_tilefp, p, *tdh); else writeFaceBlock(_tilefp, p, stride, tileres, *tdh); datasize += tdh->blocksize(); } } // output compressed tile header uint32_t tileheadersize = writeZipBlock(_tilefp, &tileHeader[0], int(sizeof(FaceDataHeader)*tileHeader.size())); // output tile data pre-header int totalsize = 0; totalsize += writeBlock(fp, &tileres, sizeof(Res)); totalsize += writeBlock(fp, &tileheadersize, sizeof(tileheadersize)); // copy compressed tile header from temp file totalsize += copyBlock(fp, _tilefp, datasize, tileheadersize); // copy tile data from temp file totalsize += copyBlock(fp, _tilefp, 0, datasize); fdh.set(totalsize, enc_tiled); } }
void PtexReader::getData(int faceid, void* buffer, int stride, Res res) { if (!_ok) return; // note - all locking is handled in called getData methods int resu = res.u(), resv = res.v(); int rowlen = _pixelsize * resu; if (stride == 0) stride = rowlen; PtexPtr<PtexFaceData> d ( getData(faceid, res) ); if (!d) return; if (d->isConstant()) { // fill dest buffer with pixel value PtexUtils::fill(d->getData(), buffer, stride, resu, resv, _pixelsize); } else if (d->isTiled()) { // loop over tiles Res tileres = d->tileRes(); int ntilesu = res.ntilesu(tileres); int ntilesv = res.ntilesv(tileres); int tileures = tileres.u(); int tilevres = tileres.v(); int tilerowlen = _pixelsize * tileures; int tile = 0; char* dsttilerow = (char*) buffer; for (int i = 0; i < ntilesv; i++) { char* dsttile = dsttilerow; for (int j = 0; j < ntilesu; j++) { PtexPtr<PtexFaceData> t ( d->getTile(tile++) ); if (!t) { i = ntilesv; break; } if (t->isConstant()) PtexUtils::fill(t->getData(), dsttile, stride, tileures, tilevres, _pixelsize); else PtexUtils::copy(t->getData(), tilerowlen, dsttile, stride, tilevres, tilerowlen); dsttile += tilerowlen; } dsttilerow += stride * tilevres; } } else { PtexUtils::copy(d->getData(), rowlen, buffer, stride, resv, rowlen); } }