Exemplo n.º 1
0
bool
ImageBuf::copy_pixels (int xbegin, int xend, int ybegin, int yend,
                       TypeDesc format, void *result) const
{
#if 1
    // Fancy method -- for each possible base type that the user
    // wants for a destination type, call a template specialization.
    switch (format.basetype) {
    case TypeDesc::UINT8 :
        copy_pixels<unsigned char> (xbegin, xend, ybegin, yend, (unsigned char *)result);
        break;
    case TypeDesc::INT8:
        copy_pixels<char> (xbegin, xend, ybegin, yend, (char *)result);
        break;
    case TypeDesc::UINT16 :
        copy_pixels<unsigned short> (xbegin, xend, ybegin, yend, (unsigned short *)result);
        break;
    case TypeDesc::INT16 :
        copy_pixels<short> (xbegin, xend, ybegin, yend, (short *)result);
        break;
    case TypeDesc::UINT :
        copy_pixels<unsigned int> (xbegin, xend, ybegin, yend, (unsigned int *)result);
        break;
    case TypeDesc::INT :
        copy_pixels<int> (xbegin, xend, ybegin, yend, (int *)result);
        break;
    case TypeDesc::HALF :
        copy_pixels<half> (xbegin, xend, ybegin, yend, (half *)result);
        break;
    case TypeDesc::FLOAT :
        copy_pixels<float> (xbegin, xend, ybegin, yend, (float *)result);
        break;
    case TypeDesc::DOUBLE :
        copy_pixels<double> (xbegin, xend, ybegin, yend, (double *)result);
        break;
    case TypeDesc::UINT64 :
        copy_pixels<unsigned long long> (xbegin, xend, ybegin, yend, (unsigned long long *)result);
        break;
    case TypeDesc::INT64 :
        copy_pixels<long long> (xbegin, xend, ybegin, yend, (long long *)result);
        break;
    default:
        return false;
    }
#else
    // Naive method -- loop over pixels, calling getpixel()
    size_t usersize = format.size() * nchannels();
    float *pel = (float *) alloca (nchannels() * sizeof(float));
    for (int y = ybegin;  y < yend;  ++y)
        for (int x = xbegin;  x < xend;  ++x) {
            getpixel (x, y, pel);
            convert_types (TypeDesc::TypeFloat, pel,
                           format, result, nchannels());
            result = (void *) ((char *)result + usersize);
        }
#endif
    return true;
}
Exemplo n.º 2
0
bool
ImageBuf::get_pixels (int xbegin, int xend, int ybegin, int yend,
                      int zbegin, int zend, TypeDesc format, void *result,
                      stride_t xstride, stride_t ystride,
                      stride_t zstride) const
{
    return get_pixel_channels (xbegin, xend, ybegin, yend, zbegin, zend,
                               0, nchannels(), format, result,
                               xstride, ystride, zstride);
}
Exemplo n.º 3
0
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();
}