summaryrefslogtreecommitdiffstats
path: root/digikam/imageplugins/texture/texture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'digikam/imageplugins/texture/texture.cpp')
-rw-r--r--digikam/imageplugins/texture/texture.cpp181
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