コード例 #1
0
ファイル: PtexWriter.cpp プロジェクト: 400notout/oiio
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);
}
コード例 #2
0
ファイル: PtexReader.cpp プロジェクト: rgba32/brdf
void PtexReader::PackedFace::reduce(FaceData*& face, PtexReader* r,
                                    Res newres, PtexUtils::ReduceFn reducefn)
{
    // get reduce lock and make sure we still need to reduce
    AutoMutex rlocker(r->reducelock);
    if (face) {
        // another thread must have generated it while we were waiting
        AutoLockCache clocker(_cache->cachelock);
        // make sure it's still there now that we have the lock
        if (face) {
            face->ref();
            return;
        }
    }

    // allocate a new face and reduce image
    DataType dt = r->datatype();
    int nchan = r->nchannels();
    PackedFace* pf = new PackedFace((void**)&face, _cache, newres,
                                    _pixelsize, _pixelsize * newres.size());
    // reduce and copy into new face
    reducefn(_data, _pixelsize * _res.u(), _res.u(), _res.v(),
             pf->_data, _pixelsize * newres.u(), dt, nchan);
    AutoLockCache clocker(_cache->cachelock);
    face = pf;

    // clean up unused data
    _cache->purgeData();
}
コード例 #3
0
ファイル: PtexWriter.cpp プロジェクト: 400notout/oiio
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);
    }
}
コード例 #4
0
ファイル: PtexReader.cpp プロジェクト: rgba32/brdf
void PtexReader::readFaceData(FilePos pos, FaceDataHeader fdh, Res res, int levelid,
                              FaceData*& face)
{
    // keep new face local until fully initialized
    FaceData* volatile newface = 0;

    seek(pos);
    switch (fdh.encoding()) {
    case enc_constant:
    {
        ConstantFace* pf = new ConstantFace((void**)&face, _cache, _pixelsize);
        readBlock(pf->data(), _pixelsize);
        if (levelid==0 && _premultiply && _header.hasAlpha())
            PtexUtils::multalpha(pf->data(), 1, _header.datatype,
                                 _header.nchannels, _header.alphachan);
        newface = pf;
    }
    break;
    case enc_tiled:
    {
        Res tileres;
        readBlock(&tileres, sizeof(tileres));
        uint32_t tileheadersize;
        readBlock(&tileheadersize, sizeof(tileheadersize));
        TiledFace* tf = new TiledFace((void**)&face, _cache, res, tileres, levelid, this);
        readZipBlock(&tf->_fdh[0], tileheadersize, FaceDataHeaderSize * tf->_ntiles);
        computeOffsets(tell(), tf->_ntiles, &tf->_fdh[0], &tf->_offsets[0]);
        newface = tf;
    }
    break;
    case enc_zipped:
    case enc_diffzipped:
    {
        int uw = res.u(), vw = res.v();
        int npixels = uw * vw;
        int unpackedSize = _pixelsize * npixels;
        PackedFace* pf = new PackedFace((void**)&face, _cache,
                                        res, _pixelsize, unpackedSize);
        bool useMalloc = unpackedSize > AllocaMax;
        void* tmp = useMalloc ? malloc(unpackedSize) : alloca(unpackedSize);
        readZipBlock(tmp, fdh.blocksize(), unpackedSize);
        if (fdh.encoding() == enc_diffzipped)
            PtexUtils::decodeDifference(tmp, unpackedSize, _header.datatype);
        PtexUtils::interleave(tmp, uw * DataSize(_header.datatype), uw, vw,
                              pf->data(), uw * _pixelsize,
                              _header.datatype, _header.nchannels);
        if (levelid==0 && _premultiply && _header.hasAlpha())
            PtexUtils::multalpha(pf->data(), npixels, _header.datatype,
                                 _header.nchannels, _header.alphachan);
        newface = pf;
        if (useMalloc) free(tmp);
    }
    break;
    }

    face = newface;
}
コード例 #5
0
Res parallel(Res a, Res b) {
    a.inv();
    b.inv();
    Res ret = a + b;
    ret.inv();

    ret.reduce();
    return ret;
}
コード例 #6
0
Res unpar(Res a, Res par) {
    par.inv();
    a.inv();
    Res b = par - a;
    b.inv();
    b.reduce();

    return b;
}
コード例 #7
0
ファイル: PtexWriter.cpp プロジェクト: 400notout/oiio
void PtexMainWriter::storeConstValue(int faceid, const void* data, int stride, Res res)
{
    // compute average value and store in _constdata block
    uint8_t* constdata = &_constdata[faceid*_pixelSize];
    PtexUtils::average(data, stride, res.u(), res.v(), constdata,
		       _header.datatype, _header.nchannels);
    if (_header.hasAlpha())
	PtexUtils::divalpha(constdata, 1, _header.datatype, _header.nchannels, _header.alphachan);
}
コード例 #8
0
ファイル: PtexWriter.cpp プロジェクト: 400notout/oiio
void PtexWriterBase::writeReduction(FILE* fp, const void* data, int stride, Res res)
{
    // reduce and write to file
    Ptex::Res newres(res.ulog2-1, res.vlog2-1);
    int buffsize = newres.size() * _pixelSize;
    bool useMalloc = buffsize > AllocaMax;
    char* buff = useMalloc ? (char*) malloc(buffsize) : (char*)alloca(buffsize);

    int dstride = newres.u() * _pixelSize;
    _reduceFn(data, stride, res.u(), res.v(), buff, dstride, _header.datatype, _header.nchannels);
    writeBlock(fp, buff, buffsize);

    if (useMalloc) free(buff);
}
コード例 #9
0
ファイル: PtexTriangleFilter.cpp プロジェクト: DINKIN/ptex
void PtexTriangleFilter::buildKernel(PtexTriangleKernel& k, float u, float v,
                                     float uw1, float vw1, float uw2, float vw2,
                                     float width, float blur, Res faceRes)
{
    const float sqrt3 = 1.7320508075688772f;

    // compute ellipse coefficients, A*u^2 + B*u*v + C*v^2 == AC - B^2/4
    float scaleAC = 0.25f * width*width;
    float scaleB = -2.0f * scaleAC;
    float A = (vw1*vw1 + vw2*vw2) * scaleAC;
    float B = (uw1*vw1 + uw2*vw2) * scaleB;
    float C = (uw1*uw1 + uw2*uw2) * scaleAC;

    // convert to cartesian domain
    float Ac = 0.75f * A;
    float Bc = float(sqrt3/2) * (B-A);
    float Cc = 0.25f * A - 0.5f * B + C;

    // compute min blur for eccentricity clamping
    const float maxEcc = 15.0f; // max eccentricity
    const float eccRatio = (maxEcc*maxEcc + 1.0f) / (maxEcc*maxEcc - 1.0f);
    float X = sqrtf(squared(Ac - Cc) + squared(Bc));
    float b_e = 0.5f * (eccRatio * X - (Ac + Cc));

    // compute min blur for texel clamping
    // (ensure that ellipse is no smaller than a texel)
    float b_t = squared(0.5f / (float)faceRes.u());

    // add blur
    float b_b = 0.25f * blur * blur;
    float b = PtexUtils::max(b_b, PtexUtils::max(b_e, b_t));
    Ac += b;
    Cc += b;

    // compute minor radius
    float m = sqrtf(2.0f*(Ac*Cc - 0.25f*Bc*Bc) / (Ac + Cc + X));

    // choose desired resolution
    int reslog2 = PtexUtils::max(0, PtexUtils::calcResFromWidth(2.0f*m));

    // convert back to triangular domain
    A = float(4/3.0) * Ac;
    B = float(2/sqrt3) * Bc + A;
    C = -0.25f * A + 0.5f * B + Cc;

    // scale by kernel width
    float scale = PtexTriangleKernelWidth * PtexTriangleKernelWidth;
    A *= scale;
    B *= scale;
    C *= scale;

    // find u,v,w extents
    float uw = PtexUtils::min(sqrtf(C), 1.0f);
    float vw = PtexUtils::min(sqrtf(A), 1.0f);
    float ww = PtexUtils::min(sqrtf(A-B+C), 1.0f);

    // init kernel
    float w = 1.0f - u - v;
    k.set(Res((int8_t)reslog2, (int8_t)reslog2), u, v, u-uw, v-vw, w-ww, u+uw, v+vw, w+ww, A, B, C);
}
コード例 #10
0
ファイル: dumbuild.cpp プロジェクト: prepare/gameswf
void ExitIfError(const Res& res, const Context& context) {
  if (res.Ok()) {
    return;
  }

  if (res.value() == ERR_SHOW_USAGE) {
    PrintUsage();
    exit(1);
  }

  fprintf(stderr, "dmb error\n");
  fprintf(stderr, "%s\n", res.ToString().c_str());

  if (context.log_verbose()) {
    context.LogAllTargets();
  }

  exit(1);
}
コード例 #11
0
void RenderTarget::AddTarget(Res<Texture> &target)
{
	if (targets.size())
	{
		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	}
	else
	{
		width = target->width();
		height = target->height();

		glGenFramebuffers(1, &fbo);
		glBindFramebuffer(GL_FRAMEBUFFER, fbo);

		if (depth)
		{
			glGenRenderbuffers(1, &rb);
			glBindRenderbuffer(GL_RENDERBUFFER, rb);
			glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
			glBindRenderbuffer(GL_RENDERBUFFER, 0);
			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
		}
	}

	target->SetAsAttachment(targets.size());
	int err = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	switch(err)
	{
	case GL_FRAMEBUFFER_COMPLETE: break;
	case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: Fatal("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\n"); break;
	case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:Fatal("GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS\n"); break;
	case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:Fatal("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\n"); break;
	case GL_FRAMEBUFFER_UNSUPPORTED:Fatal("GL_FRAMEBUFFER_UNSUPPORTED\n"); break;
	case GL_INVALID_FRAMEBUFFER_OPERATION:Fatal("GL_INVALID_FRAMEBUFFER_OPERATION\n"); break;
	case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB:Fatal("GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB\n"); break;
	case GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB:Fatal("GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB\n"); break;
	default: Fatal("Unknown framebuffer error"); break;
	}
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	targets.push_back(target);
}
コード例 #12
0
EIGEN_DONT_INLINE void bench_prod()
{
  typedef Matrix<Scalar,M,K> Lhs; Lhs a; a.setRandom();
  typedef Matrix<Scalar,K,N> Rhs; Rhs b; b.setRandom();
  typedef Matrix<Scalar,M,N> Res; Res c; c.setRandom();

  BenchTimer t;
  double n = 2.*double(M)*double(N)*double(K);
  int rep = 100000./n;
  rep /= 2;
  if(rep<1) rep = 1;
  do {
    rep *= 2;
    t.reset();
    BENCH(t,1,rep,prod<CoeffBasedProductMode>(a,b,c));
  } while(t.best()<0.1);
  
  t.reset();
  BENCH(t,5,rep,prod<Mode>(a,b,c));

  print_mode(Mode);
  std::cout << int(1e-6*n*rep/t.best()) << "\t";
}
コード例 #13
0
ファイル: PtexReader.cpp プロジェクト: rgba32/brdf
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);
    }
}
コード例 #14
0
ファイル: PtexWriter.cpp プロジェクト: 400notout/oiio
Ptex::Res PtexWriterBase::calcTileRes(Res faceres)
{
    // desired number of tiles = floor(log2(facesize / tilesize))
    int facesize = faceres.size() * _pixelSize;
    int ntileslog2 = PtexUtils::floor_log2(facesize/TileSize);
    if (ntileslog2 == 0) return faceres;

    // number of tiles is defined as:
    //   ntileslog2 = ureslog2 + vreslog2 - (tile_ureslog2 + tile_vreslog2)
    // rearranging to solve for the tile res:
    //   tile_ureslog2 + tile_vreslog2 = ureslog2 + vreslog2 - ntileslog2
    int n = faceres.ulog2 + faceres.vlog2 - ntileslog2;

    // choose u and v sizes for roughly square result (u ~= v ~= n/2)
    // and make sure tile isn't larger than face
    Res tileres;
    tileres.ulog2 = PtexUtils::min((n+1)/2, int(faceres.ulog2));
    tileres.vlog2 = PtexUtils::min(n - tileres.ulog2, int(faceres.vlog2));
    return tileres;
}
コード例 #15
0
ファイル: util.cpp プロジェクト: prepare/gameswf
Res ParseValueStringOrMap(const Context* ctx,
                          Config* cfg,
                          const Json::Value& val,
                          const string& equals_string,
                          const string& separator_string,
                          string* out) {
  if (val.isString()) {
    *out = val.asString();
  } else if (val.isArray()) {
    // Evaluate as a lisp expression.
    Res err = EvalToString(ctx, cfg, val, out);
    if (!err.Ok()) {
      err.AppendDetail("in ParseValueStringOrMap(): array eval of '" +
                       val.toStyledString() + "'");
      return err;
    }
  } else if (val.isObject()) {
    // Evaluate as a named-value map.
    bool done_first = false;
    out->clear();
    for (Json::Value::iterator it = val.begin(); it != val.end(); ++it) {
      if (!it.key().isString()) {
        return Res(ERR_PARSE,
                   "ParseValueStringOrMap(): key is not a string: '" +
                   it.key().toStyledString());
      }
      const Json::Value& map_val = *it;
      string result;
      Res err = EvalToString(ctx, cfg, map_val, &result);
      if (!err.Ok()) {
        err.AppendDetail("in ParseValueStringOrMap(): key '" +
                         it.key().toStyledString() + "'");
        return err;
      }
      if (done_first) {
        *out += separator_string;
      }
      *out += it.key().asString();
      *out += equals_string;
      *out += result;
      done_first = true;
    }
  }
  return Res(OK);
}
コード例 #16
0
ファイル: Puntaje.cpp プロジェクト: bertilxi/Pegaso
/**
 * @param part
 */
void Puntaje::sumar(Resultado *res,Modalidad *mod,QString equipo) {

    Res* resultado;
    if(equipo=="EquipoA"){
        resultado = res->getResultadoA();
    }
    else resultado = res->getResultadoB();

    //Actualizo los puntos según el resultado del equipo
    if(resultado->getNombre().toLower() =="ganó"){
        puntos+=mod->getPuntos_ganar();
        PG++;
    }
    if(resultado->getNombre().toLower()=="empate"){
        puntos+=mod->getPuntos_empate();
        PE++;
    }
    if(resultado->getNombre().toLower()=="perdió" || resultado->getNombre().toLower()=="no se presentó"){
        PP++;
    }

    //Si se presentó le agrego los puntos por presentarse
    if(resultado->getNombre().toLower() != "no se presentó"){
        puntos += mod->getPuntos_presentarse();
    }

    //Si el tipo de resultado es por puntos agrego los tantos a favor y en contra y calculo la diferencia
    if(mod->getTipoRes()->getNombre().toLower()=="por puntos"){
        if(equipo=="EquipoA"){
            TF+=res->getPuntosA();
            TC+=res->getPuntosB();
        }
        else {
            TF+=res->getPuntosB();
            TC+=res->getPuntosA();
        }
        Dif=TF-TC;
    }
}
コード例 #17
0
ファイル: dump_db.cpp プロジェクト: slazav/eventdb
void process_result(const Res & e){
  log(cfg.logfile, e.text());
  std::cout << e.json() << std::endl;
}
コード例 #18
0
Res serial(const Res &a, const Res &b) {
    Res ret = a + b;
    ret.reduce();
    return ret;
}
コード例 #19
0
EIGEN_DONT_INLINE void prod(const Lhs& a, const Rhs& b, Res& c)
{
  c.noalias() += typename ProductReturnType<Lhs,Rhs,Mode>::Type(a,b);
}
コード例 #20
0
ファイル: PtexReader.cpp プロジェクト: rgba32/brdf
void PtexReader::TiledFaceBase::reduce(FaceData*& face, PtexReader* r,
                                       Res newres, PtexUtils::ReduceFn reducefn)
{
    // get reduce lock and make sure we still need to reduce
    AutoMutex rlocker(r->reducelock);
    if (face) {
        // another thread must have generated it while we were waiting
        AutoLockCache clocker(_cache->cachelock);
        // make sure it's still there now that we have the lock
        if (face) {
            face->ref();
            return;
        }
    }

    /* Tiled reductions should generally only be anisotropic (just u
       or v, not both) since isotropic reductions are precomputed and
       stored on disk.  (This function should still work for isotropic
       reductions though.)

       In the anisotropic case, the number of tiles should be kept the
       same along the direction not being reduced in order to preserve
       the laziness of the file access.  In contrast, if reductions
       were not tiled, then any reduction would read all the tiles and
       defeat the purpose of tiling.
    */

    // keep new face local until fully initialized
    FaceData* volatile newface = 0;

    // don't tile if either dimension is 1 (rare, would complicate blendFaces too much)
    // also, don't tile triangle reductions (too complicated)
    Res newtileres;
    bool isTriangle = r->_header.meshtype == mt_triangle;
    if (newres.ulog2 == 1 || newres.vlog2 == 1 || isTriangle) {
        newtileres = newres;
    }
    else {
        // propagate the tile res to the reduction
        newtileres = _tileres;
        // but make sure tile isn't larger than the new face!
        if (newtileres.ulog2 > newres.ulog2) newtileres.ulog2 = newres.ulog2;
        if (newtileres.vlog2 > newres.vlog2) newtileres.vlog2 = newres.vlog2;
    }


    // determine how many tiles we will have on the reduction
    int newntiles = newres.ntiles(newtileres);

    if (newntiles == 1) {
        // no need to keep tiling, reduce tiles into a single face
        // first, get all tiles and check if they are constant (with the same value)
        PtexFaceData** tiles = (PtexFaceData**) alloca(_ntiles * sizeof(PtexFaceData*));
        bool allConstant = true;
        for (int i = 0; i < _ntiles; i++) {
            PtexFaceData* tile = tiles[i] = getTile(i);
            allConstant = (allConstant && tile->isConstant() &&
                           (i == 0 || (0 == memcmp(tiles[0]->getData(), tile->getData(),
                                                   _pixelsize))));
        }
        if (allConstant) {
            // allocate a new constant face
            newface = new ConstantFace((void**)&face, _cache, _pixelsize);
            memcpy(newface->getData(), tiles[0]->getData(), _pixelsize);
        }
        else if (isTriangle) {
            // reassemble all tiles into temporary contiguous image
            // (triangle reduction doesn't work on tiles)
            int tileures = _tileres.u();
            int tilevres = _tileres.v();
            int sstride = _pixelsize * tileures;
            int dstride = sstride * _ntilesu;
            int dstepv = dstride * tilevres - sstride*(_ntilesu-1);

            char* tmp = (char*) malloc(_ntiles * _tileres.size() * _pixelsize);
            char* tmpptr = tmp;
            for (int i = 0; i < _ntiles;) {
                PtexFaceData* tile = tiles[i];
                if (tile->isConstant())
                    PtexUtils::fill(tile->getData(), tmpptr, dstride,
                                    tileures, tilevres, _pixelsize);
                else
                    PtexUtils::copy(tile->getData(), sstride, tmpptr, dstride, tilevres, sstride);
                i++;
                tmpptr += i%_ntilesu ? sstride : dstepv;
            }

            // allocate a new packed face
            newface = new PackedFace((void**)&face, _cache, newres,
                                     _pixelsize, _pixelsize * newres.size());
            // reduce and copy into new face
            reducefn(tmp, _pixelsize * _res.u(), _res.u(), _res.v(),
                     newface->getData(), _pixelsize * newres.u(), _dt, _nchan);

            free(tmp);
        }
        else {
            // allocate a new packed face
            newface = new PackedFace((void**)&face, _cache, newres,
                                     _pixelsize, _pixelsize*newres.size());

            int tileures = _tileres.u();
            int tilevres = _tileres.v();
            int sstride = _pixelsize * tileures;
            int dstride = _pixelsize * newres.u();
            int dstepu = dstride/_ntilesu;
            int dstepv = dstride*newres.v()/_ntilesv - dstepu*(_ntilesu-1);

            char* dst = (char*) newface->getData();
            for (int i = 0; i < _ntiles;) {
                PtexFaceData* tile = tiles[i];
                if (tile->isConstant())
                    PtexUtils::fill(tile->getData(), dst, dstride,
                                    newres.u()/_ntilesu, newres.v()/_ntilesv,
                                    _pixelsize);
                else
                    reducefn(tile->getData(), sstride, tileures, tilevres,
                             dst, dstride, _dt, _nchan);
                i++;
                dst += i%_ntilesu ? dstepu : dstepv;
            }
        }
        // release the tiles
        for (int i = 0; i < _ntiles; i++) tiles[i]->release();
    }
    else {
        // otherwise, tile the reduced face
        newface = new TiledReducedFace((void**)&face, _cache, newres, newtileres,
                                       _dt, _nchan, this, reducefn);
    }
    AutoLockCache clocker(_cache->cachelock);
    face = newface;

    // clean up unused data
    _cache->purgeData();
}
コード例 #21
0
ファイル: PtexReader.cpp プロジェクト: rgba32/brdf
void PtexReader::blendFaces(FaceData*& face, int faceid, Res res, bool blendu)
{
    Res pres;   // parent res, 1 higher in blend direction
    int length; // length of blend edge (1xN or Nx1)
    int e1, e2; // neighboring edge ids
    if (blendu) {
        assert(res.ulog2 < 0); // res >= 0 requires reduction, not blending
        length = (res.vlog2 <= 0 ? 1 : res.v());
        e1 = e_bottom;
        e2 = e_top;
        pres = Res(res.ulog2+1, res.vlog2);
    }
    else {
        assert(res.vlog2 < 0);
        length = (res.ulog2 <= 0 ? 1 : res.u());
        e1 = e_right;
        e2 = e_left;
        pres = Res(res.ulog2, res.vlog2+1);
    }

    // get neighbor face ids
    FaceInfo& f = _faceinfo[faceid];
    int nf1 = f.adjfaces[e1], nf2 = f.adjfaces[e2];

    // compute rotation of faces relative to current
    int r1 = (f.adjedge(e1)-e1+2)&3;
    int r2 = (f.adjedge(e2)-e2+2)&3;

    // swap u and v res for faces rotated +/- 90 degrees
    Res pres1 = pres, pres2 = pres;
    if (r1 & 1) pres1.swapuv();
    if (r2 & 1) pres2.swapuv();

    // ignore faces that have insufficient res (unlikely, but possible)
    if (nf1 >= 0 && !(_faceinfo[nf1].res >= pres)) nf1 = -1;
    if (nf2 >= 0 && !(_faceinfo[nf2].res >= pres)) nf2 = -1;

    // get parent face data
    int nf = 1;			// number of faces to blend (1 to 3)
    bool flip[3];		// true if long dimension needs to be flipped
    PtexFaceData* psrc[3];	// the face data
    psrc[0] = getData(faceid, pres);
    flip[0] = 0;		// don't flip main face
    if (nf1 >= 0) {
        // face must be flipped if rot is 1 or 2 for blendu, or 2 or 3 for blendv
        // thus, just add the blendu bool val to align the ranges and check bit 1
        // also, no need to flip if length is zero
        flip[nf] = length ? (r1 + blendu) & 1 : 0;
        psrc[nf++] = getData(nf1, pres1);
    }
    if (nf2 >= 0) {
        flip[nf] = length ? (r2 + blendu) & 1 : 0;
        psrc[nf++] = getData(nf2, pres2);
    }

    // get reduce lock and make sure we still need to reduce
    AutoMutex rlocker(reducelock);
    if (face) {
        // another thread must have generated it while we were waiting
        AutoLockCache locker(_cache->cachelock);
        // make sure it's still there now that we have the lock
        if (face) {
            face->ref();
            // release parent data
            for (int i = 0; i < nf; i++) psrc[i]->release();
            return;
        }
    }

    // allocate a new face data (1 x N or N x 1)
    DataType dt = datatype();
    int nchan = nchannels();
    int size = _pixelsize * length;
    PackedFace* pf = new PackedFace((void**)&face, _cache, res,
                                    _pixelsize, size);
    void* data = pf->getData();
    if (nf == 1) {
        // no neighbors - just copy face
        memcpy(data, psrc[0]->getData(), size);
    }
    else {
        float weight = 1.0f / nf;
        memset(data, 0, size);
        for (int i = 0; i < nf; i++)
            PtexUtils::blend(psrc[i]->getData(), weight, data, flip[i],
                             length, dt, nchan);
    }

    {
        AutoLockCache clocker(_cache->cachelock);
        face = pf;

        // clean up unused data
        _cache->purgeData();
    }

    // release parent data
    for (int i = 0; i < nf; i++) psrc[i]->release();
}
コード例 #22
0
ファイル: file_deps.cpp プロジェクト: weihuoya/gameswf
Res GetIncludes(const Target* t, const Context* context,
                const string& src_path, const string& inc_dirs_str,
                vector<string>* includes) {
    Hash src_hash;
    Res res = context->ComputeOrGetFileContentHash(src_path, &src_hash);
    if (!res.Ok()) {
        return res;
    }

    Hash deps_file_id;
    deps_file_id << "includes" << src_hash << inc_dirs_str;

    ObjectStore* ostore = context->GetObjectStore();
    FILE* fp = ostore->Read(deps_file_id);
    if (fp) {
        // Read the deps file.
        static const int BUFSIZE = 1000;
        char linebuf[BUFSIZE];
        while (fgets(linebuf, BUFSIZE, fp)) {
            if (linebuf[0] == '\r' || linebuf[0] == '\n' || linebuf[0] == '#') {
                // Skip.
                continue;
            }
            int len = strlen(linebuf);

            // Trim.
            while (len >= 0 && (linebuf[len - 1] == '\n' ||
                                linebuf[len - 1] == '\r')) {
                linebuf[len - 1] = 0;
                len--;
            }

            includes->push_back(linebuf);
        }
        fclose(fp);
    } else {
        // Scan the source file.
        FILE* fp_src = fopen(src_path.c_str(), "rb");
        if (!fp_src) {
            return Res(ERR_FILE_ERROR, "Couldn't open file for include scanning: " +
                       src_path);
        }

        string src_dir = FilenamePathPart(src_path);
        static const int BUFSIZE = 1000;
        char linebuf[BUFSIZE];
        string header_file;
        string header_path;
        bool is_quoted = false;
        while (fgets(linebuf, BUFSIZE, fp_src)) {
            if (ParseIncludeLine(linebuf, &header_file, &is_quoted)) {
                if (FindHeader(src_dir, t, context, header_file, is_quoted,
                               &header_path)) {
                    includes->push_back(header_path);
                }
            }
        }
        fclose(fp_src);

        // Write the deps file.
        FILE* fp = ostore->Write(deps_file_id);
        if (!fp) {
            context->LogVerbose("Unable to write deps to ostore for file: " +
                                src_path);
        } else {
            fprintf(fp, "# includes %s\n", src_path.c_str());
            for (size_t i = 0; i < includes->size(); i++) {
                const string& header_path = (*includes)[i];
                bool ok =
                    (fwrite(header_path.c_str(), header_path.size(), 1, fp) == 1) &&
                    (fputc('\n', fp) != EOF);
                if (!ok) {
                    fclose(fp);
                    return Res(ERR_FILE_ERROR, "Error writing to deps file for " +
                               src_path);
                }
            }
            fclose(fp);
        }
    }

    return Res(OK);
}
コード例 #23
0
ファイル: PtexWriter.cpp プロジェクト: 400notout/oiio
void PtexMainWriter::generateReductions()
{
    // first generate "rfaceids", reduction faceids,
    // which are faceids reordered by decreasing smaller dimension
    int nfaces = _header.nfaces;
    _rfaceids.resize(nfaces);
    _faceids_r.resize(nfaces);
    PtexUtils::genRfaceids(&_faceinfo[0], nfaces, &_rfaceids[0], &_faceids_r[0]);

    // determine how many faces in each level, and resize _levels
    // traverse in reverse rfaceid order to find number of faces
    // larger than cutoff size of each level
    for (int rfaceid = nfaces-1, cutoffres = MinReductionLog2; rfaceid >= 0; rfaceid--) {
	int faceid = _faceids_r[rfaceid];
	FaceInfo& face = _faceinfo[faceid];
	Res res = face.res;
	int min = face.isConstant() ? 1 : PtexUtils::min(res.ulog2, res.vlog2);
	while (min > cutoffres) {
	    // i == last face for current level
	    int size = rfaceid+1;
	    _levels.push_back(LevelRec());
	    LevelRec& level = _levels.back();
	    level.pos.resize(size);
	    level.fdh.resize(size);
	    cutoffres++;
	}
    }

    // generate and cache reductions (including const data)
    // first, find largest face and allocate tmp buffer
    int buffsize = 0;
    for (int i = 0; i < nfaces; i++)
	buffsize = PtexUtils::max(buffsize, _faceinfo[i].res.size());
    buffsize *= _pixelSize;
    char* buff = (char*) malloc(buffsize);

    int nlevels = int(_levels.size());
    for (int i = 1; i < nlevels; i++) {
	LevelRec& level = _levels[i];
	int nextsize = (i+1 < nlevels)? int(_levels[i+1].fdh.size()) : 0;
	for (int rfaceid = 0, size = int(level.fdh.size()); rfaceid < size; rfaceid++) {
	    // output current reduction for face (previously generated)
	    int faceid = _faceids_r[rfaceid];
	    Res res = _faceinfo[faceid].res;
	    res.ulog2 -= i; res.vlog2 -= i;
	    int stride = res.u() * _pixelSize;
	    int blocksize = res.size() * _pixelSize;
	    fseeko(_tmpfp, _rpos[faceid], SEEK_SET);
	    readBlock(_tmpfp, buff, blocksize);
	    fseeko(_tmpfp, 0, SEEK_END);
	    level.pos[rfaceid] = ftello(_tmpfp);
	    writeFaceData(_tmpfp, buff, stride, res, level.fdh[rfaceid]);
	    if (!_ok) return;

	    // write a new reduction if needed for next level
	    if (rfaceid < nextsize) {
		fseeko(_tmpfp, _rpos[faceid], SEEK_SET);
		writeReduction(_tmpfp, buff, stride, res);
	    }
	    else {
		// the last reduction for each face is its constant value
		storeConstValue(faceid, buff, stride, res);
	    }
	}
    }
    fseeko(_tmpfp, 0, SEEK_END);
    free(buff);
}
コード例 #24
0
ファイル: file_deps.cpp プロジェクト: weihuoya/gameswf
// DepHash(src_file) = Hash(src_file) + sum(for d in deps: DepHash(d))
//
// The include_chain helps us avoid infinite recursion in case of
// include cycles.
Res AccumulateSrcFileDepHash(const Target* t, const Context* context,
                             const string& src_path, const string& inc_dirs_str,
                             std::set<string>* included,
                             Hash* dep_hash) {
    if (included->find(src_path) != included->end()) {
        // Recursive include; we've already visited this file.  Don't
        // recurse infinitely!
        *dep_hash << src_path;
        return Res(OK);
    }

    // Insert src_path into the include chain, and remove it before we
    // return.
    struct AutoInsertRemove {
    public:
        AutoInsertRemove(std::set<string>* included, const string& file) :
            included_(included), file_(file) {
            included_->insert(file_);
        }
        ~AutoInsertRemove() {
            included_->erase(file_);
        }
    private:
        std::set<string>* included_;
        const string& file_;
    };
    AutoInsertRemove auto_insert_remove(included, src_path);

    Hash content_hash;
    Res res = context->ComputeOrGetFileContentHash(src_path, &content_hash);
    if (!res.Ok()) {
        return res;
    }

    // Check to see if we've already computed this dep hash.
    HashCache<Hash>* dep_hash_cache = context->GetDepHashCache();
    assert(dep_hash_cache);
    Hash dep_cache_key;
    dep_cache_key << "dep_cache_key" << src_path << content_hash << inc_dirs_str;
    Hash cached_dep_hash;
    if (dep_hash_cache->Get(dep_cache_key, &cached_dep_hash)) {
        *dep_hash << cached_dep_hash;
        return Res(OK);
    }

    // Compute the dep hash.
    Hash computed_dep_hash;
    computed_dep_hash << content_hash;

    vector<string> includes;
    res = GetIncludes(t, context, src_path, inc_dirs_str, &includes);
    if (!res.Ok()) {
        return res;
    }

    for (size_t i = 0; i < includes.size(); i++) {
        res = AccumulateSrcFileDepHash(t, context, includes[i], inc_dirs_str,
                                       included, &computed_dep_hash);
        if (!res.Ok()) {
            return res;
        }
    }

    // Write the computed hash back to the cache, for re-use.
    dep_hash_cache->Insert(dep_cache_key, computed_dep_hash);
    *dep_hash << computed_dep_hash;

    return Res(OK);
}