void
Image::copyUnProcessedChannels(const RectI& roi,
                               const ImagePremultiplicationEnum outputPremult,
                               const ImagePremultiplicationEnum originalImagePremult,
                               const std::bitset<4> processChannels,
                               const ImagePtr& originalImage,
                               bool ignorePremult)
{
    int numComp = getComponents().getNumComponents();

    if (numComp == 0) {
        return;
    }
    if ( (numComp == 1) && processChannels[3] ) { // 1 component is alpha
        return;
    } else if ( (numComp == 2) && processChannels[0] && processChannels[1] ) {
        return;
    } else if ( (numComp == 3) && processChannels[0] && processChannels[1] && processChannels[2] ) {
        return;
    } else if ( (numComp == 4) && processChannels[0] && processChannels[1] && processChannels[2] && processChannels[3] ) {
        return;
    }


    if ( originalImage && ( getMipMapLevel() != originalImage->getMipMapLevel() ) ) {
        qDebug() << "WARNING: attempting to call copyUnProcessedChannels on images with different mipMapLevel";

        return;
    }

    QWriteLocker k(&_entryLock);
    assert( !originalImage || getBitDepth() == originalImage->getBitDepth() );


    RectI intersected;
    roi.intersect(_bounds, &intersected);

    bool premult = (outputPremult == eImagePremultiplicationPremultiplied);
    bool originalPremult = (originalImagePremult == eImagePremultiplicationPremultiplied);
    switch ( getBitDepth() ) {
    case eImageBitDepthByte:
        copyUnProcessedChannelsForDepth<unsigned char, 255>(premult, roi, processChannels, originalImage, originalPremult, ignorePremult);
        break;
    case eImageBitDepthShort:
        copyUnProcessedChannelsForDepth<unsigned short, 65535>(premult, roi, processChannels, originalImage, originalPremult, ignorePremult);
        break;
    case eImageBitDepthFloat:
        copyUnProcessedChannelsForDepth<float, 1>(premult, roi, processChannels, originalImage, originalPremult, ignorePremult);
        break;
    default:

        return;
    }
}
示例#2
0
void
Image::applyMaskMixForDstComponents(const RectI& roi,
                                    const Image* maskImg,
                                    const Image* originalImg,
                                    bool masked,
                                    bool maskInvert,
                                    float mix)
{
    ImageBitDepthEnum depth = getBitDepth();

    switch (depth) {
    case eImageBitDepthByte:
        applyMaskMixForDepth<srcNComps, dstNComps, unsigned char, 255>(roi, maskImg, originalImg, masked, maskInvert, mix);
        break;
    case eImageBitDepthShort:
        applyMaskMixForDepth<srcNComps, dstNComps, unsigned short, 65535>(roi, maskImg, originalImg, masked, maskInvert, mix);
        break;
    case eImageBitDepthFloat:
        applyMaskMixForDepth<srcNComps, dstNComps, float, 1>(roi, maskImg, originalImg, masked, maskInvert, mix);
        break;
    default:
        assert(false);
        break;
    }
}
示例#3
0
	void setBitDepthStringIfUpper( const std::string& s )
	{
		property::String& prop = getEditableProperties().fetchLocalStringProperty( kOfxImageEffectPropPixelDepth );

		if( ofx::imageEffect::mapBitDepthStringToEnum( s ) > getBitDepth() ) // we can increase the bit depth but not decrease
			prop.setValue( s );
	}
示例#4
0
	void setBitDepthStringIfUpperAndNotModifiedByPlugin( const std::string& s )
	{
		property::String& prop = getEditableProperties().fetchLocalStringProperty( kOfxImageEffectPropPixelDepth );

		if( prop.getModifiedBy() != property::eModifiedByPlugin && // if not modified by plugin
		    ofx::imageEffect::mapBitDepthStringToEnum( s ) > getBitDepth() ) // we can increase the bit depth but not decrease
			prop.setValue( s );
	}
示例#5
0
static boolByte _openSampleSourceWave(void *sampleSourcePtr, const SampleSourceOpenAs openAs)
{
    SampleSource sampleSource = (SampleSource)sampleSourcePtr;
    SampleSourcePcmData extraData = (SampleSourcePcmData)sampleSource->extraData;

    if (openAs == SAMPLE_SOURCE_OPEN_READ) {
        extraData->fileHandle = fopen(sampleSource->sourceName->data, "rb");

        if (extraData->fileHandle != NULL) {
            if (_readWaveFileInfo(sampleSource->sourceName->data, extraData)) {
                setNumChannels(extraData->numChannels);
                setSampleRate(extraData->sampleRate);
            } else {
                fclose(extraData->fileHandle);
                extraData->fileHandle = NULL;
            }
        }
    } else if (openAs == SAMPLE_SOURCE_OPEN_WRITE) {
        extraData->fileHandle = fopen(sampleSource->sourceName->data, "wb");

        if (extraData->fileHandle != NULL) {
            extraData->numChannels = (unsigned short)getNumChannels();
            extraData->sampleRate = (unsigned int)getSampleRate();
            extraData->bitDepth = getBitDepth();

            if (!_writeWaveFileInfo(extraData)) {
                fclose(extraData->fileHandle);
                extraData->fileHandle = NULL;
            }
        }
    } else {
        logInternalError("Invalid type for openAs in WAVE file");
        return false;
    }

    if (extraData->fileHandle == NULL) {
        logError("WAVE file '%s' could not be opened for %s",
                 sampleSource->sourceName->data, openAs == SAMPLE_SOURCE_OPEN_READ ? "reading" : "writing");
        return false;
    }

    sampleSource->openedAs = openAs;
    return true;
}
示例#6
0
PyObject *set_arrayref(PyObject *self, PyObject *args) {
    int arid;
    PyObject *kdobj, *arobj, **existing;
    KD kd;

    const char *name0="smooth";
    const char *name1="rho";
    const char *name2="mass";
    const char *name3="qty";
    const char *name4="qty_sm";

    const char *name;

    PyArg_ParseTuple(args, "OiO", &kdobj, &arid, &arobj);
    kd  = (KD)PyCapsule_GetPointer(kdobj, NULL);
    if(!kd) return NULL;



    switch(arid) {
    case 0:
        existing = &(kd->pNumpySmooth);
        name = name0;
        break;
    case 1:
        existing = &(kd->pNumpyDen);
        name = name1;
        break;
    case 2:
        existing = &(kd->pNumpyMass);
        name = name2;
        break;
    case 3:
        existing = &(kd->pNumpyQty);
        name = name3;
        break;
    case 4:
        existing = &(kd->pNumpyQtySmoothed);
        name = name4;
        break;
    default:
        PyErr_SetString(PyExc_ValueError, "Unknown array to set for KD tree");
        return NULL;
    }

    int bitdepth=0;
    if(arid<=2)
        bitdepth=kd->nBitDepth;
    else if(arid==3 || arid==4)
        bitdepth=getBitDepth(arobj);

    if(bitdepth==32) {
        if(checkArray<float>(arobj,name)) return NULL;
    } else if(bitdepth==64) {
        if(checkArray<double>(arobj,name)) return NULL;
    } else {
        PyErr_SetString(PyExc_ValueError, "Unsupported array dtype for kdtree");
        return NULL;
    }

    Py_XDECREF(*existing);
    (*existing) = arobj;
    Py_INCREF(arobj);
    return Py_None;
}
示例#7
0
/*==========================================================================*/
PyObject *kdinit(PyObject *self, PyObject *args)
{
    int nBucket;
    int i;

    PyObject *pos;  // Nx3 Numpy array of positions
    PyObject *mass; // Nx1 Numpy array of masses

    if (!PyArg_ParseTuple(args, "OOi", &pos, &mass, &nBucket))
        return NULL;

    int bitdepth = getBitDepth(pos);
    if(bitdepth==0) {
        PyErr_SetString(PyExc_ValueError, "Unsupported array dtype for kdtree");
        return NULL;
    }
    if(bitdepth!=getBitDepth(mass)) {
        PyErr_SetString(PyExc_ValueError, "pos and mass arrays must have matching dtypes for kdtree");
        return NULL;
    }

    if(bitdepth==64) {
        if(checkArray<double>(pos, "pos")) return NULL;
        if(checkArray<double>(mass, "mass")) return NULL;
    } else {
        if(checkArray<float>(pos, "pos")) return NULL;
        if(checkArray<float>(mass, "mass")) return NULL;
    }

    KD kd = (KD)malloc(sizeof(*kd));
    kdInit(&kd, nBucket);

    int nbodies = PyArray_DIM(pos, 0);

    kd->nParticles = nbodies;
    kd->nActive = nbodies;
    kd->nBitDepth = bitdepth;
    kd->pNumpyPos = pos;
    kd->pNumpyMass = mass;
    kd->pNumpySmooth = NULL;
    kd->pNumpyDen = NULL;
    kd->pNumpyQty = NULL;
    kd->pNumpyQtySmoothed = NULL;

    Py_INCREF(pos);
    Py_INCREF(mass);


    Py_BEGIN_ALLOW_THREADS


    // Allocate particles
    kd->p = (PARTICLE *)malloc(kd->nActive*sizeof(PARTICLE));
    assert(kd->p != NULL);

    for (i=0; i < nbodies; i++)
    {
        kd->p[i].iOrder = i;
        kd->p[i].iMark = 1;
    }

    if(bitdepth==64)
        kdBuildTree<double>(kd);
    else
        kdBuildTree<float>(kd);

    Py_END_ALLOW_THREADS

    return PyCapsule_New((void *)kd, NULL, NULL);
}
示例#8
0
void
Image::copyUnProcessedChannels(const RectI& roi,
                               const ImagePremultiplicationEnum outputPremult,
                               const ImagePremultiplicationEnum originalImagePremult,
                               const std::bitset<4> processChannels,
                               const ImagePtr& originalImage,
                               bool ignorePremult,
                               const OSGLContextPtr& glContext)
{
    int numComp = getComponents().getNumComponents();

    if (numComp == 0) {
        return;
    }
    if ( (numComp == 1) && processChannels[3] ) { // 1 component is alpha
        return;
    } else if ( (numComp == 2) && processChannels[0] && processChannels[1] ) {
        return;
    } else if ( (numComp == 3) && processChannels[0] && processChannels[1] && processChannels[2] ) {
        return;
    } else if ( (numComp == 4) && processChannels[0] && processChannels[1] && processChannels[2] && processChannels[3] ) {
        return;
    }


    if ( originalImage && ( getMipMapLevel() != originalImage->getMipMapLevel() ) ) {
        qDebug() << "WARNING: attempting to call copyUnProcessedChannels on images with different mipMapLevel";

        return;
    }

    QWriteLocker k(&_entryLock);
    assert( !originalImage || getBitDepth() == originalImage->getBitDepth() );


    RectI srcRoi;
    roi.intersect(_bounds, &srcRoi);

    if (getStorageMode() == eStorageModeGLTex) {
        assert(glContext);
        if (glContext->isGPUContext()) {
            copyUnProcessedChannelsGL<GL_GPU>(roi, outputPremult, originalImagePremult, processChannels, originalImage, ignorePremult, glContext, _bounds, srcRoi, getGLTextureTarget(), getGLTextureID(), originalImage->getGLTextureID());
        } else {
            copyUnProcessedChannelsGL<GL_CPU>(roi, outputPremult, originalImagePremult, processChannels, originalImage, ignorePremult, glContext, _bounds, srcRoi, getGLTextureTarget(), getGLTextureID(), originalImage->getGLTextureID());
        }
        return;
    }


    bool premult = (outputPremult == eImagePremultiplicationPremultiplied);
    bool originalPremult = (originalImagePremult == eImagePremultiplicationPremultiplied);
    switch ( getBitDepth() ) {
    case eImageBitDepthByte:
        copyUnProcessedChannelsForDepth<unsigned char, 255>(premult, roi, processChannels, originalImage, originalPremult, ignorePremult);
        break;
    case eImageBitDepthShort:
        copyUnProcessedChannelsForDepth<unsigned short, 65535>(premult, roi, processChannels, originalImage, originalPremult, ignorePremult);
        break;
    case eImageBitDepthFloat:
        copyUnProcessedChannelsForDepth<float, 1>(premult, roi, processChannels, originalImage, originalPremult, ignorePremult);
        break;
    default:

        return;
    }
} // copyUnProcessedChannels
示例#9
0
SampleSource _newSampleSourceWave(const CharString sampleSourceName)
{
    SampleSource sampleSource = (SampleSource)malloc(sizeof(SampleSourceMembers));
    SampleSourcePcmData extraData = (SampleSourcePcmData)malloc(sizeof(SampleSourcePcmDataMembers));

    sampleSource->sampleSourceType = SAMPLE_SOURCE_TYPE_WAVE;
    sampleSource->openedAs = SAMPLE_SOURCE_OPEN_NOT_OPENED;
    sampleSource->sourceName = newCharString();
    charStringCopy(sampleSource->sourceName, sampleSourceName);
    sampleSource->numSamplesProcessed = 0;

    sampleSource->openSampleSource = _openSampleSourceWave;
    sampleSource->readSampleBlock = _readBlockFromWaveFile;
    sampleSource->writeSampleBlock = _writeBlockToWaveFile;
    sampleSource->closeSampleSource = _closeSampleSourceWave;
    sampleSource->freeSampleSourceData = freeSampleSourceDataPcm;

    extraData->isStream = false;
    extraData->isLittleEndian = true;
    extraData->fileHandle = NULL;
    // Assume default values for these items. However, if an incoming SampleBuffer
    // has different values for the channel count or blocksize, then we will reassign
    // based on those values.
    extraData->dataBufferNumItems = getNumChannels() * getBlocksize();
    extraData->pcmSampleBuffer = newPcmSampleBuffer(getNumChannels(), getBlocksize(), getBitDepth());

    extraData->numChannels = (unsigned short)getNumChannels();
    extraData->sampleRate = (unsigned int)getSampleRate();
    extraData->bitDepth = kBitDepthDefault;

    sampleSource->extraData = extraData;
    return sampleSource;
}
示例#10
0
void
Image::applyMaskMix(const RectI& roi,
                    const Image* maskImg,
                    const Image* originalImg,
                    bool masked,
                    bool maskInvert,
                    float mix,
                    const OSGLContextPtr& glContext)
{
    ///!masked && mix == 1 has nothing to do
    if ( !masked && (mix == 1) ) {
        return;
    }

    QWriteLocker k(&_entryLock);
    boost::shared_ptr<QReadLocker> originalLock;
    boost::shared_ptr<QReadLocker> maskLock;
    if (originalImg) {
        originalLock.reset( new QReadLocker(&originalImg->_entryLock) );
    }
    if (maskImg) {
        maskLock.reset( new QReadLocker(&maskImg->_entryLock) );
    }
    RectI realRoI;
    roi.intersect(_bounds, &realRoI);

    assert( !originalImg || getBitDepth() == originalImg->getBitDepth() );
    assert( !masked || !maskImg || maskImg->getComponents() == ImageComponents::getAlphaComponents() );

    if (getStorageMode() == eStorageModeGLTex) {
        assert(glContext);
        assert(originalImg->getStorageMode() == eStorageModeGLTex);
        boost::shared_ptr<GLShader> shader = glContext->getOrCreateDefaultShader(OSGLContext::eDefaultGLShaderCopyUnprocessedChannels);
        assert(shader);
        GLuint fboID = glContext->getFBOId();

        glBindFramebuffer(GL_FRAMEBUFFER, fboID);
        int target = getGLTextureTarget();
        glEnable(target);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture( target, getGLTextureID() );
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, getGLTextureID(), 0 /*LoD*/);
        glCheckFramebufferError();

        glActiveTexture(GL_TEXTURE1);
        glBindTexture( target, originalImg->getGLTextureID() );
        glActiveTexture(GL_TEXTURE2);
        glBindTexture(target, maskImg ? maskImg->getGLTextureID() : 0);

        glViewport( realRoI.x1 - _bounds.x1, realRoI.y1 - _bounds.y1, realRoI.width(), realRoI.height() );
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho( realRoI.x1, realRoI.x2,
                realRoI.y1, realRoI.y2,
                -10.0 * (realRoI.y2 - realRoI.y1), 10.0 * (realRoI.y2 - realRoI.y1) );
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glCheckError();

        // Compute the texture coordinates to match the srcRoi
        Point srcTexCoords[4], vertexCoords[4];
        vertexCoords[0].x = realRoI.x1;
        vertexCoords[0].y = realRoI.y1;
        srcTexCoords[0].x = (realRoI.x1 - _bounds.x1) / (double)_bounds.width();
        srcTexCoords[0].y = (realRoI.y1 - _bounds.y1) / (double)_bounds.height();

        vertexCoords[1].x = realRoI.x2;
        vertexCoords[1].y = realRoI.y1;
        srcTexCoords[1].x = (realRoI.x2 - _bounds.x1) / (double)_bounds.width();
        srcTexCoords[1].y = (realRoI.y1 - _bounds.y1) / (double)_bounds.height();

        vertexCoords[2].x = realRoI.x2;
        vertexCoords[2].y = realRoI.y2;
        srcTexCoords[2].x = (realRoI.x2 - _bounds.x1) / (double)_bounds.width();
        srcTexCoords[2].y = (realRoI.y2 - _bounds.y1) / (double)_bounds.height();

        vertexCoords[3].x = realRoI.x1;
        vertexCoords[3].y = realRoI.y2;
        srcTexCoords[3].x = (realRoI.x1 - _bounds.x1) / (double)_bounds.width();
        srcTexCoords[3].y = (realRoI.y2 - _bounds.y1) / (double)_bounds.height();

        shader->bind();
        shader->setUniform("originalImageTex", 1);
        shader->setUniform("maskImageTex", 2);
        shader->setUniform("outputImageTex", 0);
        shader->setUniform("mixValue", mix);
        shader->setUniform("maskEnabled", maskImg ? 1 : 0);

        glBegin(GL_POLYGON);
        for (int i = 0; i < 4; ++i) {
            glTexCoord2d(srcTexCoords[i].x, srcTexCoords[i].y);
            glVertex2d(vertexCoords[i].x, vertexCoords[i].y);
        }
        glEnd();
        shader->unbind();


        glBindTexture(target, 0);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(target, 0);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(target, 0);
        glCheckError();

        return;
    }

    int srcNComps = originalImg ? (int)originalImg->getComponentsCount() : 0;
    //assert(0 < srcNComps && srcNComps <= 4);
    switch (srcNComps) {
    //case 0:
    //    applyMaskMixForSrcComponents<0>(realRoI, maskImg, originalImg, masked, maskInvert, mix);
    //    break;
    case 1:
        applyMaskMixForSrcComponents<1>(realRoI, maskImg, originalImg, masked, maskInvert, mix);
        break;
    case 2:
        applyMaskMixForSrcComponents<2>(realRoI, maskImg, originalImg, masked, maskInvert, mix);
        break;
    case 3:
        applyMaskMixForSrcComponents<3>(realRoI, maskImg, originalImg, masked, maskInvert, mix);
        break;
    case 4:
        applyMaskMixForSrcComponents<4>(realRoI, maskImg, originalImg, masked, maskInvert, mix);
        break;
    default:
        break;
    }
} // applyMaskMix
 uint16_t BaseAudioFile::getByteDepth() const
 {
     return getBitDepth() / 8;
 }
示例#12
0
	std::size_t getBitDepthMemorySize() const
	{
		return imageEffect::bitDepthMemorySize( getBitDepth() );
	}