void PtexWriterBase::writeFaceBlock(FILE* fp, const void* data, int stride, Res res, FaceDataHeader& fdh) { // write a single face data block // copy to temp buffer, and deinterleave int ures = res.u(), vres = res.v(); int blockSize = ures*vres*_pixelSize; bool useMalloc = blockSize > AllocaMax; char* buff = useMalloc ? (char*) malloc(blockSize) : (char*)alloca(blockSize); PtexUtils::deinterleave(data, stride, ures, vres, buff, ures*DataSize(_header.datatype), _header.datatype, _header.nchannels); // difference if needed bool diff = (_header.datatype == dt_uint8 || _header.datatype == dt_uint16); if (diff) PtexUtils::encodeDifference(buff, blockSize, _header.datatype); // compress and stream data to file, and record size in header int zippedsize = writeZipBlock(fp, buff, blockSize); // record compressed size and encoding in data header fdh.set(zippedsize, diff ? enc_diffzipped : enc_zipped); if (useMalloc) free(buff); }
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 PtexWriterBase::writeConstFaceBlock(FILE* fp, const void* data, FaceDataHeader& fdh) { // write a single const face data block // record level data for face and output the one pixel value fdh.set(_pixelSize, enc_constant); writeBlock(fp, data, _pixelSize); }