Beispiel #1
0
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);
}
Beispiel #2
0
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);
    }
}
Beispiel #3
0
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);
}