Example #1
0
void emitStatement(refObject term, set wraps)

//  PRE EMIT. Write an open brace if needed.

{ void preEmit(int hook)
  { if (isInSet(hook, wraps))
    { writeChar(target, '{'); }}

//  POST EMIT. Write a close brace if needed.

  void postEmit(int hook)
  { if (isInSet(hook, wraps))
    { writeChar(target, '}'); }}

//  Dispatch to an appropriate case based on TERM's outer hook.

   if (isPair(term))
   { switch (toHook(car(term)))

//  Write C code for a CASE clause.

    { case caseHook:
      { refObject subterm;
        preEmit(caseHook);
        term = cdr(term);
        writeFormat(target, "switch");
        writeChar(target, '(');
        emitExpression(car(term), 13);
        writeChar(target, ')');
        writeChar(target, '{');
        term = cdr(term);
        while (cdr(term) != nil)
        { emitLabels(car(term));
          term = cdr(term);
          subterm = car(term);
          if (isEffected(subterm))
          { emitStatement(subterm, withSet); }
          writeFormat(target, "break");
          writeChar(target, ';');
          term = cdr(term); }
        subterm = car(term);
        if (isEffected(subterm))
        { writeFormat(target, "default");
          writeChar(target, ':');
          emitStatement(subterm, withSet); }
        writeChar(target, '}');
        postEmit(caseHook);
        break; }

//  Write C code for an IF clause.

      case ifHook:
      { refObject subterm;
        preEmit(ifHook);
        term = cdr(term);
        while (true)
        { writeFormat(target, "if");
          writeChar(target, '(');
          emitExpression(car(term), 13);
          writeChar(target, ')');
          term = cdr(term);
          subterm = car(term);
          if (isEffected(subterm))
          { emitStatement(subterm, ifLastWithSet); }
          else
          { writeChar(target, ';'); }
          term = cdr(term);
          if (cdr(term) == nil)
          { subterm = car(term);
            if (isEffected(subterm))
            { writeFormat(target, "else");
              writeBlank(target);
              if (isCar(subterm, ifHook))
              { term = cdr(subterm); }
              else
              { emitStatement(subterm, lastWithSet);
                break; }}
            else
            { break; }}
          else
          { writeFormat(target, "else");
            writeBlank(target); }}
        postEmit(ifHook);
        break; }

//  Write C code for a LAST clause.

      case lastHook:
      { refObject subterm;
        preEmit(lastHook);
        term = cdr(term);
        while (term != nil)
        { subterm = car(term);
          if (isEffected(subterm))
          { emitStatement(subterm, withSet); }
          term = cdr(term); }
        postEmit(lastHook);
        break; }

//  Write C code for a WHILE clause.

      case whileHook:
      { preEmit(whileHook);
        term = cdr(term);
        writeFormat(target, "while");
        writeChar(target, '(');
        emitExpression(car(term), 13);
        writeChar(target, ')');
        term = cadr(term);
        if (isEffected(term))
        { emitStatement(term, lastWithSet); }
        else
        { writeChar(target, ';'); }
        postEmit(whileHook);
        break; }

//  Write C code for a WITH clause.

      case withHook:
      { refObject frame;
        preEmit(withHook);
        term = cdr(term);
        frame = car(term);
        term = cdr(term);
        if (frame == nil)
        { emitVariableDeclarations(term);
          emitFunctionDefinitions(true, term);
          emitVariableDefinitions(nil, term);
          term = car(lastPair(term));
          if (isEffected(term))
          { emitStatement(term, withSet); }}
        else
        { emitFrameDeclaration(frame, term);
          emitVariableDeclarations(term);
          emitFunctionDefinitions(true, term);
          emitFramePush(frame, frameLength(term));
          emitFrameInitialization(frame, term);
          emitVariableDefinitions(frame, term);
          term = car(lastPair(term));
          if (isEffected(term))
          { emitStatement(term, withSet); }
          emitFramePop(frame); }
        postEmit(withHook);
        break; }

//  Other TERMs become C expressions.

      default:
      { if (isEffected(term))
        { emitExpression(term, 13);
          writeChar(target, ';'); }
        break; }}}
  else
  { if (isEffected(term))
    { emitExpression(term, 13);
      writeChar(target, ';'); }}}
Example #2
0
void writingObject(refBuffer buffer, refObject object)
{ if (object == nil)
  { writeFormat(buffer, "[Nil]"); }
  else
  { switch (tag(object))
    { case cellTag:
      { writeFormat(buffer, "[Cell %X]", object);
        return; }
      case characterTag:
      { writeCharacter(buffer, toCharacter(object));
        return; }
      case evenBinderTag:
      { writeFormat(buffer, "[EvenBinder %X]", object);
        return; }
      case hookTag:
      { writeFormat(buffer, "?%s", hookTo(object));
        return; }
      case hunkTag:
      { writeFormat(buffer, "[Hunk %X]", object);
        return; }
      case integerTag:
      { writeFormat(buffer, "%i", toInteger(object));
        return; }
      case jokerTag:
      { writeFormat(buffer, "[%s]", jokerTo(object));
        return; }
      case leftBinderTag:
      { writeFormat(buffer, "[LeftBinder %X]", object);
        return; }
      case markedTag:
      { writeFormat(buffer, "[...]");
        return; }
      case matchTag:
      { writeFormat(buffer, "[Match %X]", object);
        return; }
      case nameTag:
      { writeVisibleName(buffer, object);
        return; }
      case pairTag:
      { refObject pairs = object;
        tag(object) = markedTag;
        writeChar(buffer, '(');
        writingObject(buffer, car(pairs));
        pairs = cdr(pairs);
        while (pairs != nil)
        { writeBlank(buffer);
          writingObject(buffer, car(pairs));
          pairs = cdr(pairs); }
        writeChar(buffer, ')');
        tag(object) = pairTag;
        return; }
      case realTag:
      { writeFormat(buffer, "%.17E", toReal(object));
        return; }
      case rightBinderTag:
      { writeFormat(buffer, "[RightBinder %X]", object);
        return; }
      case stringTag:
      { writeQuotedString(buffer, toRefString(object));
        return; }
      default:
      { writeFormat(buffer, "[Tag%i %X]", tag(object), object);
        return; }}}}
Example #3
0
bool PtexIncrWriter::writeFace(int faceid, const FaceInfo& f, const void* data, int stride)
{
    if (stride == 0) stride = f.res.u()*_pixelSize;

    // handle constant case
    if (PtexUtils::isConstant(data, stride, f.res.u(), f.res.v(), _pixelSize))
	return writeConstantFace(faceid, f, data);

    // init headers
    uint8_t edittype = et_editfacedata;
    uint32_t editsize;
    EditFaceDataHeader efdh;
    efdh.faceid = faceid;

    // check and store face info
    if (!storeFaceInfo(faceid, efdh.faceinfo, f))
	return 0;

    // record position and skip headers
    FilePos pos = ftello(_fp);
    writeBlank(_fp, sizeof(edittype) + sizeof(editsize) + sizeof(efdh));

    // must compute constant (average) val first
    uint8_t* constval = (uint8_t*) malloc(_pixelSize);

    if (_header.hasAlpha()) {
	// must premult alpha before averaging
	// first copy to temp buffer
	int rowlen = f.res.u() * _pixelSize, nrows = f.res.v();
	uint8_t* temp = (uint8_t*) malloc(rowlen * nrows);
	PtexUtils::copy(data, stride, temp, rowlen, nrows, rowlen);

	// multiply alpha
	PtexUtils::multalpha(temp, f.res.size(), _header.datatype, _header.nchannels,
			     _header.alphachan);
	// average
	PtexUtils::average(temp, rowlen, f.res.u(), f.res.v(), constval,
			   _header.datatype, _header.nchannels);
	// unmult alpha
	PtexUtils::divalpha(constval, 1, _header.datatype, _header.nchannels,
			    _header.alphachan);
	free(temp);
    }
    else {
	// average
	PtexUtils::average(data, stride, f.res.u(), f.res.v(), constval,
			   _header.datatype, _header.nchannels);
    }
    // write const val
    writeBlock(_fp, constval, _pixelSize);
    free(constval);

    // write face data
    writeFaceData(_fp, data, stride, f.res, efdh.fdh);

    // update editsize in header
    editsize = sizeof(efdh) + _pixelSize + efdh.fdh.blocksize();

    // rewind and write headers
    fseeko(_fp, pos, SEEK_SET);
    writeBlock(_fp, &edittype, sizeof(edittype));
    writeBlock(_fp, &editsize, sizeof(editsize));
    writeBlock(_fp, &efdh, sizeof(efdh));
    fseeko(_fp, 0, SEEK_END);
    return 1;
}
Example #4
0
void PtexMainWriter::finish()
{
    // do nothing if there's no new data to write
    if (!_hasNewData) return;

    // copy missing faces from _reader
    if (_reader) {
	for (int i = 0, nfaces = _header.nfaces; i < nfaces; i++) {
	    if (_faceinfo[i].flags == uint8_t(-1)) {
		// copy face data
                const Ptex::FaceInfo& info = _reader->getFaceInfo(i);
                int size = _pixelSize * info.res.size();
                if (info.isConstant()) {
                    PtexPtr<PtexFaceData> data ( _reader->getData(i) );
                    if (data) {
                        writeConstantFace(i, info, data->getData());
                    }
                } else {
                    void* data = malloc(size);
                    _reader->getData(i, data, 0);
                    writeFace(i, info, data, 0);
                    free(data);
                }
	    }
	}
    }
    else {
	// just flag missing faces as constant (black)
	for (int i = 0, nfaces = _header.nfaces; i < nfaces; i++) {
	    if (_faceinfo[i].flags == uint8_t(-1))
		_faceinfo[i].flags = FaceInfo::flag_constant;
	}
    }

    // write reductions to tmp file
    if (_genmipmaps)
	generateReductions();

    // flag faces w/ constant neighborhoods
    flagConstantNeighorhoods();

    // update header
    _header.nlevels = uint16_t(_levels.size());
    _header.nfaces = uint32_t(_faceinfo.size());

    // create new file
    FILE* newfp = fopen(_newpath.c_str(), "wb+");
    if (!newfp) {
	setError(fileError("Can't write to ptex file: ", _newpath.c_str()));
	return;
    }

    // write blank header (to fill in later)
    writeBlank(newfp, HeaderSize);
    writeBlank(newfp, ExtHeaderSize);

    // write compressed face info block
    _header.faceinfosize = writeZipBlock(newfp, &_faceinfo[0],
					 sizeof(FaceInfo)*_header.nfaces);

    // write compressed const data block
    _header.constdatasize = writeZipBlock(newfp, &_constdata[0], int(_constdata.size()));

    // write blank level info block (to fill in later)
    FilePos levelInfoPos = ftello(newfp);
    writeBlank(newfp, LevelInfoSize * _header.nlevels);

    // write level data blocks (and record level info)
    std::vector<LevelInfo> levelinfo(_header.nlevels);
    for (int li = 0; li < _header.nlevels; li++)
    {
	LevelInfo& info = levelinfo[li];
	LevelRec& level = _levels[li];
	int nfaces = int(level.fdh.size());
	info.nfaces = nfaces;
	// output compressed level data header
	info.levelheadersize = writeZipBlock(newfp, &level.fdh[0],
					     sizeof(FaceDataHeader)*nfaces);
	info.leveldatasize = info.levelheadersize;
	// copy level data from tmp file
	for (int fi = 0; fi < nfaces; fi++)
	    info.leveldatasize += copyBlock(newfp, _tmpfp, level.pos[fi],
					    level.fdh[fi].blocksize());
	_header.leveldatasize += info.leveldatasize;
    }
    rewind(_tmpfp);

    // write meta data (if any)
    if (!_metadata.empty())
	writeMetaData(newfp);

    // update extheader for edit data position
    _extheader.editdatapos = ftello(newfp);

    // rewrite level info block
    fseeko(newfp, levelInfoPos, SEEK_SET);
    _header.levelinfosize = writeBlock(newfp, &levelinfo[0], LevelInfoSize*_header.nlevels);

    // rewrite header
    fseeko(newfp, 0, SEEK_SET);
    writeBlock(newfp, &_header, HeaderSize);
    writeBlock(newfp, &_extheader, ExtHeaderSize);
    fclose(newfp);
}
Example #5
0
void PtexMainWriter::writeMetaData(FILE* fp)
{
    std::vector<MetaEntry*> lmdEntries; // large meta data items

    // write small meta data items in a single zip block
    for (int i = 0, n = _metadata.size(); i < n; i++) {
	MetaEntry& e = _metadata[i];
#ifndef PTEX_NO_LARGE_METADATA_BLOCKS
	if (int(e.data.size()) > MetaDataThreshold) {
	    // skip large items, but record for later
	    lmdEntries.push_back(&e);
	}
	else 
#endif
    {
	    // add small item to zip block
	    _header.metadatamemsize += writeMetaDataBlock(fp, e);
	}
    }
    if (_header.metadatamemsize) {
	// finish zip block
	_header.metadatazipsize = writeZipBlock(fp, 0, 0, /*finish*/ true);
    }

    // write compatibility barrier
    writeBlank(fp, sizeof(uint64_t));

    // write large items as separate blocks
    int nLmd = lmdEntries.size();
    if (nLmd > 0) {
	// write data records to tmp file and accumulate zip sizes for lmd header
	std::vector<FilePos> lmdoffset(nLmd);
	std::vector<uint32_t> lmdzipsize(nLmd);
	for (int i = 0; i < nLmd; i++) {
	    MetaEntry* e= lmdEntries[i];
	    lmdoffset[i] = ftello(_tmpfp);
	    lmdzipsize[i] = writeZipBlock(_tmpfp, &e->data[0], e->data.size());
	}

	// write lmd header records as single zip block
	for (int i = 0; i < nLmd; i++) {
	    MetaEntry* e = lmdEntries[i];
	    uint8_t keysize = uint8_t(e->key.size()+1);
	    uint8_t datatype = e->datatype;
	    uint32_t datasize = e->data.size();
	    uint32_t zipsize = lmdzipsize[i];

	    writeZipBlock(fp, &keysize, sizeof(keysize), false);
	    writeZipBlock(fp, e->key.c_str(), keysize, false);
	    writeZipBlock(fp, &datatype, sizeof(datatype), false);
	    writeZipBlock(fp, &datasize, sizeof(datasize), false);
	    writeZipBlock(fp, &zipsize, sizeof(zipsize), false);
	    _extheader.lmdheadermemsize +=
		sizeof(keysize) + keysize + sizeof(datatype) + sizeof(datasize) + sizeof(zipsize);
	}
	_extheader.lmdheaderzipsize = writeZipBlock(fp, 0, 0, /*finish*/ true);

	// copy data records
	for (int i = 0; i < nLmd; i++) {
	    _extheader.lmddatasize +=
		copyBlock(fp, _tmpfp, lmdoffset[i], lmdzipsize[i]);
	}
    }
}