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; }
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); } } }