diff options
Diffstat (limited to 'digikam/imageplugins/texture/texture.cpp')
-rw-r--r-- | digikam/imageplugins/texture/texture.cpp | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/digikam/imageplugins/texture/texture.cpp b/digikam/imageplugins/texture/texture.cpp new file mode 100644 index 00000000..23a1cef5 --- /dev/null +++ b/digikam/imageplugins/texture/texture.cpp @@ -0,0 +1,181 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-05-25 + * Description : Texture threaded image filter. + * + * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 2006-2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ============================================================ */ + +// C++ includes. + +#include <cmath> +#include <cstdlib> + +// Local includes. + +#include "dimg.h" +#include "ddebug.h" +#include "texture.h" + +namespace DigikamTextureImagesPlugin +{ + +Texture::Texture(Digikam::DImg *orgImage, QObject *parent, int blendGain, QString texturePath) + : Digikam::DImgThreadedFilter(orgImage, parent, "Texture") +{ + m_blendGain = blendGain; + m_texturePath = texturePath; + + initFilter(); +} + +// This method is based on the Simulate Texture Film tutorial from GimpGuru.org web site +// available at this url : http://www.gimpguru.org/Tutorials/SimulatedTexture/ + +//#define INT_MULT(a,b,t) ((t) = (a) * (b) + 0x80, ( ( (t >> 8) + t ) >> 8)) + +inline static int intMult8(uint a, uint b) +{ + uint t = a * b + 0x80; + return ((t >> 8) + t) >> 8; +} + +inline static int intMult16(uint a, uint b) +{ + uint t = a * b + 0x8000; + return ((t >> 16) + t) >> 16; +} + +void Texture::filterImage(void) +{ + // Texture tile. + + int w = m_orgImage.width(); + int h = m_orgImage.height(); + int bytesDepth = m_orgImage.bytesDepth(); + bool sixteenBit = m_orgImage.sixteenBit(); + + DDebug() << "Texture File: " << m_texturePath << endl; + Digikam::DImg texture(m_texturePath); + if ( texture.isNull() ) return; + + Digikam::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; + + Digikam::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; !m_cancel && x < w; x++) + { + for (int y = 0; !m_cancel && 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; !m_cancel && x < w; x++) + { + for (int y = 0; !m_cancel && 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); + } +} + +} // NameSpace DigikamTextureImagesPlugin |