ubyte* QtTextureLoader::loadImage(const std::string& file, ImageFormat& format) const
{
    QImage textureImg(file.c_str());

    if(textureImg.isNull())
        return nullptr;

    QImage glImg = QGLWidget::convertToGLFormat(textureImg);

    if(glImg.isNull())
    {
        LOG("Not enough memory to convert ", file, "to gl format (",
            textureImg.height(),"x", textureImg.width());

        return nullptr;
    }

    try{
        ubyte* b = new ubyte[glImg.byteCount()];
        memcpy(b, glImg.bits(), glImg.byteCount());
        format.size.x() = glImg.size().width();
        format.size.y() = glImg.size().height();
        format.nbComponent = 4;
        return b;
    }
    catch(const std::bad_alloc&)
    {
        LOG("Not enough memory to alloc ", file, " (", glImg.byteCount(), " bytes)");
    }

    return nullptr;
}
Esempio n. 2
0
void TextureFilter::filterImage()
{
    // Texture tile.

    int w           = m_orgImage.width();
    int h           = m_orgImage.height();
    int bytesDepth  = m_orgImage.bytesDepth();
    bool sixteenBit = m_orgImage.sixteenBit();

    kDebug() << "Texture File: " << m_texturePath;
    DImg texture(m_texturePath);

    if ( texture.isNull() )
    {
        return;
    }

    DImg textureImg(w, h, m_orgImage.sixteenBit(), m_orgImage.hasAlpha());

    texture.convertToDepthOfImage(&textureImg);

    for (int x = 0 ; x < w ; x+=texture.width())
    {
        for (int y = 0 ; y < h ; y+=texture.height())
        {
            textureImg.bitBltImage(&texture, x, y);
        }
    }

    // Apply texture.

    uchar* data     = m_orgImage.bits();
    uchar* pTeData  = textureImg.bits();
    uchar* pOutBits = m_destImage.bits();
    uint offset;

    DColor teData, transData, inData, outData;
    uchar* ptr, *dptr, *tptr;
    int progress;

    int blendGain;

    if (sixteenBit)
    {
        blendGain = (m_blendGain + 1) * 256 - 1;
    }
    else
    {
        blendGain = m_blendGain;
    }

    // Make textured transparent layout.

    for (int x = 0; runningFlag() && x < w; ++x)
    {
        for (int y = 0; runningFlag() && y < h; ++y)
        {
            offset = x * bytesDepth + (y * w * bytesDepth);
            ptr    = data + offset;
            tptr   = pTeData + offset;

            // Read color
            teData.setColor(tptr, sixteenBit);

            // in the old algorithm, this was
            //teData.channel.red   = (teData.channel.red * (255 - m_blendGain) +
            //      transData.channel.red * m_blendGain) >> 8;
            // but transdata was uninitialized, its components were apparently 0,
            // so I removed the part after the "+".

            if (sixteenBit)
            {
                teData.blendInvAlpha16(blendGain);
            }
            else
            {
                teData.blendInvAlpha8(blendGain);
            }

            // Overwrite RGB.
            teData.setPixel(tptr);
        }

        // Update progress bar in dialog.
        progress = (int) (((double) x * 50.0) / w);

        if (progress % 5 == 0)
        {
            postProgress(progress);
        }
    }

    // Merge layout and image using overlay method.

    for (int x = 0; runningFlag() && x < w; ++x)
    {
        for (int y = 0; runningFlag() && y < h; ++y)
        {
            offset = x * bytesDepth + (y * w * bytesDepth);
            ptr    = data + offset;
            dptr   = pOutBits + offset;
            tptr   = pTeData + offset;

            inData.setColor(ptr, sixteenBit);
            outData.setColor(dptr, sixteenBit);
            teData.setColor(tptr, sixteenBit);

            if (sixteenBit)
            {
                outData.setRed(intMult16(inData.red(), inData.red() + intMult16(2 * teData.red(), 65535 - inData.red())));
                outData.setGreen(intMult16(inData.green(), inData.green() + intMult16(2 * teData.green(), 65535 - inData.green())));
                outData.setBlue(intMult16(inData.blue(), inData.blue() + intMult16(2 * teData.blue(), 65535 - inData.blue())));
            }
            else
            {
                outData.setRed(intMult8(inData.red(), inData.red() + intMult8(2 * teData.red(), 255 - inData.red())));
                outData.setGreen(intMult8(inData.green(), inData.green() + intMult8(2 * teData.green(), 255 - inData.green())));
                outData.setBlue(intMult8(inData.blue(), inData.blue() + intMult8(2 * teData.blue(), 255 - inData.blue())));
            }

            outData.setAlpha(inData.alpha());
            outData.setPixel(dptr);
        }

        // Update progress bar in dialog.
        progress = (int) (50.0 + ((double) x * 50.0) / w);

        if (progress%5 == 0)
        {
            postProgress(progress);
        }
    }
}