summaryrefslogtreecommitdiffstats
path: root/digikam/imageplugins/raindrop
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-17 08:33:13 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-17 08:33:13 +0000
commit5543c8d9438bdee5065f9c30e418f9b664aee170 (patch)
tree3f360005ae611849a11adab769c34033dee2147f /digikam/imageplugins/raindrop
downloaddigikam-5543c8d9438bdee5065f9c30e418f9b664aee170.tar.gz
digikam-5543c8d9438bdee5065f9c30e418f9b664aee170.zip
Added developer-abandoned KDE3 version of Digikam
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/digikam@1075997 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'digikam/imageplugins/raindrop')
-rw-r--r--digikam/imageplugins/raindrop/Makefile.am34
-rw-r--r--digikam/imageplugins/raindrop/digikamimageplugin_raindrop.desktop52
-rw-r--r--digikam/imageplugins/raindrop/digikamimageplugin_raindrop_ui.rc20
-rw-r--r--digikam/imageplugins/raindrop/imageeffect_raindrop.cpp259
-rw-r--r--digikam/imageplugins/raindrop/imageeffect_raindrop.h69
-rw-r--r--digikam/imageplugins/raindrop/imageplugin_raindrop.cpp69
-rw-r--r--digikam/imageplugins/raindrop/imageplugin_raindrop.h55
-rw-r--r--digikam/imageplugins/raindrop/raindrop.cpp457
-rw-r--r--digikam/imageplugins/raindrop/raindrop.h105
-rw-r--r--digikam/imageplugins/raindrop/raindroptool.cpp254
-rw-r--r--digikam/imageplugins/raindrop/raindroptool.h81
11 files changed, 1455 insertions, 0 deletions
diff --git a/digikam/imageplugins/raindrop/Makefile.am b/digikam/imageplugins/raindrop/Makefile.am
new file mode 100644
index 0000000..fcd8359
--- /dev/null
+++ b/digikam/imageplugins/raindrop/Makefile.am
@@ -0,0 +1,34 @@
+METASOURCES = AUTO
+
+INCLUDES = -I$(top_srcdir)/digikam/utilities/imageeditor/editor \
+ -I$(top_srcdir)/digikam/utilities/imageeditor/canvas \
+ -I$(top_srcdir)/digikam/libs/histogram \
+ -I$(top_srcdir)/digikam/libs/levels \
+ -I$(top_srcdir)/digikam/libs/curves \
+ -I$(top_srcdir)/digikam/libs/whitebalance \
+ -I$(top_srcdir)/digikam/libs/widgets/common \
+ -I$(top_srcdir)/digikam/libs/widgets/iccprofiles \
+ -I$(top_srcdir)/digikam/libs/widgets/imageplugins \
+ -I$(top_srcdir)/digikam/libs/dialogs \
+ -I$(top_srcdir)/digikam/libs/dimg \
+ -I$(top_srcdir)/digikam/libs/dmetadata \
+ -I$(top_srcdir)/digikam/libs/dimg/filters \
+ -I$(top_srcdir)/digikam/digikam \
+ $(LIBKDCRAW_CFLAGS) \
+ $(all_includes)
+
+digikamimageplugin_raindrop_la_SOURCES = imageplugin_raindrop.cpp \
+ raindroptool.cpp raindrop.cpp
+
+digikamimageplugin_raindrop_la_LIBADD = $(LIB_KPARTS) \
+ $(top_builddir)/digikam/digikam/libdigikam.la
+
+digikamimageplugin_raindrop_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
+
+kde_services_DATA = digikamimageplugin_raindrop.desktop
+
+kde_module_LTLIBRARIES = digikamimageplugin_raindrop.la
+
+rcdir = $(kde_datadir)/digikam
+rc_DATA = digikamimageplugin_raindrop_ui.rc
+
diff --git a/digikam/imageplugins/raindrop/digikamimageplugin_raindrop.desktop b/digikam/imageplugins/raindrop/digikamimageplugin_raindrop.desktop
new file mode 100644
index 0000000..81b3951
--- /dev/null
+++ b/digikam/imageplugins/raindrop/digikamimageplugin_raindrop.desktop
@@ -0,0 +1,52 @@
+[Desktop Entry]
+Name=ImagePlugin_RainDrop
+Name[bg]=Приставка за снимки - Дъждовни капки
+Name[da]=Billedplugin_Regndråber
+Name[el]=ΠροσθετοΕικόνας_Βροχή
+Name[fi]=Sadepisarat
+Name[hr]=Kišne kapi
+Name[it]=PluginImmagini_GocciaDiPioggia
+Name[nl]=Afbeeldingsplugin_Regendruppels
+Name[sr]=Кишне капи
+Name[sr@Latn]=Kišne kapi
+Name[sv]=Insticksprogram för regndroppar
+Name[tr]=ResimEklentisi_YağmurDamlaları
+Name[vi]=ImagePlugin_Perspective
+Name[xx]=xxImagePlugin_RainDropxx
+Type=Service
+ServiceTypes=Digikam/ImagePlugin
+Encoding=UTF-8
+Comment=Rain dropping image effect plugin for digiKam
+Comment[bg]=Приставка на digiKam за добавяне на дъждовни капки
+Comment[ca]=Connector pel digiKam d'efecte d'imatge de gotes de pluja
+Comment[da]=Plugin til regndråbeeffekt på billeder i Digikam
+Comment[de]=digiKam-Modul zum Erzeugen eines Regentropfeneffektes
+Comment[el]=Πρόσθετο εφέ πτώσης βροχής για το digiKam
+Comment[es]=Plugin para digiKam de efectos de gotas de lluvia
+Comment[et]=DigiKami vihmapiiskade pildiefektiplugin
+Comment[fa]=وصلۀ جلوۀ تصویر بارش باران برای digiKam
+Comment[fi]=Lisää kuvan pintaan sadepisaroita
+Comment[gl]=Un plugin de digiKam para criar un efeito de pingas de chuvia
+Comment[hr]=digiKam dodatak za efekt padanja kiše
+Comment[is]=Íforrit fyrir digiKam sem setur inn regndropa!!!
+Comment[it]=Plugin per l'effetto a goccia di pioggia delle immagini per digiKam
+Comment[ja]=digiKam 雨滴効果プラグイン
+Comment[ms]=Plugin kesan imej titis hujan untuk digiKam
+Comment[nds]=digiKam-Moduul för Regendrüppeneffekten
+Comment[nl]=Digikam-plugin voor regendruppels
+Comment[pa]=ਡਿਜ਼ੀਕੈਮ ਲਈ ਕਣੀ ਚਿੱਤਰ ਪਰਭਾਵ ਪਲੱਗਇਨ
+Comment[pl]=Wtyczka do programu digiKam dodająca efekt kropel deszczu na obrazie
+Comment[pt]=Um 'plugin' do digiKam para criar um efeito de pingos de chuva
+Comment[pt_BR]=Um 'plugin' do digiKam para criar um efeito de pingos de chuva
+Comment[ru]=Модуль эффект "идущего дождя" для digiKam
+Comment[sk]=digiKam plugin pre efekt padajúcich kvapiek
+Comment[sr]=digiKam-ов прикључак за ефекат кишних капи у слици
+Comment[sr@Latn]=digiKam-ov priključak za efekat kišnih kapi u slici
+Comment[sv]=Digikam insticksprogram för regndroppsbildeffekt
+Comment[tr]=digiKam için yağmur damlaları eklentisi
+Comment[uk]=Втулок ефекту падання крапель для digiKam
+Comment[vi]=Phần bổ sung hiệu ứng ảnh giọt mưa cho digiKam
+Comment[xx]=xxRain dropping image effect plugin for digiKamxx
+
+X-KDE-Library=digikamimageplugin_raindrop
+author=Gilles Caulier, caulier dot gilles at gmail dot com
diff --git a/digikam/imageplugins/raindrop/digikamimageplugin_raindrop_ui.rc b/digikam/imageplugins/raindrop/digikamimageplugin_raindrop_ui.rc
new file mode 100644
index 0000000..cf28a3f
--- /dev/null
+++ b/digikam/imageplugins/raindrop/digikamimageplugin_raindrop_ui.rc
@@ -0,0 +1,20 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui version="5" name="digikamimageplugin_raindrop" >
+
+ <MenuBar>
+
+ <Menu name="Filters" ><text>F&amp;ilters</text>
+ <Action name="imageplugin_raindrop" />
+ </Menu>
+
+ </MenuBar>
+
+ <ToolBar name="ToolBar" >
+ <text>Main Toolbar</text>
+ </ToolBar>
+
+ <ActionProperties>
+ <Action shortcut="" name="imageplugin_raindrop" />
+ </ActionProperties>
+
+</kpartgui>
diff --git a/digikam/imageplugins/raindrop/imageeffect_raindrop.cpp b/digikam/imageplugins/raindrop/imageeffect_raindrop.cpp
new file mode 100644
index 0000000..fa72990
--- /dev/null
+++ b/digikam/imageplugins/raindrop/imageeffect_raindrop.cpp
@@ -0,0 +1,259 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-09-30
+ * Description : a plugin to add rain drop over an image
+ *
+ * Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2006-2008 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qlabel.h>
+#include <qwhatsthis.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qimage.h>
+
+// KDE includes.
+
+#include <kconfig.h>
+#include <klocale.h>
+#include <kaboutdata.h>
+#include <kiconloader.h>
+#include <kapplication.h>
+#include <kstandarddirs.h>
+#include <knuminput.h>
+
+// Local includes.
+
+#include "version.h"
+#include "ddebug.h"
+#include "imageiface.h"
+#include "imagewidget.h"
+#include "raindrop.h"
+#include "imageeffect_raindrop.h"
+#include "imageeffect_raindrop.moc"
+
+namespace DigikamRainDropImagesPlugin
+{
+
+ImageEffect_RainDrop::ImageEffect_RainDrop(QWidget* parent)
+ : Digikam::ImageGuideDlg(parent, i18n("Add Raindrops to Photograph"),
+ "raindrops", false, true, false,
+ Digikam::ImageGuideWidget::HVGuideMode)
+{
+ QString whatsThis;
+
+ KAboutData* about = new KAboutData("digikam",
+ I18N_NOOP("Raindrops"),
+ digikam_version,
+ I18N_NOOP("A digiKam image plugin to add raindrops to an image."),
+ KAboutData::License_GPL,
+ "(c) 2004-2005, Gilles Caulier\n"
+ "(c) 2006-2008, Gilles Caulier and Marcel Wiesweg",
+ 0,
+ "http://www.digikam.org");
+
+ about->addAuthor("Gilles Caulier", I18N_NOOP("Author and maintainer"),
+ "caulier dot gilles at gmail dot com");
+
+ about->addAuthor("Pieter Z. Voloshyn", I18N_NOOP("Raindrops algorithm"),
+ "pieter dot voloshyn at gmail dot com");
+
+ about->addAuthor("Marcel Wiesweg", I18N_NOOP("Developer"),
+ "marcel dot wiesweg at gmx dot de");
+
+ setAboutData(about);
+
+ QWhatsThis::add( m_imagePreviewWidget, i18n("<p>This is the preview of the Raindrop effect."
+ "<p>Note: if you have previously selected an area in the editor, "
+ "this will be unaffected by the filter. You can use this method to "
+ "disable the Raindrops effect on a human face, for example.") );
+
+ // -------------------------------------------------------------
+
+ QWidget *gboxSettings = new QWidget(plainPage());
+ QGridLayout* gridSettings = new QGridLayout( gboxSettings, 5, 2, spacingHint());
+
+ QLabel *label1 = new QLabel(i18n("Drop size:"), gboxSettings);
+
+ m_dropInput = new KIntNumInput(gboxSettings);
+ m_dropInput->setRange(0, 200, 1, true);
+ m_dropInput->setValue(80);
+ QWhatsThis::add( m_dropInput, i18n("<p>Set here the raindrops' size."));
+
+ gridSettings->addMultiCellWidget(label1, 0, 0, 0, 2);
+ gridSettings->addMultiCellWidget(m_dropInput, 1, 1, 0, 2);
+
+ // -------------------------------------------------------------
+
+ QLabel *label2 = new QLabel(i18n("Number:"), gboxSettings);
+
+ m_amountInput = new KIntNumInput(gboxSettings);
+ m_amountInput->setRange(1, 500, 1, true);
+ m_amountInput->setValue(150);
+ QWhatsThis::add( m_amountInput, i18n("<p>This value controls the maximum number of raindrops."));
+
+ gridSettings->addMultiCellWidget(label2, 2, 2, 0, 2);
+ gridSettings->addMultiCellWidget(m_amountInput, 3, 3, 0, 2);
+
+ // -------------------------------------------------------------
+
+ QLabel *label3 = new QLabel(i18n("Fish eyes:"), gboxSettings);
+
+ m_coeffInput = new KIntNumInput(gboxSettings);
+ m_coeffInput->setRange(1, 100, 1, true);
+ m_coeffInput->setValue(30);
+ QWhatsThis::add( m_coeffInput, i18n("<p>This value is the fish-eye-effect optical "
+ "distortion coefficient."));
+
+ gridSettings->addMultiCellWidget(label3, 4, 4, 0, 2);
+ gridSettings->addMultiCellWidget(m_coeffInput, 5, 5, 0, 2);
+
+ setUserAreaWidget(gboxSettings);
+
+ // -------------------------------------------------------------
+
+ connect(m_dropInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_amountInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_coeffInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+}
+
+ImageEffect_RainDrop::~ImageEffect_RainDrop()
+{
+}
+
+void ImageEffect_RainDrop::renderingFinished()
+{
+ m_dropInput->setEnabled(true);
+ m_amountInput->setEnabled(true);
+ m_coeffInput->setEnabled(true);
+}
+
+void ImageEffect_RainDrop::readUserSettings(void)
+{
+ KConfig *config = kapp->config();
+ config->setGroup("raindrops Tool Dialog");
+
+ m_dropInput->blockSignals(true);
+ m_amountInput->blockSignals(true);
+ m_coeffInput->blockSignals(true);
+
+ m_dropInput->setValue(config->readNumEntry("DropAdjustment", 80));
+ m_amountInput->setValue(config->readNumEntry("AmountAdjustment", 150));
+ m_coeffInput->setValue(config->readNumEntry("CoeffAdjustment", 30));
+
+ m_dropInput->blockSignals(false);
+ m_amountInput->blockSignals(false);
+ m_coeffInput->blockSignals(false);
+
+ slotEffect();
+}
+
+void ImageEffect_RainDrop::writeUserSettings(void)
+{
+ KConfig *config = kapp->config();
+ config->setGroup("raindrops Tool Dialog");
+ config->writeEntry("DropAdjustment", m_dropInput->value());
+ config->writeEntry("AmountAdjustment", m_amountInput->value());
+ config->writeEntry("CoeffAdjustment", m_coeffInput->value());
+ config->sync();
+}
+
+void ImageEffect_RainDrop::resetValues()
+{
+ m_dropInput->blockSignals(true);
+ m_amountInput->blockSignals(true);
+ m_coeffInput->blockSignals(true);
+
+ m_dropInput->setValue(80);
+ m_amountInput->setValue(150);
+ m_coeffInput->setValue(30);
+
+ m_dropInput->blockSignals(false);
+ m_amountInput->blockSignals(false);
+ m_coeffInput->blockSignals(false);
+}
+
+void ImageEffect_RainDrop::prepareEffect()
+{
+ m_dropInput->setEnabled(false);
+ m_amountInput->setEnabled(false);
+ m_coeffInput->setEnabled(false);
+
+ int d = m_dropInput->value();
+ int a = m_amountInput->value();
+ int c = m_coeffInput->value();
+
+ Digikam::ImageIface* iface = m_imagePreviewWidget->imageIface();
+
+ // Selected data from the image
+ QRect selection( iface->selectedXOrg(), iface->selectedYOrg(),
+ iface->selectedWidth(), iface->selectedHeight() );
+
+ m_threadedFilter = dynamic_cast<Digikam::DImgThreadedFilter *>(
+ new RainDrop(iface->getOriginalImg(), this, d, a, c, &selection));
+}
+
+void ImageEffect_RainDrop::prepareFinal()
+{
+ m_dropInput->setEnabled(false);
+ m_amountInput->setEnabled(false);
+ m_coeffInput->setEnabled(false);
+
+ int d = m_dropInput->value();
+ int a = m_amountInput->value();
+ int c = m_coeffInput->value();
+
+ Digikam::ImageIface iface(0, 0);
+
+ // Selected data from the image
+ QRect selection( iface.selectedXOrg(), iface.selectedYOrg(),
+ iface.selectedWidth(), iface.selectedHeight() );
+
+ m_threadedFilter = dynamic_cast<Digikam::DImgThreadedFilter *>(
+ new RainDrop(iface.getOriginalImg(), this, d, a, c, &selection));
+}
+
+void ImageEffect_RainDrop::putPreviewData(void)
+{
+ Digikam::ImageIface* iface = m_imagePreviewWidget->imageIface();
+
+ Digikam::DImg imDest = m_threadedFilter->getTargetImage()
+ .smoothScale(iface->previewWidth(), iface->previewHeight());
+ iface->putPreviewImage(imDest.bits());
+
+ m_imagePreviewWidget->updatePreview();
+}
+
+void ImageEffect_RainDrop::putFinalData(void)
+{
+ Digikam::ImageIface iface(0, 0);
+
+ iface.putOriginalImage(i18n("RainDrop"),
+ m_threadedFilter->getTargetImage().bits());
+}
+
+} // NameSpace DigikamRainDropImagesPlugin
+
diff --git a/digikam/imageplugins/raindrop/imageeffect_raindrop.h b/digikam/imageplugins/raindrop/imageeffect_raindrop.h
new file mode 100644
index 0000000..fd2eb0d
--- /dev/null
+++ b/digikam/imageplugins/raindrop/imageeffect_raindrop.h
@@ -0,0 +1,69 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-09-30
+ * Description : a plugin to add rain drop over an image
+ *
+ * Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2006-2008 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.
+ *
+ * ============================================================ */
+
+#ifndef IMAGEEFFECT_RAINDROP_H
+#define IMAGEEFFECT_RAINDROP_H
+
+// Digikam includes.
+
+#include "imageguidedlg.h"
+
+class KIntNumInput;
+
+namespace DigikamRainDropImagesPlugin
+{
+
+class ImageEffect_RainDrop : public Digikam::ImageGuideDlg
+{
+ Q_OBJECT
+
+public:
+
+ ImageEffect_RainDrop(QWidget *parent);
+ ~ImageEffect_RainDrop();
+
+private slots:
+
+ void readUserSettings();
+
+private:
+
+ void writeUserSettings();
+ void resetValues();
+ void prepareEffect();
+ void prepareFinal();
+ void putPreviewData();
+ void putFinalData();
+ void renderingFinished();
+
+private:
+
+ KIntNumInput *m_dropInput;
+ KIntNumInput *m_amountInput;
+ KIntNumInput *m_coeffInput;
+};
+
+} // NameSpace DigikamRainDropImagesPlugin
+
+#endif /* IMAGEEFFECT_RAINDROP_H */
diff --git a/digikam/imageplugins/raindrop/imageplugin_raindrop.cpp b/digikam/imageplugins/raindrop/imageplugin_raindrop.cpp
new file mode 100644
index 0000000..55c5831
--- /dev/null
+++ b/digikam/imageplugins/raindrop/imageplugin_raindrop.cpp
@@ -0,0 +1,69 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-09-30
+ * Description : a plugin to add rain drop over an image
+ *
+ * Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * 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.
+ *
+ * ============================================================ */
+
+// KDE includes.
+
+#include <klocale.h>
+#include <kgenericfactory.h>
+#include <klibloader.h>
+#include <kaction.h>
+#include <kcursor.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "raindroptool.h"
+#include "imageplugin_raindrop.h"
+#include "imageplugin_raindrop.moc"
+
+using namespace DigikamRainDropImagesPlugin;
+
+K_EXPORT_COMPONENT_FACTORY(digikamimageplugin_raindrop,
+ KGenericFactory<ImagePlugin_RainDrop>("digikamimageplugin_raindrop"));
+
+ImagePlugin_RainDrop::ImagePlugin_RainDrop(QObject *parent, const char*, const QStringList &)
+ : Digikam::ImagePlugin(parent, "ImagePlugin_RainDrop")
+{
+ m_raindropAction = new KAction(i18n("Raindrops..."), "raindrop", 0,
+ this, SLOT(slotRainDrop()),
+ actionCollection(), "imageplugin_raindrop");
+
+ setXMLFile( "digikamimageplugin_raindrop_ui.rc" );
+
+ DDebug() << "ImagePlugin_RainDrop plugin loaded" << endl;
+}
+
+ImagePlugin_RainDrop::~ImagePlugin_RainDrop()
+{
+}
+
+void ImagePlugin_RainDrop::setEnabledActions(bool enable)
+{
+ m_raindropAction->setEnabled(enable);
+}
+
+void ImagePlugin_RainDrop::slotRainDrop()
+{
+ RainDropTool *raindrop = new RainDropTool(this);
+ loadTool(raindrop);
+}
diff --git a/digikam/imageplugins/raindrop/imageplugin_raindrop.h b/digikam/imageplugins/raindrop/imageplugin_raindrop.h
new file mode 100644
index 0000000..75e4657
--- /dev/null
+++ b/digikam/imageplugins/raindrop/imageplugin_raindrop.h
@@ -0,0 +1,55 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-09-30
+ * Description : a plugin to add rain drop over an image
+ *
+ * Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * 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.
+ *
+ * ============================================================ */
+
+#ifndef IMAGEPLUGIN_RAINDROP_H
+#define IMAGEPLUGIN_RAINDROP_H
+
+// Digikam includes.
+
+#include "imageplugin.h"
+#include "digikam_export.h"
+
+class KAction;
+
+class DIGIKAMIMAGEPLUGINS_EXPORT ImagePlugin_RainDrop : public Digikam::ImagePlugin
+{
+ Q_OBJECT
+
+public:
+
+ ImagePlugin_RainDrop(QObject *parent, const char* name,
+ const QStringList &args);
+ ~ImagePlugin_RainDrop();
+
+ void setEnabledActions(bool enable);
+
+private slots:
+
+ void slotRainDrop();
+
+private:
+
+ KAction *m_raindropAction;
+};
+
+#endif /* IMAGEPLUGIN_RAINDROP_H */
diff --git a/digikam/imageplugins/raindrop/raindrop.cpp b/digikam/imageplugins/raindrop/raindrop.cpp
new file mode 100644
index 0000000..d24d1b4
--- /dev/null
+++ b/digikam/imageplugins/raindrop/raindrop.cpp
@@ -0,0 +1,457 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-05-25
+ * Description : Raindrop 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>
+ *
+ * Original RainDrop algorithm copyrighted 2004-2005 by
+ * Pieter Z. Voloshyn <pieter dot voloshyn at gmail dot com>.
+ *
+ * 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>
+
+// Qt includes.
+
+#include <qdeepcopy.h>
+#include <qdatetime.h>
+#include <qrect.h>
+
+// Local includes.
+
+#include "dimg.h"
+#include "dimgimagefilters.h"
+#include "raindrop.h"
+
+namespace DigikamRainDropImagesPlugin
+{
+
+RainDrop::RainDrop(Digikam::DImg *orgImage, QObject *parent, int drop,
+ int amount, int coeff, QRect *selection)
+ : Digikam::DImgThreadedFilter(orgImage, parent, "RainDrop")
+{
+ m_drop = drop;
+ m_amount = amount;
+ m_coeff = coeff;
+
+ m_selectedX = m_selectedY = m_selectedW = m_selectedH = 0;
+
+ if ( selection )
+ {
+ m_selectedX = selection->left();
+ m_selectedY = selection->top();
+ m_selectedW = selection->width();
+ m_selectedH = selection->height();
+ }
+
+ initFilter();
+}
+
+void RainDrop::filterImage(void)
+{
+ int w = m_orgImage.width();
+ int h = m_orgImage.height();
+
+ // If we have a region selection in image, use it to apply the filter modification around,
+ // else, applied the filter on the full image.
+
+ if (m_selectedW && m_selectedH)
+ {
+ Digikam::DImg zone1, zone2, zone3, zone4,
+ zone1Dest, zone2Dest, zone3Dest, zone4Dest,
+ selectedImg;
+ selectedImg = m_orgImage.copy(m_selectedX, m_selectedY, m_selectedW, m_selectedH);
+
+ // Cut the original image in 4 areas without clipping region.
+
+ zone1 = m_orgImage.copy(0, 0, m_selectedX, w);
+ zone2 = m_orgImage.copy(m_selectedX, 0, m_selectedX + m_selectedW, m_selectedY);
+ zone3 = m_orgImage.copy(m_selectedX, m_selectedY + m_selectedH, m_selectedX + m_selectedW, h);
+ zone4 = m_orgImage.copy(m_selectedX + m_selectedW, 0, w, h);
+
+ zone1Dest = Digikam::DImg(zone1.width(), zone1.height(), zone1.sixteenBit(), zone1.hasAlpha());
+ zone2Dest = Digikam::DImg(zone2.width(), zone2.height(), zone2.sixteenBit(), zone2.hasAlpha());
+ zone3Dest = Digikam::DImg(zone3.width(), zone3.height(), zone3.sixteenBit(), zone3.hasAlpha());
+ zone4Dest = Digikam::DImg(zone4.width(), zone4.height(), zone4.sixteenBit(), zone4.hasAlpha());
+
+ // Apply effect on each area.
+
+ rainDropsImage(&zone1, &zone1Dest, 0, m_drop, m_amount, m_coeff, true, 0, 25);
+ rainDropsImage(&zone2, &zone2Dest, 0, m_drop, m_amount, m_coeff, true, 25, 50);
+ rainDropsImage(&zone3, &zone3Dest, 0, m_drop, m_amount, m_coeff, true, 50, 75);
+ rainDropsImage(&zone4, &zone4Dest, 0, m_drop, m_amount, m_coeff, true, 75, 100);
+
+ // Build the target image.
+
+ m_destImage.bitBltImage(&zone1Dest, 0, 0);
+ m_destImage.bitBltImage(&zone2Dest, m_selectedX, 0);
+ m_destImage.bitBltImage(&zone3Dest, m_selectedX, m_selectedY + m_selectedH);
+ m_destImage.bitBltImage(&zone4Dest, m_selectedX + m_selectedW, 0);
+ m_destImage.bitBltImage(&selectedImg, m_selectedX, m_selectedY);
+ }
+ else
+ {
+ rainDropsImage(&m_orgImage, &m_destImage, 0, m_drop, m_amount, m_coeff, true, 0, 100);
+ }
+}
+
+/* Function to apply the RainDrops effect backported from ImageProcessing version 2
+ *
+ * orgImage => The image
+ * MinDropSize => It's the minimum random size for rain drop.
+ * MaxDropSize => It's the minimum random size for rain drop.
+ * Amount => It's the maximum number for rain drops inside the image.
+ * Coeff => It's the fisheye's coefficient.
+ * bLimitRange => If true, the drop will not be cut.
+ * progressMin => Min. value for progress bar (can be different if using clipping area).
+ * progressMax => Max. value for progress bar (can be different if using clipping area).
+ *
+ * Theory => This functions does several math's functions and the engine
+ * is simple to undestand, but a little hard to implement. A
+ * control will indicate if there is or not a raindrop in that
+ * area, if not, a fisheye effect with a random size (max=MaxDropSize)
+ * will be applied, after this, a shadow will be applied too.
+ * and after this, a blur function will finish the effect.
+ */
+void RainDrop::rainDropsImage(Digikam::DImg *orgImage, Digikam::DImg *destImage, int MinDropSize, int MaxDropSize,
+ int Amount, int Coeff, bool bLimitRange, int progressMin, int progressMax)
+{
+ bool bResp;
+ int nRandSize, i;
+ int nRandX, nRandY;
+ int nCounter = 0;
+ int nWidth = orgImage->width();
+ int nHeight = orgImage->height();
+ bool sixteenBit = orgImage->sixteenBit();
+ int bytesDepth = orgImage->bytesDepth();
+ uchar *data = orgImage->bits();
+ uchar *pResBits = destImage->bits();
+
+ if (Amount <= 0)
+ return;
+
+ if (MinDropSize >= MaxDropSize)
+ MaxDropSize = MinDropSize + 1;
+
+ if (MaxDropSize <= 0)
+ return;
+
+ uchar *pStatusBits = new uchar[nHeight * nWidth];
+ memset(pStatusBits, 0, sizeof(nHeight * nWidth));
+
+ // Initially, copy all pixels to destination
+
+ destImage->bitBltImage(orgImage, 0, 0);
+
+ // Randomize.
+
+ QDateTime dt = QDateTime::currentDateTime();
+ QDateTime Y2000( QDate(2000, 1, 1), QTime(0, 0, 0) );
+ uint seed = dt.secsTo(Y2000);
+
+ for (i = 0; !m_cancel && (i < Amount); i++)
+ {
+ nCounter = 0;
+
+ do
+ {
+ nRandX = (int)(rand_r(&seed) * ((double)( nWidth - 1) / RAND_MAX));
+ nRandY = (int)(rand_r(&seed) * ((double)(nHeight - 1) / RAND_MAX));
+
+ nRandSize = (rand() % (MaxDropSize - MinDropSize)) + MinDropSize;
+
+ bResp = CreateRainDrop (data, nWidth, nHeight, sixteenBit, bytesDepth,
+ pResBits, pStatusBits,
+ nRandX, nRandY, nRandSize, Coeff, bLimitRange);
+
+ nCounter++;
+ }
+ while ((bResp == false) && (nCounter < 10000) && !m_cancel);
+
+ // Update the progress bar in dialog.
+ if (nCounter >= 10000)
+ {
+ i = Amount;
+
+ postProgress(progressMax);
+ break;
+ }
+
+ postProgress( (int)(progressMin + ((double)(i) *
+ (double)(progressMax-progressMin)) / (double)Amount) );
+ }
+
+ delete [] pStatusBits;
+}
+
+bool RainDrop::CreateRainDrop(uchar *pBits, int Width, int Height, bool sixteenBit, int bytesDepth,
+ uchar *pResBits, uchar* pStatusBits,
+ int X, int Y, int DropSize, double Coeff, bool bLimitRange)
+{
+ register int w, h, nw1, nh1, nw2, nh2;
+ int nHalfSize = DropSize / 2;
+ int nBright;
+ double lfRadius, lfOldRadius, lfAngle, lfDiv;
+
+ Digikam::DColor imageData;
+
+ uint nTotalR, nTotalG, nTotalB, offset;
+ int nBlurPixels, nBlurRadius;
+
+ if (CanBeDropped(Width, Height, pStatusBits, X, Y, DropSize, bLimitRange))
+ {
+ Coeff *= 0.01;
+ lfDiv = (double)nHalfSize / log (Coeff * (double)nHalfSize + 1.0);
+
+ for (h = -nHalfSize; !m_cancel && (h <= nHalfSize); h++)
+ {
+ for (w = -nHalfSize; !m_cancel && (w <= nHalfSize); w++)
+ {
+ lfRadius = sqrt (h * h + w * w);
+ lfAngle = atan2 ((double)h, (double)w);
+
+ if (lfRadius <= (double)nHalfSize)
+ {
+ lfOldRadius = lfRadius;
+ lfRadius = (exp (lfRadius / lfDiv) - 1.0) / Coeff;
+
+ nw1 = (int)((double)X + lfRadius * cos (lfAngle));
+ nh1 = (int)((double)Y + lfRadius * sin (lfAngle));
+
+ nw2 = X + w;
+ nh2 = Y + h;
+
+ if (IsInside(Width, Height, nw1, nh1))
+ {
+ if (IsInside(Width, Height, nw2, nh2))
+ {
+ nBright = 0;
+
+ if (lfOldRadius >= 0.9 * (double)nHalfSize)
+ {
+ if ((lfAngle >= 0.0) && (lfAngle < 2.25))
+ nBright = -80;
+ else if ((lfAngle >= 2.25) && (lfAngle < 2.5))
+ nBright = -40;
+ else if ((lfAngle >= -0.25) && (lfAngle < 0.0))
+ nBright = -40;
+ }
+
+ else if (lfOldRadius >= 0.8 * (double)nHalfSize)
+ {
+ if ((lfAngle >= 0.75) && (lfAngle < 1.50))
+ nBright = -40;
+ else if ((lfAngle >= -0.10) && (lfAngle < 0.75))
+ nBright = -30;
+ else if ((lfAngle >= 1.50) && (lfAngle < 2.35))
+ nBright = -30;
+ }
+
+ else if (lfOldRadius >= 0.7 * (double)nHalfSize)
+ {
+ if ((lfAngle >= 0.10) && (lfAngle < 2.0))
+ nBright = -20;
+ else if ((lfAngle >= -2.50) && (lfAngle < -1.90))
+ nBright = 60;
+ }
+
+ else if (lfOldRadius >= 0.6 * (double)nHalfSize)
+ {
+ if ((lfAngle >= 0.50) && (lfAngle < 1.75))
+ nBright = -20;
+ else if ((lfAngle >= 0.0) && (lfAngle < 0.25))
+ nBright = 20;
+ else if ((lfAngle >= 2.0) && (lfAngle < 2.25))
+ nBright = 20;
+ }
+
+ else if (lfOldRadius >= 0.5 * (double)nHalfSize)
+ {
+ if ((lfAngle >= 0.25) && (lfAngle < 0.50))
+ nBright = 30;
+ else if ((lfAngle >= 1.75 ) && (lfAngle < 2.0))
+ nBright = 30;
+ }
+
+ else if (lfOldRadius >= 0.4 * (double)nHalfSize)
+ {
+ if ((lfAngle >= 0.5) && (lfAngle < 1.75))
+ nBright = 40;
+ }
+
+ else if (lfOldRadius >= 0.3 * (double)nHalfSize)
+ {
+ if ((lfAngle >= 0.0) && (lfAngle < 2.25))
+ nBright = 30;
+ }
+
+ else if (lfOldRadius >= 0.2 * (double)nHalfSize)
+ {
+ if ((lfAngle >= 0.5) && (lfAngle < 1.75))
+ nBright = 20;
+ }
+
+ imageData.setColor(pBits + Offset(Width, nw1, nh1, bytesDepth), sixteenBit);
+
+ if (sixteenBit)
+ {
+ // convert difference to 16-bit range
+ if (nBright > 0)
+ nBright = (nBright + 1) * 256 - 1;
+ else
+ nBright = (nBright - 1) * 256 + 1;
+
+ imageData.setRed (LimitValues16(imageData.red() + nBright));
+ imageData.setGreen(LimitValues16(imageData.green() + nBright));
+ imageData.setBlue (LimitValues16(imageData.blue() + nBright));
+ }
+ else
+ {
+ imageData.setRed (LimitValues8(imageData.red() + nBright));
+ imageData.setGreen(LimitValues8(imageData.green() + nBright));
+ imageData.setBlue (LimitValues8(imageData.blue() + nBright));
+ }
+
+ imageData.setPixel(pResBits + Offset(Width, nw2, nh2, bytesDepth));
+
+ }
+ }
+ }
+ }
+ }
+
+ nBlurRadius = DropSize / 25 + 1;
+
+ for (h = -nHalfSize - nBlurRadius; !m_cancel && (h <= nHalfSize + nBlurRadius); h++)
+ {
+ for (w = -nHalfSize - nBlurRadius; !m_cancel && (w <= nHalfSize + nBlurRadius); w++)
+ {
+ lfRadius = sqrt (h * h + w * w);
+
+ if (lfRadius <= (double)nHalfSize * 1.1)
+ {
+ nTotalR = nTotalG = nTotalB = 0;
+ nBlurPixels = 0;
+
+ for (nh1 = -nBlurRadius; !m_cancel && (nh1 <= nBlurRadius); nh1++)
+ {
+ for (nw1 = -nBlurRadius; !m_cancel && (nw1 <= nBlurRadius); nw1++)
+ {
+ nw2 = X + w + nw1;
+ nh2 = Y + h + nh1;
+
+ if (IsInside (Width, Height, nw2, nh2))
+ {
+ imageData.setColor(pResBits + Offset(Width, nw2, nh2, bytesDepth), sixteenBit);
+
+ nTotalR += imageData.red();
+ nTotalG += imageData.green();
+ nTotalB += imageData.blue();
+ nBlurPixels++;
+ }
+ }
+ }
+
+ nw1 = X + w;
+ nh1 = Y + h;
+
+ if (IsInside (Width, Height, nw1, nh1))
+ {
+ offset = Offset(Width, nw1, nh1, bytesDepth);
+
+ // to preserve alpha channel
+ imageData.setColor(pResBits + offset, sixteenBit);
+
+ imageData.setRed (nTotalR / nBlurPixels);
+ imageData.setGreen(nTotalG / nBlurPixels);
+ imageData.setBlue (nTotalB / nBlurPixels);
+
+ imageData.setPixel(pResBits + offset);
+ }
+ }
+ }
+ }
+
+ SetDropStatusBits (Width, Height, pStatusBits, X, Y, DropSize);
+ }
+ else
+ return (false);
+
+ return (true);
+}
+
+
+bool RainDrop::CanBeDropped(int Width, int Height, uchar *pStatusBits, int X, int Y,
+ int DropSize, bool bLimitRange)
+{
+ register int w, h, i = 0;
+ int nHalfSize = DropSize / 2;
+
+ if (pStatusBits == NULL)
+ return (true);
+
+ for (h = Y - nHalfSize; h <= Y + nHalfSize; h++)
+ {
+ for (w = X - nHalfSize; w <= X + nHalfSize; w++)
+ {
+ if (IsInside (Width, Height, w, h))
+ {
+ i = h * Width + w;
+ if (pStatusBits[i])
+ return (false);
+ }
+ else
+ {
+ if (bLimitRange)
+ return (false);
+ }
+ }
+ }
+
+ return (true);
+}
+
+bool RainDrop::SetDropStatusBits (int Width, int Height, uchar *pStatusBits,
+ int X, int Y, int DropSize)
+{
+ register int w, h, i = 0;
+ int nHalfSize = DropSize / 2;
+
+ if (pStatusBits == NULL)
+ return (false);
+
+ for (h = Y - nHalfSize; h <= Y + nHalfSize; h++)
+ {
+ for (w = X - nHalfSize; w <= X + nHalfSize; w++)
+ {
+ if (IsInside (Width, Height, w, h))
+ {
+ i = h * Width + w;
+ pStatusBits[i] = 255;
+ }
+ }
+ }
+
+ return (true);
+}
+
+} // NameSpace DigikamRainDropImagesPlugin
diff --git a/digikam/imageplugins/raindrop/raindrop.h b/digikam/imageplugins/raindrop/raindrop.h
new file mode 100644
index 0000000..7acf101
--- /dev/null
+++ b/digikam/imageplugins/raindrop/raindrop.h
@@ -0,0 +1,105 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-05-25
+ * Description : Raindrop 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.
+ *
+ * ============================================================ */
+
+#ifndef RAINDROP_H
+#define RAINDROP_H
+
+// Digikam includes.
+
+#include "dimgthreadedfilter.h"
+
+class QRect;
+
+namespace DigikamRainDropImagesPlugin
+{
+
+class RainDrop : public Digikam::DImgThreadedFilter
+{
+
+public:
+
+ RainDrop(Digikam::DImg *orgImage, QObject *parent=0, int drop=80,
+ int amount=150, int coeff=30, QRect *selection=0L);
+
+ ~RainDrop(){};
+
+private:
+
+ virtual void filterImage(void);
+
+ void rainDropsImage(Digikam::DImg *orgImage, Digikam::DImg *destImage, int MinDropSize, int MaxDropSize,
+ int Amount, int Coeff, bool bLimitRange, int progressMin, int progressMax);
+
+ bool CreateRainDrop(uchar *pBits, int Width, int Height, bool sixteenBit, int bytesDepth,
+ uchar *pResBits, uchar* pStatusBits,
+ int X, int Y, int DropSize, double Coeff, bool bLimitRange);
+
+ bool CanBeDropped(int Width, int Height, uchar *pStatusBits, int X, int Y, int DropSize, bool bLimitRange);
+
+ bool SetDropStatusBits (int Width, int Height, uchar *pStatusBits, int X, int Y, int DropSize);
+
+ // A color is represented in RGB value (e.g. 0xFFFFFF is white color).
+ // But R, G and B values has 256 values to be used so, this function analize
+ // the value and limits to this range.
+ inline int LimitValues8(int ColorValue)
+ {
+ if (ColorValue > 255) ColorValue = 255;
+ if (ColorValue < 0) ColorValue = 0;
+ return ColorValue;
+ };
+
+ inline int LimitValues16(int ColorValue)
+ {
+ if (ColorValue > 65535) ColorValue = 65535;
+ if (ColorValue < 0) ColorValue = 0;
+ return ColorValue;
+ };
+
+ inline bool IsInside (int Width, int Height, int X, int Y)
+ {
+ bool bIsWOk = ((X < 0) ? false : (X >= Width ) ? false : true);
+ bool bIsHOk = ((Y < 0) ? false : (Y >= Height) ? false : true);
+ return (bIsWOk && bIsHOk);
+ };
+
+ inline int Offset(int Width, int X, int Y, int bytesDepth)
+ {
+ return (Y * Width * bytesDepth + X * bytesDepth);
+ };
+
+private:
+
+ int m_drop;
+ int m_amount;
+ int m_coeff;
+
+ int m_selectedX;
+ int m_selectedY;
+ int m_selectedW;
+ int m_selectedH;
+};
+
+} // NameSpace DigikamRainDropImagesPlugin
+
+#endif /* RAINDROP_H */
diff --git a/digikam/imageplugins/raindrop/raindroptool.cpp b/digikam/imageplugins/raindrop/raindroptool.cpp
new file mode 100644
index 0000000..d43a79d
--- /dev/null
+++ b/digikam/imageplugins/raindrop/raindroptool.cpp
@@ -0,0 +1,254 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-09-30
+ * Description : a plugin to add rain drop over an image
+ *
+ * Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2006-2008 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qframe.h>
+#include <qimage.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qwhatsthis.h>
+
+// KDE includes.
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+// LibKDcraw includes.
+
+#include <libkdcraw/rnuminput.h>
+
+// Local includes.
+
+#include "daboutdata.h"
+#include "ddebug.h"
+#include "editortoolsettings.h"
+#include "imageiface.h"
+#include "imagewidget.h"
+#include "raindrop.h"
+#include "raindroptool.h"
+#include "raindroptool.moc"
+
+using namespace KDcrawIface;
+using namespace Digikam;
+
+namespace DigikamRainDropImagesPlugin
+{
+
+RainDropTool::RainDropTool(QObject* parent)
+ : EditorToolThreaded(parent)
+{
+ setName("raindrops");
+ setToolName(i18n("Raindrops"));
+ setToolIcon(SmallIcon("raindrop"));
+
+ m_previewWidget = new ImageWidget("raindrops Tool", 0,
+ i18n("<p>This is the preview of the Raindrop effect."
+ "<p>Note: if you have previously selected an area in the editor, "
+ "this will be unaffected by the filter. You can use this method to "
+ "disable the Raindrops effect on a human face, for example."),
+ false);
+
+ setToolView(m_previewWidget);
+
+ // -------------------------------------------------------------
+
+ m_gboxSettings = new EditorToolSettings(EditorToolSettings::Default|
+ EditorToolSettings::Ok|
+ EditorToolSettings::Cancel);
+
+ QGridLayout* gridSettings = new QGridLayout( m_gboxSettings->plainPage(), 7, 2);
+
+ QLabel *label1 = new QLabel(i18n("Drop size:"), m_gboxSettings->plainPage());
+
+ m_dropInput = new RIntNumInput(m_gboxSettings->plainPage());
+ m_dropInput->setRange(0, 200, 1);
+ m_dropInput->setDefaultValue(80);
+ QWhatsThis::add( m_dropInput, i18n("<p>Set here the raindrops' size."));
+
+ // -------------------------------------------------------------
+
+ QLabel *label2 = new QLabel(i18n("Number:"), m_gboxSettings->plainPage());
+
+ m_amountInput = new RIntNumInput(m_gboxSettings->plainPage());
+ m_amountInput->setRange(1, 500, 1);
+ m_amountInput->setDefaultValue(150);
+ QWhatsThis::add( m_amountInput, i18n("<p>This value controls the maximum number of raindrops."));
+
+ // -------------------------------------------------------------
+
+ QLabel *label3 = new QLabel(i18n("Fish eyes:"), m_gboxSettings->plainPage());
+
+ m_coeffInput = new RIntNumInput(m_gboxSettings->plainPage());
+ m_coeffInput->setRange(1, 100, 1);
+ m_coeffInput->setDefaultValue(30);
+ QWhatsThis::add( m_coeffInput, i18n("<p>This value is the fish-eye-effect optical "
+ "distortion coefficient."));
+
+ gridSettings->addMultiCellWidget(label1, 0, 0, 0, 1);
+ gridSettings->addMultiCellWidget(m_dropInput, 1, 1, 0, 1);
+ gridSettings->addMultiCellWidget(label2, 2, 2, 0, 1);
+ gridSettings->addMultiCellWidget(m_amountInput, 3, 3, 0, 1);
+ gridSettings->addMultiCellWidget(label3, 4, 4, 0, 1);
+ gridSettings->addMultiCellWidget(m_coeffInput, 5, 5, 0, 1);
+ gridSettings->setRowStretch(6, 10);
+
+ setToolSettings(m_gboxSettings);
+ init();
+
+ // -------------------------------------------------------------
+
+ connect(m_dropInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_amountInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_coeffInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+}
+
+RainDropTool::~RainDropTool()
+{
+}
+
+void RainDropTool::renderingFinished()
+{
+ m_dropInput->setEnabled(true);
+ m_amountInput->setEnabled(true);
+ m_coeffInput->setEnabled(true);
+}
+
+void RainDropTool::readSettings()
+{
+ KConfig *config = kapp->config();
+ config->setGroup("raindrops Tool");
+
+ m_dropInput->blockSignals(true);
+ m_amountInput->blockSignals(true);
+ m_coeffInput->blockSignals(true);
+
+ m_dropInput->setValue(config->readNumEntry("DropAdjustment", m_dropInput->defaultValue()));
+ m_amountInput->setValue(config->readNumEntry("AmountAdjustment", m_amountInput->defaultValue()));
+ m_coeffInput->setValue(config->readNumEntry("CoeffAdjustment", m_coeffInput->defaultValue()));
+
+ m_dropInput->blockSignals(false);
+ m_amountInput->blockSignals(false);
+ m_coeffInput->blockSignals(false);
+
+ slotEffect();
+}
+
+void RainDropTool::writeSettings()
+{
+ KConfig *config = kapp->config();
+ config->setGroup("raindrops Tool");
+ config->writeEntry("DropAdjustment", m_dropInput->value());
+ config->writeEntry("AmountAdjustment", m_amountInput->value());
+ config->writeEntry("CoeffAdjustment", m_coeffInput->value());
+ m_previewWidget->writeSettings();
+ config->sync();
+}
+
+void RainDropTool::slotResetSettings()
+{
+ m_dropInput->blockSignals(true);
+ m_amountInput->blockSignals(true);
+ m_coeffInput->blockSignals(true);
+
+ m_dropInput->slotReset();
+ m_amountInput->slotReset();
+ m_coeffInput->slotReset();
+
+ m_dropInput->blockSignals(false);
+ m_amountInput->blockSignals(false);
+ m_coeffInput->blockSignals(false);
+
+ slotEffect();
+}
+
+void RainDropTool::prepareEffect()
+{
+ m_dropInput->setEnabled(false);
+ m_amountInput->setEnabled(false);
+ m_coeffInput->setEnabled(false);
+
+ int d = m_dropInput->value();
+ int a = m_amountInput->value();
+ int c = m_coeffInput->value();
+
+ ImageIface* iface = m_previewWidget->imageIface();
+
+ // Selected data from the image
+ QRect selection(iface->selectedXOrg(), iface->selectedYOrg(),
+ iface->selectedWidth(), iface->selectedHeight());
+
+ setFilter(dynamic_cast<DImgThreadedFilter *>
+ (new RainDrop(iface->getOriginalImg(), this, d, a, c, &selection)));
+}
+
+void RainDropTool::prepareFinal()
+{
+ m_dropInput->setEnabled(false);
+ m_amountInput->setEnabled(false);
+ m_coeffInput->setEnabled(false);
+
+ int d = m_dropInput->value();
+ int a = m_amountInput->value();
+ int c = m_coeffInput->value();
+
+ ImageIface iface(0, 0);
+
+ // Selected data from the image
+ QRect selection(iface.selectedXOrg(), iface.selectedYOrg(),
+ iface.selectedWidth(), iface.selectedHeight());
+
+ setFilter(dynamic_cast<DImgThreadedFilter *>
+ (new RainDrop(iface.getOriginalImg(), this, d, a, c, &selection)));
+}
+
+void RainDropTool::putPreviewData(void)
+{
+ ImageIface* iface = m_previewWidget->imageIface();
+
+ DImg imDest = filter()->getTargetImage()
+ .smoothScale(iface->previewWidth(), iface->previewHeight());
+ iface->putPreviewImage(imDest.bits());
+
+ m_previewWidget->updatePreview();
+}
+
+void RainDropTool::putFinalData(void)
+{
+ ImageIface iface(0, 0);
+
+ iface.putOriginalImage(i18n("RainDrop"), filter()->getTargetImage().bits());
+}
+
+} // NameSpace DigikamRainDropImagesPlugin
+
diff --git a/digikam/imageplugins/raindrop/raindroptool.h b/digikam/imageplugins/raindrop/raindroptool.h
new file mode 100644
index 0000000..896047b
--- /dev/null
+++ b/digikam/imageplugins/raindrop/raindroptool.h
@@ -0,0 +1,81 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-09-30
+ * Description : a plugin to add rain drop over an image
+ *
+ * Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2006-2008 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.
+ *
+ * ============================================================ */
+
+#ifndef RAINDROPTOOL_H
+#define RAINDROPTOOL_H
+
+// Digikam includes.
+
+#include "editortool.h"
+
+namespace KDcrawIface
+{
+class RIntNumInput;
+}
+
+namespace Digikam
+{
+class ImageWidget;
+}
+
+namespace DigikamRainDropImagesPlugin
+{
+
+class RainDropTool : public Digikam::EditorToolThreaded
+{
+ Q_OBJECT
+
+public:
+
+ RainDropTool(QObject *parent);
+ ~RainDropTool();
+
+private slots:
+
+ void slotResetSettings();
+
+private:
+
+ void readSettings();
+ void writeSettings();
+ void prepareEffect();
+ void prepareFinal();
+ void putPreviewData();
+ void putFinalData();
+ void renderingFinished();
+
+private:
+
+ KDcrawIface::RIntNumInput *m_dropInput;
+ KDcrawIface::RIntNumInput *m_amountInput;
+ KDcrawIface::RIntNumInput *m_coeffInput;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::EditorToolSettings *m_gboxSettings;
+};
+
+} // NameSpace DigikamRainDropImagesPlugin
+
+#endif /* RAINDROPTOOL_H */