summaryrefslogtreecommitdiffstats
path: root/digikam/imageplugins/coreplugin
diff options
context:
space:
mode:
Diffstat (limited to 'digikam/imageplugins/coreplugin')
-rw-r--r--digikam/imageplugins/coreplugin/Makefile.am48
-rw-r--r--digikam/imageplugins/coreplugin/autocorrectiontool.cpp438
-rw-r--r--digikam/imageplugins/coreplugin/autocorrectiontool.h127
-rw-r--r--digikam/imageplugins/coreplugin/bcgtool.cpp366
-rw-r--r--digikam/imageplugins/coreplugin/bcgtool.h114
-rw-r--r--digikam/imageplugins/coreplugin/blurtool.cpp169
-rw-r--r--digikam/imageplugins/coreplugin/blurtool.h80
-rw-r--r--digikam/imageplugins/coreplugin/bwsepiatool.cpp1177
-rw-r--r--digikam/imageplugins/coreplugin/bwsepiatool.h192
-rw-r--r--digikam/imageplugins/coreplugin/digikamimageplugin_core.desktop47
-rw-r--r--digikam/imageplugins/coreplugin/digikamimageplugin_core_ui.rc56
-rw-r--r--digikam/imageplugins/coreplugin/hsl/Makefile.am26
-rw-r--r--digikam/imageplugins/coreplugin/hsl/hsltool.cpp453
-rw-r--r--digikam/imageplugins/coreplugin/hsl/hsltool.h125
-rw-r--r--digikam/imageplugins/coreplugin/hsl/hspreviewwidget.cpp126
-rw-r--r--digikam/imageplugins/coreplugin/hsl/hspreviewwidget.h63
-rw-r--r--digikam/imageplugins/coreplugin/hsl/imageeffect_hsl.cpp428
-rw-r--r--digikam/imageplugins/coreplugin/hsl/imageeffect_hsl.h115
-rw-r--r--digikam/imageplugins/coreplugin/iccprooftool.cpp1310
-rw-r--r--digikam/imageplugins/coreplugin/iccprooftool.h208
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_autocorrection.cpp431
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_autocorrection.h127
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_bcg.cpp350
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_bcg.h109
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_blur.cpp147
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_blur.h67
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_bwsepia.cpp1183
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_bwsepia.h194
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_iccproof.cpp1284
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_iccproof.h203
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_redeye.cpp574
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_redeye.h152
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_rgb.cpp419
-rw-r--r--digikam/imageplugins/coreplugin/imageeffect_rgb.h112
-rw-r--r--digikam/imageplugins/coreplugin/imageplugin_core.cpp295
-rw-r--r--digikam/imageplugins/coreplugin/imageplugin_core.h84
-rw-r--r--digikam/imageplugins/coreplugin/ratiocrop/Makefile.am26
-rw-r--r--digikam/imageplugins/coreplugin/ratiocrop/imageeffect_ratiocrop.cpp799
-rw-r--r--digikam/imageplugins/coreplugin/ratiocrop/imageeffect_ratiocrop.h131
-rw-r--r--digikam/imageplugins/coreplugin/ratiocrop/imageselectionwidget.cpp1422
-rw-r--r--digikam/imageplugins/coreplugin/ratiocrop/imageselectionwidget.h175
-rw-r--r--digikam/imageplugins/coreplugin/ratiocrop/ratiocroptool.cpp853
-rw-r--r--digikam/imageplugins/coreplugin/ratiocrop/ratiocroptool.h134
-rw-r--r--digikam/imageplugins/coreplugin/redeyetool.cpp587
-rw-r--r--digikam/imageplugins/coreplugin/redeyetool.h156
-rw-r--r--digikam/imageplugins/coreplugin/rgbtool.cpp440
-rw-r--r--digikam/imageplugins/coreplugin/rgbtool.h118
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/Makefile.am32
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/LICENCE12
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/Makefile.am7
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/README2
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/abort_.c16
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/blaswrap.h158
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/clapack.h5079
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/close.c94
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgemm.c313
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dger.c143
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgesv.c117
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgetf2.c157
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgetrf.c197
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgetrs.c159
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dlaswp.c143
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dscal.c62
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dswap.c81
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dtrsm.c404
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/endfile.c121
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/err.c271
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/f2c.h223
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fio.h107
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.c516
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.h100
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fmtlib.c45
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fp.h28
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/idamax.c61
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/ieeeck.c150
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/ilaenv.c610
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/lsame.c101
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/open.c291
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/s_cmp.c44
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/s_copy.c51
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/s_stop.c42
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/sfe.c31
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/sig_die.c45
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/util.c53
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/wref.c276
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/wrtfmt.c365
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/wsfe.c73
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/clapack/xerbla.c58
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/imageeffect_sharpen.cpp696
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/imageeffect_sharpen.h101
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/matrix.cpp663
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/matrix.h129
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/refocus.cpp199
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/refocus.h67
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/sharpentool.cpp741
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/sharpentool.h110
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/unsharp.cpp127
-rw-r--r--digikam/imageplugins/coreplugin/sharpnesseditor/unsharp.h58
98 files changed, 29969 insertions, 0 deletions
diff --git a/digikam/imageplugins/coreplugin/Makefile.am b/digikam/imageplugins/coreplugin/Makefile.am
new file mode 100644
index 0000000..9ac947e
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/Makefile.am
@@ -0,0 +1,48 @@
+SUBDIRS = sharpnesseditor hsl ratiocrop
+COMPILE_FIRST = sharpnesseditor hsl ratiocrop
+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 \
+ -I$(top_srcdir)/digikam/imageplugins/coreplugin/sharpnesseditor \
+ -I$(top_srcdir)/digikam/imageplugins/coreplugin/hsl \
+ -I$(top_srcdir)/digikam/imageplugins/coreplugin/ratiocrop \
+ $(LIBKDCRAW_CFLAGS) \
+ $(all_includes)
+
+digikamimageplugin_core_la_SOURCES = imageplugin_core.cpp bwsepiatool.cpp \
+ autocorrectiontool.cpp \
+ rgbtool.cpp \
+ redeyetool.cpp blurtool.cpp \
+ iccprooftool.cpp bcgtool.cpp
+
+noinst_HEADERS = autocorrectiontool.h blurtool.h \
+ rgbtool.h bcgtool.h \
+ bwsepiatool.h iccprooftool.h redeyetool.h
+
+digikamimageplugin_core_la_LIBADD = $(LIB_KPARTS) \
+ $(top_builddir)/digikam/imageplugins/coreplugin/sharpnesseditor/libsharpnesseditor.la \
+ $(top_builddir)/digikam/imageplugins/coreplugin/hsl/libhsl.la \
+ $(top_builddir)/digikam/imageplugins/coreplugin/ratiocrop/libratiocrop.la \
+ $(top_builddir)/digikam/digikam/libdigikam.la
+
+digikamimageplugin_core_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
+
+kde_services_DATA = digikamimageplugin_core.desktop
+
+kde_module_LTLIBRARIES = digikamimageplugin_core.la
+
+rcdir = $(kde_datadir)/digikam
+rc_DATA = digikamimageplugin_core_ui.rc
diff --git a/digikam/imageplugins/coreplugin/autocorrectiontool.cpp b/digikam/imageplugins/coreplugin/autocorrectiontool.cpp
new file mode 100644
index 0000000..736f524
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/autocorrectiontool.cpp
@@ -0,0 +1,438 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-05-31
+ * Description : Auto-Color correction tool.
+ *
+ * Copyright (C) 2005-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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qcheckbox.h>
+#include <qcolor.h>
+#include <qcombobox.h>
+#include <qframe.h>
+#include <qgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qhgroupbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlistbox.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qtimer.h>
+#include <qtooltip.h>
+#include <qvbox.h>
+#include <qvgroupbox.h>
+#include <qwhatsthis.h>
+
+// KDE includes.
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+// Digikam includes.
+
+#include "colorgradientwidget.h"
+#include "dimg.h"
+#include "dimgimagefilters.h"
+#include "editortoolsettings.h"
+#include "histogramwidget.h"
+#include "imageiface.h"
+#include "imagewidget.h"
+#include "listboxpreviewitem.h"
+#include "whitebalance.h"
+
+// Local includes.
+
+#include "autocorrectiontool.h"
+#include "autocorrectiontool.moc"
+
+using namespace Digikam;
+
+namespace DigikamImagesPluginCore
+{
+
+AutoCorrectionTool::AutoCorrectionTool(QObject* parent)
+ : EditorTool(parent)
+{
+ setName("autocorrection");
+ setToolName(i18n("Auto-Correction"));
+ setToolIcon(SmallIcon("autocorrection"));
+ setToolHelp("autocolorcorrectiontool.anchor");
+
+ // -------------------------------------------------------------
+
+ m_previewWidget = new ImageWidget("autocorrection Tool", 0,
+ i18n("<p>Here you can see the auto-color correction tool "
+ "preview. You can pick color on image "
+ "to see the color level corresponding on histogram."));
+ setToolView(m_previewWidget);
+
+ // -------------------------------------------------------------
+
+ ImageIface iface(0, 0);
+ m_thumbnailImage = iface.getOriginalImg()->smoothScale(128, 128, QSize::ScaleMin);
+ m_destinationPreviewData = 0;
+
+ EditorToolSettings *gboxSettings = new EditorToolSettings(EditorToolSettings::Default|
+ EditorToolSettings::Ok|
+ EditorToolSettings::Cancel);
+
+ QGridLayout* gridSettings = new QGridLayout(gboxSettings->plainPage(), 2, 4);
+
+ QLabel *label1 = new QLabel(i18n("Channel:"), gboxSettings->plainPage());
+ label1->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ m_channelCB = new QComboBox( false, gboxSettings->plainPage() );
+ m_channelCB->insertItem( i18n("Luminosity") );
+ m_channelCB->insertItem( i18n("Red") );
+ m_channelCB->insertItem( i18n("Green") );
+ m_channelCB->insertItem( i18n("Blue") );
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red image-channel values.<p>"
+ "<b>Green</b>: display the green image-channel values.<p>"
+ "<b>Blue</b>: display the blue image-channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(gboxSettings->plainPage());
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin( 0 );
+ QWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximal counts are small, you can use the linear scale.<p>"
+ "Logarithmic scale can be used when the maximal counts are big; "
+ "if it is used, all values (small and large) will be visible on the graph."));
+
+ QPushButton *linHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(linHistoButton, i18n("<p>Linear"));
+ m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap( QPixmap( directory + "histogram-lin.png" ) );
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(logHistoButton, i18n("<p>Logarithmic"));
+ m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap(QPixmap(directory + "histogram-log.png"));
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(gboxSettings->plainPage());
+ m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram drawing "
+ "of the selected image channel. This one is re-computed at any "
+ "settings changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, histoBox);
+ m_hGradient->setColors(QColor("black"), QColor("white"));
+
+ // -------------------------------------------------------------
+
+ m_correctionTools = new QListBox(gboxSettings->plainPage());
+ m_correctionTools->setColumnMode(1);
+ m_correctionTools->setVariableWidth(false);
+ m_correctionTools->setVariableHeight(false);
+ ListBoxWhatsThis* whatsThis = new ListBoxWhatsThis(m_correctionTools);
+
+ QPixmap pix = getThumbnailForEffect(AutoLevelsCorrection);
+ ListBoxPreviewItem *item = new ListBoxPreviewItem(pix, i18n("Auto Levels"));
+ whatsThis->add( item, i18n("<b>Auto Levels</b>:"
+ "<p>This option maximizes the tonal range in the Red, "
+ "Green, and Blue channels. It searches the image shadow and highlight "
+ "limit values and adjusts the Red, Green, and Blue channels "
+ "to a full histogram range.</p>"));
+ m_correctionTools->insertItem(item, AutoLevelsCorrection);
+
+ pix = getThumbnailForEffect(NormalizeCorrection);
+ item = new ListBoxPreviewItem(pix, i18n("Normalize"));
+ whatsThis->add( item, i18n("<b>Normalize</b>:"
+ "<p>This option scales brightness values across the active "
+ "image so that the darkest point becomes black, and the "
+ "brightest point becomes as bright as possible without "
+ "altering its hue. This is often a \"magic fix\" for "
+ "images that are dim or washed out.</p>"));
+ m_correctionTools->insertItem(item, NormalizeCorrection);
+
+ pix = getThumbnailForEffect(EqualizeCorrection);
+ item = new ListBoxPreviewItem(pix, i18n("Equalize"));
+ whatsThis->add( item, i18n("<b>Equalize</b>:"
+ "<p>This option adjusts the brightness of colors across the "
+ "active image so that the histogram for the value channel "
+ "is as nearly as possible flat, that is, so that each possible "
+ "brightness value appears at about the same number of pixels "
+ "as each other value. Sometimes Equalize works wonderfully at "
+ "enhancing the contrasts in an image. Other times it gives "
+ "garbage. It is a very powerful operation, which can either work "
+ "miracles on an image or destroy it.</p>"));
+ m_correctionTools->insertItem(item, EqualizeCorrection);
+
+ pix = getThumbnailForEffect(StretchContrastCorrection);
+ item = new ListBoxPreviewItem(pix, i18n("Stretch Contrast"));
+ whatsThis->add( item, i18n("<b>Stretch Contrast</b>:"
+ "<p>This option enhances the contrast and brightness "
+ "of the RGB values of an image by stretching the lowest "
+ "and highest values to their fullest range, adjusting "
+ "everything in between.</p>"));
+ m_correctionTools->insertItem(item, StretchContrastCorrection);
+
+ pix = getThumbnailForEffect(AutoExposureCorrection);
+ item = new ListBoxPreviewItem(pix, i18n("Auto Exposure"));
+ whatsThis->add( item, i18n("<b>Auto Exposure</b>:"
+ "<p>This option enhances the contrast and brightness "
+ "of the RGB values of an image to calculate optimal "
+ "exposition and black level using image histogram "
+ "properties.</p>"));
+ m_correctionTools->insertItem(item, AutoExposureCorrection);
+
+ // -------------------------------------------------------------
+
+ m_correctionTools->setFocus();
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4);
+ gridSettings->addMultiCellWidget(histoBox, 1, 1, 0, 4);
+ gridSettings->addMultiCellWidget(m_correctionTools, 2, 2, 0, 4);
+ gridSettings->setRowStretch(2, 10);
+ gridSettings->setSpacing(gboxSettings->spacingHint());
+ gridSettings->setMargin(gboxSettings->spacingHint());
+
+ setToolSettings(gboxSettings);
+ init();
+
+ // -------------------------------------------------------------
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget(const DColor&, const QPoint&)),
+ this, SLOT(slotColorSelectedFromTarget(const DColor&)));
+
+ connect(m_correctionTools, SIGNAL(highlighted(int)),
+ this, SLOT(slotEffect()));
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+}
+
+AutoCorrectionTool::~AutoCorrectionTool()
+{
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+}
+
+void AutoCorrectionTool::slotChannelChanged(int channel)
+{
+ switch(channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::ValueHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "red" ) );
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "green" ) );
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "blue" ) );
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void AutoCorrectionTool::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+}
+
+void AutoCorrectionTool::slotColorSelectedFromTarget(const DColor& color)
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void AutoCorrectionTool::readSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("autocorrection Tool");
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", HistogramWidget::LogScaleHistogram));
+ m_correctionTools->setCurrentItem(config->readNumEntry("Auto Correction Filter", AutoLevelsCorrection));
+ m_histogramWidget->reset();
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+}
+
+void AutoCorrectionTool::writeSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("autocorrection Tool");
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writeEntry("Auto Correction Filter", m_correctionTools->currentItem());
+ m_previewWidget->writeSettings();
+ config->sync();
+}
+
+void AutoCorrectionTool::slotResetSettings()
+{
+ m_correctionTools->blockSignals(true);
+ m_correctionTools->setCurrentItem(AutoLevelsCorrection);
+ m_correctionTools->blockSignals(false);
+
+ slotEffect();
+}
+
+void AutoCorrectionTool::slotEffect()
+{
+ kapp->setOverrideCursor(KCursor::waitCursor());
+
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ ImageIface* iface = m_previewWidget->imageIface();
+ m_destinationPreviewData = iface->getPreviewImage();
+ int w = iface->previewWidth();
+ int h = iface->previewHeight();
+ bool sb = iface->previewSixteenBit();
+
+ autoCorrection(m_destinationPreviewData, w, h, sb, m_correctionTools->currentItem());
+
+ iface->putPreviewImage(m_destinationPreviewData);
+ m_previewWidget->updatePreview();
+
+ // Update histogram.
+
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false);
+
+ kapp->restoreOverrideCursor();
+}
+
+QPixmap AutoCorrectionTool::getThumbnailForEffect(AutoCorrectionType type)
+{
+ DImg thumb = m_thumbnailImage.copy();
+ autoCorrection(thumb.bits(), thumb.width(), thumb.height(), thumb.sixteenBit(), type);
+ return (thumb.convertToPixmap());
+}
+
+
+void AutoCorrectionTool::finalRendering()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+ ImageIface* iface = m_previewWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int w = iface->originalWidth();
+ int h = iface->originalHeight();
+ bool sb = iface->originalSixteenBit();
+
+ if (data)
+ {
+ int type = m_correctionTools->currentItem();
+ autoCorrection(data, w, h, sb, type);
+ QString name;
+
+ switch (type)
+ {
+ case AutoLevelsCorrection:
+ name = i18n("Auto Levels");
+ break;
+
+ case NormalizeCorrection:
+ name = i18n("Normalize");
+ break;
+
+ case EqualizeCorrection:
+ name = i18n("Equalize");
+ break;
+
+ case StretchContrastCorrection:
+ name = i18n("Stretch Contrast");
+ break;
+
+ case AutoExposureCorrection:
+ name = i18n("Auto Exposure");
+ break;
+ }
+
+ iface->putOriginalImage(name, data);
+ delete [] data;
+ }
+
+ kapp->restoreOverrideCursor();
+}
+
+void AutoCorrectionTool::autoCorrection(uchar *data, int w, int h, bool sb, int type)
+{
+ DImgImageFilters filter;
+
+ switch (type)
+ {
+ case AutoLevelsCorrection:
+ filter.autoLevelsCorrectionImage(data, w, h, sb);
+ break;
+
+ case NormalizeCorrection:
+ filter.normalizeImage(data, w, h, sb);
+ break;
+
+ case EqualizeCorrection:
+ filter.equalizeImage(data, w, h, sb);
+ break;
+
+ case StretchContrastCorrection:
+ filter.stretchContrastImage(data, w, h, sb);
+ break;
+
+ case AutoExposureCorrection:
+ WhiteBalance wbFilter(sb);
+ double blackLevel;
+ double exposureLevel;
+ wbFilter.autoExposureAdjustement(data, w, h, sb, blackLevel, exposureLevel);
+ wbFilter.whiteBalance(data, w, h, sb, blackLevel, exposureLevel);
+ break;
+ }
+}
+
+} // NameSpace DigikamImagesPluginCore
+
diff --git a/digikam/imageplugins/coreplugin/autocorrectiontool.h b/digikam/imageplugins/coreplugin/autocorrectiontool.h
new file mode 100644
index 0000000..b9d1b44
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/autocorrectiontool.h
@@ -0,0 +1,127 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-05-31
+ * Description : Auto-Color correction tool.
+ *
+ * Copyright (C) 2005-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 AUTOCORRECTIONTOOL_H
+#define AUTOCORRECTIONTOOL_H
+
+// Qt includes.
+
+#include <qstring.h>
+
+// Digikam includes.
+
+#include "editortool.h"
+
+class QHButtonGroup;
+class QComboBox;
+class QListBox;
+class QButtonGroup;
+
+namespace Digikam
+{
+class HistogramWidget;
+class ColorGradientWidget;
+class ImageWidget;
+class DColor;
+class DImg;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class AutoCorrectionTool : public Digikam::EditorTool
+{
+ Q_OBJECT
+
+public:
+
+ AutoCorrectionTool(QObject *parent);
+ ~AutoCorrectionTool();
+
+protected:
+
+ void finalRendering();
+
+private slots:
+
+ void slotEffect();
+ void slotResetSettings();
+ void slotChannelChanged(int channel);
+ void slotScaleChanged(int scale);
+ void slotColorSelectedFromTarget(const Digikam::DColor &color);
+
+private:
+
+ enum AutoCorrectionType
+ {
+ AutoLevelsCorrection=0,
+ NormalizeCorrection,
+ EqualizeCorrection,
+ StretchContrastCorrection,
+ AutoExposureCorrection
+ };
+
+private:
+
+ void readSettings();
+ void writeSettings();
+
+ void autoCorrection(uchar *data, int w, int h, bool sb, int type);
+ QPixmap getThumbnailForEffect(AutoCorrectionType type);
+
+private:
+
+ enum HistogramScale
+ {
+ Linear=0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel=0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ uchar *m_destinationPreviewData;
+
+ QComboBox *m_channelCB;
+
+ QHButtonGroup *m_scaleBG;
+
+ QListBox *m_correctionTools;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+
+ Digikam::DImg m_thumbnailImage;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* AUTOCORRECTIONTOOL_H */
diff --git a/digikam/imageplugins/coreplugin/bcgtool.cpp b/digikam/imageplugins/coreplugin/bcgtool.cpp
new file mode 100644
index 0000000..a6fba7b
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/bcgtool.cpp
@@ -0,0 +1,366 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-06-05
+ * Description : digiKam image editor to adjust Brightness,
+ Contrast, and Gamma of picture.
+ *
+ * Copyright (C) 2004 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * Copyright (C) 2005-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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qcheckbox.h>
+#include <qcolor.h>
+#include <qcombobox.h>
+#include <qframe.h>
+#include <qgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qhgroupbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qtooltip.h>
+#include <qvbox.h>
+#include <qvgroupbox.h>
+#include <qwhatsthis.h>
+
+// KDE includes.
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+// LibKDcraw includes.
+
+#include <libkdcraw/rnuminput.h>
+
+// Digikam includes.
+
+#include "bcgmodifier.h"
+#include "colorgradientwidget.h"
+#include "dimg.h"
+#include "editortoolsettings.h"
+#include "histogramwidget.h"
+#include "imageiface.h"
+#include "imagewidget.h"
+
+// Local includes.
+
+#include "bcgtool.h"
+#include "bcgtool.moc"
+
+using namespace KDcrawIface;
+using namespace Digikam;
+
+namespace DigikamImagesPluginCore
+{
+
+BCGTool::BCGTool(QObject* parent)
+ : EditorTool(parent)
+{
+ setName("bcgadjust");
+ setToolName(i18n("Brightness / Contrast / Gamma"));
+ setToolIcon(SmallIcon("contrast"));
+ setToolHelp("bcgadjusttool.anchor");
+
+ m_destinationPreviewData = 0;
+
+ m_previewWidget = new ImageWidget("bcgadjust Tool", 0,
+ i18n("<p>Here you can see the image "
+ "brightness-contrast-gamma adjustments preview. "
+ "You can pick color on image "
+ "to see the color level corresponding on histogram."));
+ setToolView(m_previewWidget);
+
+ // -------------------------------------------------------------
+
+ m_gboxSettings = new EditorToolSettings(EditorToolSettings::Default|
+ EditorToolSettings::Ok|
+ EditorToolSettings::Cancel);
+
+ QGridLayout* gridSettings = new QGridLayout(m_gboxSettings->plainPage(), 9, 4);
+
+ QLabel *label1 = new QLabel(i18n("Channel:"), m_gboxSettings->plainPage());
+ label1->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ m_channelCB = new QComboBox(false, m_gboxSettings->plainPage());
+ m_channelCB->insertItem(i18n("Luminosity"));
+ m_channelCB->insertItem(i18n("Red"));
+ m_channelCB->insertItem(i18n("Green"));
+ m_channelCB->insertItem(i18n("Blue"));
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red image-channel values.<p>"
+ "<b>Green</b>: display the green image-channel values.<p>"
+ "<b>Blue</b>: display the blue image-channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(m_gboxSettings->plainPage());
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin(0);
+ QWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximal counts are small, you can use the linear scale.<p>"
+ "Logarithmic scale can be used when the maximal counts are big; "
+ "if it is used, all values (small and large) will be visible on the graph."));
+
+ QPushButton *linHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(linHistoButton, i18n("<p>Linear"));
+ m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap(QPixmap(directory + "histogram-lin.png"));
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(logHistoButton, i18n("<p>Logarithmic"));
+ m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap(QPixmap(directory + "histogram-log.png"));
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(m_gboxSettings->plainPage());
+ m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram drawing "
+ "of the selected image channel. This one is re-computed at any "
+ "settings changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, histoBox);
+ m_hGradient->setColors(QColor("black"), QColor("white"));
+
+ // -------------------------------------------------------------
+
+ QLabel *label2 = new QLabel(i18n("Brightness:"), m_gboxSettings->plainPage());
+ m_bInput = new RIntNumInput(m_gboxSettings->plainPage());
+ m_bInput->setRange(-100, 100, 1);
+ m_bInput->setDefaultValue(0);
+ QWhatsThis::add( m_bInput, i18n("<p>Set here the brightness adjustment of the image."));
+
+ QLabel *label3 = new QLabel(i18n("Contrast:"), m_gboxSettings->plainPage());
+ m_cInput = new RIntNumInput(m_gboxSettings->plainPage());
+ m_cInput->setRange(-100, 100, 1);
+ m_cInput->setDefaultValue(0);
+ QWhatsThis::add( m_cInput, i18n("<p>Set here the contrast adjustment of the image."));
+
+ QLabel *label4 = new QLabel(i18n("Gamma:"), m_gboxSettings->plainPage());
+ m_gInput = new RDoubleNumInput(m_gboxSettings->plainPage());
+ m_gInput->setPrecision(2);
+ m_gInput->setRange(0.1, 3.0, 0.01);
+ m_gInput->setDefaultValue(1.0);
+ QWhatsThis::add( m_gInput, i18n("<p>Set here the gamma adjustment of the image."));
+
+ // -------------------------------------------------------------
+
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4);
+ gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4);
+ gridSettings->addMultiCellWidget(label2, 3, 3, 0, 4);
+ gridSettings->addMultiCellWidget(m_bInput, 4, 4, 0, 4);
+ gridSettings->addMultiCellWidget(label3, 5, 5, 0, 4);
+ gridSettings->addMultiCellWidget(m_cInput, 6, 6, 0, 4);
+ gridSettings->addMultiCellWidget(label4, 7, 7, 0, 4);
+ gridSettings->addMultiCellWidget(m_gInput, 8, 8, 0, 4);
+ gridSettings->setRowStretch(9, 10);
+
+ setToolSettings(m_gboxSettings);
+ init();
+
+ // -------------------------------------------------------------
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const QPoint & )),
+ this, SLOT(slotColorSelectedFromTarget( const Digikam::DColor & )));
+
+ connect(m_bInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_cInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_gInput, SIGNAL(valueChanged(double)),
+ this, SLOT(slotTimer()));
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+
+ // -------------------------------------------------------------
+
+ m_gboxSettings->enableButton(EditorToolSettings::Ok, false);
+}
+
+BCGTool::~BCGTool()
+{
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+}
+
+void BCGTool::slotChannelChanged(int channel)
+{
+ switch (channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::ValueHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("white"));
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("red"));
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("green"));
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("blue"));
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void BCGTool::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+}
+
+void BCGTool::slotColorSelectedFromTarget(const DColor &color)
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void BCGTool::readSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("bcgadjust Tool");
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", HistogramWidget::LogScaleHistogram));
+ m_bInput->setValue(config->readNumEntry("BrightnessAjustment", m_bInput->defaultValue()));
+ m_cInput->setValue(config->readNumEntry("ContrastAjustment", m_cInput->defaultValue()));
+ m_gInput->setValue(config->readDoubleNumEntry("GammaAjustment", m_gInput->defaultValue()));
+ m_histogramWidget->reset();
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+}
+
+void BCGTool::writeSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("bcgadjust Tool");
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writeEntry("BrightnessAjustment", m_bInput->value());
+ config->writeEntry("ContrastAjustment", m_cInput->value());
+ config->writeEntry("GammaAjustment", m_gInput->value());
+ m_previewWidget->writeSettings();
+ config->sync();
+}
+
+void BCGTool::slotResetSettings()
+{
+ m_bInput->blockSignals(true);
+ m_cInput->blockSignals(true);
+ m_gInput->blockSignals(true);
+
+ m_bInput->slotReset();
+ m_cInput->slotReset();
+ m_gInput->slotReset();
+
+ m_bInput->blockSignals(false);
+ m_cInput->blockSignals(false);
+ m_gInput->blockSignals(false);
+
+ slotEffect();
+}
+
+void BCGTool::slotEffect()
+{
+ kapp->setOverrideCursor(KCursor::waitCursor());
+
+ double b = (double) m_bInput->value() / 250.0;
+ double c = (double) (m_cInput->value() / 100.0) + 1.00;
+ double g = m_gInput->value();
+
+ m_gboxSettings->enableButton(EditorToolSettings::Ok,
+ ( b != 0.0 || c != 1.0 || g != 1.0 ));
+
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ ImageIface* iface = m_previewWidget->imageIface();
+ m_destinationPreviewData = iface->getPreviewImage();
+ int w = iface->previewWidth();
+ int h = iface->previewHeight();
+ bool a = iface->previewHasAlpha();
+ bool sb = iface->previewSixteenBit();
+
+ DImg preview(w, h, sb, a, m_destinationPreviewData);
+ BCGModifier cmod;
+ cmod.setGamma(g);
+ cmod.setBrightness(b);
+ cmod.setContrast(c);
+ cmod.applyBCG(preview);
+ iface->putPreviewImage(preview.bits());
+
+ m_previewWidget->updatePreview();
+
+ // Update histogram.
+
+ memcpy(m_destinationPreviewData, preview.bits(), preview.numBytes());
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false);
+
+ kapp->restoreOverrideCursor();
+}
+
+void BCGTool::finalRendering()
+{
+ kapp->setOverrideCursor(KCursor::waitCursor());
+ ImageIface* iface = m_previewWidget->imageIface();
+
+ double b = (double) m_bInput->value() / 250.0;
+ double c = (double) (m_cInput->value() / 100.0) + 1.00;
+ double g = m_gInput->value();
+
+ iface->setOriginalBCG(b, c, g);
+ kapp->restoreOverrideCursor();
+}
+
+} // NameSpace DigikamImagesPluginCore
+
diff --git a/digikam/imageplugins/coreplugin/bcgtool.h b/digikam/imageplugins/coreplugin/bcgtool.h
new file mode 100644
index 0000000..3e797de
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/bcgtool.h
@@ -0,0 +1,114 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-06-05
+ * Description : digiKam image editor to adjust Brightness,
+ Contrast, and Gamma of picture.
+ *
+ * Copyright (C) 2004 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * Copyright (C) 2005-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 BCGTOOL_H
+#define BCGTOOL_H
+
+// Digikam includes.
+
+#include "editortool.h"
+
+class QCheckBox;
+class QComboBox;
+class QHButtonGroup;
+
+namespace KDcrawIface
+{
+class RIntNumInput;
+class RDoubleNumInput;
+}
+
+namespace Digikam
+{
+class HistogramWidget;
+class ColorGradientWidget;
+class ImageWidget;
+class DColor;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class BCGTool : public Digikam::EditorTool
+{
+ Q_OBJECT
+
+public:
+
+ BCGTool(QObject *parent);
+ ~BCGTool();
+
+private slots:
+
+ void slotEffect();
+ void slotResetSettings();
+ void slotChannelChanged(int channel);
+ void slotScaleChanged(int scale);
+ void slotColorSelectedFromTarget( const Digikam::DColor &color );
+
+private:
+
+ void readSettings();
+ void writeSettings();
+ void finalRendering();
+
+private:
+
+ enum HistogramScale
+ {
+ Linear=0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel=0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ uchar *m_destinationPreviewData;
+
+ QComboBox *m_channelCB;
+
+ QHButtonGroup *m_scaleBG;
+
+ KDcrawIface::RIntNumInput *m_bInput;
+ KDcrawIface::RIntNumInput *m_cInput;
+ KDcrawIface::RDoubleNumInput *m_gInput;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+
+ Digikam::EditorToolSettings *m_gboxSettings;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* BCGTOOL_H */
diff --git a/digikam/imageplugins/coreplugin/blurtool.cpp b/digikam/imageplugins/coreplugin/blurtool.cpp
new file mode 100644
index 0000000..38b0b10
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/blurtool.cpp
@@ -0,0 +1,169 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-09
+ * Description : a tool to blur 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+
+// KDE includes.
+
+#include <kaboutdata.h>
+#include <kiconloader.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <klocale.h>
+#include <kapplication.h>
+
+// Digikam includes.
+
+#include "ddebug.h"
+#include "imageiface.h"
+#include "imagepanelwidget.h"
+#include "editortoolsettings.h"
+#include "dimggaussianblur.h"
+
+// LibKDcraw includes.
+
+#include <libkdcraw/rnuminput.h>
+
+// Local includes.
+
+#include "blurtool.h"
+#include "blurtool.moc"
+
+using namespace KDcrawIface;
+using namespace Digikam;
+
+namespace DigikamImagesPluginCore
+{
+
+BlurTool::BlurTool(QObject* parent)
+ : EditorToolThreaded(parent)
+{
+ setName("gaussianblur");
+ setToolName(i18n("Blur"));
+ setToolIcon(SmallIcon("blurimage"));
+ setToolHelp("blursharpentool.anchor");
+
+ // ---------------------------------------------------------------------------------
+
+ m_gboxSettings = new EditorToolSettings(EditorToolSettings::Default|
+ EditorToolSettings::Ok|
+ EditorToolSettings::Cancel|
+ EditorToolSettings::Try,
+ EditorToolSettings::PanIcon);
+ QGridLayout* grid = new QGridLayout( m_gboxSettings->plainPage(), 2, 1);
+ QLabel *label = new QLabel(i18n("Smoothness:"), m_gboxSettings->plainPage());
+
+ m_radiusInput = new RIntNumInput(m_gboxSettings->plainPage());
+ m_radiusInput->setRange(0, 100, 1);
+ m_radiusInput->setDefaultValue(0);
+ QWhatsThis::add(m_radiusInput, i18n("<p>A smoothness of 0 has no effect, "
+ "1 and above determine the Gaussian blur matrix radius "
+ "that determines how much to blur the image."));
+
+ grid->addMultiCellWidget(label, 0, 0, 0, 1);
+ grid->addMultiCellWidget(m_radiusInput, 1, 1, 0, 1);
+ grid->setRowStretch(2, 10);
+ grid->setMargin(m_gboxSettings->spacingHint());
+ grid->setSpacing(m_gboxSettings->spacingHint());
+
+ setToolSettings(m_gboxSettings);
+
+ m_previewWidget = new ImagePanelWidget(470, 350, "gaussianblur Tool", m_gboxSettings->panIconView());
+
+ setToolView(m_previewWidget);
+ init();
+}
+
+BlurTool::~BlurTool()
+{
+}
+
+void BlurTool::readSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("gaussianblur Tool");
+ m_radiusInput->setValue(config->readNumEntry("RadiusAjustment", m_radiusInput->defaultValue()));
+}
+
+void BlurTool::writeSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("gaussianblur Tool");
+ config->writeEntry("RadiusAjustment", m_radiusInput->value());
+ config->sync();
+}
+
+void BlurTool::slotResetSettings()
+{
+ m_radiusInput->blockSignals(true);
+ m_radiusInput->slotReset();
+ m_radiusInput->blockSignals(false);
+}
+
+void BlurTool::prepareEffect()
+{
+ m_radiusInput->setEnabled(false);
+
+ DImg img = m_previewWidget->getOriginalRegionImage();
+
+ setFilter(dynamic_cast<DImgThreadedFilter*>(new DImgGaussianBlur(&img, this, m_radiusInput->value())));
+}
+
+void BlurTool::prepareFinal()
+{
+ m_radiusInput->setEnabled(false);
+
+ ImageIface iface(0, 0);
+ uchar *data = iface.getOriginalImage();
+ int w = iface.originalWidth();
+ int h = iface.originalHeight();
+ bool sixteenBit = iface.originalSixteenBit();
+ bool hasAlpha = iface.originalHasAlpha();
+ DImg orgImage = DImg(w, h, sixteenBit, hasAlpha ,data);
+ delete [] data;
+ setFilter(dynamic_cast<DImgThreadedFilter*>(new DImgGaussianBlur(&orgImage, this, m_radiusInput->value())));
+}
+
+void BlurTool::putPreviewData()
+{
+ DImg imDest = filter()->getTargetImage();
+ m_previewWidget->setPreviewImage(imDest);
+}
+
+void BlurTool::putFinalData()
+{
+ ImageIface iface(0, 0);
+ DImg imDest = filter()->getTargetImage();
+ iface.putOriginalImage(i18n("Gaussian Blur"), imDest.bits());
+}
+
+void BlurTool::renderingFinished()
+{
+ m_radiusInput->setEnabled(true);
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/blurtool.h b/digikam/imageplugins/coreplugin/blurtool.h
new file mode 100644
index 0000000..b94e874
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/blurtool.h
@@ -0,0 +1,80 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-09
+ * Description : a tool to blur 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 IMAGEEFFECT_BLUR_H
+#define IMAGEEFFECT_BLUR_H
+
+// Digikam includes.
+
+#include "editortool.h"
+
+namespace KDcrawIface
+{
+class RIntNumInput;
+}
+
+namespace Digikam
+{
+class EditorToolSettings;
+class ImagePanelWidget;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class BlurTool : public Digikam::EditorToolThreaded
+{
+ Q_OBJECT
+
+public:
+
+ BlurTool(QObject *parent);
+ ~BlurTool();
+
+private slots:
+
+ void slotResetSettings();
+
+private:
+
+ void readSettings();
+ void writeSettings();
+ void prepareEffect();
+ void prepareFinal();
+ void abortPreview();
+ void putPreviewData();
+ void putFinalData();
+ void renderingFinished();
+
+private:
+
+ KDcrawIface::RIntNumInput *m_radiusInput;
+
+ Digikam::ImagePanelWidget *m_previewWidget;
+
+ Digikam::EditorToolSettings *m_gboxSettings;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* IMAGEEFFECT_BLUR_H */
diff --git a/digikam/imageplugins/coreplugin/bwsepiatool.cpp b/digikam/imageplugins/coreplugin/bwsepiatool.cpp
new file mode 100644
index 0000000..c32dccf
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/bwsepiatool.cpp
@@ -0,0 +1,1177 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-12-06
+ * Description : Black and White conversion tool.
+ *
+ * Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * Copyright (C) 2006-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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qcolor.h>
+#include <qcombobox.h>
+#include <qfile.h>
+#include <qframe.h>
+#include <qgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qhgroupbox.h>
+#include <qintdict.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlistbox.h>
+#include <qpushbutton.h>
+#include <qtextstream.h>
+#include <qtimer.h>
+#include <qtooltip.h>
+#include <qvbox.h>
+#include <qvgroupbox.h>
+#include <qwhatsthis.h>
+
+// KDE includes.
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kfiledialog.h>
+#include <kglobalsettings.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <ktabwidget.h>
+
+// LibKDcraw includes.
+
+#include <libkdcraw/rnuminput.h>
+
+// Digikam includes.
+
+#include "bcgmodifier.h"
+#include "colorgradientwidget.h"
+#include "curveswidget.h"
+#include "dimg.h"
+#include "dimgimagefilters.h"
+#include "editortoolsettings.h"
+#include "histogramwidget.h"
+#include "imagecurves.h"
+#include "imagehistogram.h"
+#include "imageiface.h"
+#include "imagewidget.h"
+#include "listboxpreviewitem.h"
+
+// Local includes.
+
+#include "bwsepiatool.h"
+#include "bwsepiatool.moc"
+
+using namespace KDcrawIface;
+using namespace Digikam;
+
+namespace DigikamImagesPluginCore
+{
+
+class PreviewPixmapFactory : public QObject
+{
+public:
+
+ PreviewPixmapFactory(BWSepiaTool* bwSepia);
+
+ void invalidate() { m_previewPixmapMap.clear(); }
+
+ const QPixmap* pixmap(int id);
+
+private:
+
+ QPixmap makePixmap(int id);
+
+ QIntDict<QPixmap> m_previewPixmapMap;
+ BWSepiaTool *m_bwSepia;
+};
+
+PreviewPixmapFactory::PreviewPixmapFactory(BWSepiaTool* bwSepia)
+ : QObject(bwSepia), m_bwSepia(bwSepia)
+{
+ m_previewPixmapMap.setAutoDelete(true);
+}
+
+const QPixmap* PreviewPixmapFactory::pixmap(int id)
+{
+ if (m_previewPixmapMap.find(id) == 0)
+ {
+ QPixmap pix = makePixmap(id);
+ m_previewPixmapMap.insert(id, new QPixmap(pix));
+ }
+
+ QPixmap* res = m_previewPixmapMap[id];
+
+ return res;
+}
+
+QPixmap PreviewPixmapFactory::makePixmap(int id)
+{
+ return m_bwSepia->getThumbnailForEffect(id);
+}
+
+// -----------------------------------------------------------------------------------
+
+class ListBoxBWPreviewItem : public ListBoxPreviewItem
+{
+
+public:
+
+ ListBoxBWPreviewItem(QListBox *listbox, const QString &text,
+ PreviewPixmapFactory* factory, int id)
+ : ListBoxPreviewItem(listbox, QPixmap(), text)
+ {
+ m_previewPixmapFactory = factory;
+ m_id = id;
+ };
+
+ virtual const QPixmap* pixmap() const;
+
+private:
+
+ int m_id;
+ PreviewPixmapFactory* m_previewPixmapFactory;
+};
+
+const QPixmap* ListBoxBWPreviewItem::pixmap() const
+{
+ return m_previewPixmapFactory->pixmap(m_id);
+}
+
+// -----------------------------------------------------------------------------------
+
+BWSepiaTool::BWSepiaTool(QObject* parent)
+ : EditorTool(parent)
+{
+ setName("convertbw");
+ setToolName(i18n("Black && White"));
+ setToolIcon(SmallIcon("bwtonal"));
+ setToolHelp("blackandwhitetool.anchor");
+
+ m_destinationPreviewData = 0;
+
+ ImageIface iface(0, 0);
+ m_originalImage = iface.getOriginalImg();
+ m_thumbnailImage = m_originalImage->smoothScale(128, 128, QSize::ScaleMin);
+
+ // -------------------------------------------------------------
+
+ m_previewWidget = new ImageWidget("convertbw Tool", 0,
+ i18n("<p>Here you can see the black and white conversion tool preview. "
+ "You can pick color on image "
+ "to see the color level corresponding on histogram."));
+ setToolView(m_previewWidget);
+
+ // -------------------------------------------------------------
+
+ EditorToolSettings *gboxSettings = new EditorToolSettings(EditorToolSettings::Default|
+ EditorToolSettings::Load|
+ EditorToolSettings::SaveAs|
+ EditorToolSettings::Ok|
+ EditorToolSettings::Cancel);
+
+ QGridLayout* gridSettings = new QGridLayout(gboxSettings->plainPage(), 4, 4);
+
+ QLabel *label1 = new QLabel(i18n("Channel:"), gboxSettings->plainPage());
+ label1->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ m_channelCB = new QComboBox(false, gboxSettings->plainPage());
+ m_channelCB->insertItem(i18n("Luminosity"));
+ m_channelCB->insertItem(i18n("Red"));
+ m_channelCB->insertItem(i18n("Green"));
+ m_channelCB->insertItem(i18n("Blue"));
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red image-channel values.<p>"
+ "<b>Green</b>: display the green image-channel values.<p>"
+ "<b>Blue</b>: display the blue image-channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(gboxSettings->plainPage());
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin(0);
+ QWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximal counts are small, you can use the linear scale.<p>"
+ "Logarithmic scale can be used when the maximal counts are big; "
+ "if it is used, all values (small and large) will be visible on the graph."));
+
+ QPushButton *linHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(linHistoButton, i18n("<p>Linear"));
+ m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap(QPixmap(directory + "histogram-lin.png"));
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(logHistoButton, i18n("<p>Logarithmic"));
+ m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap(QPixmap(directory + "histogram-log.png"));
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(gboxSettings->plainPage());
+ m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram drawing "
+ "of the selected image channel. This one is re-computed at any "
+ "settings changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, histoBox);
+ m_hGradient->setColors(QColor("black"), QColor("white"));
+
+ gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4);
+
+ // -------------------------------------------------------------
+
+ m_tab = new KTabWidget(gboxSettings->plainPage());
+
+ m_bwFilm = new QListBox(m_tab);
+ m_bwFilm->setColumnMode(1);
+ m_bwFilm->setVariableWidth(false);
+ m_bwFilm->setVariableHeight(false);
+ ListBoxWhatsThis* whatsThis2 = new ListBoxWhatsThis(m_bwFilm);
+ m_previewPixmapFactory = new PreviewPixmapFactory(this);
+
+ int type = BWGeneric;
+
+ ListBoxBWPreviewItem *item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Generic"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Generic</b>:"
+ "<p>Simulate a generic black and white film</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Agfa 200X"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Agfa 200X</b>:"
+ "<p>Simulate the Agfa 200X black and white film at 200 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Agfa Pan 25"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Agfa Pan 25</b>:"
+ "<p>Simulate the Agfa Pan black and white film at 25 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Agfa Pan 100"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Agfa Pan 100</b>:"
+ "<p>Simulate the Agfa Pan black and white film at 100 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Agfa Pan 400"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Agfa Pan 400</b>:"
+ "<p>Simulate the Agfa Pan black and white film at 400 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford Delta 100"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford Delta 100</b>:"
+ "<p>Simulate the Ilford Delta black and white film at 100 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford Delta 400"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford Delta 400</b>:"
+ "<p>Simulate the Ilford Delta black and white film at 400 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford Delta 400 Pro 3200"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford Delta 400 Pro 3200</b>:"
+ "<p>Simulate the Ilford Delta 400 Pro black and white film at 3200 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford FP4 Plus"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford FP4 Plus</b>:"
+ "<p>Simulate the Ilford FP4 Plus black and white film at 125 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford HP5 Plus"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford HP5 Plus</b>:"
+ "<p>Simulate the Ilford HP5 Plus black and white film at 400 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford PanF Plus"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford PanF Plus</b>:"
+ "<p>Simulate the Ilford PanF Plus black and white film at 50 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford XP2 Super"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford XP2 Super</b>:"
+ "<p>Simulate the Ilford XP2 Super black and white film at 400 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Kodak Tmax 100"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Kodak Tmax 100</b>:"
+ "<p>Simulate the Kodak Tmax black and white film at 100 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Kodak Tmax 400"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Kodak Tmax 400</b>:"
+ "<p>Simulate the Kodak Tmax black and white film at 400 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Kodak TriX"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Kodak TriX</b>:"
+ "<p>Simulate the Kodak TriX black and white film at 400 ISO</p>"));
+
+ // -------------------------------------------------------------
+
+ QVBox *vbox = new QVBox(m_tab);
+
+ m_bwFilters = new QListBox(vbox);
+ m_bwFilters->setColumnMode(1);
+ m_bwFilters->setVariableWidth(false);
+ m_bwFilters->setVariableHeight(false);
+ ListBoxWhatsThis* whatsThis = new ListBoxWhatsThis(m_bwFilters);
+
+ type = BWNoFilter;
+
+ item = new ListBoxBWPreviewItem(m_bwFilters,
+ i18n("No Lens Filter"), m_previewPixmapFactory, type);
+ whatsThis->add( item, i18n("<b>No Lens Filter</b>:"
+ "<p>Do not apply a lens filter when rendering the image.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilters, i18n("Green Filter"), m_previewPixmapFactory, type);
+ whatsThis->add( item, i18n("<b>Black & White with Green Filter</b>:"
+ "<p>Simulate black and white film exposure using a green filter. "
+ "This is usefule for all scenic shoots, especially portraits "
+ "photographed against the sky.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilters, i18n("Orange Filter"), m_previewPixmapFactory, type);
+ whatsThis->add( item, i18n("<b>Black & White with Orange Filter</b>:"
+ "<p>Simulate black and white film exposure using an orange filter. "
+ "This will enhance landscapes, marine scenes and aerial "
+ "photography.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilters, i18n("Red Filter"), m_previewPixmapFactory, type);
+ whatsThis->add( item, i18n("<b>Black & White with Red Filter</b>:"
+ "<p>Simulate black and white film exposure using a red filter. "
+ "This creates dramatic sky effects, and simulates moonlight scenes "
+ "in the daytime.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilters, i18n("Yellow Filter"), m_previewPixmapFactory, type);
+ whatsThis->add( item, i18n("<b>Black & White with Yellow Filter</b>:"
+ "<p>Simulate black and white film exposure using a yellow filter. "
+ "This has the most natural tonal correction, and improves contrast. Ideal for "
+ "landscapes.</p>"));
+
+ m_strengthInput = new RIntNumInput(vbox);
+ m_strengthInput->input()->setLabel(i18n("Strength:"), AlignLeft | AlignVCenter);
+ m_strengthInput->setRange(1, 5, 1);
+ m_strengthInput->setDefaultValue(1);
+ QWhatsThis::add(m_strengthInput, i18n("<p>Here, set the strength adjustment of the lens filter."));
+
+ // -------------------------------------------------------------
+
+ m_bwTone = new QListBox(m_tab);
+ m_bwTone->setColumnMode(1);
+ m_bwTone->setVariableWidth(false);
+ m_bwTone->setVariableHeight(false);
+ ListBoxWhatsThis* whatsThis3 = new ListBoxWhatsThis(m_bwTone);
+
+ type = BWNoTone;
+
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("No Tone Filter"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>No Tone Filter</b>:"
+ "<p>Do not apply a tone filter to the image.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("Sepia Tone"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>Black & White with Sepia Tone</b>:"
+ "<p>Gives a warm highlight and mid-tone while adding a bit of coolness to "
+ "the shadows - very similar to the process of bleaching a print and "
+ "re-developing in a sepia toner.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("Brown Tone"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>Black & White with Brown Tone</b>:"
+ "<p>This filter is more neutral than the Sepia Tone "
+ "filter.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("Cold Tone"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>Black & White with Cold Tone</b>:"
+ "<p>Start subtle and replicates printing on a cold tone black and white "
+ "paper such as a bromide enlarging "
+ "paper.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("Selenium Tone"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>Black & White with Selenium Tone</b>:"
+ "<p>This effect replicates traditional selenium chemical toning done "
+ "in the darkroom.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("Platinum Tone"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>Black & White with Platinum Tone</b>:"
+ "<p>This effect replicates traditional platinum chemical toning done "
+ "in the darkroom.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("Green Tone"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>Black & White with greenish tint</b>:"
+ "<p>This effect is also known as Verdante.</p>"));
+
+ // -------------------------------------------------------------
+
+ QWidget *curveBox = new QWidget( m_tab );
+ QGridLayout *gridTab2 = new QGridLayout(curveBox, 5, 2, 0);
+
+ ColorGradientWidget* vGradient = new ColorGradientWidget(
+ ColorGradientWidget::Vertical,
+ 10, curveBox);
+ vGradient->setColors(QColor("white"), QColor("black"));
+
+ QLabel *spacev = new QLabel(curveBox);
+ spacev->setFixedWidth(1);
+
+ m_curvesWidget = new CurvesWidget(256, 256, m_originalImage->bits(), m_originalImage->width(),
+ m_originalImage->height(), m_originalImage->sixteenBit(),
+ curveBox);
+ QWhatsThis::add( m_curvesWidget, i18n("<p>This is the curve adjustment of the image luminosity"));
+
+ QLabel *spaceh = new QLabel(curveBox);
+ spaceh->setFixedHeight(1);
+
+ ColorGradientWidget *hGradient = new ColorGradientWidget(
+ ColorGradientWidget::Horizontal,
+ 10, curveBox);
+ hGradient->setColors(QColor("black"), QColor("white"));
+
+ m_cInput = new RIntNumInput(curveBox);
+ m_cInput->input()->setLabel(i18n("Contrast:"), AlignLeft | AlignVCenter);
+ m_cInput->setRange(-100, 100, 1);
+ m_cInput->setDefaultValue(0);
+ QWhatsThis::add( m_cInput, i18n("<p>Set here the contrast adjustment of the image."));
+
+ gridTab2->addMultiCellWidget(vGradient, 0, 0, 0, 0);
+ gridTab2->addMultiCellWidget(spacev, 0, 0, 1, 1);
+ gridTab2->addMultiCellWidget(m_curvesWidget, 0, 0, 2, 2);
+ gridTab2->addMultiCellWidget(spaceh, 1, 1, 2, 2);
+ gridTab2->addMultiCellWidget(hGradient, 2, 2, 2, 2);
+ gridTab2->addMultiCellWidget(m_cInput, 4, 4, 0, 2);
+// gridTab2->setRowSpacing(3);
+ gridTab2->setRowStretch(5, 10);
+
+ // -------------------------------------------------------------
+
+ m_tab->insertTab(m_bwFilm, i18n("Film"), FilmTab);
+ m_tab->insertTab(vbox, i18n("Lens Filters"), BWFiltersTab);
+ m_tab->insertTab(m_bwTone, i18n("Tone"), ToneTab);
+ m_tab->insertTab(curveBox, i18n("Lightness"), LuminosityTab);
+
+ gridSettings->addMultiCellWidget(m_tab, 3, 3, 0, 4);
+ gridSettings->setRowStretch(3, 10);
+ setToolSettings(gboxSettings);
+ init();
+
+ // -------------------------------------------------------------
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromOriginal(const Digikam::DColor&, const QPoint&)),
+ this, SLOT(slotSpotColorChanged(const Digikam::DColor&)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const QPoint & )),
+ this, SLOT(slotColorSelectedFromTarget( const Digikam::DColor & )));
+
+ connect(m_bwFilters, SIGNAL(highlighted(int)),
+ this, SLOT(slotFilterSelected(int)));
+
+ connect(m_strengthInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_bwFilm, SIGNAL(highlighted(int)),
+ this, SLOT(slotEffect()));
+
+ connect(m_bwTone, SIGNAL(highlighted(int)),
+ this, SLOT(slotEffect()));
+
+ connect(m_curvesWidget, SIGNAL(signalCurvesChanged()),
+ this, SLOT(slotTimer()));
+
+ connect(m_cInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+}
+
+BWSepiaTool::~BWSepiaTool()
+{
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+}
+
+void BWSepiaTool::slotFilterSelected(int filter)
+{
+ if (filter == BWNoFilter)
+ m_strengthInput->setEnabled(false);
+ else
+ m_strengthInput->setEnabled(true);
+
+ slotEffect();
+}
+
+QPixmap BWSepiaTool::getThumbnailForEffect(int type)
+{
+ DImg thumb = m_thumbnailImage.copy();
+ int w = thumb.width();
+ int h = thumb.height();
+ bool sb = thumb.sixteenBit();
+ bool a = thumb.hasAlpha();
+
+ if (type < BWGeneric)
+ {
+ // In Filter view, we will render a preview of the B&W filter with the generic B&W film.
+ blackAndWhiteConversion(thumb.bits(), w, h, sb, type);
+ blackAndWhiteConversion(thumb.bits(), w, h, sb, BWGeneric);
+ }
+ else
+ {
+ // In Film and Tone view, we will render the preview without to use the B&W Filter
+ blackAndWhiteConversion(thumb.bits(), w, h, sb, type);
+ }
+
+ if (m_curvesWidget->curves()) // in case we're called before the creator is done
+ {
+ uchar *targetData = new uchar[w*h*(sb ? 8 : 4)];
+ m_curvesWidget->curves()->curvesLutSetup(ImageHistogram::AlphaChannel);
+ m_curvesWidget->curves()->curvesLutProcess(thumb.bits(), targetData, w, h);
+
+ DImg preview(w, h, sb, a, targetData);
+ BCGModifier cmod;
+ cmod.setContrast((double)(m_cInput->value()/100.0) + 1.00);
+ cmod.applyBCG(preview);
+
+ thumb.putImageData(preview.bits());
+
+ delete [] targetData;
+ }
+ return (thumb.convertToPixmap());
+}
+
+void BWSepiaTool::slotChannelChanged(int channel)
+{
+ switch (channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::ValueHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("white"));
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("red"));
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("green"));
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("blue"));
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void BWSepiaTool::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+ m_curvesWidget->m_scaleType = scale;
+ m_curvesWidget->repaint(false);
+}
+
+void BWSepiaTool::slotSpotColorChanged(const DColor &color)
+{
+ m_curvesWidget->setCurveGuide(color);
+}
+
+void BWSepiaTool::slotColorSelectedFromTarget(const DColor &color)
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void BWSepiaTool::readSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("convertbw Tool");
+
+ m_tab->setCurrentPage(config->readNumEntry("Settings Tab", BWFiltersTab));
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", HistogramWidget::LogScaleHistogram));
+ m_bwFilters->setCurrentItem(config->readNumEntry("BW Filter", 0));
+ m_bwFilm->setCurrentItem(config->readNumEntry("BW Film", 0));
+ m_bwTone->setCurrentItem(config->readNumEntry("BW Tone", 0));
+ m_cInput->setValue(config->readNumEntry("ContrastAjustment", m_cInput->defaultValue()));
+ m_strengthInput->setValue(config->readNumEntry("StrengthAjustment", m_strengthInput->defaultValue()));
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curvesWidget->curves()->curvesChannelReset(i);
+
+ m_curvesWidget->curves()->setCurveType(m_curvesWidget->m_channelType, ImageCurves::CURVE_SMOOTH);
+ m_curvesWidget->reset();
+
+ for (int j = 0 ; j < 17 ; j++)
+ {
+ QPoint disable(-1, -1);
+ QPoint p = config->readPointEntry(QString("CurveAjustmentPoint%1").arg(j), &disable);
+
+ if (m_originalImage->sixteenBit() && p.x() != -1)
+ {
+ p.setX(p.x()*255);
+ p.setY(p.y()*255);
+ }
+
+ m_curvesWidget->curves()->setCurvePoint(ImageHistogram::ValueChannel, j, p);
+ }
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curvesWidget->curves()->curvesCalculateCurve(i);
+
+ m_histogramWidget->reset();
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+ slotFilterSelected(m_bwFilters->currentItem());
+}
+
+void BWSepiaTool::writeSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("convertbw Tool");
+ config->writeEntry("Settings Tab", m_tab->currentPageIndex());
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writeEntry("BW Filter", m_bwFilters->currentItem());
+ config->writeEntry("BW Film", m_bwFilm->currentItem());
+ config->writeEntry("BW Tone", m_bwTone->currentItem());
+ config->writeEntry("ContrastAjustment", m_cInput->value());
+ config->writeEntry("StrengthAjustment", m_strengthInput->value());
+
+ for (int j = 0 ; j < 17 ; j++)
+ {
+ QPoint p = m_curvesWidget->curves()->getCurvePoint(ImageHistogram::ValueChannel, j);
+
+ if (m_originalImage->sixteenBit() && p.x() != -1)
+ {
+ p.setX(p.x()/255);
+ p.setY(p.y()/255);
+ }
+
+ config->writeEntry(QString("CurveAjustmentPoint%1").arg(j), p);
+ }
+
+ m_previewWidget->writeSettings();
+ config->sync();
+}
+
+void BWSepiaTool::slotResetSettings()
+{
+ m_bwFilm->blockSignals(true);
+ m_bwFilters->blockSignals(true);
+ m_bwTone->blockSignals(true);
+ m_cInput->blockSignals(true);
+ m_strengthInput->blockSignals(true);
+
+ m_bwFilm->setCurrentItem(0);
+ m_bwFilm->setSelected(0, true);
+
+ m_bwFilters->setCurrentItem(0);
+ m_bwFilters->setSelected(0, true);
+
+ m_bwTone->setCurrentItem(0);
+ m_bwTone->setSelected(0, true);
+
+ m_cInput->slotReset();
+ m_strengthInput->slotReset();
+
+ for (int channel = 0; channel < 5; channel++)
+ m_curvesWidget->curves()->curvesChannelReset(channel);
+
+ m_curvesWidget->reset();
+
+ m_bwFilm->blockSignals(false);
+ m_bwFilters->blockSignals(false);
+ m_bwTone->blockSignals(false);
+ m_cInput->blockSignals(false);
+ m_strengthInput->blockSignals(false);
+
+ m_histogramWidget->reset();
+ m_previewPixmapFactory->invalidate();
+ m_bwFilters->triggerUpdate(false);
+ m_bwTone->triggerUpdate(false);
+
+ slotEffect();
+}
+
+void BWSepiaTool::slotEffect()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ m_histogramWidget->stopHistogramComputation();
+
+ delete [] m_destinationPreviewData;
+
+ ImageIface* iface = m_previewWidget->imageIface();
+ m_destinationPreviewData = iface->getPreviewImage();
+ int w = iface->previewWidth();
+ int h = iface->previewHeight();
+ bool a = iface->previewHasAlpha();
+ bool sb = iface->previewSixteenBit();
+
+ // Apply black and white filter.
+
+ blackAndWhiteConversion(m_destinationPreviewData, w, h, sb, m_bwFilters->currentItem());
+
+ // Apply black and white film type.
+
+ blackAndWhiteConversion(m_destinationPreviewData, w, h, sb, m_bwFilm->currentItem() + BWGeneric);
+
+ // Apply color tone filter.
+
+ blackAndWhiteConversion(m_destinationPreviewData, w, h, sb, m_bwTone->currentItem() + BWNoTone);
+
+ // Calculate and apply the curve on image.
+
+ uchar *targetData = new uchar[w*h*(sb ? 8 : 4)];
+ m_curvesWidget->curves()->curvesLutSetup(ImageHistogram::AlphaChannel);
+ m_curvesWidget->curves()->curvesLutProcess(m_destinationPreviewData, targetData, w, h);
+
+ // Adjust contrast.
+
+ DImg preview(w, h, sb, a, targetData);
+ BCGModifier cmod;
+ cmod.setContrast((double)(m_cInput->value()/100.0) + 1.00);
+ cmod.applyBCG(preview);
+ iface->putPreviewImage(preview.bits());
+
+ m_previewWidget->updatePreview();
+
+ // Update histogram.
+
+ memcpy(m_destinationPreviewData, preview.bits(), preview.numBytes());
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false);
+ delete [] targetData;
+
+ kapp->restoreOverrideCursor();
+}
+
+void BWSepiaTool::finalRendering()
+{
+ kapp->setOverrideCursor(KCursor::waitCursor());
+ ImageIface* iface = m_previewWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int w = iface->originalWidth();
+ int h = iface->originalHeight();
+ bool a = iface->originalHasAlpha();
+ bool sb = iface->originalSixteenBit();
+
+ if (data)
+ {
+ // Apply black and white filter.
+
+ blackAndWhiteConversion(data, w, h, sb, m_bwFilters->currentItem());
+
+ // Apply black and white film type.
+
+ blackAndWhiteConversion(data, w, h, sb, m_bwFilm->currentItem() + BWGeneric);
+
+ // Apply color tone filter.
+
+ blackAndWhiteConversion(data, w, h, sb, m_bwTone->currentItem() + BWNoTone);
+
+ // Calculate and apply the curve on image.
+
+ uchar *targetData = new uchar[w*h*(sb ? 8 : 4)];
+ m_curvesWidget->curves()->curvesLutSetup(ImageHistogram::AlphaChannel);
+ m_curvesWidget->curves()->curvesLutProcess(data, targetData, w, h);
+
+ // Adjust contrast.
+
+ DImg img(w, h, sb, a, targetData);
+ BCGModifier cmod;
+ cmod.setContrast((double)(m_cInput->value()/100.0) + 1.00);
+ cmod.applyBCG(img);
+
+ iface->putOriginalImage(i18n("Convert to Black && White"), img.bits());
+
+ delete [] data;
+ delete [] targetData;
+ }
+
+ kapp->restoreOverrideCursor();
+}
+
+void BWSepiaTool::blackAndWhiteConversion(uchar *data, int w, int h, bool sb, int type)
+{
+ // Value to multiply RGB 8 bits component of mask used by changeTonality() method.
+ int mul = sb ? 255 : 1;
+ DImgImageFilters filter;
+ double strength = 1.0 + ((double)m_strengthInput->value() - 1.0) * (1.0 / 3.0);
+
+ switch (type)
+ {
+ case BWNoFilter:
+ m_redAttn = 0.0;
+ m_greenAttn = 0.0;
+ m_blueAttn = 0.0;
+ break;
+
+ case BWGreenFilter:
+ m_redAttn = -0.20 * strength;
+ m_greenAttn = +0.11 * strength;
+ m_blueAttn = +0.09 * strength;
+ break;
+
+ case BWOrangeFilter:
+ m_redAttn = +0.48 * strength;
+ m_greenAttn = -0.37 * strength;
+ m_blueAttn = -0.11 * strength;
+ break;
+
+ case BWRedFilter:
+ m_redAttn = +0.60 * strength;
+ m_greenAttn = -0.49 * strength;
+ m_blueAttn = -0.11 * strength;
+ break;
+
+ case BWYellowFilter:
+ m_redAttn = +0.30 * strength;
+ m_greenAttn = -0.31 * strength;
+ m_blueAttn = +0.01 * strength;
+ break;
+
+ // --------------------------------------------------------------------------------
+
+ case BWGeneric:
+ case BWNoTone:
+ m_redMult = 0.24;
+ m_greenMult = 0.68;
+ m_blueMult = 0.08;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWAgfa200X:
+ m_redMult = 0.18;
+ m_greenMult = 0.41;
+ m_blueMult = 0.41;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWAgfapan25:
+ m_redMult = 0.25;
+ m_greenMult = 0.39;
+ m_blueMult = 0.36;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWAgfapan100:
+ m_redMult = 0.21;
+ m_greenMult = 0.40;
+ m_blueMult = 0.39;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWAgfapan400:
+ m_redMult = 0.20;
+ m_greenMult = 0.41;
+ m_blueMult = 0.39;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordDelta100:
+ m_redMult = 0.21;
+ m_greenMult = 0.42;
+ m_blueMult = 0.37;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordDelta400:
+ m_redMult = 0.22;
+ m_greenMult = 0.42;
+ m_blueMult = 0.36;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordDelta400Pro3200:
+ m_redMult = 0.31;
+ m_greenMult = 0.36;
+ m_blueMult = 0.33;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordFP4:
+ m_redMult = 0.28;
+ m_greenMult = 0.41;
+ m_blueMult = 0.31;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordHP5:
+ m_redMult = 0.23;
+ m_greenMult = 0.37;
+ m_blueMult = 0.40;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordPanF:
+ m_redMult = 0.33;
+ m_greenMult = 0.36;
+ m_blueMult = 0.31;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordXP2Super:
+ m_redMult = 0.21;
+ m_greenMult = 0.42;
+ m_blueMult = 0.37;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWKodakTmax100:
+ m_redMult = 0.24;
+ m_greenMult = 0.37;
+ m_blueMult = 0.39;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWKodakTmax400:
+ m_redMult = 0.27;
+ m_greenMult = 0.36;
+ m_blueMult = 0.37;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWKodakTriX:
+ m_redMult = 0.25;
+ m_greenMult = 0.35;
+ m_blueMult = 0.40;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ // --------------------------------------------------------------------------------
+
+ case BWSepiaTone:
+ filter.changeTonality(data, w, h, sb, 162*mul, 132*mul, 101*mul);
+ break;
+
+ case BWBrownTone:
+ filter.changeTonality(data, w, h, sb, 129*mul, 115*mul, 104*mul);
+ break;
+
+ case BWColdTone:
+ filter.changeTonality(data, w, h, sb, 102*mul, 109*mul, 128*mul);
+ break;
+
+ case BWSeleniumTone:
+ filter.changeTonality(data, w, h, sb, 122*mul, 115*mul, 122*mul);
+ break;
+
+ case BWPlatinumTone:
+ filter.changeTonality(data, w, h, sb, 115*mul, 110*mul, 106*mul);
+ break;
+
+ case BWGreenTone:
+ filter.changeTonality(data, w, h, sb, 108*mul, 116*mul, 100*mul);
+ break;
+
+ }
+}
+
+//-- Load all settings from file --------------------------------------
+
+void BWSepiaTool::slotLoadSettings()
+{
+ KURL loadFile = KFileDialog::getOpenURL(KGlobalSettings::documentPath(),
+ QString( "*" ), kapp->activeWindow(),
+ QString( i18n("Black & White Settings File to Load")) );
+ if( loadFile.isEmpty() )
+ return;
+
+ QFile file(loadFile.path());
+
+ if (file.open(IO_ReadOnly))
+ {
+ QTextStream stream(&file);
+
+ if (stream.readLine() != "# Black & White Configuration File")
+ {
+ KMessageBox::error(kapp->activeWindow(),
+ i18n("\"%1\" is not a Black & White settings text file.")
+ .arg(loadFile.fileName()));
+ file.close();
+ return;
+ }
+
+ m_bwFilters->blockSignals(true);
+ m_bwTone->blockSignals(true);
+ m_cInput->blockSignals(true);
+
+ m_bwFilters->setCurrentItem(stream.readLine().toInt());
+ m_bwTone->setCurrentItem(stream.readLine().toInt());
+ m_cInput->setValue(stream.readLine().toInt());
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curvesWidget->curves()->curvesChannelReset(i);
+
+ m_curvesWidget->curves()->setCurveType(m_curvesWidget->m_channelType, ImageCurves::CURVE_SMOOTH);
+ m_curvesWidget->reset();
+
+ for (int j = 0; j < 17; j++)
+ {
+ QPoint disable(-1, -1);
+ QPoint p;
+ p.setX(stream.readLine().toInt());
+ p.setY(stream.readLine().toInt());
+
+ if (m_originalImage->sixteenBit() && p != disable)
+ {
+ p.setX(p.x()*255);
+ p.setY(p.y()*255);
+ }
+
+ m_curvesWidget->curves()->setCurvePoint(ImageHistogram::ValueChannel, j, p);
+ }
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curvesWidget->curves()->curvesCalculateCurve(i);
+
+ m_bwFilters->blockSignals(false);
+ m_bwTone->blockSignals(false);
+ m_cInput->blockSignals(false);
+
+ m_histogramWidget->reset();
+ m_previewPixmapFactory->invalidate();
+ m_bwFilters->triggerUpdate(false);
+ m_bwTone->triggerUpdate(false);
+
+ slotEffect();
+ }
+ else
+ KMessageBox::error(kapp->activeWindow(),
+ i18n("Cannot load settings from the Black & White text file."));
+
+ file.close();
+}
+
+//-- Save all settings to file ---------------------------------------
+
+void BWSepiaTool::slotSaveAsSettings()
+{
+ KURL saveFile = KFileDialog::getSaveURL(KGlobalSettings::documentPath(),
+ QString( "*" ), kapp->activeWindow(),
+ QString( i18n("Black & White Settings File to Save")));
+ if( saveFile.isEmpty() )
+ return;
+
+ QFile file(saveFile.path());
+
+ if (file.open(IO_WriteOnly))
+ {
+ QTextStream stream(&file);
+ stream << "# Black & White Configuration File\n";
+ stream << m_bwFilters->currentItem() << "\n";
+ stream << m_bwTone->currentItem() << "\n";
+ stream << m_cInput->value() << "\n";
+
+ for (int j = 0; j < 17; j++)
+ {
+ QPoint p = m_curvesWidget->curves()->getCurvePoint(ImageHistogram::ValueChannel, j);
+ if (m_originalImage->sixteenBit())
+ {
+ p.setX(p.x() / 255);
+ p.setY(p.y() / 255);
+ }
+ stream << p.x() << "\n";
+ stream << p.y() << "\n";
+ }
+ }
+ else
+ KMessageBox::error(kapp->activeWindow(),
+ i18n("Cannot save settings to the Black & White text file."));
+
+ file.close();
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/bwsepiatool.h b/digikam/imageplugins/coreplugin/bwsepiatool.h
new file mode 100644
index 0000000..476281b
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/bwsepiatool.h
@@ -0,0 +1,192 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-12-06
+ * Description : Black and White conversion tool.
+ *
+ * Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * Copyright (C) 2006-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 BWSEPIATOOL_H
+#define BWSEPIATOOL_H
+
+// Qt includes.
+
+#include <qstring.h>
+
+// Digikam includes.
+
+#include "editortool.h"
+
+class QHButtonGroup;
+class QComboBox;
+class QButtonGroup;
+class QListBox;
+
+class KTabWidget;
+
+namespace KDcrawIface
+{
+class RIntNumInput;
+}
+
+namespace Digikam
+{
+class HistogramWidget;
+class ColorGradientWidget;
+class ImageWidget;
+class DColor;
+class DImg;
+class CurvesWidget;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class PreviewPixmapFactory;
+
+class BWSepiaTool : public Digikam::EditorTool
+{
+ Q_OBJECT
+
+public:
+
+ BWSepiaTool(QObject *parent);
+ ~BWSepiaTool();
+
+ friend class PreviewPixmapFactory;
+
+protected:
+
+ QPixmap getThumbnailForEffect(int type);
+ void finalRendering();
+
+private:
+
+ void readSettings();
+ void writeSettings();
+ void blackAndWhiteConversion(uchar *data, int w, int h, bool sb, int type);
+
+private slots:
+
+ void slotResetSettings();
+ void slotSaveAsSettings();
+ void slotLoadSettings();
+ void slotEffect();
+ void slotChannelChanged(int channel);
+ void slotScaleChanged(int scale);
+ void slotSpotColorChanged(const Digikam::DColor &color);
+ void slotColorSelectedFromTarget( const Digikam::DColor &color );
+ void slotFilterSelected(int filter);
+
+private:
+
+ enum BlackWhiteConversionType
+ {
+ BWNoFilter=0, // B&W filter to the front of lens.
+ BWGreenFilter,
+ BWOrangeFilter,
+ BWRedFilter,
+ BWYellowFilter,
+
+ BWGeneric, // B&W film simulation.
+ BWAgfa200X,
+ BWAgfapan25,
+ BWAgfapan100,
+ BWAgfapan400,
+ BWIlfordDelta100,
+ BWIlfordDelta400,
+ BWIlfordDelta400Pro3200,
+ BWIlfordFP4,
+ BWIlfordHP5,
+ BWIlfordPanF,
+ BWIlfordXP2Super,
+ BWKodakTmax100,
+ BWKodakTmax400,
+ BWKodakTriX,
+
+ BWNoTone, // Chemical color tone filter.
+ BWSepiaTone,
+ BWBrownTone,
+ BWColdTone,
+ BWSeleniumTone,
+ BWPlatinumTone,
+ BWGreenTone
+ };
+
+ enum HistogramScale
+ {
+ Linear=0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel=0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ enum SettingsTab
+ {
+ FilmTab=0,
+ BWFiltersTab,
+ ToneTab,
+ LuminosityTab
+ };
+
+ // Color filter attenuation in percents.
+ double m_redAttn, m_greenAttn, m_blueAttn;
+
+ // Channel mixer color multiplier.
+ double m_redMult, m_greenMult, m_blueMult;
+
+ uchar *m_destinationPreviewData;
+
+ QComboBox *m_channelCB;
+
+ QHButtonGroup *m_scaleBG;
+
+ QListBox *m_bwFilters;
+ QListBox *m_bwFilm;
+ QListBox *m_bwTone;
+
+ KDcrawIface::RIntNumInput *m_cInput;
+ KDcrawIface::RIntNumInput *m_strengthInput;
+
+ KTabWidget *m_tab;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+
+ Digikam::CurvesWidget *m_curvesWidget;
+
+ Digikam::DImg *m_originalImage;
+ Digikam::DImg m_thumbnailImage;
+
+ PreviewPixmapFactory *m_previewPixmapFactory;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* BWSEPIATOOL_H */
diff --git a/digikam/imageplugins/coreplugin/digikamimageplugin_core.desktop b/digikam/imageplugins/coreplugin/digikamimageplugin_core.desktop
new file mode 100644
index 0000000..5d80a0b
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/digikamimageplugin_core.desktop
@@ -0,0 +1,47 @@
+[Desktop Entry]
+Name=ImagePlugin_Core
+Name[el]=ΠρόσθετοΕικόνας_Πυρήνας
+Name[fi]=Liitännäisten ydin
+Name[hr]=Jezgra
+Name[it]=PluginImmagini_Nocciolo
+Name[nl]=Afbeeldingsplugin_Kern
+Name[sr]=Језгро прикључака
+Name[sr@Latn]=Jezgro priključaka
+Name[sv]=Insticksprogram med bildkärna
+Name[tr]=ResimEklentisi_Çekirdek
+Name[xx]=xxImagePlugin_Corexx
+Type=Service
+ServiceTypes=Digikam/ImagePlugin
+Encoding=UTF-8
+Comment=digiKam Core Image Plugin
+Comment[bg]=Основна приставка за снимки на digiKam
+Comment[ca]=Connector d'imatges bàsic del digiKam
+Comment[da]=Grundlæggende Digikam billed-plugin
+Comment[de]=digiKam-Kernmodul
+Comment[el]=Πρόσθετο εικόνων πυρήνα digiKam
+Comment[es]=Plugin fundamental de digiKam de imágenes
+Comment[et]=DigiKami peamine pildiplugin
+Comment[fa]=وصلۀ تصویر هستۀ digiKam
+Comment[fi]=digiKamin liitännäisten ydin
+Comment[gl]=Plugin de Imaxe Básico de digiKam
+Comment[hr]=digiKam dodatak za slike
+Comment[it]=Plugin delle immagini centrale di digiKam
+Comment[ja]=digiKam コア画像プラグイン
+Comment[nds]=Karn-Bildmoduul vun digiKam
+Comment[nl]=Digikam kernafbeeldingsplugin
+Comment[pa]=ਡਿਜ਼ੀਕੈਮ ਕੋਰ ਚਿੱਤਰ ਪਲੱਗਇਨ
+Comment[pl]=Podstawowa wtyczka obrazu digiKama
+Comment[pt]='Plugin' de Imagem Básico do digiKam
+Comment[pt_BR]=Plugin digiKam para Centralização da imagem
+Comment[ru]=Модуль digiKam основная работа с изображением
+Comment[sk]=Základný obrázkový plugin digiKamu
+Comment[sr]=Језгро digiKam-ових сликовних прикључака
+Comment[sr@Latn]=Jezgro digiKam-ovih slikovnih priključaka
+Comment[sv]=Insticksprogram med bildkärna för Digikam
+Comment[tr]=digiKam Çekirdek Resim Eklentisi
+Comment[uk]=Втулок основи зображення для digiKam
+Comment[vi]=Phần bổ sung ảnh lõi digiKam
+Comment[xx]=xxdigiKam Core Image Pluginxx
+
+X-KDE-Library=digikamimageplugin_core
+author=Caulier Gilles, caulier dot gilles at gmail dot com
diff --git a/digikam/imageplugins/coreplugin/digikamimageplugin_core_ui.rc b/digikam/imageplugins/coreplugin/digikamimageplugin_core_ui.rc
new file mode 100644
index 0000000..cb1148b
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/digikamimageplugin_core_ui.rc
@@ -0,0 +1,56 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui version="7" name="digikamimageplugin_core" >
+
+ <MenuBar>
+
+ <Menu name="Color"><text>&amp;Color</text>
+ <Action name="implugcore_autocorrection" />
+ <Action name="imageplugin_whitebalance" />
+ <Action name="implugcore_bcg" />
+ <Action name="implugcore_hsl" />
+ <Action name="imageplugin_colorfx" />
+ <Action name="implugcore_rgb" />
+ <Separator />
+ <Action name="imageplugin_adjustcurves" />
+ <Action name="imageplugin_adjustlevels" />
+ <Action name="implugcore_invert" />
+ <Action name="implugcore_blackwhite" />
+ <Menu name="Depth"><text>&amp;Depth</text>
+ <Action name="implugcore_convertto8bits" />
+ <Action name="implugcore_convertto16bits" />
+ </Menu>
+ <Separator />
+ <Action name="implugcore_colormanagement" />
+ <Separator />
+ </Menu>
+ <Menu name="Enhance"><text>Enh&amp;ance</text>
+ <Action name="implugcore_sharpen" />
+ <Action name="implugcore_blur" />
+ <Separator />
+ <Action name="implugcore_redeye" />
+ </Menu>
+
+ <Menu name="Transform" ><text>Tra&amp;nsform</text>
+ <Action name="implugcore_ratiocrop" />
+ </Menu>
+
+ <Menu name="Filters" ><text>F&amp;ilters</text>
+ <Action name="imageplugin_infrared" />
+ <Action name="imageplugin_filmgrain" />
+ <Action name="imageplugin_oilpaint" />
+ <Action name="imageplugin_charcoal" />
+ <Action name="imageplugin_emboss" />
+ <Action name="imageplugin_distortionfx" />
+ <Action name="imageplugin_blurfx" />
+ <Action name="imageplugin_raindrop" />
+ </Menu>
+
+ </MenuBar>
+
+ <ToolBar name="ToolBar" >
+ <text>Main Toolbar</text>
+ </ToolBar>
+
+ <ActionProperties/>
+
+</kpartgui>
diff --git a/digikam/imageplugins/coreplugin/hsl/Makefile.am b/digikam/imageplugins/coreplugin/hsl/Makefile.am
new file mode 100644
index 0000000..b349cca
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/hsl/Makefile.am
@@ -0,0 +1,26 @@
+noinst_LTLIBRARIES = libhsl.la
+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)
+
+libhsl_la_SOURCES = hsltool.cpp hspreviewwidget.cpp
+
+libhsl_la_LDFLAGS = $(all_libraries)
+
+noinst_HEADERS = hsltool.h hspreviewwidget.h
+
diff --git a/digikam/imageplugins/coreplugin/hsl/hsltool.cpp b/digikam/imageplugins/coreplugin/hsl/hsltool.cpp
new file mode 100644
index 0000000..5a9d521
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/hsl/hsltool.cpp
@@ -0,0 +1,453 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-16
+ * Description : digiKam image editor to adjust Hue, Saturation,
+ * and Lightness of picture.
+ *
+ * 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qcolor.h>
+#include <qcombobox.h>
+#include <qframe.h>
+#include <qgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qhgroupbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qtimer.h>
+#include <qtooltip.h>
+#include <qvbox.h>
+#include <qvgroupbox.h>
+#include <qwhatsthis.h>
+
+// KDE includes.
+
+#include <kapplication.h>
+#include <kcolordialog.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+// LibKDcraw includes.
+
+#include <libkdcraw/rnuminput.h>
+
+// Digikam includes.
+
+#include "colorgradientwidget.h"
+#include "dimg.h"
+#include "editortoolsettings.h"
+#include "histogramwidget.h"
+#include "hslmodifier.h"
+#include "hspreviewwidget.h"
+#include "imageiface.h"
+#include "imagewidget.h"
+
+// Local includes.
+
+#include "hsltool.h"
+#include "hsltool.moc"
+
+using namespace KDcrawIface;
+using namespace Digikam;
+
+namespace DigikamImagesPluginCore
+{
+
+HSLTool::HSLTool(QObject* parent)
+ : EditorTool(parent)
+{
+ setName("adjusthsl");
+ setToolName(i18n("Hue / Saturation / Lightness"));
+ setToolIcon(SmallIcon("adjusthsl"));
+ setToolHelp("hsladjusttool.anchor");
+
+ m_destinationPreviewData = 0;
+
+ ImageIface iface(0, 0);
+ m_originalImage = iface.getOriginalImg();
+
+ m_previewWidget = new ImageWidget("hsladjust Tool", 0,
+ i18n("<p>Here you can see the image "
+ "Hue/Saturation/Lightness adjustments preview. "
+ "You can pick color on image "
+ "to see the color level corresponding on histogram."));
+ setToolView(m_previewWidget);
+
+ // -------------------------------------------------------------
+
+ m_gboxSettings = new EditorToolSettings(EditorToolSettings::Default|
+ EditorToolSettings::Ok|
+ EditorToolSettings::Cancel);
+
+ QGridLayout* gridSettings = new QGridLayout(m_gboxSettings->plainPage(), 11, 4);
+
+ QLabel *label1 = new QLabel(i18n("Channel:"), m_gboxSettings->plainPage());
+ label1->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ m_channelCB = new QComboBox(false, m_gboxSettings->plainPage());
+ m_channelCB->insertItem(i18n("Luminosity"));
+ m_channelCB->insertItem(i18n("Red"));
+ m_channelCB->insertItem(i18n("Green"));
+ m_channelCB->insertItem(i18n("Blue"));
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red image-channel values.<p>"
+ "<b>Green</b>: display the green image-channel values.<p>"
+ "<b>Blue</b>: display the blue image-channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(m_gboxSettings->plainPage());
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin( 0 );
+ QWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximal counts are small, you can use the linear scale.<p>"
+ "Logarithmic scale can be used when the maximal counts are big; "
+ "if it is used, all values (small and large) will be visible on the graph."));
+
+ QPushButton *linHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(linHistoButton, i18n("<p>Linear"));
+ m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap(QPixmap(directory + "histogram-lin.png"));
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(logHistoButton, i18n("<p>Logarithmic"));
+ m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap(QPixmap(directory + "histogram-log.png"));
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(m_gboxSettings->plainPage());
+ m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram drawing "
+ "of the selected image channel. This one is re-computed at any "
+ "settings changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, histoBox);
+ m_hGradient->setColors(QColor("black"), QColor("white"));
+
+ gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4);
+
+ // -------------------------------------------------------------
+
+ m_HSSelector = new KHSSelector(m_gboxSettings->plainPage());
+ QWhatsThis::add( m_HSSelector, i18n("<p>Select the hue and saturation adjustments of the image here."));
+ m_HSSelector->setMinimumSize(256, 142);
+ gridSettings->addMultiCellWidget(m_HSSelector, 3, 3, 0, 4);
+
+ m_HSPreview = new HSPreviewWidget(m_gboxSettings->plainPage());
+ QWhatsThis::add( m_HSPreview, i18n("<p>You can see here a color preview of the hue and "
+ "saturation adjustments."));
+ m_HSPreview->setMinimumSize(256, 15);
+ gridSettings->addMultiCellWidget(m_HSPreview, 4, 4, 0, 4);
+
+ QLabel *label2 = new QLabel(i18n("Hue:"), m_gboxSettings->plainPage());
+ m_hInput = new RDoubleNumInput(m_gboxSettings);
+ m_hInput->setPrecision(0);
+ m_hInput->setRange(-180.0, 180.0, 1.0);
+ m_hInput->setDefaultValue(0.0);
+ QWhatsThis::add( m_hInput, i18n("<p>Set here the hue adjustment of the image."));
+ gridSettings->addMultiCellWidget(label2, 5, 5, 0, 4);
+ gridSettings->addMultiCellWidget(m_hInput, 6, 6, 0, 4);
+
+ QLabel *label3 = new QLabel(i18n("Saturation:"), m_gboxSettings->plainPage());
+ m_sInput = new RDoubleNumInput(m_gboxSettings);
+ m_sInput->setPrecision(2);
+ m_sInput->setRange(-100.0, 100.0, 0.01);
+ m_sInput->setDefaultValue(0.0);
+ QWhatsThis::add( m_sInput, i18n("<p>Set here the saturation adjustment of the image."));
+ gridSettings->addMultiCellWidget(label3, 7, 7, 0, 4);
+ gridSettings->addMultiCellWidget(m_sInput, 8, 8, 0, 4);
+
+ QLabel *label4 = new QLabel(i18n("Lightness:"), m_gboxSettings->plainPage());
+ m_lInput = new RDoubleNumInput(m_gboxSettings->plainPage());
+ m_lInput->setPrecision(2);
+ m_lInput->setRange(-100.0, 100.0, 0.01);
+ m_lInput->setDefaultValue(0.0);
+ QWhatsThis::add( m_lInput, i18n("<p>Set here the lightness adjustment of the image."));
+ gridSettings->addMultiCellWidget(label4, 9, 9, 0, 4);
+ gridSettings->addMultiCellWidget(m_lInput, 10, 10, 0, 4);
+
+ gridSettings->setRowStretch(11, 10);
+ setToolSettings(m_gboxSettings);
+ init();
+
+ // -------------------------------------------------------------
+
+ connect(m_HSSelector, SIGNAL(valueChanged(int, int)),
+ this, SLOT(slotHSChanged(int, int)));
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const QPoint & )),
+ this, SLOT(slotColorSelectedFromTarget( const Digikam::DColor & )));
+
+ connect(m_hInput, SIGNAL(valueChanged (double)),
+ this, SLOT(slotTimer()));
+
+ connect(m_hInput, SIGNAL(valueChanged (double)),
+ this, SLOT(slotHChanged(double)));
+
+ connect(m_sInput, SIGNAL(valueChanged (double)),
+ this, SLOT(slotTimer()));
+
+ connect(m_sInput, SIGNAL(valueChanged (double)),
+ this, SLOT(slotSChanged(double)));
+
+ connect(m_lInput, SIGNAL(valueChanged (double)),
+ this, SLOT(slotTimer()));
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+
+ // -------------------------------------------------------------
+
+ m_gboxSettings->enableButton(EditorToolSettings::Ok, false);
+}
+
+HSLTool::~HSLTool()
+{
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+}
+
+void HSLTool::slotChannelChanged(int channel)
+{
+ switch (channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::ValueHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("white"));
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("red"));
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("green"));
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("blue"));
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void HSLTool::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+}
+
+void HSLTool::slotColorSelectedFromTarget( const DColor &color )
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void HSLTool::slotHSChanged(int h, int s)
+{
+ double hue = double(h);
+ if (h >= 180 && h <= 359)
+ hue = double(h) - 359.0;
+
+ double sat = ((double) s * (200.0 / 255.0)) - 100.0;
+
+ m_hInput->blockSignals(true);
+ m_sInput->blockSignals(true);
+
+ m_hInput->setValue(hue);
+ m_sInput->setValue(sat);
+
+ m_hInput->blockSignals(false);
+ m_sInput->blockSignals(false);
+
+ slotTimer();
+}
+
+void HSLTool::slotHChanged(double h)
+{
+ int hue = int(h);
+ if (h >= -180 && h < 0)
+ hue = int(h) + 359;
+
+ m_HSSelector->blockSignals(true);
+ m_HSSelector->setXValue(hue);
+ m_HSSelector->blockSignals(false);
+}
+
+void HSLTool::slotSChanged(double s)
+{
+ int sat = (int) ((s + 100.0) * (255.0 / 200.0));
+
+ m_HSSelector->blockSignals(true);
+ m_HSSelector->setYValue(sat);
+ m_HSSelector->blockSignals(false);
+}
+
+void HSLTool::readSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("hsladjust Tool");
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", HistogramWidget::LogScaleHistogram));
+ m_hInput->setValue(config->readDoubleNumEntry("HueAjustment", m_hInput->defaultValue()));
+ m_sInput->setValue(config->readDoubleNumEntry("SaturationAjustment", m_sInput->defaultValue()));
+ m_lInput->setValue(config->readDoubleNumEntry("LighnessAjustment", m_lInput->defaultValue()));
+ slotHChanged(m_hInput->value());
+ slotSChanged(m_sInput->value());
+
+ m_histogramWidget->reset();
+
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+}
+
+void HSLTool::writeSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("hsladjust Tool");
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writeEntry("HueAjustment", m_hInput->value());
+ config->writeEntry("SaturationAjustment", m_sInput->value());
+ config->writeEntry("LighnessAjustment", m_lInput->value());
+ m_previewWidget->writeSettings();
+ config->sync();
+}
+
+void HSLTool::slotResetSettings()
+{
+ m_hInput->blockSignals(true);
+ m_sInput->blockSignals(true);
+ m_lInput->blockSignals(true);
+
+ m_hInput->slotReset();
+ m_sInput->slotReset();
+ m_lInput->slotReset();
+
+ slotHChanged(0.0);
+ slotSChanged(0.0);
+
+ slotEffect();
+
+ m_hInput->blockSignals(false);
+ m_sInput->blockSignals(false);
+ m_lInput->blockSignals(false);
+}
+
+void HSLTool::slotEffect()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ double hu = m_hInput->value();
+ double sa = m_sInput->value();
+ double lu = m_lInput->value();
+
+ m_gboxSettings->enableButton(EditorToolSettings::Ok,
+ ( hu != 0.0 || sa != 0.0 || lu != 0.0));
+
+ m_HSPreview->setHS(hu, sa);
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ ImageIface* iface = m_previewWidget->imageIface();
+ m_destinationPreviewData = iface->getPreviewImage();
+ int w = iface->previewWidth();
+ int h = iface->previewHeight();
+ bool a = iface->previewHasAlpha();
+ bool sb = iface->previewSixteenBit();
+
+ DImg preview(w, h, sb, a, m_destinationPreviewData);
+ HSLModifier cmod;
+ cmod.setHue(hu);
+ cmod.setSaturation(sa);
+ cmod.setLightness(lu);
+ cmod.applyHSL(preview);
+ iface->putPreviewImage(preview.bits());
+
+ m_previewWidget->updatePreview();
+
+ // Update histogram.
+
+ memcpy(m_destinationPreviewData, preview.bits(), preview.numBytes());
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false);
+
+ kapp->restoreOverrideCursor();
+}
+
+void HSLTool::finalRendering()
+{
+ kapp->setOverrideCursor(KCursor::waitCursor());
+
+ double hu = m_hInput->value();
+ double sa = m_sInput->value();
+ double lu = m_lInput->value();
+
+ ImageIface* iface = m_previewWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int w = iface->originalWidth();
+ int h = iface->originalHeight();
+ bool a = iface->originalHasAlpha();
+ bool sb = iface->originalSixteenBit();
+ DImg original(w, h, sb, a, data);
+ delete [] data;
+
+ HSLModifier cmod;
+ cmod.setHue(hu);
+ cmod.setSaturation(sa);
+ cmod.setLightness(lu);
+ cmod.applyHSL(original);
+
+ iface->putOriginalImage(i18n("HSL Adjustments"), original.bits());
+ kapp->restoreOverrideCursor();
+}
+
+} // NameSpace DigikamImagesPluginCore
+
diff --git a/digikam/imageplugins/coreplugin/hsl/hsltool.h b/digikam/imageplugins/coreplugin/hsl/hsltool.h
new file mode 100644
index 0000000..be63182
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/hsl/hsltool.h
@@ -0,0 +1,125 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-16
+ * Description : digiKam image editor to adjust Hue, Saturation,
+ * and Lightness of picture.
+ *
+ * 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 HSLTOOL_H
+#define HSLTOOL_H
+
+// Digikam includes.
+
+#include "editortool.h"
+
+class QComboBox;
+class QHButtonGroup;
+
+class KHSSelector;
+
+namespace KDcrawIface
+{
+class RDoubleNumInput;
+}
+
+namespace Digikam
+{
+class HistogramWidget;
+class ColorGradientWidget;
+class ImageWidget;
+class DColor;
+class DImg;
+class EditorToolSettings;
+}
+
+namespace DigikamImagesPluginCore
+{
+class HSPreviewWidget;
+
+class HSLTool : public Digikam::EditorTool
+{
+ Q_OBJECT
+
+public:
+
+ HSLTool(QObject *parent);
+ ~HSLTool();
+
+private slots:
+
+ void slotEffect();
+ void slotChannelChanged(int channel);
+ void slotScaleChanged(int scale);
+ void slotColorSelectedFromTarget( const Digikam::DColor &color );
+ void slotHSChanged(int h, int s);
+ void slotHChanged(double h);
+ void slotSChanged(double s);
+ void slotResetSettings();
+
+private:
+
+ void writeSettings();
+ void readSettings();
+ void finalRendering();
+
+private:
+
+ enum HistogramScale
+ {
+ Linear=0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel=0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ uchar *m_destinationPreviewData;
+
+ QComboBox *m_channelCB;
+
+ QHButtonGroup *m_scaleBG;
+
+ KDcrawIface::RDoubleNumInput *m_hInput;
+ KDcrawIface::RDoubleNumInput *m_sInput;
+ KDcrawIface::RDoubleNumInput *m_lInput;
+
+ KHSSelector *m_HSSelector;
+
+ HSPreviewWidget *m_HSPreview;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+
+ Digikam::DImg *m_originalImage;
+
+ Digikam::EditorToolSettings *m_gboxSettings;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* HSLTOOL_H */
diff --git a/digikam/imageplugins/coreplugin/hsl/hspreviewwidget.cpp b/digikam/imageplugins/coreplugin/hsl/hspreviewwidget.cpp
new file mode 100644
index 0000000..4bdcdfa
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/hsl/hspreviewwidget.cpp
@@ -0,0 +1,126 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2007-01-08
+ * Description : Hue/Saturation preview widget
+ *
+ * Copyright (C) 2007 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qdrawutil.h>
+#include <qimage.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+
+// KDE includes.
+
+#include <kapplication.h>
+#include <klocale.h>
+#include <kimageeffect.h>
+
+// Local includes.
+
+#include "hslmodifier.h"
+#include "dimg.h"
+#include "hspreviewwidget.h"
+#include "hspreviewwidget.moc"
+
+namespace DigikamImagesPluginCore
+{
+
+class HSPreviewWidgetPrivate
+{
+
+public:
+
+ HSPreviewWidgetPrivate()
+ {
+ hue = 0.0;
+ sat = 0.0;
+ }
+
+ int xBorder;
+
+ double hue;
+ double sat;
+
+ QPixmap pixmap;
+};
+
+HSPreviewWidget::HSPreviewWidget(QWidget *parent, int xBorder)
+ : QWidget(parent, 0, Qt::WDestructiveClose)
+{
+ d = new HSPreviewWidgetPrivate;
+ d->xBorder = xBorder;
+}
+
+HSPreviewWidget::~HSPreviewWidget()
+{
+ delete d;
+}
+
+void HSPreviewWidget::setHS(double hue, double sat)
+{
+ d->hue = hue;
+ d->sat = sat;
+ updatePixmap();
+ update();
+}
+
+void HSPreviewWidget::resizeEvent( QResizeEvent * )
+{
+ updatePixmap();
+}
+
+void HSPreviewWidget::paintEvent( QPaintEvent * )
+{
+ bitBlt(this, 0+d->xBorder, 0, &d->pixmap);
+}
+
+void HSPreviewWidget::updatePixmap()
+{
+ int xSize = width()-2*d->xBorder;
+ int ySize = height();
+
+ Digikam::DImg image(xSize, ySize, false, false, 0, false);
+ QColor col;
+ uint *p;
+
+ for ( int s = ySize-1; s >= 0; s-- )
+ {
+ p = (uint *)image.scanLine(ySize - s - 1);
+
+ for( int h = 0 ; h < xSize ; h++ )
+ {
+ col.setHsv( 359*h/(xSize-1), 255, 192 );
+ *p = col.rgb();
+ p++;
+ }
+ }
+
+ Digikam::HSLModifier cmod;
+ cmod.setHue(d->hue);
+ cmod.setSaturation(d->sat);
+ cmod.setLightness(0.0);
+ cmod.applyHSL(image);
+
+ d->pixmap = image.convertToPixmap();
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/hsl/hspreviewwidget.h b/digikam/imageplugins/coreplugin/hsl/hspreviewwidget.h
new file mode 100644
index 0000000..aebc314
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/hsl/hspreviewwidget.h
@@ -0,0 +1,63 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2007-01-08
+ * Description : Hue/Saturation preview widget
+ *
+ * Copyright (C) 2007 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 HSPREVIEWWIDGET_H
+#define HSPREVIEWWIDGET_H
+
+// Qt includes.
+
+#include <qwidget.h>
+
+namespace DigikamImagesPluginCore
+{
+
+class HSPreviewWidgetPrivate;
+
+class HSPreviewWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+
+ HSPreviewWidget(QWidget *parent=0, int xBorder=0);
+ ~HSPreviewWidget();
+
+ void setHS(double hue, double sat);
+
+protected:
+
+ void resizeEvent( QResizeEvent * );
+ void paintEvent( QPaintEvent * );
+
+private:
+
+ void updatePixmap();
+
+private:
+
+ HSPreviewWidgetPrivate *d;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* HSPREVIEWWIDGET_H */
diff --git a/digikam/imageplugins/coreplugin/hsl/imageeffect_hsl.cpp b/digikam/imageplugins/coreplugin/hsl/imageeffect_hsl.cpp
new file mode 100644
index 0000000..7940b51
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/hsl/imageeffect_hsl.cpp
@@ -0,0 +1,428 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-16
+ * Description : digiKam image editor to adjust Hue, Saturation,
+ * and Lightness of picture.
+ *
+ * Copyright (C) 2004-2007 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qcolor.h>
+#include <qgroupbox.h>
+#include <qhgroupbox.h>
+#include <qvgroupbox.h>
+#include <qvbox.h>
+#include <qhbuttongroup.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qcombobox.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+#include <qtimer.h>
+
+// KDE includes.
+
+#include <knuminput.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kstandarddirs.h>
+#include <kcolordialog.h>
+
+// Digikam includes.
+
+#include "imageiface.h"
+#include "imagewidget.h"
+#include "histogramwidget.h"
+#include "colorgradientwidget.h"
+#include "hslmodifier.h"
+#include "dimg.h"
+
+// Local includes.
+
+#include "hspreviewwidget.h"
+#include "imageeffect_hsl.h"
+#include "imageeffect_hsl.moc"
+
+namespace DigikamImagesPluginCore
+{
+
+ImageEffect_HSL::ImageEffect_HSL(QWidget* parent)
+ : Digikam::ImageDlgBase(parent, i18n("Hue/Saturation/Lightness"), "hsladjust", false)
+{
+ m_destinationPreviewData = 0L;
+ setHelp("hsladjusttool.anchor", "digikam");
+
+ m_previewWidget = new Digikam::ImageWidget("hsladjust Tool Dialog", plainPage(),
+ i18n("<p>Here you can see the image "
+ "Hue/Saturation/Lightness adjustments preview. "
+ "You can pick color on image "
+ "to see the color level corresponding on histogram."));
+ setPreviewAreaWidget(m_previewWidget);
+
+ // -------------------------------------------------------------
+
+ QWidget *gboxSettings = new QWidget(plainPage());
+ QGridLayout* gridSettings = new QGridLayout(gboxSettings, 11, 4, spacingHint());
+
+ QLabel *label1 = new QLabel(i18n("Channel:"), gboxSettings);
+ label1->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ m_channelCB = new QComboBox( false, gboxSettings );
+ m_channelCB->insertItem( i18n("Luminosity") );
+ m_channelCB->insertItem( i18n("Red") );
+ m_channelCB->insertItem( i18n("Green") );
+ m_channelCB->insertItem( i18n("Blue") );
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red image-channel values.<p>"
+ "<b>Green</b>: display the green image-channel values.<p>"
+ "<b>Blue</b>: display the blue image-channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(gboxSettings);
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin( 0 );
+ QWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximal counts are small, you can use the linear scale.<p>"
+ "Logarithmic scale can be used when the maximal counts are big; "
+ "if it is used, all values (small and large) will be visible on the graph."));
+
+ QPushButton *linHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( linHistoButton, i18n( "<p>Linear" ) );
+ m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap( QPixmap( directory + "histogram-lin.png" ) );
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) );
+ m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap( QPixmap( directory + "histogram-log.png" ) );
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(gboxSettings);
+ m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram drawing "
+ "of the selected image channel. This one is re-computed at any "
+ "settings changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new Digikam::ColorGradientWidget( Digikam::ColorGradientWidget::Horizontal, 10, histoBox );
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+
+ gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4);
+
+ // -------------------------------------------------------------
+
+ m_HSSelector = new KHSSelector(gboxSettings);
+ QWhatsThis::add( m_HSSelector, i18n("<p>Select the hue and saturation adjustments of the image here."));
+ m_HSSelector->setMinimumSize(256, 142);
+ gridSettings->addMultiCellWidget(m_HSSelector, 3, 3, 0, 4);
+
+ m_HSPreview = new HSPreviewWidget(gboxSettings, spacingHint());
+ QWhatsThis::add( m_HSPreview, i18n("<p>You can see here a color preview of the hue and "
+ "saturation adjustments."));
+ m_HSPreview->setMinimumSize(256, 15);
+ gridSettings->addMultiCellWidget(m_HSPreview, 4, 4, 0, 4);
+
+ QLabel *label2 = new QLabel(i18n("Hue:"), gboxSettings);
+ m_hInput = new KDoubleNumInput(gboxSettings);
+ m_hInput->setPrecision(0);
+ m_hInput->setRange(-180.0, 180.0, 1.0, true);
+ m_hInput->setValue(0.0);
+ QWhatsThis::add( m_hInput, i18n("<p>Set here the hue adjustment of the image."));
+ gridSettings->addMultiCellWidget(label2, 5, 5, 0, 4);
+ gridSettings->addMultiCellWidget(m_hInput, 6, 6, 0, 4);
+
+ QLabel *label3 = new QLabel(i18n("Saturation:"), gboxSettings);
+ m_sInput = new KDoubleNumInput(gboxSettings);
+ m_sInput->setPrecision(2);
+ m_sInput->setRange(-100.0, 100.0, 0.01, true);
+ m_sInput->setValue(0.0);
+ QWhatsThis::add( m_sInput, i18n("<p>Set here the saturation adjustment of the image."));
+ gridSettings->addMultiCellWidget(label3, 7, 7, 0, 4);
+ gridSettings->addMultiCellWidget(m_sInput, 8, 8, 0, 4);
+
+ QLabel *label4 = new QLabel(i18n("Lightness:"), gboxSettings);
+ m_lInput = new KDoubleNumInput(gboxSettings);
+ m_lInput->setPrecision(2);
+ m_lInput->setRange(-100.0, 100.0, 0.01, true);
+ m_lInput->setValue(0.0);
+ QWhatsThis::add( m_lInput, i18n("<p>Set here the lightness adjustment of the image."));
+ gridSettings->addMultiCellWidget(label4, 9, 9, 0, 4);
+ gridSettings->addMultiCellWidget(m_lInput, 10, 10, 0, 4);
+
+ gridSettings->setRowStretch(11, 10);
+ setUserAreaWidget(gboxSettings);
+
+ // -------------------------------------------------------------
+
+ connect(m_HSSelector, SIGNAL(valueChanged(int, int)),
+ this, SLOT(slotHSChanged(int, int)));
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const QPoint & )),
+ this, SLOT(slotColorSelectedFromTarget( const Digikam::DColor & )));
+
+ connect(m_hInput, SIGNAL(valueChanged (double)),
+ this, SLOT(slotTimer()));
+
+ connect(m_hInput, SIGNAL(valueChanged (double)),
+ this, SLOT(slotHChanged(double)));
+
+ connect(m_sInput, SIGNAL(valueChanged (double)),
+ this, SLOT(slotTimer()));
+
+ connect(m_sInput, SIGNAL(valueChanged (double)),
+ this, SLOT(slotSChanged(double)));
+
+ connect(m_lInput, SIGNAL(valueChanged (double)),
+ this, SLOT(slotTimer()));
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+
+ // -------------------------------------------------------------
+
+ enableButtonOK( false );
+}
+
+ImageEffect_HSL::~ImageEffect_HSL()
+{
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ delete m_histogramWidget;
+ delete m_previewWidget;
+}
+
+void ImageEffect_HSL::slotChannelChanged(int channel)
+{
+ switch(channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::ValueHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "red" ) );
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "green" ) );
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "blue" ) );
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_HSL::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_HSL::slotColorSelectedFromTarget( const Digikam::DColor &color )
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void ImageEffect_HSL::slotHSChanged(int h, int s)
+{
+ double hue = double(h);
+ if (h >= 180 && h <= 359)
+ hue = double(h) - 359.0;
+
+ double sat = ((double)s * (200.0/255.0)) - 100.0;
+
+ m_hInput->blockSignals(true);
+ m_sInput->blockSignals(true);
+ m_hInput->setValue(hue);
+ m_sInput->setValue(sat);
+ m_hInput->blockSignals(false);
+ m_sInput->blockSignals(false);
+ slotTimer();
+}
+
+void ImageEffect_HSL::slotHChanged(double h)
+{
+ int hue = int(h);
+ if (h >= -180 && h < 0)
+ hue = int(h) + 359;
+
+ m_HSSelector->blockSignals(true);
+ m_HSSelector->setXValue(hue);
+ m_HSSelector->blockSignals(false);
+}
+
+void ImageEffect_HSL::slotSChanged(double s)
+{
+ int sat = (int)((s + 100.0) * (255.0/200.0));
+
+ m_HSSelector->blockSignals(true);
+ m_HSSelector->setYValue(sat);
+ m_HSSelector->blockSignals(false);
+}
+
+void ImageEffect_HSL::readUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("hsladjust Tool Dialog");
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", Digikam::HistogramWidget::LogScaleHistogram));
+ m_hInput->setValue(config->readDoubleNumEntry("HueAjustment", 0.0));
+ m_sInput->setValue(config->readDoubleNumEntry("SaturationAjustment", 0.0));
+ m_lInput->setValue(config->readDoubleNumEntry("LighnessAjustment", 0.0));
+ slotHChanged(m_hInput->value());
+ slotSChanged(m_sInput->value());
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+}
+
+void ImageEffect_HSL::writeUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("hsladjust Tool Dialog");
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writeEntry("HueAjustment", m_hInput->value());
+ config->writeEntry("SaturationAjustment", m_sInput->value());
+ config->writeEntry("LighnessAjustment", m_lInput->value());
+ config->sync();
+}
+
+void ImageEffect_HSL::resetValues()
+{
+ m_hInput->blockSignals(true);
+ m_sInput->blockSignals(true);
+ m_lInput->blockSignals(true);
+ m_hInput->setValue(0.0);
+ m_sInput->setValue(0.0);
+ m_lInput->setValue(0.0);
+ slotHChanged(0.0);
+ slotSChanged(0.0);
+ m_hInput->blockSignals(false);
+ m_sInput->blockSignals(false);
+ m_lInput->blockSignals(false);
+}
+
+void ImageEffect_HSL::slotEffect()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ double hu = m_hInput->value();
+ double sa = m_sInput->value();
+ double lu = m_lInput->value();
+
+ enableButtonOK( hu != 0.0 || sa != 0.0 || lu != 0.0);
+
+ m_HSPreview->setHS(hu, sa);
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ m_destinationPreviewData = iface->getPreviewImage();
+ int w = iface->previewWidth();
+ int h = iface->previewHeight();
+ bool a = iface->previewHasAlpha();
+ bool sb = iface->previewSixteenBit();
+
+ Digikam::DImg preview(w, h, sb, a, m_destinationPreviewData);
+ Digikam::HSLModifier cmod;
+ cmod.setHue(hu);
+ cmod.setSaturation(sa);
+ cmod.setLightness(lu);
+ cmod.applyHSL(preview);
+ iface->putPreviewImage(preview.bits());
+
+ m_previewWidget->updatePreview();
+
+ // Update histogram.
+
+ memcpy(m_destinationPreviewData, preview.bits(), preview.numBytes());
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false);
+
+ kapp->restoreOverrideCursor();
+}
+
+void ImageEffect_HSL::finalRendering()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ double hu = m_hInput->value();
+ double sa = m_sInput->value();
+ double lu = m_lInput->value();
+
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int w = iface->originalWidth();
+ int h = iface->originalHeight();
+ bool a = iface->originalHasAlpha();
+ bool sb = iface->originalSixteenBit();
+ Digikam::DImg original(w, h, sb, a, data);
+ delete [] data;
+
+ Digikam::HSLModifier cmod;
+ cmod.setHue(hu);
+ cmod.setSaturation(sa);
+ cmod.setLightness(lu);
+ cmod.applyHSL(original);
+
+ iface->putOriginalImage(i18n("HSL Adjustments"), original.bits());
+ kapp->restoreOverrideCursor();
+ accept();
+}
+
+} // NameSpace DigikamImagesPluginCore
+
diff --git a/digikam/imageplugins/coreplugin/hsl/imageeffect_hsl.h b/digikam/imageplugins/coreplugin/hsl/imageeffect_hsl.h
new file mode 100644
index 0000000..c2f5db5
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/hsl/imageeffect_hsl.h
@@ -0,0 +1,115 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-16
+ * Description : digiKam image editor to adjust Hue, Saturation,
+ * and Lightness of picture.
+ *
+ * Copyright (C) 2004-2007 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 IMAGEEFFECT_HSL_H
+#define IMAGEEFFECT_HSL_H
+
+// Digikam include.
+
+#include "imagedlgbase.h"
+
+class QComboBox;
+class QHButtonGroup;
+
+class KDoubleNumInput;
+class KHSSelector;
+
+namespace Digikam
+{
+class HistogramWidget;
+class ColorGradientWidget;
+class ImageWidget;
+class DColor;
+}
+
+namespace DigikamImagesPluginCore
+{
+class HSPreviewWidget;
+
+class ImageEffect_HSL : public Digikam::ImageDlgBase
+{
+ Q_OBJECT
+
+public:
+
+ ImageEffect_HSL(QWidget *parent);
+ ~ImageEffect_HSL();
+
+private slots:
+
+ void slotEffect();
+ void slotChannelChanged(int channel);
+ void slotScaleChanged(int scale);
+ void slotColorSelectedFromTarget( const Digikam::DColor &color );
+ void slotHSChanged(int h, int s);
+ void slotHChanged(double h);
+ void slotSChanged(double s);
+
+private:
+
+ void writeUserSettings();
+ void readUserSettings();
+ void resetValues();
+ void finalRendering();
+
+private:
+
+ enum HistogramScale
+ {
+ Linear=0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel=0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ uchar *m_destinationPreviewData;
+
+ QComboBox *m_channelCB;
+
+ QHButtonGroup *m_scaleBG;
+
+ KDoubleNumInput *m_hInput;
+ KDoubleNumInput *m_sInput;
+ KDoubleNumInput *m_lInput;
+
+ KHSSelector *m_HSSelector;
+
+ HSPreviewWidget *m_HSPreview;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* IMAGEEFFECT_HSL_H */
diff --git a/digikam/imageplugins/coreplugin/iccprooftool.cpp b/digikam/imageplugins/coreplugin/iccprooftool.cpp
new file mode 100644
index 0000000..76fd506
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/iccprooftool.cpp
@@ -0,0 +1,1310 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-12-21
+ * Description : digiKam image editor tool to correct picture
+ * colors using an ICC color profile
+ *
+ * Copyright (C) 2005-2006 by F.J. Cruz <fj.cruz@supercable.es>
+ * Copyright (C) 2006-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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qcheckbox.h>
+#include <qcolor.h>
+#include <qcombobox.h>
+#include <qfile.h>
+#include <qframe.h>
+#include <qgroupbox.h>
+#include <qhbox.h>
+#include <qhbuttongroup.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpoint.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qtextstream.h>
+#include <qtoolbox.h>
+#include <qtooltip.h>
+#include <qvbox.h>
+#include <qvbuttongroup.h>
+#include <qwhatsthis.h>
+
+// KDE includes.
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kfile.h>
+#include <kfiledialog.h>
+#include <kglobalsettings.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <ksqueezedtextlabel.h>
+#include <kstandarddirs.h>
+#include <ktabwidget.h>
+#include <kurllabel.h>
+#include <kurlrequester.h>
+
+// LibKDcraw includes.
+
+#include <libkdcraw/rnuminput.h>
+#include <libkdcraw/rcombobox.h>
+
+// Digikam includes.
+
+#include "bcgmodifier.h"
+#include "colorgradientwidget.h"
+#include "curveswidget.h"
+#include "ddebug.h"
+#include "dimg.h"
+#include "dimgimagefilters.h"
+#include "editortoolsettings.h"
+#include "histogramwidget.h"
+#include "iccpreviewwidget.h"
+#include "iccprofileinfodlg.h"
+#include "icctransform.h"
+#include "imagecurves.h"
+#include "imagehistogram.h"
+#include "imageiface.h"
+#include "imagewidget.h"
+
+// Local includes.
+
+#include "iccprooftool.h"
+#include "iccprooftool.moc"
+
+using namespace KDcrawIface;
+using namespace Digikam;
+
+namespace DigikamImagesPluginCore
+{
+
+ICCProofTool::ICCProofTool(QObject* parent)
+ : EditorTool(parent)
+{
+ setName("colormanagement");
+ setToolName(i18n("Color Management"));
+ setToolIcon(SmallIcon("colormanagement"));
+ setToolHelp("colormanagement.anchor");
+
+ m_destinationPreviewData = 0;
+ m_cmEnabled = true;
+ m_hasICC = false;
+
+ ImageIface iface(0, 0);
+ m_originalImage = iface.getOriginalImg();
+ m_embeddedICC = iface.getEmbeddedICCFromOriginalImage();
+
+ m_previewWidget = new ImageWidget("colormanagement Tool",0,
+ i18n("<p>Here you can see the image preview after "
+ "applying a color profile</p>"));
+ setToolView(m_previewWidget);
+
+ // -------------------------------------------------------------------
+
+ m_gboxSettings = new EditorToolSettings(EditorToolSettings::Default|
+ EditorToolSettings::Load|
+ EditorToolSettings::SaveAs|
+ EditorToolSettings::Ok|
+ EditorToolSettings::Cancel);
+
+ QGridLayout *gridSettings = new QGridLayout(m_gboxSettings->plainPage(), 3, 2);
+
+ QLabel *label1 = new QLabel(i18n("Channel: "), m_gboxSettings->plainPage());
+ label1->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ m_channelCB = new QComboBox(false, m_gboxSettings->plainPage());
+ m_channelCB->insertItem(i18n("Luminosity"));
+ m_channelCB->insertItem(i18n("Red"));
+ m_channelCB->insertItem(i18n("Green"));
+ m_channelCB->insertItem(i18n("Blue"));
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red channel values.<p>"
+ "<b>Green</b>: display the green channel values.<p>"
+ "<b>Blue</b>: display the blue channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(m_gboxSettings->plainPage());
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin(0);
+ QWhatsThis::add(m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximal values are small, you can use the linear scale.<p>"
+ "Logarithmic scale can be used when the maximal values are big; "
+ "if it is used, all values (small and large) will be visible on the "
+ "graph."));
+
+ QPushButton *linHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(linHistoButton, i18n("<p>Linear"));
+ m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap(QPixmap(directory + "histogram-lin.png"));
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(logHistoButton, i18n("<p>Logarithmic"));
+ m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap(QPixmap(directory + "histogram-log.png"));
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 2);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(m_gboxSettings->plainPage());
+ m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram "
+ "of the selected image channel. "
+ "This one is updated after setting changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new ColorGradientWidget( ColorGradientWidget::Horizontal, 10,
+ histoBox );
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+
+ gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 2);
+
+ // -------------------------------------------------------------
+
+ m_toolBoxWidgets = new QToolBox(m_gboxSettings->plainPage());
+ QWidget *generalOptions = new QWidget(m_toolBoxWidgets);
+ QWidget *inProfiles = new QWidget(m_toolBoxWidgets);
+ QWidget *spaceProfiles = new QWidget(m_toolBoxWidgets);
+ QWidget *proofProfiles = new QWidget(m_toolBoxWidgets);
+ QWidget *lightnessadjust = new QWidget(m_toolBoxWidgets);
+
+ //---------- "General" Page Setup ----------------------------------
+
+ m_toolBoxWidgets->insertItem(GENERALPAGE, generalOptions,
+ SmallIconSet("misc"), i18n("General Settings"));
+ QWhatsThis::add(generalOptions, i18n("<p>Here you can set general parameters.</p>"));
+
+ QGridLayout *zeroPageLayout = new QGridLayout(generalOptions, 5, 1);
+
+ m_doSoftProofBox = new QCheckBox(generalOptions);
+ m_doSoftProofBox->setText(i18n("Soft-proofing"));
+ QWhatsThis::add(m_doSoftProofBox, i18n("<p>Rendering emulation of the device described "
+ "by the \"Proofing\" profile. Useful to preview the final "
+ "result without rendering to physical medium.</p>"));
+
+ m_checkGamutBox = new QCheckBox(generalOptions);
+ m_checkGamutBox->setText(i18n("Check gamut"));
+ QWhatsThis::add(m_checkGamutBox, i18n("<p>You can use this option if you want to show "
+ "the colors that are outside the printer's gamut<p>"));
+
+ m_embeddProfileBox = new QCheckBox(generalOptions);
+ m_embeddProfileBox->setChecked(true);
+ m_embeddProfileBox->setText(i18n("Assign profile"));
+ QWhatsThis::add(m_embeddProfileBox, i18n("<p>You can use this option to embed "
+ "the selected workspace color profile into the image.</p>"));
+
+ m_BPCBox = new QCheckBox(generalOptions);
+ m_BPCBox->setText(i18n("Use BPC"));
+ QWhatsThis::add(m_BPCBox, i18n("<p>The Black Point Compensation (BPC) feature does work in conjunction "
+ "with Relative Colorimetric Intent. Perceptual intent should make no "
+ "difference, since BPC is always on, and in Absolute Colorimetric "
+ "Intent it is always turned off.</p>"
+ "<p>BPC does compensate for a lack of ICC profiles in the dark tone rendering. "
+ "With BPC the dark tones are optimally mapped (no clipping) from original media "
+ "to the destination rendering media, e.g. the combination of paper and ink.</p>"));
+
+ QLabel *intent = new QLabel(i18n("Rendering Intent:"), generalOptions);
+ m_renderingIntentsCB = new RComboBox(generalOptions);
+ m_renderingIntentsCB->insertItem("Perceptual");
+ m_renderingIntentsCB->insertItem("Absolute Colorimetric");
+ m_renderingIntentsCB->insertItem("Relative Colorimetric");
+ m_renderingIntentsCB->insertItem("Saturation");
+ m_renderingIntentsCB->setDefaultItem(0);
+ QWhatsThis::add( m_renderingIntentsCB, i18n("<ul><li>Perceptual intent causes the full gamut "
+ "of the image to be compressed or expanded to fill the gamut of the destination media, "
+ "so that gray balance is preserved but colorimetric accuracy may not be preserved.<br>"
+ "In other words, if certain colors in an image fall outside of the range of colors that "
+ "the output device can render, the image intent will cause all the colors in the image "
+ "to be adjusted so that every color in the image falls within the range that can be "
+ "rendered and so that the relationship between colors is preserved as much as possible.<br>"
+ "This intent is most suitable for display of photographs and images, and is the default "
+ "intent.</li>"
+ "<li> Absolute Colorimetric intent causes any colors that fall outside the range that the "
+ "output device can render to be adjusted to the closest color that can be rendered, while all "
+ "other colors are left unchanged.<br>"
+ "This intent preserves the white point and is most suitable for spot colors (Pantone, "
+ "TruMatch, logo colors, ...).</li>"
+ "<li>Relative Colorimetric intent is defined such that any colors that fall outside the "
+ "range that the output device can render are adjusted to the closest color that can be "
+ "rendered, while all other colors are left unchanged. Proof intent does not preserve "
+ "the white point.</li>"
+ "<li>Saturation intent preserves the saturation of colors in the image at the possible "
+ "expense of hue and lightness.<br>"
+ "Implementation of this intent remains somewhat problematic, and the ICC is still working "
+ "on methods to achieve the desired effects.<br>"
+ "This intent is most suitable for business graphics such as charts, where it is more "
+ "important that the colors be vivid and contrast well with each other rather than a "
+ "specific color.</li></ul>"));
+
+ KURLLabel *lcmsLogoLabel = new KURLLabel(generalOptions);
+ lcmsLogoLabel->setAlignment(AlignTop | AlignRight);
+ lcmsLogoLabel->setText(QString());
+ lcmsLogoLabel->setURL("http://www.littlecms.com");
+ KGlobal::dirs()->addResourceType("logo-lcms", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("logo-lcms", "logo-lcms.png");
+ lcmsLogoLabel->setPixmap(QPixmap(directory + "logo-lcms.png"));
+ QToolTip::add(lcmsLogoLabel, i18n("Visit Little CMS project website"));
+
+ zeroPageLayout->addMultiCellWidget(m_doSoftProofBox, 0, 0, 0, 0);
+ zeroPageLayout->addMultiCellWidget(m_checkGamutBox, 1, 1, 0, 0);
+ zeroPageLayout->addMultiCellWidget(m_embeddProfileBox, 2, 2, 0, 0);
+ zeroPageLayout->addMultiCellWidget(lcmsLogoLabel, 0, 2, 1, 1);
+ zeroPageLayout->addMultiCellWidget(m_BPCBox, 3, 3, 0, 0);
+ zeroPageLayout->addMultiCellWidget(intent, 4, 4, 0, 0);
+ zeroPageLayout->addMultiCellWidget(m_renderingIntentsCB, 4, 4, 1, 1);
+ zeroPageLayout->setRowStretch(5, 10);
+
+ //---------- "Input" Page Setup ----------------------------------
+
+ m_toolBoxWidgets->insertItem(INPUTPAGE, inProfiles, SmallIconSet("camera"), i18n("Input Profile"));
+ QWhatsThis::add(inProfiles, i18n("<p>Set here all parameters relevant of Input Color "
+ "Profiles.</p>"));
+
+ QGridLayout *firstPageLayout = new QGridLayout(inProfiles, 4, 2);
+
+ m_inProfileBG = new QButtonGroup(4, Qt::Vertical, inProfiles);
+ m_inProfileBG->setFrameStyle(QFrame::NoFrame);
+ m_inProfileBG->setInsideMargin(0);
+
+ m_useEmbeddedProfile = new QRadioButton(m_inProfileBG);
+ m_useEmbeddedProfile->setText(i18n("Use embedded profile"));
+
+ m_useSRGBDefaultProfile = new QRadioButton(m_inProfileBG);
+ m_useSRGBDefaultProfile->setText(i18n("Use builtin sRGB profile"));
+ m_useSRGBDefaultProfile->setChecked(true);
+
+ m_useInDefaultProfile = new QRadioButton(m_inProfileBG);
+ m_useInDefaultProfile->setText(i18n("Use default profile"));
+
+ m_useInSelectedProfile = new QRadioButton(m_inProfileBG);
+ m_useInSelectedProfile->setText(i18n("Use selected profile"));
+
+ m_inProfilesPath = new KURLRequester(inProfiles);
+ m_inProfilesPath->setMode(KFile::File|KFile::ExistingOnly);
+ m_inProfilesPath->setFilter("*.icc *.icm|"+i18n("ICC Files (*.icc; *.icm)"));
+ KFileDialog *inProfiles_dialog = m_inProfilesPath->fileDialog();
+ m_iccInPreviewWidget = new ICCPreviewWidget(inProfiles_dialog);
+ inProfiles_dialog->setPreviewWidget(m_iccInPreviewWidget);
+
+ QPushButton *inProfilesInfo = new QPushButton(i18n("Info..."), inProfiles);
+
+ QGroupBox *pictureInfo = new QGroupBox(2, Qt::Horizontal, i18n("Camera information"), inProfiles);
+ new QLabel(i18n("Make:"), pictureInfo);
+ KSqueezedTextLabel *make = new KSqueezedTextLabel(0, pictureInfo);
+ new QLabel(i18n("Model:"), pictureInfo);
+ KSqueezedTextLabel *model = new KSqueezedTextLabel(0, pictureInfo);
+ make->setText(iface.getPhotographInformations().make);
+ model->setText(iface.getPhotographInformations().model);
+
+ firstPageLayout->addMultiCellWidget(m_inProfileBG, 0, 1, 0, 0);
+ firstPageLayout->addMultiCellWidget(inProfilesInfo, 0, 0, 2, 2);
+ firstPageLayout->addMultiCellWidget(m_inProfilesPath, 2, 2, 0, 2);
+ firstPageLayout->addMultiCellWidget(pictureInfo, 3, 3, 0, 2);
+ firstPageLayout->setColStretch(1, 10);
+ firstPageLayout->setRowStretch(4, 10);
+
+ //---------- "Workspace" Page Setup ---------------------------------
+
+ m_toolBoxWidgets->insertItem(WORKSPACEPAGE, spaceProfiles,
+ SmallIconSet("tablet"), i18n("Workspace Profile"));
+ QWhatsThis::add(spaceProfiles, i18n("<p>Set here all parameters relevant to Color Workspace "
+ "Profiles.</p>"));
+
+ QGridLayout *secondPageLayout = new QGridLayout(spaceProfiles, 3, 2);
+
+ m_spaceProfileBG = new QButtonGroup(2, Qt::Vertical, spaceProfiles);
+ m_spaceProfileBG->setFrameStyle(QFrame::NoFrame);
+ m_spaceProfileBG->setInsideMargin(0);
+
+ m_useSpaceDefaultProfile = new QRadioButton(m_spaceProfileBG);
+ m_useSpaceDefaultProfile->setText(i18n("Use default workspace profile"));
+
+ m_useSpaceSelectedProfile = new QRadioButton(m_spaceProfileBG);
+ m_useSpaceSelectedProfile->setText(i18n("Use selected profile"));
+
+ m_spaceProfilePath = new KURLRequester(spaceProfiles);
+ m_spaceProfilePath->setMode(KFile::File|KFile::ExistingOnly);
+ m_spaceProfilePath->setFilter("*.icc *.icm|"+i18n("ICC Files (*.icc; *.icm)"));
+ KFileDialog *spaceProfiles_dialog = m_spaceProfilePath->fileDialog();
+ m_iccSpacePreviewWidget = new ICCPreviewWidget(spaceProfiles_dialog);
+ spaceProfiles_dialog->setPreviewWidget(m_iccSpacePreviewWidget);
+
+ QPushButton *spaceProfilesInfo = new QPushButton(i18n("Info..."), spaceProfiles);
+
+ secondPageLayout->addMultiCellWidget(m_spaceProfileBG, 0, 1, 0, 0);
+ secondPageLayout->addMultiCellWidget(spaceProfilesInfo, 0, 0, 2, 2);
+ secondPageLayout->addMultiCellWidget(m_spaceProfilePath, 2, 2, 0, 2);
+ secondPageLayout->setColStretch(1, 10);
+ secondPageLayout->setRowStretch(3, 10);
+
+ //---------- "Proofing" Page Setup ---------------------------------
+
+ m_toolBoxWidgets->insertItem(PROOFINGPAGE, proofProfiles,
+ SmallIconSet("printer1"), i18n("Proofing Profile"));
+ QWhatsThis::add(proofProfiles, i18n("<p>Set here all parameters relevant to Proofing Color "
+ "Profiles.</p>"));
+
+ QGridLayout *thirdPageLayout = new QGridLayout(proofProfiles, 3, 2);
+
+ m_proofProfileBG = new QButtonGroup(2, Qt::Vertical, proofProfiles);
+ m_proofProfileBG->setFrameStyle(QFrame::NoFrame);
+ m_proofProfileBG->setInsideMargin(0);
+
+ m_useProofDefaultProfile = new QRadioButton(m_proofProfileBG);
+ m_useProofDefaultProfile->setText(i18n("Use default proof profile"));
+
+ m_useProofSelectedProfile = new QRadioButton(m_proofProfileBG);
+ m_useProofSelectedProfile->setText(i18n("Use selected profile"));
+
+ m_proofProfilePath = new KURLRequester(proofProfiles);
+ m_proofProfilePath->setMode(KFile::File|KFile::ExistingOnly);
+ m_proofProfilePath->setFilter("*.icc *.icm|"+i18n("ICC Files (*.icc; *.icm)"));
+ KFileDialog *proofProfiles_dialog = m_proofProfilePath->fileDialog();
+ m_iccProofPreviewWidget = new ICCPreviewWidget(proofProfiles_dialog);
+ proofProfiles_dialog->setPreviewWidget(m_iccProofPreviewWidget);
+
+ QPushButton *proofProfilesInfo = new QPushButton(i18n("Info..."), proofProfiles);
+
+ thirdPageLayout->addMultiCellWidget(m_proofProfileBG, 0, 1, 0, 0);
+ thirdPageLayout->addMultiCellWidget(proofProfilesInfo, 0, 0, 2, 2);
+ thirdPageLayout->addMultiCellWidget(m_proofProfilePath, 2, 2, 0, 2);
+ thirdPageLayout->setColStretch(1, 10);
+ thirdPageLayout->setRowStretch(3, 10);
+
+ //---------- "Lightness" Page Setup ----------------------------------
+
+ m_toolBoxWidgets->insertItem(LIGHTNESSPAGE, lightnessadjust,
+ SmallIconSet("blend"), i18n("Lightness Adjustments"));
+ QWhatsThis::add(lightnessadjust, i18n("<p>Set here all lightness adjustments to the target image.</p>"));
+
+ QGridLayout *fourPageLayout = new QGridLayout( lightnessadjust, 5, 2);
+
+ ColorGradientWidget* vGradient = new ColorGradientWidget(ColorGradientWidget::Vertical,
+ 10, lightnessadjust );
+ vGradient->setColors(QColor("white"), QColor("black"));
+
+ QLabel *spacev = new QLabel(lightnessadjust);
+ spacev->setFixedWidth(1);
+
+ m_curvesWidget = new CurvesWidget(256, 192, m_originalImage->bits(), m_originalImage->width(),
+ m_originalImage->height(), m_originalImage->sixteenBit(),
+ lightnessadjust);
+ QWhatsThis::add( m_curvesWidget, i18n("<p>This is the curve adjustment of the image luminosity"));
+
+ QLabel *spaceh = new QLabel(lightnessadjust);
+ spaceh->setFixedHeight(1);
+
+ ColorGradientWidget *hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal,
+ 10,
+ lightnessadjust);
+
+ hGradient->setColors(QColor("black"), QColor("white"));
+
+ m_cInput = new RIntNumInput(lightnessadjust);
+ m_cInput->input()->setLabel(i18n("Contrast:"), AlignLeft | AlignVCenter);
+ m_cInput->setRange(-100, 100, 1);
+ m_cInput->setDefaultValue(0);
+ QWhatsThis::add( m_cInput, i18n("<p>Set here the contrast adjustment of the image."));
+
+ fourPageLayout->addMultiCellWidget(vGradient, 0, 0, 0, 0);
+ fourPageLayout->addMultiCellWidget(spacev, 0, 0, 1, 1);
+ fourPageLayout->addMultiCellWidget(m_curvesWidget, 0, 0, 2, 2);
+ fourPageLayout->addMultiCellWidget(spaceh, 1, 1, 2, 2);
+ fourPageLayout->addMultiCellWidget(hGradient, 2, 2, 2, 2);
+ fourPageLayout->addMultiCellWidget(m_cInput, 4, 4, 0, 2);
+// fourPageLayout->setRowSpacing(3);
+ fourPageLayout->setRowStretch(5, 10);
+
+ // -------------------------------------------------------------
+
+ gridSettings->addMultiCellWidget(m_toolBoxWidgets, 3, 3, 0, 2);
+
+ setToolSettings(m_gboxSettings);
+ m_gboxSettings->enableButton(EditorToolSettings::Ok, false);
+ init();
+
+ // -------------------------------------------------------------
+
+ connect(lcmsLogoLabel, SIGNAL(leftClickedURL(const QString&)),
+ this, SLOT(processLCMSURL(const QString&)));
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_curvesWidget, SIGNAL(signalCurvesChanged()),
+ this, SLOT(slotTimer()));
+
+ connect(m_cInput, SIGNAL(valueChanged (int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_renderingIntentsCB, SIGNAL(activated(int)),
+ this, SLOT(slotEffect()));
+
+ //-- Check box options connections -------------------------------------------
+
+ connect(m_doSoftProofBox, SIGNAL(toggled (bool)),
+ this, SLOT(slotEffect()));
+
+ connect(m_checkGamutBox, SIGNAL(toggled (bool)),
+ this, SLOT(slotEffect()));
+
+ connect(m_BPCBox, SIGNAL(toggled (bool)),
+ this, SLOT(slotEffect()));
+
+ //-- Button Group ICC profile options connections ----------------------------
+
+ connect(m_inProfileBG, SIGNAL(released (int)),
+ this, SLOT(slotEffect()));
+
+ connect(m_spaceProfileBG, SIGNAL(released (int)),
+ this, SLOT(slotEffect()));
+
+ connect(m_proofProfileBG, SIGNAL(released (int)),
+ this, SLOT(slotEffect()));
+
+ //-- url requester ICC profile connections -----------------------------------
+
+ connect(m_inProfilesPath, SIGNAL(urlSelected(const QString&)),
+ this, SLOT(slotEffect()));
+
+ connect(m_spaceProfilePath, SIGNAL(urlSelected(const QString&)),
+ this, SLOT(slotEffect()));
+
+ connect(m_proofProfilePath, SIGNAL(urlSelected(const QString&)),
+ this, SLOT(slotEffect()));
+
+ //-- Image preview widget connections ----------------------------
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromOriginal( const Digikam::DColor &, const QPoint & )),
+ this, SLOT(slotSpotColorChanged( const Digikam::DColor & )));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const QPoint & )),
+ this, SLOT(slotColorSelectedFromTarget( const Digikam::DColor & )));
+
+ //-- ICC profile preview connections -----------------------------
+
+ connect(inProfilesInfo, SIGNAL(clicked()),
+ this, SLOT(slotInICCInfo()));
+
+ connect(spaceProfilesInfo, SIGNAL(clicked()),
+ this, SLOT(slotSpaceICCInfo()));
+
+ connect(proofProfilesInfo, SIGNAL(clicked()),
+ this, SLOT(slotProofICCInfo()));
+}
+
+ICCProofTool::~ICCProofTool()
+{
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+}
+
+void ICCProofTool::readSettings()
+{
+ QString defaultICCPath = KGlobalSettings::documentPath();
+ KConfig* config = kapp->config();
+
+ // General settings of digiKam Color Management
+ config->setGroup("Color Management");
+
+ if (!config->readBoolEntry("EnableCM", false))
+ {
+ m_cmEnabled = false;
+ slotToggledWidgets(false);
+ }
+ else
+ {
+ m_inPath = config->readPathEntry("InProfileFile");
+ m_spacePath = config->readPathEntry("WorkProfileFile");
+ m_proofPath = config->readPathEntry("ProofProfileFile");
+
+ if (QFile::exists(config->readPathEntry("DefaultPath")))
+ {
+ defaultICCPath = config->readPathEntry("DefaultPath");
+ }
+ else
+ {
+ QString message = i18n("The ICC profiles path seems to be invalid. You won't be able to use the \"Default profile\"\
+ options.<p>Please fix this in the digiKam ICC setup.");
+ slotToggledWidgets( false );
+ KMessageBox::information(kapp->activeWindow(), message);
+ }
+ }
+
+ // Plugin settings.
+ config->setGroup("colormanagement Tool");
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", HistogramWidget::LogScaleHistogram));
+ m_toolBoxWidgets->setCurrentIndex(config->readNumEntry("Settings Tab", GENERALPAGE));
+ m_inProfilesPath->setURL(config->readPathEntry("InputProfilePath", defaultICCPath));
+ m_proofProfilePath->setURL(config->readPathEntry("ProofProfilePath", defaultICCPath));
+ m_spaceProfilePath->setURL(config->readPathEntry("SpaceProfilePath", defaultICCPath));
+ m_renderingIntentsCB->setCurrentItem(config->readNumEntry("RenderingIntent", m_renderingIntentsCB->defaultItem()));
+ m_doSoftProofBox->setChecked(config->readBoolEntry("DoSoftProof", false));
+ m_checkGamutBox->setChecked(config->readBoolEntry("CheckGamut", false));
+ m_embeddProfileBox->setChecked(config->readBoolEntry("EmbeddProfile", true));
+ m_BPCBox->setChecked(config->readBoolEntry("BPC", true));
+ m_inProfileBG->setButton(config->readNumEntry("InputProfileMethod", 0));
+ m_spaceProfileBG->setButton(config->readNumEntry("SpaceProfileMethod", 0));
+ m_proofProfileBG->setButton(config->readNumEntry("ProofProfileMethod", 0));
+ m_cInput->setValue(config->readNumEntry("ContrastAjustment", m_cInput->defaultValue()));
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curvesWidget->curves()->curvesChannelReset(i);
+
+ m_curvesWidget->curves()->setCurveType(m_curvesWidget->m_channelType, ImageCurves::CURVE_SMOOTH);
+ m_curvesWidget->reset();
+
+ for (int j = 0 ; j < 17 ; j++)
+ {
+ QPoint disable(-1, -1);
+ QPoint p = config->readPointEntry(QString("CurveAjustmentPoint%1").arg(j), &disable);
+
+ if (m_originalImage->sixteenBit() && p.x() != -1)
+ {
+ p.setX(p.x()*255);
+ p.setY(p.y()*255);
+ }
+
+ m_curvesWidget->curves()->setCurvePoint(ImageHistogram::ValueChannel, j, p);
+ }
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curvesWidget->curves()->curvesCalculateCurve(i);
+
+ m_histogramWidget->reset();
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+}
+
+void ICCProofTool::writeSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("colormanagement Tool");
+ config->writeEntry("Settings Tab", m_toolBoxWidgets->currentIndex());
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writePathEntry("InputProfilePath", m_inProfilesPath->url());
+ config->writePathEntry("ProofProfilePath", m_proofProfilePath->url());
+ config->writePathEntry("SpaceProfilePath", m_spaceProfilePath->url());
+ config->writeEntry("RenderingIntent", m_renderingIntentsCB->currentItem());
+ config->writeEntry("DoSoftProof", m_doSoftProofBox->isChecked());
+ config->writeEntry("CheckGamut", m_checkGamutBox->isChecked());
+ config->writeEntry("EmbeddProfile", m_embeddProfileBox->isChecked());
+ config->writeEntry("BPC", m_BPCBox->isChecked());
+ config->writeEntry("InputProfileMethod", m_inProfileBG->selectedId());
+ config->writeEntry("SpaceProfileMethod", m_spaceProfileBG->selectedId());
+ config->writeEntry("ProofProfileMethod", m_proofProfileBG->selectedId());
+ config->writeEntry("ContrastAjustment", m_cInput->value());
+
+ for (int j = 0; j < 17; j++)
+ {
+ QPoint p = m_curvesWidget->curves()->getCurvePoint(ImageHistogram::ValueChannel, j);
+
+ if (m_originalImage->sixteenBit() && p.x() != -1)
+ {
+ p.setX(p.x() / 255);
+ p.setY(p.y() / 255);
+ }
+
+ config->writeEntry(QString("CurveAjustmentPoint%1").arg(j), p);
+ }
+
+ m_previewWidget->writeSettings();
+ config->sync();
+}
+
+void ICCProofTool::processLCMSURL(const QString& url)
+{
+ KApplication::kApplication()->invokeBrowser(url);
+}
+
+void ICCProofTool::slotSpotColorChanged(const DColor &color)
+{
+ m_curvesWidget->setCurveGuide(color);
+}
+
+void ICCProofTool::slotColorSelectedFromTarget( const DColor &color )
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void ICCProofTool::slotChannelChanged( int channel )
+{
+ switch (channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::ValueHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("white"));
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("red"));
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("green"));
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("blue"));
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void ICCProofTool::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+}
+
+void ICCProofTool::slotResetSettings()
+{
+ m_cInput->blockSignals(true);
+ m_renderingIntentsCB->blockSignals(true);
+
+ m_cInput->slotReset();
+ m_renderingIntentsCB->slotReset();
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curvesWidget->curves()->curvesChannelReset(i);
+
+ m_curvesWidget->reset();
+ m_cInput->blockSignals(false);
+ m_renderingIntentsCB->blockSignals(false);
+}
+
+void ICCProofTool::slotEffect()
+{
+ kapp->setOverrideCursor(KCursor::waitCursor());
+ m_gboxSettings->enableButton(EditorToolSettings::Ok, true);
+ m_histogramWidget->stopHistogramComputation();
+
+ IccTransform transform;
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ ImageIface *iface = m_previewWidget->imageIface();
+ m_destinationPreviewData = iface->getPreviewImage();
+ int w = iface->previewWidth();
+ int h = iface->previewHeight();
+ bool a = iface->previewHasAlpha();
+ bool sb = iface->previewSixteenBit();
+
+ DImg preview(w, h, sb, a, m_destinationPreviewData);
+
+ QString tmpInPath = QString();
+ QString tmpProofPath = QString();
+ QString tmpSpacePath = QString();
+
+ bool proofCondition = false;
+ bool spaceCondition = false;
+
+ //-- Input profile parameters ------------------
+
+ if (useDefaultInProfile())
+ {
+ tmpInPath = m_inPath;
+ }
+ else if (useSelectedInProfile())
+ {
+ tmpInPath = m_inProfilesPath->url();
+ QFileInfo info(tmpInPath);
+ if (!info.exists() || !info.isReadable() || !info.isFile())
+ {
+ KMessageBox::information(kapp->activeWindow(),
+ i18n("<p>The selected ICC input profile path seems to be invalid.<p>"
+ "Please check it."));
+ return;
+ }
+ }
+
+ //-- Proof profile parameters ------------------
+
+ if (useDefaultProofProfile())
+ {
+ tmpProofPath = m_proofPath;
+ }
+ else
+ {
+ tmpProofPath = m_proofProfilePath->url();
+ QFileInfo info(tmpProofPath);
+ if (!info.exists() || !info.isReadable() || !info.isFile())
+ {
+ KMessageBox::information(kapp->activeWindow(),
+ i18n("<p>The selected ICC proof profile path seems to be invalid.<p>"
+ "Please check it."));
+ return;
+ }
+ }
+
+ if (m_doSoftProofBox->isChecked())
+ proofCondition = tmpProofPath.isEmpty();
+
+ //-- Workspace profile parameters --------------
+
+ if (useDefaultSpaceProfile())
+ {
+ tmpSpacePath = m_spacePath;
+ }
+ else
+ {
+ tmpSpacePath = m_spaceProfilePath->url();
+ QFileInfo info(tmpSpacePath);
+ if (!info.exists() || !info.isReadable() || !info.isFile())
+ {
+ KMessageBox::information(kapp->activeWindow(),
+ i18n("<p>Selected ICC workspace profile path seems to be invalid.<p>"
+ "Please check it."));
+ return;
+ }
+ }
+
+ spaceCondition = tmpSpacePath.isEmpty();
+
+ //-- Perform the color transformations ------------------
+
+ transform.getTransformType(m_doSoftProofBox->isChecked());
+
+ if (m_doSoftProofBox->isChecked())
+ {
+ if (m_useEmbeddedProfile->isChecked())
+ {
+ transform.setProfiles(tmpSpacePath, tmpProofPath, true);
+ }
+ else
+ {
+ transform.setProfiles(tmpInPath, tmpSpacePath, tmpProofPath);
+ }
+ }
+ else
+ {
+ if (m_useEmbeddedProfile->isChecked())
+ {
+ transform.setProfiles(tmpSpacePath);
+ }
+ else
+ {
+ transform.setProfiles(tmpInPath, tmpSpacePath);
+ }
+ }
+
+ if ( proofCondition || spaceCondition )
+ {
+ kapp->restoreOverrideCursor();
+ QString error = i18n("<p>Your settings are not sufficient.</p>"
+ "<p>To apply a color transform, you need at least two ICC profiles:</p>"
+ "<ul><li>An \"Input\" profile.</li>"
+ "<li>A \"Workspace\" profile.</li></ul>"
+ "<p>If you want to do a \"soft-proof\" transform, in addition to these profiles "
+ "you need a \"Proof\" profile.</p>");
+ KMessageBox::information(kapp->activeWindow(), error);
+ m_gboxSettings->enableButton(EditorToolSettings::Ok, false);
+ }
+ else
+ {
+ if (m_useEmbeddedProfile->isChecked())
+ {
+ transform.apply(preview, m_embeddedICC, m_renderingIntentsCB->currentItem(), useBPC(),
+ m_checkGamutBox->isChecked(), useBuiltinProfile());
+ }
+ else
+ {
+ QByteArray fakeProfile = QByteArray();
+ transform.apply(preview, fakeProfile, m_renderingIntentsCB->currentItem(), useBPC(),
+ m_checkGamutBox->isChecked(), useBuiltinProfile());
+ }
+
+ //-- Calculate and apply the curve on image after transformation -------------
+
+ DImg preview2(w, h, sb, a, 0, false);
+ m_curvesWidget->curves()->curvesLutSetup(ImageHistogram::AlphaChannel);
+ m_curvesWidget->curves()->curvesLutProcess(preview.bits(), preview2.bits(), w, h);
+
+ //-- Adjust contrast ---------------------------------------------------------
+
+ BCGModifier cmod;
+ cmod.setContrast((double)(m_cInput->value()/100.0) + 1.00);
+ cmod.applyBCG(preview2);
+
+ iface->putPreviewImage(preview2.bits());
+ m_previewWidget->updatePreview();
+
+ //-- Update histogram --------------------------------------------------------
+
+ memcpy(m_destinationPreviewData, preview2.bits(), preview2.numBytes());
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false);
+ kapp->restoreOverrideCursor();
+ }
+}
+
+void ICCProofTool::finalRendering()
+{
+ if (!m_doSoftProofBox->isChecked())
+ {
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ ImageIface *iface = m_previewWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int w = iface->originalWidth();
+ int h = iface->originalHeight();
+ bool a = iface->originalHasAlpha();
+ bool sb = iface->originalSixteenBit();
+
+ if (data)
+ {
+ IccTransform transform;
+
+ DImg img(w, h, sb, a, data);
+
+ QString tmpInPath;
+ QString tmpProofPath;
+ QString tmpSpacePath;
+ bool proofCondition;
+
+ //-- Input profile parameters ------------------
+
+ if (useDefaultInProfile())
+ {
+ tmpInPath = m_inPath;
+ }
+ else if (useSelectedInProfile())
+ {
+ tmpInPath = m_inProfilesPath->url();
+ QFileInfo info(tmpInPath);
+ if (!info.exists() || !info.isReadable() || !info.isFile())
+ {
+ KMessageBox::information(kapp->activeWindow(),
+ i18n("<p>Selected ICC input profile path seems "
+ "to be invalid.<p>Please check it."));
+ return;
+ }
+ }
+
+ //-- Proof profile parameters ------------------
+
+ if (useDefaultProofProfile())
+ {
+ tmpProofPath = m_proofPath;
+ }
+ else
+ {
+ tmpProofPath = m_proofProfilePath->url();
+ QFileInfo info(tmpProofPath);
+ if (!info.exists() || !info.isReadable() || !info.isFile())
+ {
+ KMessageBox::information(kapp->activeWindow(),
+ i18n("<p>The selected ICC proof profile path seems "
+ "to be invalid.<p>Please check it."));
+ return;
+ }
+ }
+
+ if (tmpProofPath.isNull())
+ proofCondition = false;
+
+ //-- Workspace profile parameters --------------
+
+ if (useDefaultSpaceProfile())
+ {
+ tmpSpacePath = m_spacePath;
+ }
+ else
+ {
+ tmpSpacePath = m_spaceProfilePath->url();
+ QFileInfo info(tmpSpacePath);
+ if (!info.exists() || !info.isReadable() || !info.isFile())
+ {
+ KMessageBox::information(kapp->activeWindow(),
+ i18n("<p>Selected ICC workspace profile path seems "
+ "to be invalid.<p>Please check it."));
+ return;
+ }
+ }
+
+ //-- Perform the color transformations ------------------
+
+ transform.getTransformType(m_doSoftProofBox->isChecked());
+
+ if (m_doSoftProofBox->isChecked())
+ {
+ if (m_useEmbeddedProfile->isChecked())
+ {
+ transform.setProfiles( tmpSpacePath, tmpProofPath, true );
+ }
+ else
+ {
+ transform.setProfiles( tmpInPath, tmpSpacePath, tmpProofPath);
+ }
+ }
+ else
+ {
+ if (m_useEmbeddedProfile->isChecked())
+ {
+ transform.setProfiles( tmpSpacePath );
+ }
+ else
+ {
+ transform.setProfiles( tmpInPath, tmpSpacePath );
+ }
+ }
+
+ if (m_useEmbeddedProfile->isChecked())
+ {
+ transform.apply(img, m_embeddedICC, m_renderingIntentsCB->currentItem(), useBPC(),
+ m_checkGamutBox->isChecked(), useBuiltinProfile());
+ }
+ else
+ {
+ QByteArray fakeProfile = QByteArray();
+ transform.apply(img, fakeProfile, m_renderingIntentsCB->currentItem(), useBPC(),
+ m_checkGamutBox->isChecked(), useBuiltinProfile());
+ }
+
+ //-- Embed the workspace profile if necessary --------------------------------
+
+ if (m_embeddProfileBox->isChecked())
+ {
+ iface->setEmbeddedICCToOriginalImage(tmpSpacePath);
+ DDebug() << k_funcinfo << QFile::encodeName(tmpSpacePath) << endl;
+ }
+
+ //-- Calculate and apply the curve on image after transformation -------------
+
+ DImg img2(w, h, sb, a, 0, false);
+ m_curvesWidget->curves()->curvesLutSetup(ImageHistogram::AlphaChannel);
+ m_curvesWidget->curves()->curvesLutProcess(img.bits(), img2.bits(), w, h);
+
+ //-- Adjust contrast ---------------------------------------------------------
+
+ BCGModifier cmod;
+ cmod.setContrast((double)(m_cInput->value()/100.0) + 1.00);
+ cmod.applyBCG(img2);
+
+ iface->putOriginalImage("Color Management", img2.bits());
+ delete [] data;
+ }
+
+ kapp->restoreOverrideCursor();
+ }
+}
+
+void ICCProofTool::slotToggledWidgets( bool t)
+{
+ m_useInDefaultProfile->setEnabled(t);
+ m_useProofDefaultProfile->setEnabled(t);
+ m_useSpaceDefaultProfile->setEnabled(t);
+}
+
+void ICCProofTool::slotInICCInfo()
+{
+ if (useEmbeddedProfile())
+ {
+ getICCInfo(m_embeddedICC);
+ }
+ else if (useBuiltinProfile())
+ {
+ QString message = i18n("<p>You have selected the \"Default builtin sRGB profile\"</p>");
+ message.append(i18n("<p>This profile is built on the fly, so there is no relevant information "
+ "about it.</p>"));
+ KMessageBox::information(kapp->activeWindow(), message);
+ }
+ else if (useDefaultInProfile())
+ {
+ getICCInfo(m_inPath);
+ }
+ else if (useSelectedInProfile())
+ {
+ getICCInfo(m_inProfilesPath->url());
+ }
+}
+
+void ICCProofTool::slotProofICCInfo()
+{
+ if (useDefaultProofProfile())
+ {
+ getICCInfo(m_proofPath);
+ }
+ else
+ {
+ getICCInfo(m_proofProfilePath->url());
+ }
+}
+
+void ICCProofTool::slotSpaceICCInfo()
+{
+ if (useDefaultSpaceProfile())
+ {
+ getICCInfo(m_spacePath);
+ }
+ else
+ {
+ getICCInfo(m_spaceProfilePath->url());
+ }
+}
+
+void ICCProofTool::getICCInfo(const QString& profile)
+{
+ if (profile.isEmpty())
+ {
+ KMessageBox::error(kapp->activeWindow(),
+ i18n("Sorry, there is no selected profile"),
+ i18n("Profile Error"));
+ return;
+ }
+
+ ICCProfileInfoDlg infoDlg(kapp->activeWindow(), profile);
+ infoDlg.exec();
+}
+
+void ICCProofTool::getICCInfo(const QByteArray& profile)
+{
+ if (profile.isNull())
+ {
+ KMessageBox::error(kapp->activeWindow(),
+ i18n("Sorry, it seems there is no embedded profile"),
+ i18n("Profile Error"));
+ return;
+ }
+
+ ICCProfileInfoDlg infoDlg(kapp->activeWindow(), QString(), profile);
+ infoDlg.exec();
+}
+
+void ICCProofTool::slotCMDisabledWarning()
+{
+ if (!m_cmEnabled)
+ {
+ QString message = i18n("<p>You have not enabled Color Management in the digiKam preferences.</p>");
+ message.append(i18n("<p>\"Use of default profile\" options will be disabled now.</p>"));
+ KMessageBox::information(kapp->activeWindow(), message);
+ slotToggledWidgets(false);
+ }
+}
+
+//-- General Tab ---------------------------
+
+bool ICCProofTool::useBPC()
+{
+ return m_BPCBox->isChecked();
+}
+
+bool ICCProofTool::doProof()
+{
+ return m_doSoftProofBox->isChecked();
+}
+
+bool ICCProofTool::checkGamut()
+{
+ return m_checkGamutBox->isChecked();
+}
+
+bool ICCProofTool::embedProfile()
+{
+ return m_embeddProfileBox->isChecked();
+}
+
+//-- Input Tab ---------------------------
+
+bool ICCProofTool::useEmbeddedProfile()
+{
+ return m_useEmbeddedProfile->isChecked();
+}
+
+bool ICCProofTool::useBuiltinProfile()
+{
+ return m_useSRGBDefaultProfile->isChecked();
+}
+
+bool ICCProofTool::useDefaultInProfile()
+{
+ return m_useInDefaultProfile->isChecked();
+}
+
+bool ICCProofTool::useSelectedInProfile()
+{
+ return m_useInSelectedProfile->isChecked();
+}
+
+//-- Workspace Tab ---------------------------
+
+bool ICCProofTool::useDefaultSpaceProfile()
+{
+ return m_useSpaceDefaultProfile->isChecked();
+}
+
+//-- Proofing Tab ---------------------------
+
+bool ICCProofTool::useDefaultProofProfile()
+{
+ return m_useProofDefaultProfile->isChecked();
+}
+
+//-- Load all settings from file --------------------------------------
+
+void ICCProofTool::slotLoadSettings()
+{
+ KURL loadColorManagementFile = KFileDialog::getOpenURL(KGlobalSettings::documentPath(),
+ QString("*"), kapp->activeWindow(),
+ QString(i18n("Color Management Settings File to Load")));
+ if (loadColorManagementFile.isEmpty())
+ return;
+
+ QFile file(loadColorManagementFile.path());
+
+ if (file.open(IO_ReadOnly))
+ {
+ QTextStream stream(&file);
+
+ if (stream.readLine() != "# Color Management Configuration File")
+ {
+ KMessageBox::error(kapp->activeWindow(),
+ i18n("\"%1\" is not a Color Management settings text file.")
+ .arg(loadColorManagementFile.fileName()));
+ file.close();
+ return;
+ }
+
+ blockSignals(true);
+
+ m_renderingIntentsCB->setCurrentItem(stream.readLine().toInt());
+ m_doSoftProofBox->setChecked((bool) (stream.readLine().toUInt()));
+ m_checkGamutBox->setChecked((bool) (stream.readLine().toUInt()));
+ m_embeddProfileBox->setChecked((bool) (stream.readLine().toUInt()));
+ m_BPCBox->setChecked((bool) (stream.readLine().toUInt()));
+ m_inProfileBG->setButton(stream.readLine().toInt());
+ m_spaceProfileBG->setButton(stream.readLine().toInt());
+ m_proofProfileBG->setButton(stream.readLine().toInt());
+ m_inProfilesPath->setURL(stream.readLine());
+ m_proofProfilePath->setURL(stream.readLine());
+ m_spaceProfilePath->setURL(stream.readLine());
+ m_cInput->setValue(stream.readLine().toInt());
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curvesWidget->curves()->curvesChannelReset(i);
+
+ m_curvesWidget->curves()->setCurveType(m_curvesWidget->m_channelType, ImageCurves::CURVE_SMOOTH);
+ m_curvesWidget->reset();
+
+ for (int j = 0; j < 17; j++)
+ {
+ QPoint disable(-1, -1);
+ QPoint p;
+ p.setX(stream.readLine().toInt());
+ p.setY(stream.readLine().toInt());
+
+ if (m_originalImage->sixteenBit() && p != disable)
+ {
+ p.setX(p.x() * 255);
+ p.setY(p.y() * 255);
+ }
+
+ m_curvesWidget->curves()->setCurvePoint(ImageHistogram::ValueChannel, j, p);
+ }
+
+ blockSignals(false);
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curvesWidget->curves()->curvesCalculateCurve(i);
+
+ m_histogramWidget->reset();
+ slotEffect();
+ }
+ else
+ KMessageBox::error(kapp->activeWindow(),
+ i18n("Cannot load settings from the Color Management text file."));
+
+ file.close();
+}
+
+//-- Save all settings to file ---------------------------------------
+
+void ICCProofTool::slotSaveAsSettings()
+{
+ KURL saveColorManagementFile = KFileDialog::getSaveURL(KGlobalSettings::documentPath(),
+ QString( "*" ), kapp->activeWindow(),
+ QString(i18n("Color Management Settings File to Save")));
+ if (saveColorManagementFile.isEmpty())
+ return;
+
+ QFile file(saveColorManagementFile.path());
+
+ if (file.open(IO_WriteOnly))
+ {
+ QTextStream stream(&file);
+ stream << "# Color Management Configuration File\n";
+ stream << m_renderingIntentsCB->currentItem() << "\n";
+ stream << m_doSoftProofBox->isChecked() << "\n";
+ stream << m_checkGamutBox->isChecked() << "\n";
+ stream << m_embeddProfileBox->isChecked() << "\n";
+ stream << m_BPCBox->isChecked() << "\n";
+ stream << m_inProfileBG->selectedId() << "\n";
+ stream << m_spaceProfileBG->selectedId() << "\n";
+ stream << m_proofProfileBG->selectedId() << "\n";
+ stream << m_inProfilesPath->url() << "\n";
+ stream << m_proofProfilePath->url() << "\n";
+ stream << m_spaceProfilePath->url() << "\n";
+ stream << m_cInput->value() << "\n";
+
+ for (int j = 0; j < 17; j++)
+ {
+ QPoint p = m_curvesWidget->curves()->getCurvePoint(ImageHistogram::ValueChannel, j);
+ if (m_originalImage->sixteenBit())
+ {
+ p.setX(p.x() / 255);
+ p.setY(p.y() / 255);
+ }
+ stream << p.x() << "\n";
+ stream << p.y() << "\n";
+ }
+ }
+ else
+ KMessageBox::error(kapp->activeWindow(),
+ i18n("Cannot save settings to the Color Management text file."));
+
+ file.close();
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/iccprooftool.h b/digikam/imageplugins/coreplugin/iccprooftool.h
new file mode 100644
index 0000000..cd1d783
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/iccprooftool.h
@@ -0,0 +1,208 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-12-21
+ * Description : digiKam image editor tool to correct picture
+ * colors using an ICC color profile
+ *
+ * Copyright (C) 2005-2006 by F.J. Cruz <fj.cruz@supercable.es>
+ * Copyright (C) 2006-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 ICCPROOFTOOL_H
+#define ICCPROOFTOOL_H
+
+// Digikam includes.
+
+#include "editortool.h"
+
+class QCheckBox;
+class QComboBox;
+class QVButtonGroup;
+class QButtonGroup;
+class QHButtonGroup;
+class QRadioButton;
+class QPushButton;
+class QToolBox;
+
+class KURLRequester;
+
+namespace KDcrawIface
+{
+class RIntNumInput;
+class RComboBox;
+}
+
+namespace Digikam
+{
+class ICCTransform;
+class ImageWidget;
+class HistogramWidget;
+class ColorGradientWidget;
+class DColor;
+class ICCPreviewWidget;
+class CurvesWidget;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class ICCProofTool : public Digikam::EditorTool
+{
+ Q_OBJECT
+
+public:
+
+ ICCProofTool(QObject* parent);
+ ~ICCProofTool();
+
+protected:
+
+ void finalRendering();
+
+private:
+
+ void readSettings();
+ void writeSettings();
+
+ void getICCInfo(const QString&);
+ void getICCInfo(const QByteArray&);
+
+ bool useBPC();
+ bool doProof();
+ bool checkGamut();
+ bool embedProfile();
+
+ bool useEmbeddedProfile();
+ bool useBuiltinProfile();
+ bool useDefaultInProfile();
+ bool useSelectedInProfile();
+
+ bool useDefaultSpaceProfile();
+ bool useSelectedSpaceProfile();
+
+ bool useDefaultProofProfile();
+ bool useSelectedProofProfile();
+
+private slots:
+
+ void slotSaveAsSettings();
+ void slotLoadSettings();
+ void slotEffect();
+ void slotResetSettings();
+ void slotChannelChanged(int);
+ void slotScaleChanged(int);
+ void slotSpotColorChanged(const Digikam::DColor &);
+ void slotColorSelectedFromTarget(const Digikam::DColor &);
+ void slotToggledWidgets(bool);
+ void slotInICCInfo();
+ void slotProofICCInfo();
+ void slotSpaceICCInfo();
+ void slotCMDisabledWarning();
+ void processLCMSURL(const QString&);
+
+private:
+
+ enum HistogramScale
+ {
+ Linear = 0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel = 0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ enum ICCSettingsTab
+ {
+ GENERALPAGE=0,
+ INPUTPAGE,
+ WORKSPACEPAGE,
+ PROOFINGPAGE,
+ LIGHTNESSPAGE
+ };
+
+ bool m_cmEnabled;
+ bool m_hasICC;
+
+ uchar *m_destinationPreviewData;
+
+ QComboBox *m_channelCB;
+
+ QCheckBox *m_doSoftProofBox;
+ QCheckBox *m_checkGamutBox;
+ QCheckBox *m_embeddProfileBox;
+ QCheckBox *m_BPCBox;
+
+ QRadioButton *m_useEmbeddedProfile;
+ QRadioButton *m_useInDefaultProfile;
+ QRadioButton *m_useInSelectedProfile;
+ QRadioButton *m_useProofDefaultProfile;
+ QRadioButton *m_useProofSelectedProfile;
+ QRadioButton *m_useSpaceDefaultProfile;
+ QRadioButton *m_useSpaceSelectedProfile;
+ QRadioButton *m_useSRGBDefaultProfile;
+
+ QString m_inPath;
+ QString m_spacePath;
+ QString m_proofPath;
+
+ QButtonGroup *m_optionsBG;
+ QButtonGroup *m_inProfileBG;
+ QButtonGroup *m_spaceProfileBG;
+ QButtonGroup *m_proofProfileBG;
+
+ QHButtonGroup *m_scaleBG;
+ QVButtonGroup *m_renderingIntentBG;
+ QVButtonGroup *m_profilesBG;
+
+ QByteArray m_embeddedICC;
+
+ QToolBox *m_toolBoxWidgets;
+
+ KURLRequester *m_inProfilesPath;
+ KURLRequester *m_spaceProfilePath;
+ KURLRequester *m_proofProfilePath;
+
+ KDcrawIface::RIntNumInput *m_cInput;
+
+ KDcrawIface::RComboBox *m_renderingIntentsCB;
+
+ Digikam::DImg *m_originalImage;
+
+ Digikam::CurvesWidget *m_curvesWidget;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+
+ Digikam::ICCPreviewWidget *m_iccInPreviewWidget;
+ Digikam::ICCPreviewWidget *m_iccSpacePreviewWidget;
+ Digikam::ICCPreviewWidget *m_iccProofPreviewWidget;
+
+ Digikam::EditorToolSettings *m_gboxSettings;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif // ICCPROOFTOOL_H
diff --git a/digikam/imageplugins/coreplugin/imageeffect_autocorrection.cpp b/digikam/imageplugins/coreplugin/imageeffect_autocorrection.cpp
new file mode 100644
index 0000000..1d4a232
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_autocorrection.cpp
@@ -0,0 +1,431 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-05-31
+ * Description : Auto-Color correction tool.
+ *
+ * Copyright (C) 2005-2007 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.
+ *
+ * ============================================================ */
+
+ // Qt includes.
+
+#include <qcolor.h>
+#include <qgroupbox.h>
+#include <qhgroupbox.h>
+#include <qvgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qradiobutton.h>
+#include <qvgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qtimer.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qlistbox.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+
+// KDE includes.
+
+#include <kcursor.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kapplication.h>
+
+// Digikam includes.
+
+#include "imageiface.h"
+#include "imagewidget.h"
+#include "histogramwidget.h"
+#include "colorgradientwidget.h"
+#include "dimgimagefilters.h"
+#include "whitebalance.h"
+#include "dimg.h"
+#include "listboxpreviewitem.h"
+
+// Local includes.
+
+#include "imageeffect_autocorrection.h"
+#include "imageeffect_autocorrection.moc"
+
+namespace DigikamImagesPluginCore
+{
+
+ImageEffect_AutoCorrection::ImageEffect_AutoCorrection(QWidget* parent)
+ : Digikam::ImageDlgBase(parent, i18n("Auto Color Correction"),
+ "autocorrection", false), m_destinationPreviewData(0L)
+{
+ setHelp("autocolorcorrectiontool.anchor", "digikam");
+
+ // -------------------------------------------------------------
+
+ m_previewWidget = new Digikam::ImageWidget("autocorrection Tool Dialog", plainPage(),
+ i18n("<p>Here you can see the auto-color correction tool "
+ "preview. You can pick color on image "
+ "to see the color level corresponding on histogram."));
+ setPreviewAreaWidget(m_previewWidget);
+
+ // -------------------------------------------------------------
+
+ Digikam::ImageIface iface(0, 0);
+ m_thumbnailImage = iface.getOriginalImg()->smoothScale(128, 128, QSize::ScaleMin);
+
+ QWidget *gboxSettings = new QWidget(plainPage());
+ QGridLayout* gridSettings = new QGridLayout( gboxSettings, 4, 4, spacingHint());
+
+ QLabel *label1 = new QLabel(i18n("Channel:"), gboxSettings);
+ label1->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ m_channelCB = new QComboBox( false, gboxSettings );
+ m_channelCB->insertItem( i18n("Luminosity") );
+ m_channelCB->insertItem( i18n("Red") );
+ m_channelCB->insertItem( i18n("Green") );
+ m_channelCB->insertItem( i18n("Blue") );
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red image-channel values.<p>"
+ "<b>Green</b>: display the green image-channel values.<p>"
+ "<b>Blue</b>: display the blue image-channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(gboxSettings);
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin( 0 );
+ QWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximal counts are small, you can use the linear scale.<p>"
+ "Logarithmic scale can be used when the maximal counts are big; "
+ "if it is used, all values (small and large) will be visible on the graph."));
+
+ QPushButton *linHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( linHistoButton, i18n( "<p>Linear" ) );
+ m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap( QPixmap( directory + "histogram-lin.png" ) );
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) );
+ m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap( QPixmap( directory + "histogram-log.png" ) );
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(gboxSettings);
+ m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram drawing "
+ "of the selected image channel. This one is re-computed at any "
+ "settings changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new Digikam::ColorGradientWidget( Digikam::ColorGradientWidget::Horizontal, 10, histoBox );
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+
+ gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4);
+
+ // -------------------------------------------------------------
+
+ m_correctionTools = new QListBox(gboxSettings);
+ m_correctionTools->setColumnMode(1);
+ m_correctionTools->setVariableWidth(false);
+ m_correctionTools->setVariableHeight(false);
+ Digikam::ListBoxWhatsThis* whatsThis = new Digikam::ListBoxWhatsThis(m_correctionTools);
+
+ QPixmap pix = getThumbnailForEffect(AutoLevelsCorrection);
+ Digikam::ListBoxPreviewItem *item = new Digikam::ListBoxPreviewItem(pix, i18n("Auto Levels"));
+ whatsThis->add( item, i18n("<b>Auto Levels</b>:"
+ "<p>This option maximizes the tonal range in the Red, "
+ "Green, and Blue channels. It searches the image shadow and highlight "
+ "limit values and adjusts the Red, Green, and Blue channels "
+ "to a full histogram range.</p>"));
+ m_correctionTools->insertItem(item, AutoLevelsCorrection);
+
+ pix = getThumbnailForEffect(NormalizeCorrection);
+ item = new Digikam::ListBoxPreviewItem(pix, i18n("Normalize"));
+ whatsThis->add( item, i18n("<b>Normalize</b>:"
+ "<p>This option scales brightness values across the active "
+ "image so that the darkest point becomes black, and the "
+ "brightest point becomes as bright as possible without "
+ "altering its hue. This is often a \"magic fix\" for "
+ "images that are dim or washed out.</p>"));
+ m_correctionTools->insertItem(item, NormalizeCorrection);
+
+ pix = getThumbnailForEffect(EqualizeCorrection);
+ item = new Digikam::ListBoxPreviewItem(pix, i18n("Equalize"));
+ whatsThis->add( item, i18n("<b>Equalize</b>:"
+ "<p>This option adjusts the brightness of colors across the "
+ "active image so that the histogram for the value channel "
+ "is as nearly as possible flat, that is, so that each possible "
+ "brightness value appears at about the same number of pixels "
+ "as each other value. Sometimes Equalize works wonderfully at "
+ "enhancing the contrasts in an image. Other times it gives "
+ "garbage. It is a very powerful operation, which can either work "
+ "miracles on an image or destroy it.</p>"));
+ m_correctionTools->insertItem(item, EqualizeCorrection);
+
+ pix = getThumbnailForEffect(StretchContrastCorrection);
+ item = new Digikam::ListBoxPreviewItem(pix, i18n("Stretch Contrast"));
+ whatsThis->add( item, i18n("<b>Stretch Contrast</b>:"
+ "<p>This option enhances the contrast and brightness "
+ "of the RGB values of an image by stretching the lowest "
+ "and highest values to their fullest range, adjusting "
+ "everything in between.</p>"));
+ m_correctionTools->insertItem(item, StretchContrastCorrection);
+
+ pix = getThumbnailForEffect(AutoExposureCorrection);
+ item = new Digikam::ListBoxPreviewItem(pix, i18n("Auto Exposure"));
+ whatsThis->add( item, i18n("<b>Auto Exposure</b>:"
+ "<p>This option enhances the contrast and brightness "
+ "of the RGB values of an image to calculate optimal "
+ "exposition and black level using image histogram "
+ "properties.</p>"));
+ m_correctionTools->insertItem(item, AutoExposureCorrection);
+
+ // -------------------------------------------------------------
+
+ m_correctionTools->setFocus();
+ gridSettings->addMultiCellWidget(m_correctionTools, 3, 3, 0, 4);
+ gridSettings->setRowStretch(3, 10);
+ setUserAreaWidget(gboxSettings);
+
+ // -------------------------------------------------------------
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const QPoint & )),
+ this, SLOT(slotColorSelectedFromTarget( const Digikam::DColor & )));
+
+ connect(m_correctionTools, SIGNAL(highlighted(int)),
+ this, SLOT(slotEffect()));
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+}
+
+ImageEffect_AutoCorrection::~ImageEffect_AutoCorrection()
+{
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ delete m_histogramWidget;
+ delete m_previewWidget;
+}
+
+void ImageEffect_AutoCorrection::slotChannelChanged(int channel)
+{
+ switch(channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::ValueHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "red" ) );
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "green" ) );
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "blue" ) );
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_AutoCorrection::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_AutoCorrection::slotColorSelectedFromTarget( const Digikam::DColor &color )
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void ImageEffect_AutoCorrection::readUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("autocorrection Tool Dialog");
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", Digikam::HistogramWidget::LogScaleHistogram));
+ m_correctionTools->setCurrentItem(config->readNumEntry("Auto Correction Filter", AutoLevelsCorrection));
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+}
+
+void ImageEffect_AutoCorrection::writeUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("autocorrection Tool Dialog");
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writeEntry("Auto Correction Filter", m_correctionTools->currentItem());
+ config->sync();
+}
+
+void ImageEffect_AutoCorrection::resetValues()
+{
+ m_correctionTools->blockSignals(true);
+ m_correctionTools->setCurrentItem(AutoLevelsCorrection);
+ m_correctionTools->blockSignals(false);
+}
+
+void ImageEffect_AutoCorrection::slotEffect()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ uchar *m_destinationPreviewData = iface->getPreviewImage();
+ int w = iface->previewWidth();
+ int h = iface->previewHeight();
+ bool sb = iface->previewSixteenBit();
+
+ autoCorrection(m_destinationPreviewData, w, h, sb, m_correctionTools->currentItem());
+
+ iface->putPreviewImage(m_destinationPreviewData);
+ m_previewWidget->updatePreview();
+
+ // Update histogram.
+
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false);
+
+ kapp->restoreOverrideCursor();
+}
+
+QPixmap ImageEffect_AutoCorrection::getThumbnailForEffect(AutoCorrectionType type)
+{
+ Digikam::DImg thumb = m_thumbnailImage.copy();
+ autoCorrection(thumb.bits(), thumb.width(), thumb.height(), thumb.sixteenBit(), type);
+ return (thumb.convertToPixmap());
+}
+
+
+void ImageEffect_AutoCorrection::finalRendering()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int w = iface->originalWidth();
+ int h = iface->originalHeight();
+ bool sb = iface->originalSixteenBit();
+
+ if (data)
+ {
+ int type = m_correctionTools->currentItem();
+ autoCorrection(data, w, h, sb, type);
+ QString name;
+
+ switch (type)
+ {
+ case AutoLevelsCorrection:
+ name = i18n("Auto Levels");
+ break;
+
+ case NormalizeCorrection:
+ name = i18n("Normalize");
+ break;
+
+ case EqualizeCorrection:
+ name = i18n("Equalize");
+ break;
+
+ case StretchContrastCorrection:
+ name = i18n("Stretch Contrast");
+ break;
+
+ case AutoExposureCorrection:
+ name = i18n("Auto Exposure");
+ break;
+ }
+
+ iface->putOriginalImage(name, data);
+ delete [] data;
+ }
+
+ kapp->restoreOverrideCursor();
+ accept();
+}
+
+void ImageEffect_AutoCorrection::autoCorrection(uchar *data, int w, int h, bool sb, int type)
+{
+ Digikam::DImgImageFilters filter;
+
+ switch (type)
+ {
+ case AutoLevelsCorrection:
+ filter.autoLevelsCorrectionImage(data, w, h, sb);
+ break;
+
+ case NormalizeCorrection:
+ filter.normalizeImage(data, w, h, sb);
+ break;
+
+ case EqualizeCorrection:
+ filter.equalizeImage(data, w, h, sb);
+ break;
+
+ case StretchContrastCorrection:
+ filter.stretchContrastImage(data, w, h, sb);
+ break;
+
+ case AutoExposureCorrection:
+ Digikam::WhiteBalance wbFilter(sb);
+ double blackLevel;
+ double exposureLevel;
+ wbFilter.autoExposureAdjustement(data, w, h, sb, blackLevel, exposureLevel);
+ wbFilter.whiteBalance(data, w, h, sb, blackLevel, exposureLevel);
+ break;
+ }
+}
+
+} // NameSpace DigikamImagesPluginCore
+
diff --git a/digikam/imageplugins/coreplugin/imageeffect_autocorrection.h b/digikam/imageplugins/coreplugin/imageeffect_autocorrection.h
new file mode 100644
index 0000000..286fc01
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_autocorrection.h
@@ -0,0 +1,127 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-05-31
+ * Description : Auto-Color correction tool.
+ *
+ * Copyright (C) 2005-2007 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 IMAGEEFFECT_AUTOCORRECTION_H
+#define IMAGEEFFECT_AUTOCORRECTION_H
+
+// Qt Includes.
+
+#include <qstring.h>
+
+// Digikam include.
+
+#include "imagedlgbase.h"
+
+class QHButtonGroup;
+class QComboBox;
+class QListBox;
+class QButtonGroup;
+
+namespace Digikam
+{
+class HistogramWidget;
+class ColorGradientWidget;
+class ImageWidget;
+class DColor;
+class DImg;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class ImageEffect_AutoCorrection : public Digikam::ImageDlgBase
+{
+ Q_OBJECT
+
+public:
+
+ ImageEffect_AutoCorrection(QWidget *parent);
+ ~ImageEffect_AutoCorrection();
+
+protected:
+
+ void finalRendering();
+
+private slots:
+
+ void slotEffect();
+ void slotChannelChanged(int channel);
+ void slotScaleChanged(int scale);
+ void slotColorSelectedFromTarget(const Digikam::DColor &color);
+
+private:
+
+ enum AutoCorrectionType
+ {
+ AutoLevelsCorrection=0,
+ NormalizeCorrection,
+ EqualizeCorrection,
+ StretchContrastCorrection,
+ AutoExposureCorrection
+ };
+
+private:
+
+ void readUserSettings();
+ void writeUserSettings();
+ void resetValues();
+
+ void autoCorrection(uchar *data, int w, int h, bool sb, int type);
+ QPixmap getThumbnailForEffect(AutoCorrectionType type);
+
+private:
+
+ enum HistogramScale
+ {
+ Linear=0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel=0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ uchar *m_destinationPreviewData;
+
+ QComboBox *m_channelCB;
+
+ QHButtonGroup *m_scaleBG;
+
+ QListBox *m_correctionTools;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+
+ Digikam::DImg m_thumbnailImage;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* IMAGEEFFECT_AUTOCORRECTION_H */
diff --git a/digikam/imageplugins/coreplugin/imageeffect_bcg.cpp b/digikam/imageplugins/coreplugin/imageeffect_bcg.cpp
new file mode 100644
index 0000000..9607e04
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_bcg.cpp
@@ -0,0 +1,350 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-06-05
+ * Description : digiKam image editor to adjust Brightness,
+ Contrast, and Gamma of picture.
+ *
+ * Copyright (C) 2004 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * Copyright (C) 2005-2007 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qcolor.h>
+#include <qgroupbox.h>
+#include <qhgroupbox.h>
+#include <qvgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qlabel.h>
+#include <qvbox.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+
+// KDE includes.
+
+#include <knuminput.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kstandarddirs.h>
+
+// Digikam includes.
+
+#include "imageiface.h"
+#include "imagewidget.h"
+#include "histogramwidget.h"
+#include "colorgradientwidget.h"
+#include "bcgmodifier.h"
+#include "dimg.h"
+
+// Local includes.
+
+#include "imageeffect_bcg.h"
+#include "imageeffect_bcg.moc"
+
+namespace DigikamImagesPluginCore
+{
+
+ImageEffect_BCG::ImageEffect_BCG(QWidget* parent)
+ : Digikam::ImageDlgBase(parent, i18n("Brightness Contrast Gamma Adjustments"),
+ "bcgadjust", false)
+{
+ m_destinationPreviewData = 0L;
+ setHelp("bcgadjusttool.anchor", "digikam");
+
+ m_previewWidget = new Digikam::ImageWidget("bcgadjust Tool Dialog", plainPage(),
+ i18n("<p>Here you can see the image "
+ "brightness-contrast-gamma adjustments preview. "
+ "You can pick color on image "
+ "to see the color level corresponding on histogram."));
+ setPreviewAreaWidget(m_previewWidget);
+
+ // -------------------------------------------------------------
+
+ QWidget *gboxSettings = new QWidget(plainPage());
+ QGridLayout* gridSettings = new QGridLayout( gboxSettings, 9, 4, spacingHint());
+
+ QLabel *label1 = new QLabel(i18n("Channel:"), gboxSettings);
+ label1->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ m_channelCB = new QComboBox( false, gboxSettings );
+ m_channelCB->insertItem( i18n("Luminosity") );
+ m_channelCB->insertItem( i18n("Red") );
+ m_channelCB->insertItem( i18n("Green") );
+ m_channelCB->insertItem( i18n("Blue") );
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red image-channel values.<p>"
+ "<b>Green</b>: display the green image-channel values.<p>"
+ "<b>Blue</b>: display the blue image-channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(gboxSettings);
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin( 0 );
+ QWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximal counts are small, you can use the linear scale.<p>"
+ "Logarithmic scale can be used when the maximal counts are big; "
+ "if it is used, all values (small and large) will be visible on the graph."));
+
+ QPushButton *linHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( linHistoButton, i18n( "<p>Linear" ) );
+ m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap( QPixmap( directory + "histogram-lin.png" ) );
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) );
+ m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap( QPixmap( directory + "histogram-log.png" ) );
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(gboxSettings);
+ m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram drawing "
+ "of the selected image channel. This one is re-computed at any "
+ "settings changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new Digikam::ColorGradientWidget( Digikam::ColorGradientWidget::Horizontal, 10, histoBox );
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+
+ gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4);
+
+ // -------------------------------------------------------------
+
+ QLabel *label2 = new QLabel(i18n("Brightness:"), gboxSettings);
+ m_bInput = new KIntNumInput(gboxSettings);
+ m_bInput->setRange(-100, 100, 1, true);
+ m_bInput->setValue(0);
+ QWhatsThis::add( m_bInput, i18n("<p>Set here the brightness adjustment of the image."));
+ gridSettings->addMultiCellWidget(label2, 3, 3, 0, 4);
+ gridSettings->addMultiCellWidget(m_bInput, 4, 4, 0, 4);
+
+ QLabel *label3 = new QLabel(i18n("Contrast:"), gboxSettings);
+ m_cInput = new KIntNumInput(gboxSettings);
+ m_cInput->setRange(-100, 100, 1, true);
+ m_cInput->setValue(0);
+ QWhatsThis::add( m_cInput, i18n("<p>Set here the contrast adjustment of the image."));
+ gridSettings->addMultiCellWidget(label3, 5, 5, 0, 4);
+ gridSettings->addMultiCellWidget(m_cInput, 6, 6, 0, 4);
+
+ QLabel *label4 = new QLabel(i18n("Gamma:"), gboxSettings);
+ m_gInput = new KDoubleNumInput(gboxSettings);
+ m_gInput->setPrecision(2);
+ m_gInput->setRange(0.1, 3.0, 0.01, true);
+ m_gInput->setValue(1.0);
+ QWhatsThis::add( m_gInput, i18n("<p>Set here the gamma adjustment of the image."));
+ gridSettings->addMultiCellWidget(label4, 7, 7, 0, 4);
+ gridSettings->addMultiCellWidget(m_gInput, 8, 8, 0, 4);
+
+ gridSettings->setRowStretch(9, 10);
+ setUserAreaWidget(gboxSettings);
+
+ // -------------------------------------------------------------
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const QPoint & )),
+ this, SLOT(slotColorSelectedFromTarget( const Digikam::DColor & )));
+
+ connect(m_bInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_cInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_gInput, SIGNAL(valueChanged(double)),
+ this, SLOT(slotTimer()));
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+
+ // -------------------------------------------------------------
+
+ enableButtonOK( false );
+}
+
+ImageEffect_BCG::~ImageEffect_BCG()
+{
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ delete m_histogramWidget;
+ delete m_previewWidget;
+}
+
+void ImageEffect_BCG::slotChannelChanged(int channel)
+{
+ switch(channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::ValueHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "red" ) );
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "green" ) );
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "blue" ) );
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_BCG::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_BCG::slotColorSelectedFromTarget( const Digikam::DColor &color )
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void ImageEffect_BCG::readUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("bcgadjust Tool Dialog");
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", Digikam::HistogramWidget::LogScaleHistogram));
+ m_bInput->setValue(config->readNumEntry("BrightnessAjustment", 0));
+ m_cInput->setValue(config->readNumEntry("ContrastAjustment", 0));
+ m_gInput->setValue(config->readDoubleNumEntry("GammaAjustment", 1.0));
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+}
+
+void ImageEffect_BCG::writeUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("bcgadjust Tool Dialog");
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writeEntry("BrightnessAjustment", m_bInput->value());
+ config->writeEntry("ContrastAjustment", m_cInput->value());
+ config->writeEntry("GammaAjustment", m_gInput->value());
+ config->sync();
+}
+
+void ImageEffect_BCG::resetValues()
+{
+ m_bInput->blockSignals(true);
+ m_cInput->blockSignals(true);
+ m_gInput->blockSignals(true);
+ m_bInput->setValue(0);
+ m_cInput->setValue(0);
+ m_gInput->setValue(1.0);
+ m_bInput->blockSignals(false);
+ m_cInput->blockSignals(false);
+ m_gInput->blockSignals(false);
+}
+
+void ImageEffect_BCG::slotEffect()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ double b = (double)m_bInput->value()/250.0;
+ double c = (double)(m_cInput->value()/100.0) + 1.00;
+ double g = m_gInput->value();
+
+ enableButtonOK( b != 0.0 || c != 1.0 || g != 1.0 );
+
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ m_destinationPreviewData = iface->getPreviewImage();
+ int w = iface->previewWidth();
+ int h = iface->previewHeight();
+ bool a = iface->previewHasAlpha();
+ bool sb = iface->previewSixteenBit();
+
+ Digikam::DImg preview(w, h, sb, a, m_destinationPreviewData);
+ Digikam::BCGModifier cmod;
+ cmod.setGamma(g);
+ cmod.setBrightness(b);
+ cmod.setContrast(c);
+ cmod.applyBCG(preview);
+ iface->putPreviewImage(preview.bits());
+
+ m_previewWidget->updatePreview();
+
+ // Update histogram.
+
+ memcpy(m_destinationPreviewData, preview.bits(), preview.numBytes());
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false);
+
+ kapp->restoreOverrideCursor();
+}
+
+void ImageEffect_BCG::finalRendering()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+
+ double b = (double)m_bInput->value()/250.0;
+ double c = (double)(m_cInput->value()/100.0) + 1.00;
+ double g = m_gInput->value();
+
+ iface->setOriginalBCG(b, c, g);
+ kapp->restoreOverrideCursor();
+ accept();
+}
+
+} // NameSpace DigikamImagesPluginCore
+
diff --git a/digikam/imageplugins/coreplugin/imageeffect_bcg.h b/digikam/imageplugins/coreplugin/imageeffect_bcg.h
new file mode 100644
index 0000000..c2ce110
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_bcg.h
@@ -0,0 +1,109 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-06-05
+ * Description : digiKam image editor to adjust Brightness,
+ Contrast, and Gamma of picture.
+ *
+ * Copyright (C) 2004 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * Copyright (C) 2005-2007 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 IMAGEEFFECT_BCG_H
+#define IMAGEEFFECT_BCG_H
+
+// Digikam include.
+
+#include "imagedlgbase.h"
+
+class QCheckBox;
+class QComboBox;
+class QHButtonGroup;
+
+class KIntNumInput;
+class KDoubleNumInput;
+
+namespace Digikam
+{
+class HistogramWidget;
+class ColorGradientWidget;
+class ImageWidget;
+class DColor;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class ImageEffect_BCG : public Digikam::ImageDlgBase
+{
+ Q_OBJECT
+
+public:
+
+ ImageEffect_BCG(QWidget *parent);
+ ~ImageEffect_BCG();
+
+private slots:
+
+ void slotEffect();
+ void slotChannelChanged(int channel);
+ void slotScaleChanged(int scale);
+ void slotColorSelectedFromTarget( const Digikam::DColor &color );
+
+private:
+
+ void readUserSettings();
+ void writeUserSettings();
+ void resetValues();
+ void finalRendering();
+
+private:
+
+ enum HistogramScale
+ {
+ Linear=0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel=0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ uchar *m_destinationPreviewData;
+
+ QComboBox *m_channelCB;
+
+ QHButtonGroup *m_scaleBG;
+
+ KIntNumInput *m_bInput;
+ KIntNumInput *m_cInput;
+ KDoubleNumInput *m_gInput;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* IMAGEEFFECT_BCG_H */
diff --git a/digikam/imageplugins/coreplugin/imageeffect_blur.cpp b/digikam/imageplugins/coreplugin/imageeffect_blur.cpp
new file mode 100644
index 0000000..d11d156
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_blur.cpp
@@ -0,0 +1,147 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-09
+ * Description : a tool to blur an image
+ *
+ * Copyright (C) 2004-2007 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+
+// KDE includes.
+
+#include <kaboutdata.h>
+#include <knuminput.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <klocale.h>
+#include <kapplication.h>
+
+// Digikam includes.
+
+#include "ddebug.h"
+#include "imageiface.h"
+#include "dimggaussianblur.h"
+
+// Local includes.
+
+#include "imageeffect_blur.h"
+#include "imageeffect_blur.moc"
+
+namespace DigikamImagesPluginCore
+{
+
+ImageEffect_Blur::ImageEffect_Blur(QWidget* parent)
+ : Digikam::CtrlPanelDlg(parent, i18n("Apply Gaussian Blur on Photograph"),
+ "gaussianblur", false, true, true)
+{
+ setHelp("blursharpentool.anchor", "digikam");
+
+ QWidget *gboxSettings = new QWidget(m_imagePreviewWidget);
+ QGridLayout* gridSettings = new QGridLayout( gboxSettings, 1, 1, 0, spacingHint());
+ QLabel *label = new QLabel(i18n("Smoothness:"), gboxSettings);
+
+ m_radiusInput = new KIntNumInput(gboxSettings);
+ m_radiusInput->setRange(0, 100, 1, true);
+ m_radiusInput->setValue(0);
+ QWhatsThis::add( m_radiusInput, i18n("<p>A smoothness of 0 has no effect, "
+ "1 and above determine the Gaussian blur matrix radius "
+ "that determines how much to blur the image."));
+
+ gridSettings->addMultiCellWidget(label, 0, 0, 0, 1);
+ gridSettings->addMultiCellWidget(m_radiusInput, 1, 1, 0, 1);
+
+ m_imagePreviewWidget->setUserAreaWidget(gboxSettings);
+}
+
+ImageEffect_Blur::~ImageEffect_Blur()
+{
+}
+
+void ImageEffect_Blur::readUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("gaussianblur Tool Dialog");
+ m_radiusInput->setValue(config->readNumEntry("RadiusAjustment", 0));
+}
+
+void ImageEffect_Blur::writeUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("gaussianblur Tool Dialog");
+ config->writeEntry("RadiusAjustment", m_radiusInput->value());
+ config->sync();
+}
+
+void ImageEffect_Blur::resetValues(void)
+{
+ m_radiusInput->blockSignals(true);
+ m_radiusInput->setValue(0);
+ m_radiusInput->blockSignals(false);
+}
+
+void ImageEffect_Blur::prepareEffect()
+{
+ m_radiusInput->setEnabled(false);
+
+ Digikam::DImg img = m_imagePreviewWidget->getOriginalRegionImage();
+
+ m_threadedFilter = dynamic_cast<Digikam::DImgThreadedFilter *>
+ (new Digikam::DImgGaussianBlur(&img, this, m_radiusInput->value()));
+}
+
+void ImageEffect_Blur::prepareFinal()
+{
+ m_radiusInput->setEnabled(false);
+
+ Digikam::ImageIface iface(0, 0);
+ uchar *data = iface.getOriginalImage();
+ int w = iface.originalWidth();
+ int h = iface.originalHeight();
+ bool sixteenBit = iface.originalSixteenBit();
+ bool hasAlpha = iface.originalHasAlpha();
+ Digikam::DImg orgImage = Digikam::DImg(w, h, sixteenBit, hasAlpha ,data);
+ delete [] data;
+ m_threadedFilter = dynamic_cast<Digikam::DImgThreadedFilter *>
+ (new Digikam::DImgGaussianBlur(&orgImage, this, m_radiusInput->value()));
+}
+
+void ImageEffect_Blur::putPreviewData(void)
+{
+ Digikam::DImg imDest = m_threadedFilter->getTargetImage();
+ m_imagePreviewWidget->setPreviewImage(imDest);
+}
+
+void ImageEffect_Blur::putFinalData(void)
+{
+ Digikam::ImageIface iface(0, 0);
+ Digikam::DImg imDest = m_threadedFilter->getTargetImage();
+ iface.putOriginalImage(i18n("Gaussian Blur"), imDest.bits());
+}
+
+void ImageEffect_Blur::renderingFinished(void)
+{
+ m_radiusInput->setEnabled(true);
+}
+
+} // NameSpace DigikamImagesPluginCore
+
diff --git a/digikam/imageplugins/coreplugin/imageeffect_blur.h b/digikam/imageplugins/coreplugin/imageeffect_blur.h
new file mode 100644
index 0000000..c0448f7
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_blur.h
@@ -0,0 +1,67 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-09
+ * Description : a tool to blur an image
+ *
+ * Copyright (C) 2004-2007 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 IMAGEEFFECT_BLUR_H
+#define IMAGEEFFECT_BLUR_H
+
+// Digikam include.
+
+#include "ctrlpaneldlg.h"
+
+class KIntNumInput;
+
+namespace DigikamImagesPluginCore
+{
+
+class ImageEffect_Blur : public Digikam::CtrlPanelDlg
+{
+ Q_OBJECT
+
+public:
+
+ ImageEffect_Blur(QWidget *parent);
+ ~ImageEffect_Blur();
+
+private slots:
+
+ void readUserSettings();
+
+private:
+
+ void writeUserSettings();
+ void resetValues();
+ void prepareEffect();
+ void prepareFinal();
+ void abortPreview();
+ void putPreviewData();
+ void putFinalData();
+ void renderingFinished();
+
+private:
+
+ KIntNumInput *m_radiusInput;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* IMAGEEFFECT_BLUR_H */
diff --git a/digikam/imageplugins/coreplugin/imageeffect_bwsepia.cpp b/digikam/imageplugins/coreplugin/imageeffect_bwsepia.cpp
new file mode 100644
index 0000000..11aed2f
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_bwsepia.cpp
@@ -0,0 +1,1183 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-12-06
+ * Description : Black and White conversion tool.
+ *
+ * Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * Copyright (C) 2006-2007 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.
+ *
+ * ============================================================ */
+
+ // Qt includes.
+
+#include <qcolor.h>
+#include <qgroupbox.h>
+#include <qhgroupbox.h>
+#include <qvgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qlistbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qtimer.h>
+#include <qcombobox.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+#include <qintdict.h>
+#include <qtextstream.h>
+#include <qfile.h>
+#include <qvbox.h>
+
+// KDE includes.
+
+#include <kfiledialog.h>
+#include <kglobalsettings.h>
+#include <kmessagebox.h>
+#include <kcursor.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kapplication.h>
+#include <knuminput.h>
+#include <ktabwidget.h>
+#include <kconfig.h>
+
+// Digikam includes.
+
+#include "imageiface.h"
+#include "imagehistogram.h"
+#include "dimgimagefilters.h"
+#include "imagewidget.h"
+#include "imagecurves.h"
+#include "histogramwidget.h"
+#include "curveswidget.h"
+#include "colorgradientwidget.h"
+#include "dimg.h"
+#include "bcgmodifier.h"
+#include "listboxpreviewitem.h"
+
+// Local includes.
+
+#include "imageeffect_bwsepia.h"
+#include "imageeffect_bwsepia.moc"
+
+namespace DigikamImagesPluginCore
+{
+
+class PreviewPixmapFactory : public QObject
+{
+public:
+
+ PreviewPixmapFactory(ImageEffect_BWSepia* bwSepia);
+
+ void invalidate() { m_previewPixmapMap.clear(); }
+
+ const QPixmap* pixmap(int id);
+
+private:
+
+ QPixmap makePixmap(int id);
+
+ QIntDict<QPixmap> m_previewPixmapMap;
+ ImageEffect_BWSepia *m_bwSepia;
+};
+
+PreviewPixmapFactory::PreviewPixmapFactory(ImageEffect_BWSepia* bwSepia)
+ : QObject(bwSepia), m_bwSepia(bwSepia)
+{
+ m_previewPixmapMap.setAutoDelete(true);
+}
+
+const QPixmap* PreviewPixmapFactory::pixmap(int id)
+{
+ if (m_previewPixmapMap.find(id) == 0)
+ {
+ QPixmap pix = makePixmap(id);
+ m_previewPixmapMap.insert(id, new QPixmap(pix));
+ }
+
+ QPixmap* res = m_previewPixmapMap[id];
+
+ return res;
+}
+
+QPixmap PreviewPixmapFactory::makePixmap(int id)
+{
+ return m_bwSepia->getThumbnailForEffect(id);
+}
+
+// -----------------------------------------------------------------------------------
+
+class ListBoxBWPreviewItem : public Digikam::ListBoxPreviewItem
+{
+
+public:
+
+ ListBoxBWPreviewItem(QListBox *listbox, const QString &text,
+ PreviewPixmapFactory* factory, int id)
+ : ListBoxPreviewItem(listbox, QPixmap(), text)
+ {
+ m_previewPixmapFactory = factory;
+ m_id = id;
+ };
+
+ virtual const QPixmap* pixmap() const;
+
+private:
+
+ int m_id;
+ PreviewPixmapFactory* m_previewPixmapFactory;
+};
+
+const QPixmap* ListBoxBWPreviewItem::pixmap() const
+{
+ return m_previewPixmapFactory->pixmap(m_id);
+}
+
+// -----------------------------------------------------------------------------------
+
+ImageEffect_BWSepia::ImageEffect_BWSepia(QWidget* parent)
+ : Digikam::ImageDlgBase(parent, i18n("Convert to Black & White"),
+ "convertbw", true, false),
+ m_destinationPreviewData(0L),
+ m_channelCB(0),
+ m_scaleBG(0),
+ m_bwFilters(0),
+ m_bwTone(0),
+ m_cInput(0),
+ m_tab(0),
+ m_previewWidget(0),
+ m_histogramWidget(0),
+ m_curvesWidget(0),
+ m_curves(0),
+ m_originalImage(0),
+ m_previewPixmapFactory(0)
+{
+ setHelp("blackandwhitetool.anchor", "digikam");
+
+ Digikam::ImageIface iface(0, 0);
+ m_originalImage = iface.getOriginalImg();
+ m_thumbnailImage = m_originalImage->smoothScale(128, 128, QSize::ScaleMin);
+ m_curves = new Digikam::ImageCurves(m_originalImage->sixteenBit());
+
+ // -------------------------------------------------------------
+
+ m_previewWidget = new Digikam::ImageWidget("convertbw Tool Dialog", plainPage(),
+ i18n("<p>Here you can see the black and white conversion tool preview. "
+ "You can pick color on image "
+ "to see the color level corresponding on histogram."));
+ setPreviewAreaWidget(m_previewWidget);
+
+ // -------------------------------------------------------------
+
+ QWidget *gboxSettings = new QWidget(plainPage());
+ QGridLayout* gridSettings = new QGridLayout( gboxSettings, 4, 4, spacingHint());
+
+ QLabel *label1 = new QLabel(i18n("Channel:"), gboxSettings);
+ label1->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ m_channelCB = new QComboBox( false, gboxSettings );
+ m_channelCB->insertItem( i18n("Luminosity") );
+ m_channelCB->insertItem( i18n("Red") );
+ m_channelCB->insertItem( i18n("Green") );
+ m_channelCB->insertItem( i18n("Blue") );
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red image-channel values.<p>"
+ "<b>Green</b>: display the green image-channel values.<p>"
+ "<b>Blue</b>: display the blue image-channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(gboxSettings);
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin( 0 );
+ QWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximal counts are small, you can use the linear scale.<p>"
+ "Logarithmic scale can be used when the maximal counts are big; "
+ "if it is used, all values (small and large) will be visible on the graph."));
+
+ QPushButton *linHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( linHistoButton, i18n( "<p>Linear" ) );
+ m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap( QPixmap( directory + "histogram-lin.png" ) );
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) );
+ m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap( QPixmap( directory + "histogram-log.png" ) );
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(gboxSettings);
+ m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram drawing "
+ "of the selected image channel. This one is re-computed at any "
+ "settings changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new Digikam::ColorGradientWidget( Digikam::ColorGradientWidget::Horizontal, 10, histoBox );
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+
+ gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4);
+
+ // -------------------------------------------------------------
+
+ m_tab = new KTabWidget(gboxSettings);
+
+ m_bwFilm = new QListBox(m_tab);
+ m_bwFilm->setColumnMode(1);
+ m_bwFilm->setVariableWidth(false);
+ m_bwFilm->setVariableHeight(false);
+ Digikam::ListBoxWhatsThis* whatsThis2 = new Digikam::ListBoxWhatsThis(m_bwFilm);
+ m_previewPixmapFactory = new PreviewPixmapFactory(this);
+
+ int type = BWGeneric;
+
+ ListBoxBWPreviewItem *item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Generic"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Generic</b>:"
+ "<p>Simulate a generic black and white film</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Agfa 200X"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Agfa 200X</b>:"
+ "<p>Simulate the Agfa 200X black and white film at 200 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Agfa Pan 25"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Agfa Pan 25</b>:"
+ "<p>Simulate the Agfa Pan black and white film at 25 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Agfa Pan 100"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Agfa Pan 100</b>:"
+ "<p>Simulate the Agfa Pan black and white film at 100 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Agfa Pan 400"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Agfa Pan 400</b>:"
+ "<p>Simulate the Agfa Pan black and white film at 400 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford Delta 100"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford Delta 100</b>:"
+ "<p>Simulate the Ilford Delta black and white film at 100 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford Delta 400"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford Delta 400</b>:"
+ "<p>Simulate the Ilford Delta black and white film at 400 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford Delta 400 Pro 3200"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford Delta 400 Pro 3200</b>:"
+ "<p>Simulate the Ilford Delta 400 Pro black and white film at 3200 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford FP4 Plus"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford FP4 Plus</b>:"
+ "<p>Simulate the Ilford FP4 Plus black and white film at 125 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford HP5 Plus"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford HP5 Plus</b>:"
+ "<p>Simulate the Ilford HP5 Plus black and white film at 400 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford PanF Plus"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford PanF Plus</b>:"
+ "<p>Simulate the Ilford PanF Plus black and white film at 50 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Ilford XP2 Super"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Ilford XP2 Super</b>:"
+ "<p>Simulate the Ilford XP2 Super black and white film at 400 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Kodak Tmax 100"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Kodak Tmax 100</b>:"
+ "<p>Simulate the Kodak Tmax black and white film at 100 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Kodak Tmax 400"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Kodak Tmax 400</b>:"
+ "<p>Simulate the Kodak Tmax black and white film at 400 ISO</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilm, i18n("Kodak TriX"), m_previewPixmapFactory, type);
+ whatsThis2->add( item, i18n("<b>Kodak TriX</b>:"
+ "<p>Simulate the Kodak TriX black and white film at 400 ISO</p>"));
+
+ // -------------------------------------------------------------
+
+ QVBox *vbox = new QVBox(m_tab);
+ vbox->setSpacing(spacingHint());
+
+ m_bwFilters = new QListBox(vbox);
+ m_bwFilters->setColumnMode(1);
+ m_bwFilters->setVariableWidth(false);
+ m_bwFilters->setVariableHeight(false);
+ Digikam::ListBoxWhatsThis* whatsThis = new Digikam::ListBoxWhatsThis(m_bwFilters);
+
+ type = BWNoFilter;
+
+ item = new ListBoxBWPreviewItem(m_bwFilters,
+ i18n("No Lens Filter"), m_previewPixmapFactory, type);
+ whatsThis->add( item, i18n("<b>No Lens Filter</b>:"
+ "<p>Do not apply a lens filter when rendering the image.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilters, i18n("Green Filter"), m_previewPixmapFactory, type);
+ whatsThis->add( item, i18n("<b>Black & White with Green Filter</b>:"
+ "<p>Simulate black and white film exposure using a green filter. "
+ "This is usefule for all scenic shoots, especially portraits "
+ "photographed against the sky.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilters, i18n("Orange Filter"), m_previewPixmapFactory, type);
+ whatsThis->add( item, i18n("<b>Black & White with Orange Filter</b>:"
+ "<p>Simulate black and white film exposure using an orange filter. "
+ "This will enhance landscapes, marine scenes and aerial "
+ "photography.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilters, i18n("Red Filter"), m_previewPixmapFactory, type);
+ whatsThis->add( item, i18n("<b>Black & White with Red Filter</b>:"
+ "<p>Simulate black and white film exposure using a red filter. "
+ "This creates dramatic sky effects, and simulates moonlight scenes "
+ "in the daytime.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwFilters, i18n("Yellow Filter"), m_previewPixmapFactory, type);
+ whatsThis->add( item, i18n("<b>Black & White with Yellow Filter</b>:"
+ "<p>Simulate black and white film exposure using a yellow filter. "
+ "This has the most natural tonal correction, and improves contrast. Ideal for "
+ "landscapes.</p>"));
+
+ m_strengthInput = new KIntNumInput(vbox);
+ m_strengthInput->setLabel(i18n("Strength:"), AlignLeft | AlignVCenter);
+ m_strengthInput->setRange(1, 5, 1, true);
+ m_strengthInput->setValue(1);
+ QWhatsThis::add(m_strengthInput, i18n("<p>Here, set the strength adjustment of the lens filter."));
+
+ // -------------------------------------------------------------
+
+ m_bwTone = new QListBox(m_tab);
+ m_bwTone->setColumnMode(1);
+ m_bwTone->setVariableWidth(false);
+ m_bwTone->setVariableHeight(false);
+ Digikam::ListBoxWhatsThis* whatsThis3 = new Digikam::ListBoxWhatsThis(m_bwTone);
+
+ type = BWNoTone;
+
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("No Tone Filter"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>No Tone Filter</b>:"
+ "<p>Do not apply a tone filter to the image.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("Sepia Tone"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>Black & White with Sepia Tone</b>:"
+ "<p>Gives a warm highlight and mid-tone while adding a bit of coolness to "
+ "the shadows - very similar to the process of bleaching a print and "
+ "re-developing in a sepia toner.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("Brown Tone"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>Black & White with Brown Tone</b>:"
+ "<p>This filter is more neutral than the Sepia Tone "
+ "filter.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("Cold Tone"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>Black & White with Cold Tone</b>:"
+ "<p>Start subtle and replicates printing on a cold tone black and white "
+ "paper such as a bromide enlarging "
+ "paper.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("Selenium Tone"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>Black & White with Selenium Tone</b>:"
+ "<p>This effect replicates traditional selenium chemical toning done "
+ "in the darkroom.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("Platinum Tone"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>Black & White with Platinum Tone</b>:"
+ "<p>This effect replicates traditional platinum chemical toning done "
+ "in the darkroom.</p>"));
+
+ ++type;
+ item = new ListBoxBWPreviewItem(m_bwTone, i18n("Green Tone"), m_previewPixmapFactory, type);
+ whatsThis3->add( item, i18n("<b>Black & White with greenish tint</b>:"
+ "<p>This effect is also known as Verdante.</p>"));
+
+ // -------------------------------------------------------------
+
+ QWidget *curveBox = new QWidget( m_tab );
+ QGridLayout *gridTab2 = new QGridLayout(curveBox, 5, 2, spacingHint(), 0);
+
+ Digikam::ColorGradientWidget* vGradient = new Digikam::ColorGradientWidget(
+ Digikam::ColorGradientWidget::Vertical,
+ 10, curveBox );
+ vGradient->setColors( QColor( "white" ), QColor( "black" ) );
+
+ QLabel *spacev = new QLabel(curveBox);
+ spacev->setFixedWidth(1);
+
+ m_curvesWidget = new Digikam::CurvesWidget(256, 256, m_originalImage->bits(), m_originalImage->width(),
+ m_originalImage->height(), m_originalImage->sixteenBit(),
+ m_curves, curveBox);
+ QWhatsThis::add( m_curvesWidget, i18n("<p>This is the curve adjustment of the image luminosity"));
+
+ QLabel *spaceh = new QLabel(curveBox);
+ spaceh->setFixedHeight(1);
+
+ Digikam::ColorGradientWidget *hGradient = new Digikam::ColorGradientWidget(
+ Digikam::ColorGradientWidget::Horizontal,
+ 10, curveBox );
+ hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+
+ m_cInput = new KIntNumInput(curveBox);
+ m_cInput->setLabel(i18n("Contrast:"), AlignLeft | AlignVCenter);
+ m_cInput->setRange(-100, 100, 1, true);
+ m_cInput->setValue(0);
+ QWhatsThis::add( m_cInput, i18n("<p>Set here the contrast adjustment of the image."));
+
+ gridTab2->addMultiCellWidget(vGradient, 0, 0, 0, 0);
+ gridTab2->addMultiCellWidget(spacev, 0, 0, 1, 1);
+ gridTab2->addMultiCellWidget(m_curvesWidget, 0, 0, 2, 2);
+ gridTab2->addMultiCellWidget(spaceh, 1, 1, 2, 2);
+ gridTab2->addMultiCellWidget(hGradient, 2, 2, 2, 2);
+ gridTab2->addMultiCellWidget(m_cInput, 4, 4, 0, 2);
+ gridTab2->setRowSpacing(3, spacingHint());
+ gridTab2->setRowStretch(5, 10);
+
+ // -------------------------------------------------------------
+
+ m_tab->insertTab(m_bwFilm, i18n("Film"), FilmTab);
+ m_tab->insertTab(vbox, i18n("Lens Filters"), BWFiltersTab);
+ m_tab->insertTab(m_bwTone, i18n("Tone"), ToneTab);
+ m_tab->insertTab(curveBox, i18n("Lightness"), LuminosityTab);
+
+ gridSettings->addMultiCellWidget(m_tab, 3, 3, 0, 4);
+ gridSettings->setRowStretch(3, 10);
+ setUserAreaWidget(gboxSettings);
+
+ // -------------------------------------------------------------
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromOriginal(const Digikam::DColor&, const QPoint&)),
+ this, SLOT(slotSpotColorChanged(const Digikam::DColor&)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const QPoint & )),
+ this, SLOT(slotColorSelectedFromTarget( const Digikam::DColor & )));
+
+ connect(m_bwFilters, SIGNAL(highlighted(int)),
+ this, SLOT(slotFilterSelected(int)));
+
+ connect(m_strengthInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_bwFilm, SIGNAL(highlighted(int)),
+ this, SLOT(slotEffect()));
+
+ connect(m_bwTone, SIGNAL(highlighted(int)),
+ this, SLOT(slotEffect()));
+
+ connect(m_curvesWidget, SIGNAL(signalCurvesChanged()),
+ this, SLOT(slotTimer()));
+
+ connect(m_cInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+}
+
+ImageEffect_BWSepia::~ImageEffect_BWSepia()
+{
+ m_histogramWidget->stopHistogramComputation();
+
+ delete [] m_destinationPreviewData;
+
+ delete m_histogramWidget;
+ delete m_previewWidget;
+ delete m_curvesWidget;
+ delete m_curves;
+}
+
+void ImageEffect_BWSepia::slotFilterSelected(int filter)
+{
+ if (filter == BWNoFilter)
+ m_strengthInput->setEnabled(false);
+ else
+ m_strengthInput->setEnabled(true);
+
+ slotEffect();
+}
+
+QPixmap ImageEffect_BWSepia::getThumbnailForEffect(int type)
+{
+ Digikam::DImg thumb = m_thumbnailImage.copy();
+ int w = thumb.width();
+ int h = thumb.height();
+ bool sb = thumb.sixteenBit();
+ bool a = thumb.hasAlpha();
+
+ if (type < BWGeneric)
+ {
+ // In Filter view, we will render a preview of the B&W filter with the generic B&W film.
+ blackAndWhiteConversion(thumb.bits(), w, h, sb, type);
+ blackAndWhiteConversion(thumb.bits(), w, h, sb, BWGeneric);
+ }
+ else
+ {
+ // In Film and Tone view, we will render the preview without to use the B&W Filter
+ blackAndWhiteConversion(thumb.bits(), w, h, sb, type);
+ }
+
+ if (m_curves) // in case we're called before the creator is done
+ {
+ uchar *targetData = new uchar[w*h*(sb ? 8 : 4)];
+ m_curves->curvesLutSetup(Digikam::ImageHistogram::AlphaChannel);
+ m_curves->curvesLutProcess(thumb.bits(), targetData, w, h);
+
+ Digikam::DImg preview(w, h, sb, a, targetData);
+ Digikam::BCGModifier cmod;
+ cmod.setContrast((double)(m_cInput->value()/100.0) + 1.00);
+ cmod.applyBCG(preview);
+
+ thumb.putImageData(preview.bits());
+
+ delete [] targetData;
+ }
+ return (thumb.convertToPixmap());
+}
+
+void ImageEffect_BWSepia::slotChannelChanged(int channel)
+{
+ switch(channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::ValueHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "red" ) );
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "green" ) );
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "blue" ) );
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_BWSepia::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+ m_curvesWidget->m_scaleType = scale;
+ m_curvesWidget->repaint(false);
+}
+
+void ImageEffect_BWSepia::slotSpotColorChanged(const Digikam::DColor &color)
+{
+ m_curvesWidget->setCurveGuide(color);
+}
+
+void ImageEffect_BWSepia::slotColorSelectedFromTarget( const Digikam::DColor &color )
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void ImageEffect_BWSepia::readUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("convertbw Tool Dialog");
+
+ m_tab->setCurrentPage(config->readNumEntry("Settings Tab", BWFiltersTab));
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", Digikam::HistogramWidget::LogScaleHistogram));
+ m_bwFilters->setCurrentItem(config->readNumEntry("BW Filter", 0));
+ m_bwFilm->setCurrentItem(config->readNumEntry("BW Film", 0));
+ m_bwTone->setCurrentItem(config->readNumEntry("BW Tone", 0));
+ m_cInput->setValue(config->readNumEntry("ContrastAjustment", 0));
+ m_strengthInput->setValue(config->readNumEntry("StrengthAjustment", 1));
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curves->curvesChannelReset(i);
+
+ m_curves->setCurveType(m_curvesWidget->m_channelType, Digikam::ImageCurves::CURVE_SMOOTH);
+ m_curvesWidget->reset();
+
+ for (int j = 0 ; j < 17 ; j++)
+ {
+ QPoint disable(-1, -1);
+ QPoint p = config->readPointEntry(QString("CurveAjustmentPoint%1").arg(j), &disable);
+
+ if (m_originalImage->sixteenBit() && p.x() != -1)
+ {
+ p.setX(p.x()*255);
+ p.setY(p.y()*255);
+ }
+
+ m_curves->setCurvePoint(Digikam::ImageHistogram::ValueChannel, j, p);
+ }
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curves->curvesCalculateCurve(i);
+
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+ slotFilterSelected(m_bwFilters->currentItem());
+}
+
+void ImageEffect_BWSepia::writeUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("convertbw Tool Dialog");
+ config->writeEntry("Settings Tab", m_tab->currentPageIndex());
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writeEntry("BW Filter", m_bwFilters->currentItem());
+ config->writeEntry("BW Film", m_bwFilm->currentItem());
+ config->writeEntry("BW Tone", m_bwTone->currentItem());
+ config->writeEntry("ContrastAjustment", m_cInput->value());
+ config->writeEntry("StrengthAjustment", m_strengthInput->value());
+
+ for (int j = 0 ; j < 17 ; j++)
+ {
+ QPoint p = m_curves->getCurvePoint(Digikam::ImageHistogram::ValueChannel, j);
+
+ if (m_originalImage->sixteenBit() && p.x() != -1)
+ {
+ p.setX(p.x()/255);
+ p.setY(p.y()/255);
+ }
+
+ config->writeEntry(QString("CurveAjustmentPoint%1").arg(j), p);
+ }
+
+ config->sync();
+}
+
+void ImageEffect_BWSepia::resetValues()
+{
+ m_bwFilters->blockSignals(true);
+ m_bwTone->blockSignals(true);
+ m_cInput->blockSignals(true);
+ m_strengthInput->blockSignals(true);
+
+ m_bwFilters->setCurrentItem(0);
+ m_bwFilters->setSelected(0, true);
+
+ m_bwTone->setCurrentItem(0);
+ m_bwTone->setSelected(0, true);
+
+ m_cInput->setValue(0);
+
+ for (int channel = 0 ; channel < 5 ; channel++)
+ m_curves->curvesChannelReset(channel);
+
+ m_curvesWidget->reset();
+
+ m_cInput->blockSignals(false);
+ m_bwTone->blockSignals(false);
+ m_bwFilters->blockSignals(false);
+ m_strengthInput->blockSignals(false);
+
+ m_histogramWidget->reset();
+ m_previewPixmapFactory->invalidate();
+ m_bwFilters->triggerUpdate(false);
+ m_bwTone->triggerUpdate(false);
+}
+
+void ImageEffect_BWSepia::slotEffect()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ m_histogramWidget->stopHistogramComputation();
+
+ delete [] m_destinationPreviewData;
+
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ m_destinationPreviewData = iface->getPreviewImage();
+ int w = iface->previewWidth();
+ int h = iface->previewHeight();
+ bool a = iface->previewHasAlpha();
+ bool sb = iface->previewSixteenBit();
+
+ // Apply black and white filter.
+
+ blackAndWhiteConversion(m_destinationPreviewData, w, h, sb, m_bwFilters->currentItem());
+
+ // Apply black and white film type.
+
+ blackAndWhiteConversion(m_destinationPreviewData, w, h, sb, m_bwFilm->currentItem() + BWGeneric);
+
+ // Apply color tone filter.
+
+ blackAndWhiteConversion(m_destinationPreviewData, w, h, sb, m_bwTone->currentItem() + BWNoTone);
+
+ // Calculate and apply the curve on image.
+
+ uchar *targetData = new uchar[w*h*(sb ? 8 : 4)];
+ m_curves->curvesLutSetup(Digikam::ImageHistogram::AlphaChannel);
+ m_curves->curvesLutProcess(m_destinationPreviewData, targetData, w, h);
+
+ // Adjust contrast.
+
+ Digikam::DImg preview(w, h, sb, a, targetData);
+ Digikam::BCGModifier cmod;
+ cmod.setContrast((double)(m_cInput->value()/100.0) + 1.00);
+ cmod.applyBCG(preview);
+ iface->putPreviewImage(preview.bits());
+
+ m_previewWidget->updatePreview();
+
+ // Update histogram.
+
+ memcpy(m_destinationPreviewData, preview.bits(), preview.numBytes());
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false);
+ delete [] targetData;
+
+ kapp->restoreOverrideCursor();
+}
+
+void ImageEffect_BWSepia::slotTimer()
+{
+ Digikam::ImageDlgBase::slotTimer();
+ if (m_previewPixmapFactory && m_bwFilters && m_bwTone)
+ {
+ m_previewPixmapFactory->invalidate();
+ m_bwFilters->triggerUpdate(false);
+ m_bwTone->triggerUpdate(false);
+ }
+}
+
+void ImageEffect_BWSepia::finalRendering()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int w = iface->originalWidth();
+ int h = iface->originalHeight();
+ bool a = iface->originalHasAlpha();
+ bool sb = iface->originalSixteenBit();
+
+ if (data)
+ {
+ // Apply black and white filter.
+
+ blackAndWhiteConversion(data, w, h, sb, m_bwFilters->currentItem());
+
+ // Apply black and white film type.
+
+ blackAndWhiteConversion(data, w, h, sb, m_bwFilm->currentItem() + BWGeneric);
+
+ // Apply color tone filter.
+
+ blackAndWhiteConversion(data, w, h, sb, m_bwTone->currentItem() + BWNoTone);
+
+ // Calculate and apply the curve on image.
+
+ uchar *targetData = new uchar[w*h*(sb ? 8 : 4)];
+ m_curves->curvesLutSetup(Digikam::ImageHistogram::AlphaChannel);
+ m_curves->curvesLutProcess(data, targetData, w, h);
+
+ // Adjust contrast.
+
+ Digikam::DImg img(w, h, sb, a, targetData);
+ Digikam::BCGModifier cmod;
+ cmod.setContrast((double)(m_cInput->value()/100.0) + 1.00);
+ cmod.applyBCG(img);
+
+ iface->putOriginalImage(i18n("Convert to Black && White"), img.bits());
+
+ delete [] data;
+ delete [] targetData;
+ }
+
+ kapp->restoreOverrideCursor();
+ accept();
+}
+
+void ImageEffect_BWSepia::blackAndWhiteConversion(uchar *data, int w, int h, bool sb, int type)
+{
+ // Value to multiply RGB 8 bits component of mask used by changeTonality() method.
+ int mul = sb ? 255 : 1;
+ Digikam::DImgImageFilters filter;
+ double strength = 1.0 + ((double)m_strengthInput->value() - 1.0) * (1.0 / 3.0);
+
+ switch (type)
+ {
+ case BWNoFilter:
+ m_redAttn = 0.0;
+ m_greenAttn = 0.0;
+ m_blueAttn = 0.0;
+ break;
+
+ case BWGreenFilter:
+ m_redAttn = -0.20 * strength;
+ m_greenAttn = +0.11 * strength;
+ m_blueAttn = +0.09 * strength;
+ break;
+
+ case BWOrangeFilter:
+ m_redAttn = +0.48 * strength;
+ m_greenAttn = -0.37 * strength;
+ m_blueAttn = -0.11 * strength;
+ break;
+
+ case BWRedFilter:
+ m_redAttn = +0.60 * strength;
+ m_greenAttn = -0.49 * strength;
+ m_blueAttn = -0.11 * strength;
+ break;
+
+ case BWYellowFilter:
+ m_redAttn = +0.30 * strength;
+ m_greenAttn = -0.31 * strength;
+ m_blueAttn = +0.01 * strength;
+ break;
+
+ // --------------------------------------------------------------------------------
+
+ case BWGeneric:
+ case BWNoTone:
+ m_redMult = 0.24;
+ m_greenMult = 0.68;
+ m_blueMult = 0.08;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWAgfa200X:
+ m_redMult = 0.18;
+ m_greenMult = 0.41;
+ m_blueMult = 0.41;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWAgfapan25:
+ m_redMult = 0.25;
+ m_greenMult = 0.39;
+ m_blueMult = 0.36;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWAgfapan100:
+ m_redMult = 0.21;
+ m_greenMult = 0.40;
+ m_blueMult = 0.39;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWAgfapan400:
+ m_redMult = 0.20;
+ m_greenMult = 0.41;
+ m_blueMult = 0.39;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordDelta100:
+ m_redMult = 0.21;
+ m_greenMult = 0.42;
+ m_blueMult = 0.37;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordDelta400:
+ m_redMult = 0.22;
+ m_greenMult = 0.42;
+ m_blueMult = 0.36;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordDelta400Pro3200:
+ m_redMult = 0.31;
+ m_greenMult = 0.36;
+ m_blueMult = 0.33;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordFP4:
+ m_redMult = 0.28;
+ m_greenMult = 0.41;
+ m_blueMult = 0.31;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordHP5:
+ m_redMult = 0.23;
+ m_greenMult = 0.37;
+ m_blueMult = 0.40;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordPanF:
+ m_redMult = 0.33;
+ m_greenMult = 0.36;
+ m_blueMult = 0.31;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWIlfordXP2Super:
+ m_redMult = 0.21;
+ m_greenMult = 0.42;
+ m_blueMult = 0.37;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWKodakTmax100:
+ m_redMult = 0.24;
+ m_greenMult = 0.37;
+ m_blueMult = 0.39;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWKodakTmax400:
+ m_redMult = 0.27;
+ m_greenMult = 0.36;
+ m_blueMult = 0.37;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ case BWKodakTriX:
+ m_redMult = 0.25;
+ m_greenMult = 0.35;
+ m_blueMult = 0.40;
+ filter.channelMixerImage(data, w, h, sb, true, true,
+ m_redMult + m_redMult*m_redAttn, m_greenMult + m_greenMult*m_greenAttn, m_blueMult + m_blueMult*m_blueAttn,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0);
+ break;
+
+ // --------------------------------------------------------------------------------
+
+ case BWSepiaTone:
+ filter.changeTonality(data, w, h, sb, 162*mul, 132*mul, 101*mul);
+ break;
+
+ case BWBrownTone:
+ filter.changeTonality(data, w, h, sb, 129*mul, 115*mul, 104*mul);
+ break;
+
+ case BWColdTone:
+ filter.changeTonality(data, w, h, sb, 102*mul, 109*mul, 128*mul);
+ break;
+
+ case BWSeleniumTone:
+ filter.changeTonality(data, w, h, sb, 122*mul, 115*mul, 122*mul);
+ break;
+
+ case BWPlatinumTone:
+ filter.changeTonality(data, w, h, sb, 115*mul, 110*mul, 106*mul);
+ break;
+
+ case BWGreenTone:
+ filter.changeTonality(data, w, h, sb, 108*mul, 116*mul, 100*mul);
+ break;
+
+ }
+}
+
+//-- Load all settings from file --------------------------------------
+
+void ImageEffect_BWSepia::slotUser3()
+{
+ KURL loadFile = KFileDialog::getOpenURL(KGlobalSettings::documentPath(),
+ QString( "*" ), this,
+ QString( i18n("Black & White Settings File to Load")) );
+ if( loadFile.isEmpty() )
+ return;
+
+ QFile file(loadFile.path());
+
+ if ( file.open(IO_ReadOnly) )
+ {
+ QTextStream stream( &file );
+
+ if ( stream.readLine() != "# Black & White Configuration File" )
+ {
+ KMessageBox::error(this,
+ i18n("\"%1\" is not a Black & White settings text file.")
+ .arg(loadFile.fileName()));
+ file.close();
+ return;
+ }
+
+ m_bwFilters->blockSignals(true);
+ m_bwTone->blockSignals(true);
+ m_cInput->blockSignals(true);
+
+ m_bwFilters->setCurrentItem(stream.readLine().toInt());
+ m_bwTone->setCurrentItem(stream.readLine().toInt());
+ m_cInput->setValue(stream.readLine().toInt());
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curves->curvesChannelReset(i);
+
+ m_curves->setCurveType(m_curvesWidget->m_channelType, Digikam::ImageCurves::CURVE_SMOOTH);
+ m_curvesWidget->reset();
+
+ for (int j = 0 ; j < 17 ; j++)
+ {
+ QPoint disable(-1, -1);
+ QPoint p;
+ p.setX( stream.readLine().toInt() );
+ p.setY( stream.readLine().toInt() );
+
+ if (m_originalImage->sixteenBit() && p != disable)
+ {
+ p.setX(p.x()*255);
+ p.setY(p.y()*255);
+ }
+
+ m_curves->setCurvePoint(Digikam::ImageHistogram::ValueChannel, j, p);
+ }
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curves->curvesCalculateCurve(i);
+
+ m_bwFilters->blockSignals(false);
+ m_bwTone->blockSignals(false);
+ m_cInput->blockSignals(false);
+
+ m_histogramWidget->reset();
+ m_previewPixmapFactory->invalidate();
+ m_bwFilters->triggerUpdate(false);
+ m_bwTone->triggerUpdate(false);
+
+ slotEffect();
+ }
+ else
+ KMessageBox::error(this, i18n("Cannot load settings from the Black & White text file."));
+
+ file.close();
+}
+
+//-- Save all settings to file ---------------------------------------
+
+void ImageEffect_BWSepia::slotUser2()
+{
+ KURL saveFile = KFileDialog::getSaveURL(KGlobalSettings::documentPath(),
+ QString( "*" ), this,
+ QString( i18n("Black & White Settings File to Save")) );
+ if( saveFile.isEmpty() )
+ return;
+
+ QFile file(saveFile.path());
+
+ if ( file.open(IO_WriteOnly) )
+ {
+ QTextStream stream( &file );
+ stream << "# Black & White Configuration File\n";
+ stream << m_bwFilters->currentItem() << "\n";
+ stream << m_bwTone->currentItem() << "\n";
+ stream << m_cInput->value() << "\n";
+
+ for (int j = 0 ; j < 17 ; j++)
+ {
+ QPoint p = m_curves->getCurvePoint(Digikam::ImageHistogram::ValueChannel, j);
+ if (m_originalImage->sixteenBit())
+ {
+ p.setX(p.x()/255);
+ p.setY(p.y()/255);
+ }
+ stream << p.x() << "\n";
+ stream << p.y() << "\n";
+ }
+ }
+ else
+ KMessageBox::error(this, i18n("Cannot save settings to the Black & White text file."));
+
+ file.close();
+}
+
+} // NameSpace DigikamImagesPluginCore
+
+
diff --git a/digikam/imageplugins/coreplugin/imageeffect_bwsepia.h b/digikam/imageplugins/coreplugin/imageeffect_bwsepia.h
new file mode 100644
index 0000000..49e8c66
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_bwsepia.h
@@ -0,0 +1,194 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-12-06
+ * Description : Black and White conversion tool.
+ *
+ * Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * Copyright (C) 2006-2007 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 IMAGEEFFECT_BWSEPIA_H
+#define IMAGEEFFECT_BWSEPIA_H
+
+// Qt Includes.
+
+#include <qstring.h>
+
+// Digikam include.
+
+#include "imagedlgbase.h"
+
+class QHButtonGroup;
+class QComboBox;
+class QButtonGroup;
+
+class KIntNumInput;
+class KTabWidget;
+
+namespace Digikam
+{
+class HistogramWidget;
+class ColorGradientWidget;
+class ImageWidget;
+class DColor;
+class DImg;
+class ImageCurves;
+class CurvesWidget;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class PreviewPixmapFactory;
+
+class ImageEffect_BWSepia : public Digikam::ImageDlgBase
+{
+ Q_OBJECT
+
+public:
+
+ ImageEffect_BWSepia(QWidget *parent);
+ ~ImageEffect_BWSepia();
+
+ friend class PreviewPixmapFactory;
+
+protected:
+
+ QPixmap getThumbnailForEffect(int type);
+ void finalRendering();
+
+protected slots:
+
+ virtual void slotTimer();
+
+private:
+
+ void readUserSettings();
+ void writeUserSettings();
+ void resetValues();
+ void blackAndWhiteConversion(uchar *data, int w, int h, bool sb, int type);
+
+private slots:
+
+ void slotUser2();
+ void slotUser3();
+ void slotEffect();
+ void slotChannelChanged(int channel);
+ void slotScaleChanged(int scale);
+ void slotSpotColorChanged(const Digikam::DColor &color);
+ void slotColorSelectedFromTarget( const Digikam::DColor &color );
+ void slotFilterSelected(int filter);
+
+private:
+
+ enum BlackWhiteConversionType
+ {
+ BWNoFilter=0, // B&W filter to the front of lens.
+ BWGreenFilter,
+ BWOrangeFilter,
+ BWRedFilter,
+ BWYellowFilter,
+
+ BWGeneric, // B&W film simulation.
+ BWAgfa200X,
+ BWAgfapan25,
+ BWAgfapan100,
+ BWAgfapan400,
+ BWIlfordDelta100,
+ BWIlfordDelta400,
+ BWIlfordDelta400Pro3200,
+ BWIlfordFP4,
+ BWIlfordHP5,
+ BWIlfordPanF,
+ BWIlfordXP2Super,
+ BWKodakTmax100,
+ BWKodakTmax400,
+ BWKodakTriX,
+
+ BWNoTone, // Chemical color tone filter.
+ BWSepiaTone,
+ BWBrownTone,
+ BWColdTone,
+ BWSeleniumTone,
+ BWPlatinumTone,
+ BWGreenTone
+ };
+
+ enum HistogramScale
+ {
+ Linear=0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel=0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ enum SettingsTab
+ {
+ FilmTab=0,
+ BWFiltersTab,
+ ToneTab,
+ LuminosityTab
+ };
+
+ // Color filter attenuation in percents.
+ double m_redAttn, m_greenAttn, m_blueAttn;
+
+ // Channel mixer color multiplier.
+ double m_redMult, m_greenMult, m_blueMult;
+
+ uchar *m_destinationPreviewData;
+
+ QComboBox *m_channelCB;
+
+ QHButtonGroup *m_scaleBG;
+
+ QListBox *m_bwFilters;
+ QListBox *m_bwFilm;
+ QListBox *m_bwTone;
+
+ KIntNumInput *m_cInput;
+ KIntNumInput *m_strengthInput;
+
+ KTabWidget *m_tab;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+
+ Digikam::CurvesWidget *m_curvesWidget;
+
+ Digikam::ImageCurves *m_curves;
+
+ Digikam::DImg *m_originalImage;
+ Digikam::DImg m_thumbnailImage;
+
+ PreviewPixmapFactory *m_previewPixmapFactory;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* IMAGEEFFECT_BWSEPIA_H */
diff --git a/digikam/imageplugins/coreplugin/imageeffect_iccproof.cpp b/digikam/imageplugins/coreplugin/imageeffect_iccproof.cpp
new file mode 100644
index 0000000..34c32f8
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_iccproof.cpp
@@ -0,0 +1,1284 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-12-21
+ * Description : digiKam image editor tool to correct picture
+ * colors using an ICC color profile
+ *
+ * Copyright (C) 2005-2006 by F.J. Cruz <fj.cruz@supercable.es>
+ * Copyright (C) 2006-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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qcolor.h>
+#include <qgroupbox.h>
+#include <qhbox.h>
+#include <qhbuttongroup.h>
+#include <qvbuttongroup.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qpoint.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+#include <qradiobutton.h>
+#include <qfile.h>
+#include <qtoolbox.h>
+#include <qtextstream.h>
+
+// KDE includes.
+
+#include <knuminput.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kcursor.h>
+#include <kstandarddirs.h>
+#include <ktabwidget.h>
+#include <kconfig.h>
+#include <kurlrequester.h>
+#include <kurllabel.h>
+#include <kfiledialog.h>
+#include <kfile.h>
+#include <kmessagebox.h>
+#include <kglobalsettings.h>
+#include <kiconloader.h>
+#include <ksqueezedtextlabel.h>
+
+// Digikam includes.
+
+#include "ddebug.h"
+#include "bcgmodifier.h"
+#include "imageiface.h"
+#include "imagewidget.h"
+#include "imagehistogram.h"
+#include "imagecurves.h"
+#include "curveswidget.h"
+#include "histogramwidget.h"
+#include "colorgradientwidget.h"
+#include "dimg.h"
+#include "dimgimagefilters.h"
+#include "iccpreviewwidget.h"
+#include "icctransform.h"
+#include "iccprofileinfodlg.h"
+
+// Local includes.
+
+#include "imageeffect_iccproof.h"
+#include "imageeffect_iccproof.moc"
+
+namespace DigikamImagesPluginCore
+{
+
+ImageEffect_ICCProof::ImageEffect_ICCProof(QWidget* parent)
+ : Digikam::ImageDlgBase(parent,i18n("Color Management"),
+ "colormanagement", true, false)
+{
+ m_destinationPreviewData = 0;
+ m_cmEnabled = true;
+ m_hasICC = false;
+
+ setHelp("colormanagement.anchor", "digikam");
+
+ Digikam::ImageIface iface(0, 0);
+ m_originalImage = iface.getOriginalImg();
+ m_embeddedICC = iface.getEmbeddedICCFromOriginalImage();
+ m_curves = new Digikam::ImageCurves(m_originalImage->sixteenBit());
+
+ m_previewWidget = new Digikam::ImageWidget("colormanagement Tool Dialog", plainPage(),
+ i18n("<p>Here you can see the image preview after "
+ "applying a color profile</p>"));
+ setPreviewAreaWidget(m_previewWidget);
+
+ // -------------------------------------------------------------------
+
+ QWidget *gboxSettings = new QWidget(plainPage());
+ QGridLayout *gridSettings = new QGridLayout( gboxSettings, 3, 2, spacingHint());
+
+ QLabel *label1 = new QLabel(i18n("Channel: "), gboxSettings);
+ label1->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ m_channelCB = new QComboBox(false, gboxSettings);
+ m_channelCB->insertItem(i18n("Luminosity"));
+ m_channelCB->insertItem(i18n("Red"));
+ m_channelCB->insertItem(i18n("Green"));
+ m_channelCB->insertItem(i18n("Blue"));
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red channel values.<p>"
+ "<b>Green</b>: display the green channel values.<p>"
+ "<b>Blue</b>: display the blue channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(gboxSettings);
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin( 0 );
+ QWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximal values are small, you can use the linear scale.<p>"
+ "Logarithmic scale can be used when the maximal values are big; "
+ "if it is used, all values (small and large) will be visible on the "
+ "graph."));
+
+ QPushButton *linHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( linHistoButton, i18n( "<p>Linear" ) );
+ m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap( QPixmap( directory + "histogram-lin.png" ) );
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) );
+ m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap( QPixmap( directory + "histogram-log.png" ) );
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 2);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(gboxSettings);
+ m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram "
+ "of the selected image channel. "
+ "This one is updated after setting changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new Digikam::ColorGradientWidget( Digikam::ColorGradientWidget::Horizontal, 10,
+ histoBox );
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+
+ gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 2);
+
+ // -------------------------------------------------------------
+
+ m_toolBoxWidgets = new QToolBox(gboxSettings);
+ QWidget *generalOptions = new QWidget(m_toolBoxWidgets);
+ QWidget *inProfiles = new QWidget(m_toolBoxWidgets);
+ QWidget *spaceProfiles = new QWidget(m_toolBoxWidgets);
+ QWidget *proofProfiles = new QWidget(m_toolBoxWidgets);
+ QWidget *lightnessadjust = new QWidget(m_toolBoxWidgets);
+
+ //---------- "General" Page Setup ----------------------------------
+
+ m_toolBoxWidgets->insertItem(GENERALPAGE, generalOptions,
+ SmallIconSet("misc"), i18n("General Settings"));
+ QWhatsThis::add(generalOptions, i18n("<p>Here you can set general parameters.</p>"));
+
+ QGridLayout *zeroPageLayout = new QGridLayout(generalOptions, 5, 1, spacingHint());
+
+ m_doSoftProofBox = new QCheckBox(generalOptions);
+ m_doSoftProofBox->setText(i18n("Soft-proofing"));
+ QWhatsThis::add(m_doSoftProofBox, i18n("<p>Rendering emulation of the device described "
+ "by the \"Proofing\" profile. Useful to preview the final "
+ "result without rendering to physical medium.</p>"));
+
+ m_checkGamutBox = new QCheckBox(generalOptions);
+ m_checkGamutBox->setText(i18n("Check gamut"));
+ QWhatsThis::add(m_checkGamutBox, i18n("<p>You can use this option if you want to show "
+ "the colors that are outside the printer's gamut<p>"));
+
+ m_embeddProfileBox = new QCheckBox(generalOptions);
+ m_embeddProfileBox->setChecked(true);
+ m_embeddProfileBox->setText(i18n("Assign profile"));
+ QWhatsThis::add(m_embeddProfileBox, i18n("<p>You can use this option to embed "
+ "the selected workspace color profile into the image.</p>"));
+
+ m_BPCBox = new QCheckBox(generalOptions);
+ m_BPCBox->setText(i18n("Use BPC"));
+ QWhatsThis::add(m_BPCBox, i18n("<p>The Black Point Compensation (BPC) feature does work in conjunction "
+ "with Relative Colorimetric Intent. Perceptual intent should make no "
+ "difference, since BPC is always on, and in Absolute Colorimetric "
+ "Intent it is always turned off.</p>"
+ "<p>BPC does compensate for a lack of ICC profiles in the dark tone rendering. "
+ "With BPC the dark tones are optimally mapped (no clipping) from original media "
+ "to the destination rendering media, e.g. the combination of paper and ink.</p>"));
+
+ QLabel *intent = new QLabel(i18n("Rendering Intent:"), generalOptions);
+ m_renderingIntentsCB = new QComboBox(false, generalOptions);
+ m_renderingIntentsCB->insertItem("Perceptual");
+ m_renderingIntentsCB->insertItem("Absolute Colorimetric");
+ m_renderingIntentsCB->insertItem("Relative Colorimetric");
+ m_renderingIntentsCB->insertItem("Saturation");
+ QWhatsThis::add( m_renderingIntentsCB, i18n("<ul><li>Perceptual intent causes the full gamut "
+ "of the image to be compressed or expanded to fill the gamut of the destination media, "
+ "so that gray balance is preserved but colorimetric accuracy may not be preserved.<br>"
+ "In other words, if certain colors in an image fall outside of the range of colors that "
+ "the output device can render, the image intent will cause all the colors in the image "
+ "to be adjusted so that every color in the image falls within the range that can be "
+ "rendered and so that the relationship between colors is preserved as much as possible.<br>"
+ "This intent is most suitable for display of photographs and images, and is the default "
+ "intent.</li>"
+ "<li> Absolute Colorimetric intent causes any colors that fall outside the range that the "
+ "output device can render to be adjusted to the closest color that can be rendered, while all "
+ "other colors are left unchanged.<br>"
+ "This intent preserves the white point and is most suitable for spot colors (Pantone, "
+ "TruMatch, logo colors, ...).</li>"
+ "<li>Relative Colorimetric intent is defined such that any colors that fall outside the "
+ "range that the output device can render are adjusted to the closest color that can be "
+ "rendered, while all other colors are left unchanged. Proof intent does not preserve "
+ "the white point.</li>"
+ "<li>Saturation intent preserves the saturation of colors in the image at the possible "
+ "expense of hue and lightness.<br>"
+ "Implementation of this intent remains somewhat problematic, and the ICC is still working "
+ "on methods to achieve the desired effects.<br>"
+ "This intent is most suitable for business graphics such as charts, where it is more "
+ "important that the colors be vivid and contrast well with each other rather than a "
+ "specific color.</li></ul>"));
+
+ KURLLabel *lcmsLogoLabel = new KURLLabel(generalOptions);
+ lcmsLogoLabel->setAlignment( AlignTop | AlignRight );
+ lcmsLogoLabel->setText(QString());
+ lcmsLogoLabel->setURL("http://www.littlecms.com");
+ KGlobal::dirs()->addResourceType("logo-lcms", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("logo-lcms", "logo-lcms.png");
+ lcmsLogoLabel->setPixmap( QPixmap( directory + "logo-lcms.png" ) );
+ QToolTip::add(lcmsLogoLabel, i18n("Visit Little CMS project website"));
+
+ zeroPageLayout->addMultiCellWidget(m_doSoftProofBox, 0, 0, 0, 0);
+ zeroPageLayout->addMultiCellWidget(m_checkGamutBox, 1, 1, 0, 0);
+ zeroPageLayout->addMultiCellWidget(m_embeddProfileBox, 2, 2, 0, 0);
+ zeroPageLayout->addMultiCellWidget(lcmsLogoLabel, 0, 2, 1, 1);
+ zeroPageLayout->addMultiCellWidget(m_BPCBox, 3, 3, 0, 0);
+ zeroPageLayout->addMultiCellWidget(intent, 4, 4, 0, 0);
+ zeroPageLayout->addMultiCellWidget(m_renderingIntentsCB, 4, 4, 1, 1);
+ zeroPageLayout->setRowStretch(5, 10);
+
+ //---------- "Input" Page Setup ----------------------------------
+
+ m_toolBoxWidgets->insertItem(INPUTPAGE, inProfiles, SmallIconSet("camera"), i18n("Input Profile"));
+ QWhatsThis::add(inProfiles, i18n("<p>Set here all parameters relevant of Input Color "
+ "Profiles.</p>"));
+
+ QGridLayout *firstPageLayout = new QGridLayout(inProfiles, 4, 2, spacingHint());
+
+ m_inProfileBG = new QButtonGroup(4, Qt::Vertical, inProfiles);
+ m_inProfileBG->setFrameStyle(QFrame::NoFrame);
+ m_inProfileBG->setInsideMargin(0);
+
+ m_useEmbeddedProfile = new QRadioButton(m_inProfileBG);
+ m_useEmbeddedProfile->setText(i18n("Use embedded profile"));
+
+ m_useSRGBDefaultProfile = new QRadioButton(m_inProfileBG);
+ m_useSRGBDefaultProfile->setText(i18n("Use builtin sRGB profile"));
+ m_useSRGBDefaultProfile->setChecked(true);
+
+ m_useInDefaultProfile = new QRadioButton(m_inProfileBG);
+ m_useInDefaultProfile->setText(i18n("Use default profile"));
+
+ m_useInSelectedProfile = new QRadioButton(m_inProfileBG);
+ m_useInSelectedProfile->setText(i18n("Use selected profile"));
+
+ m_inProfilesPath = new KURLRequester(inProfiles);
+ m_inProfilesPath->setMode(KFile::File|KFile::ExistingOnly);
+ m_inProfilesPath->setFilter("*.icc *.icm|"+i18n("ICC Files (*.icc; *.icm)"));
+ KFileDialog *inProfiles_dialog = m_inProfilesPath->fileDialog();
+ m_iccInPreviewWidget = new Digikam::ICCPreviewWidget(inProfiles_dialog);
+ inProfiles_dialog->setPreviewWidget(m_iccInPreviewWidget);
+
+ QPushButton *inProfilesInfo = new QPushButton(i18n("Info..."), inProfiles);
+
+ QGroupBox *pictureInfo = new QGroupBox(2, Qt::Horizontal, i18n("Camera information"), inProfiles);
+ new QLabel(i18n("Make:"), pictureInfo);
+ KSqueezedTextLabel *make = new KSqueezedTextLabel(0, pictureInfo);
+ new QLabel(i18n("Model:"), pictureInfo);
+ KSqueezedTextLabel *model = new KSqueezedTextLabel(0, pictureInfo);
+ make->setText(iface.getPhotographInformations().make);
+ model->setText(iface.getPhotographInformations().model);
+
+ firstPageLayout->addMultiCellWidget(m_inProfileBG, 0, 1, 0, 0);
+ firstPageLayout->addMultiCellWidget(inProfilesInfo, 0, 0, 2, 2);
+ firstPageLayout->addMultiCellWidget(m_inProfilesPath, 2, 2, 0, 2);
+ firstPageLayout->addMultiCellWidget(pictureInfo, 3, 3, 0, 2);
+ firstPageLayout->setColStretch(1, 10);
+ firstPageLayout->setRowStretch(4, 10);
+
+ //---------- "Workspace" Page Setup ---------------------------------
+
+ m_toolBoxWidgets->insertItem(WORKSPACEPAGE, spaceProfiles,
+ SmallIconSet("tablet"), i18n("Workspace Profile"));
+ QWhatsThis::add(spaceProfiles, i18n("<p>Set here all parameters relevant to Color Workspace "
+ "Profiles.</p>"));
+
+ QGridLayout *secondPageLayout = new QGridLayout(spaceProfiles, 3, 2, spacingHint());
+
+ m_spaceProfileBG = new QButtonGroup(2, Qt::Vertical, spaceProfiles);
+ m_spaceProfileBG->setFrameStyle(QFrame::NoFrame);
+ m_spaceProfileBG->setInsideMargin(0);
+
+ m_useSpaceDefaultProfile = new QRadioButton(m_spaceProfileBG);
+ m_useSpaceDefaultProfile->setText(i18n("Use default workspace profile"));
+
+ m_useSpaceSelectedProfile = new QRadioButton(m_spaceProfileBG);
+ m_useSpaceSelectedProfile->setText(i18n("Use selected profile"));
+
+ m_spaceProfilePath = new KURLRequester(spaceProfiles);
+ m_spaceProfilePath->setMode(KFile::File|KFile::ExistingOnly);
+ m_spaceProfilePath->setFilter("*.icc *.icm|"+i18n("ICC Files (*.icc; *.icm)"));
+ KFileDialog *spaceProfiles_dialog = m_spaceProfilePath->fileDialog();
+ m_iccSpacePreviewWidget = new Digikam::ICCPreviewWidget(spaceProfiles_dialog);
+ spaceProfiles_dialog->setPreviewWidget(m_iccSpacePreviewWidget);
+
+ QPushButton *spaceProfilesInfo = new QPushButton(i18n("Info..."), spaceProfiles);
+
+ secondPageLayout->addMultiCellWidget(m_spaceProfileBG, 0, 1, 0, 0);
+ secondPageLayout->addMultiCellWidget(spaceProfilesInfo, 0, 0, 2, 2);
+ secondPageLayout->addMultiCellWidget(m_spaceProfilePath, 2, 2, 0, 2);
+ secondPageLayout->setColStretch(1, 10);
+ secondPageLayout->setRowStretch(3, 10);
+
+ //---------- "Proofing" Page Setup ---------------------------------
+
+ m_toolBoxWidgets->insertItem(PROOFINGPAGE, proofProfiles,
+ SmallIconSet("printer1"), i18n("Proofing Profile"));
+ QWhatsThis::add(proofProfiles, i18n("<p>Set here all parameters relevant to Proofing Color "
+ "Profiles.</p>"));
+
+ QGridLayout *thirdPageLayout = new QGridLayout(proofProfiles, 3, 2,
+ spacingHint(), spacingHint());
+
+ m_proofProfileBG = new QButtonGroup(2, Qt::Vertical, proofProfiles);
+ m_proofProfileBG->setFrameStyle(QFrame::NoFrame);
+ m_proofProfileBG->setInsideMargin(0);
+
+ m_useProofDefaultProfile = new QRadioButton(m_proofProfileBG);
+ m_useProofDefaultProfile->setText(i18n("Use default proof profile"));
+
+ m_useProofSelectedProfile = new QRadioButton(m_proofProfileBG);
+ m_useProofSelectedProfile->setText(i18n("Use selected profile"));
+
+ m_proofProfilePath = new KURLRequester(proofProfiles);
+ m_proofProfilePath->setMode(KFile::File|KFile::ExistingOnly);
+ m_proofProfilePath->setFilter("*.icc *.icm|"+i18n("ICC Files (*.icc; *.icm)"));
+ KFileDialog *proofProfiles_dialog = m_proofProfilePath->fileDialog();
+ m_iccProofPreviewWidget = new Digikam::ICCPreviewWidget(proofProfiles_dialog);
+ proofProfiles_dialog->setPreviewWidget(m_iccProofPreviewWidget);
+
+ QPushButton *proofProfilesInfo = new QPushButton(i18n("Info..."), proofProfiles);
+
+ thirdPageLayout->addMultiCellWidget(m_proofProfileBG, 0, 1, 0, 0);
+ thirdPageLayout->addMultiCellWidget(proofProfilesInfo, 0, 0, 2, 2);
+ thirdPageLayout->addMultiCellWidget(m_proofProfilePath, 2, 2, 0, 2);
+ thirdPageLayout->setColStretch(1, 10);
+ thirdPageLayout->setRowStretch(3, 10);
+
+ //---------- "Lightness" Page Setup ----------------------------------
+
+ m_toolBoxWidgets->insertItem(LIGHTNESSPAGE, lightnessadjust,
+ SmallIconSet("blend"), i18n("Lightness Adjustments"));
+ QWhatsThis::add(lightnessadjust, i18n("<p>Set here all lightness adjustments to the target image.</p>"));
+
+ QGridLayout *fourPageLayout = new QGridLayout( lightnessadjust, 5, 2, spacingHint(), 0);
+
+ Digikam::ColorGradientWidget* vGradient = new Digikam::ColorGradientWidget(
+ Digikam::ColorGradientWidget::Vertical,
+ 10, lightnessadjust );
+ vGradient->setColors( QColor( "white" ), QColor( "black" ) );
+
+ QLabel *spacev = new QLabel(lightnessadjust);
+ spacev->setFixedWidth(1);
+
+ m_curvesWidget = new Digikam::CurvesWidget(256, 192, m_originalImage->bits(), m_originalImage->width(),
+ m_originalImage->height(), m_originalImage->sixteenBit(),
+ m_curves, lightnessadjust);
+ QWhatsThis::add( m_curvesWidget, i18n("<p>This is the curve adjustment of the image luminosity"));
+
+ QLabel *spaceh = new QLabel(lightnessadjust);
+ spaceh->setFixedHeight(1);
+
+ Digikam::ColorGradientWidget *hGradient = new Digikam::ColorGradientWidget(
+ Digikam::ColorGradientWidget::Horizontal,
+ 10, lightnessadjust );
+ hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+
+ m_cInput = new KIntNumInput(lightnessadjust);
+ m_cInput->setLabel(i18n("Contrast:"), AlignLeft | AlignVCenter);
+ m_cInput->setRange(-100, 100, 1, true);
+ m_cInput->setValue(0);
+ QWhatsThis::add( m_cInput, i18n("<p>Set here the contrast adjustment of the image."));
+
+ fourPageLayout->addMultiCellWidget(vGradient, 0, 0, 0, 0);
+ fourPageLayout->addMultiCellWidget(spacev, 0, 0, 1, 1);
+ fourPageLayout->addMultiCellWidget(m_curvesWidget, 0, 0, 2, 2);
+ fourPageLayout->addMultiCellWidget(spaceh, 1, 1, 2, 2);
+ fourPageLayout->addMultiCellWidget(hGradient, 2, 2, 2, 2);
+ fourPageLayout->addMultiCellWidget(m_cInput, 4, 4, 0, 2);
+ fourPageLayout->setRowSpacing(3, spacingHint());
+ fourPageLayout->setRowStretch(5, 10);
+
+ // -------------------------------------------------------------
+
+ gridSettings->addMultiCellWidget(m_toolBoxWidgets, 3, 3, 0, 2);
+ setUserAreaWidget(gboxSettings);
+ enableButtonOK(false);
+
+ // -------------------------------------------------------------
+
+ connect(lcmsLogoLabel, SIGNAL(leftClickedURL(const QString&)),
+ this, SLOT(processLCMSURL(const QString&)));
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_curvesWidget, SIGNAL(signalCurvesChanged()),
+ this, SLOT(slotTimer()));
+
+ connect(m_cInput, SIGNAL(valueChanged (int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_renderingIntentsCB, SIGNAL(activated(int)),
+ this, SLOT(slotEffect()));
+
+ //-- Check box options connections -------------------------------------------
+
+ connect(m_doSoftProofBox, SIGNAL(toggled (bool)),
+ this, SLOT(slotEffect()));
+
+ connect(m_checkGamutBox, SIGNAL(toggled (bool)),
+ this, SLOT(slotEffect()));
+
+ connect(m_BPCBox, SIGNAL(toggled (bool)),
+ this, SLOT(slotEffect()));
+
+ //-- Button Group ICC profile options connections ----------------------------
+
+ connect(m_inProfileBG, SIGNAL(released (int)),
+ this, SLOT(slotEffect()));
+
+ connect(m_spaceProfileBG, SIGNAL(released (int)),
+ this, SLOT(slotEffect()));
+
+ connect(m_proofProfileBG, SIGNAL(released (int)),
+ this, SLOT(slotEffect()));
+
+ //-- url requester ICC profile connections -----------------------------------
+
+ connect(m_inProfilesPath, SIGNAL(urlSelected(const QString&)),
+ this, SLOT(slotEffect()));
+
+ connect(m_spaceProfilePath, SIGNAL(urlSelected(const QString&)),
+ this, SLOT(slotEffect()));
+
+ connect(m_proofProfilePath, SIGNAL(urlSelected(const QString&)),
+ this, SLOT(slotEffect()));
+
+ //-- Image preview widget connections ----------------------------
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromOriginal( const Digikam::DColor &, const QPoint & )),
+ this, SLOT(slotSpotColorChanged( const Digikam::DColor & )));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const QPoint & )),
+ this, SLOT(slotColorSelectedFromTarget( const Digikam::DColor & )));
+
+ //-- ICC profile preview connections -----------------------------
+
+ connect(inProfilesInfo, SIGNAL(clicked()),
+ this, SLOT(slotInICCInfo()));
+
+ connect(spaceProfilesInfo, SIGNAL(clicked()),
+ this, SLOT(slotSpaceICCInfo()));
+
+ connect(proofProfilesInfo, SIGNAL(clicked()),
+ this, SLOT(slotProofICCInfo()));
+}
+
+ImageEffect_ICCProof::~ImageEffect_ICCProof()
+{
+ m_histogramWidget->stopHistogramComputation();
+
+ delete [] m_destinationPreviewData;
+ delete m_histogramWidget;
+ delete m_previewWidget;
+ delete m_curvesWidget;
+ delete m_curves;
+}
+
+void ImageEffect_ICCProof::readUserSettings()
+{
+ QString defaultICCPath = KGlobalSettings::documentPath();
+ KConfig* config = kapp->config();
+
+ // General settings of digiKam Color Management
+ config->setGroup("Color Management");
+
+ if (!config->readBoolEntry("EnableCM", false))
+ {
+ m_cmEnabled = false;
+ slotToggledWidgets(false);
+ }
+ else
+ {
+ m_inPath = config->readPathEntry("InProfileFile");
+ m_spacePath = config->readPathEntry("WorkProfileFile");
+ m_proofPath = config->readPathEntry("ProofProfileFile");
+
+ if (QFile::exists(config->readPathEntry("DefaultPath")))
+ {
+ defaultICCPath = config->readPathEntry("DefaultPath");
+ }
+ else
+ {
+ QString message = i18n("The ICC profiles path seems to be invalid. You won't be able to use the \"Default profile\"\
+ options.<p>Please fix this in the digiKam ICC setup.");
+ slotToggledWidgets( false );
+ KMessageBox::information(this, message);
+ }
+ }
+
+ // Plugin settings.
+ config->setGroup("colormanagement Tool Dialog");
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", Digikam::HistogramWidget::LogScaleHistogram));
+ m_toolBoxWidgets->setCurrentIndex(config->readNumEntry("Settings Tab", GENERALPAGE));
+ m_inProfilesPath->setURL(config->readPathEntry("InputProfilePath", defaultICCPath));
+ m_proofProfilePath->setURL(config->readPathEntry("ProofProfilePath", defaultICCPath));
+ m_spaceProfilePath->setURL(config->readPathEntry("SpaceProfilePath", defaultICCPath));
+ m_renderingIntentsCB->setCurrentItem(config->readNumEntry("RenderingIntent", 0));
+ m_doSoftProofBox->setChecked(config->readBoolEntry("DoSoftProof", false));
+ m_checkGamutBox->setChecked(config->readBoolEntry("CheckGamut", false));
+ m_embeddProfileBox->setChecked(config->readBoolEntry("EmbeddProfile", true));
+ m_BPCBox->setChecked(config->readBoolEntry("BPC", true));
+ m_inProfileBG->setButton(config->readNumEntry("InputProfileMethod", 0));
+ m_spaceProfileBG->setButton(config->readNumEntry("SpaceProfileMethod", 0));
+ m_proofProfileBG->setButton(config->readNumEntry("ProofProfileMethod", 0));
+ m_cInput->setValue(config->readNumEntry("ContrastAjustment", 0));
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curves->curvesChannelReset(i);
+
+ m_curves->setCurveType(m_curvesWidget->m_channelType, Digikam::ImageCurves::CURVE_SMOOTH);
+ m_curvesWidget->reset();
+
+ for (int j = 0 ; j < 17 ; j++)
+ {
+ QPoint disable(-1, -1);
+ QPoint p = config->readPointEntry(QString("CurveAjustmentPoint%1").arg(j), &disable);
+
+ if (m_originalImage->sixteenBit() && p.x() != -1)
+ {
+ p.setX(p.x()*255);
+ p.setY(p.y()*255);
+ }
+
+ m_curves->setCurvePoint(Digikam::ImageHistogram::ValueChannel, j, p);
+ }
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curves->curvesCalculateCurve(i);
+
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+}
+
+void ImageEffect_ICCProof::writeUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("colormanagement Tool Dialog");
+ config->writeEntry("Settings Tab", m_toolBoxWidgets->currentIndex());
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writePathEntry("InputProfilePath", m_inProfilesPath->url());
+ config->writePathEntry("ProofProfilePath", m_proofProfilePath->url());
+ config->writePathEntry("SpaceProfilePath", m_spaceProfilePath->url());
+ config->writeEntry("RenderingIntent", m_renderingIntentsCB->currentItem());
+ config->writeEntry("DoSoftProof", m_doSoftProofBox->isChecked());
+ config->writeEntry("CheckGamut", m_checkGamutBox->isChecked());
+ config->writeEntry("EmbeddProfile", m_embeddProfileBox->isChecked());
+ config->writeEntry("BPC", m_BPCBox->isChecked());
+ config->writeEntry("InputProfileMethod", m_inProfileBG->selectedId());
+ config->writeEntry("SpaceProfileMethod", m_spaceProfileBG->selectedId());
+ config->writeEntry("ProofProfileMethod", m_proofProfileBG->selectedId());
+ config->writeEntry("ContrastAjustment", m_cInput->value());
+
+ for (int j = 0 ; j < 17 ; j++)
+ {
+ QPoint p = m_curves->getCurvePoint(Digikam::ImageHistogram::ValueChannel, j);
+
+ if (m_originalImage->sixteenBit() && p.x() != -1)
+ {
+ p.setX(p.x()/255);
+ p.setY(p.y()/255);
+ }
+
+ config->writeEntry(QString("CurveAjustmentPoint%1").arg(j), p);
+ }
+
+ config->sync();
+}
+
+void ImageEffect_ICCProof::processLCMSURL(const QString& url)
+{
+ KApplication::kApplication()->invokeBrowser(url);
+}
+
+void ImageEffect_ICCProof::slotSpotColorChanged(const Digikam::DColor &color)
+{
+ m_curvesWidget->setCurveGuide(color);
+}
+
+void ImageEffect_ICCProof::slotColorSelectedFromTarget( const Digikam::DColor &color )
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void ImageEffect_ICCProof::slotChannelChanged( int channel )
+{
+ switch(channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::ValueHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "red" ) );
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "green" ) );
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "blue" ) );
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_ICCProof::slotScaleChanged( int scale )
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_ICCProof::resetValues()
+{
+ m_cInput->blockSignals(true);
+ m_cInput->setValue(0);
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curves->curvesChannelReset(i);
+
+ m_curvesWidget->reset();
+ m_cInput->blockSignals(false);
+}
+
+void ImageEffect_ICCProof::slotEffect()
+{
+ kapp->setOverrideCursor(KCursor::waitCursor());
+ enableButtonOK(true);
+ m_histogramWidget->stopHistogramComputation();
+
+ Digikam::IccTransform transform;
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ Digikam::ImageIface *iface = m_previewWidget->imageIface();
+ m_destinationPreviewData = iface->getPreviewImage();
+ int w = iface->previewWidth();
+ int h = iface->previewHeight();
+ bool a = iface->previewHasAlpha();
+ bool sb = iface->previewSixteenBit();
+
+ Digikam::DImg preview(w, h, sb, a, m_destinationPreviewData);
+
+ QString tmpInPath = QString();
+ QString tmpProofPath = QString();
+ QString tmpSpacePath = QString();
+
+ bool proofCondition = false;
+ bool spaceCondition = false;
+
+ //-- Input profile parameters ------------------
+
+ if (useDefaultInProfile())
+ {
+ tmpInPath = m_inPath;
+ }
+ else if (useSelectedInProfile())
+ {
+ tmpInPath = m_inProfilesPath->url();
+ QFileInfo info(tmpInPath);
+ if (!info.exists() || !info.isReadable() || !info.isFile() )
+ {
+ KMessageBox::information(this, i18n("<p>The selected ICC input profile path seems to be invalid.<p>"
+ "Please check it."));
+ return;
+ }
+ }
+
+ //-- Proof profile parameters ------------------
+
+ if (useDefaultProofProfile())
+ {
+ tmpProofPath = m_proofPath;
+ }
+ else
+ {
+ tmpProofPath = m_proofProfilePath->url();
+ QFileInfo info(tmpProofPath);
+ if (!info.exists() || !info.isReadable() || !info.isFile() )
+ {
+ KMessageBox::information(this, i18n("<p>The selected ICC proof profile path seems to be invalid.<p>"
+ "Please check it."));
+ return;
+ }
+ }
+
+ if (m_doSoftProofBox->isChecked())
+ proofCondition = tmpProofPath.isEmpty();
+
+ //-- Workspace profile parameters --------------
+
+ if (useDefaultSpaceProfile())
+ {
+ tmpSpacePath = m_spacePath;
+ }
+ else
+ {
+ tmpSpacePath = m_spaceProfilePath->url();
+ QFileInfo info(tmpSpacePath);
+ if (!info.exists() || !info.isReadable() || !info.isFile() )
+ {
+ KMessageBox::information(this, i18n("<p>Selected ICC workspace profile path seems to be invalid.<p>"
+ "Please check it."));
+ return;
+ }
+ }
+
+ spaceCondition = tmpSpacePath.isEmpty();
+
+ //-- Perform the color transformations ------------------
+
+ transform.getTransformType(m_doSoftProofBox->isChecked());
+
+ if (m_doSoftProofBox->isChecked())
+ {
+ if (m_useEmbeddedProfile->isChecked())
+ {
+ transform.setProfiles( tmpSpacePath, tmpProofPath, true );
+ }
+ else
+ {
+ transform.setProfiles( tmpInPath, tmpSpacePath, tmpProofPath);
+ }
+ }
+ else
+ {
+ if (m_useEmbeddedProfile->isChecked())
+ {
+ transform.setProfiles( tmpSpacePath );
+ }
+ else
+ {
+ transform.setProfiles( tmpInPath, tmpSpacePath );
+ }
+ }
+
+ if ( proofCondition || spaceCondition )
+ {
+ kapp->restoreOverrideCursor();
+ QString error = i18n("<p>Your settings are not sufficient.</p>"
+ "<p>To apply a color transform, you need at least two ICC profiles:</p>"
+ "<ul><li>An \"Input\" profile.</li>"
+ "<li>A \"Workspace\" profile.</li></ul>"
+ "<p>If you want to do a \"soft-proof\" transform, in addition to these profiles "
+ "you need a \"Proof\" profile.</p>");
+ KMessageBox::information(this, error);
+ enableButtonOK(false);
+ }
+ else
+ {
+ if (m_useEmbeddedProfile->isChecked())
+ {
+ transform.apply(preview, m_embeddedICC, m_renderingIntentsCB->currentItem(), useBPC(),
+ m_checkGamutBox->isChecked(), useBuiltinProfile());
+ }
+ else
+ {
+ QByteArray fakeProfile = QByteArray();
+ transform.apply(preview, fakeProfile, m_renderingIntentsCB->currentItem(), useBPC(),
+ m_checkGamutBox->isChecked(), useBuiltinProfile());
+ }
+
+ //-- Calculate and apply the curve on image after transformation -------------
+
+ Digikam::DImg preview2(w, h, sb, a, 0, false);
+ m_curves->curvesLutSetup(Digikam::ImageHistogram::AlphaChannel);
+ m_curves->curvesLutProcess(preview.bits(), preview2.bits(), w, h);
+
+ //-- Adjust contrast ---------------------------------------------------------
+
+ Digikam::BCGModifier cmod;
+ cmod.setContrast((double)(m_cInput->value()/100.0) + 1.00);
+ cmod.applyBCG(preview2);
+
+ iface->putPreviewImage(preview2.bits());
+ m_previewWidget->updatePreview();
+
+ //-- Update histogram --------------------------------------------------------
+
+ memcpy(m_destinationPreviewData, preview2.bits(), preview2.numBytes());
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false);
+ kapp->restoreOverrideCursor();
+ }
+}
+
+void ImageEffect_ICCProof::finalRendering()
+{
+ if (!m_doSoftProofBox->isChecked())
+ {
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ Digikam::ImageIface *iface = m_previewWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int w = iface->originalWidth();
+ int h = iface->originalHeight();
+ bool a = iface->originalHasAlpha();
+ bool sb = iface->originalSixteenBit();
+
+ if (data)
+ {
+ Digikam::IccTransform transform;
+
+ Digikam::DImg img(w, h, sb, a, data);
+
+ QString tmpInPath;
+ QString tmpProofPath;
+ QString tmpSpacePath;
+ bool proofCondition;
+
+ //-- Input profile parameters ------------------
+
+ if (useDefaultInProfile())
+ {
+ tmpInPath = m_inPath;
+ }
+ else if (useSelectedInProfile())
+ {
+ tmpInPath = m_inProfilesPath->url();
+ QFileInfo info(tmpInPath);
+ if (!info.exists() || !info.isReadable() || !info.isFile() )
+ {
+ KMessageBox::information(this, i18n("<p>Selected ICC input profile path seems "
+ "to be invalid.<p>Please check it."));
+ return;
+ }
+ }
+
+ //-- Proof profile parameters ------------------
+
+ if (useDefaultProofProfile())
+ {
+ tmpProofPath = m_proofPath;
+ }
+ else
+ {
+ tmpProofPath = m_proofProfilePath->url();
+ QFileInfo info(tmpProofPath);
+ if (!info.exists() || !info.isReadable() || !info.isFile() )
+ {
+ KMessageBox::information(this, i18n("<p>The selected ICC proof profile path seems "
+ "to be invalid.<p>Please check it."));
+ return;
+ }
+ }
+
+ if (tmpProofPath.isNull())
+ proofCondition = false;
+
+ //-- Workspace profile parameters --------------
+
+ if (useDefaultSpaceProfile())
+ {
+ tmpSpacePath = m_spacePath;
+ }
+ else
+ {
+ tmpSpacePath = m_spaceProfilePath->url();
+ QFileInfo info(tmpSpacePath);
+ if (!info.exists() || !info.isReadable() || !info.isFile() )
+ {
+ KMessageBox::information(this, i18n("<p>Selected ICC workspace profile path seems "
+ "to be invalid.<p>Please check it."));
+ return;
+ }
+ }
+
+ //-- Perform the color transformations ------------------
+
+ transform.getTransformType(m_doSoftProofBox->isChecked());
+
+ if (m_doSoftProofBox->isChecked())
+ {
+ if (m_useEmbeddedProfile->isChecked())
+ {
+ transform.setProfiles( tmpSpacePath, tmpProofPath, true );
+ }
+ else
+ {
+ transform.setProfiles( tmpInPath, tmpSpacePath, tmpProofPath);
+ }
+ }
+ else
+ {
+ if (m_useEmbeddedProfile->isChecked())
+ {
+ transform.setProfiles( tmpSpacePath );
+ }
+ else
+ {
+ transform.setProfiles( tmpInPath, tmpSpacePath );
+ }
+ }
+
+ if (m_useEmbeddedProfile->isChecked())
+ {
+ transform.apply(img, m_embeddedICC, m_renderingIntentsCB->currentItem(), useBPC(),
+ m_checkGamutBox->isChecked(), useBuiltinProfile());
+ }
+ else
+ {
+ QByteArray fakeProfile = QByteArray();
+ transform.apply(img, fakeProfile, m_renderingIntentsCB->currentItem(), useBPC(),
+ m_checkGamutBox->isChecked(), useBuiltinProfile());
+ }
+
+ //-- Embed the workspace profile if necessary --------------------------------
+
+ if (m_embeddProfileBox->isChecked())
+ {
+ iface->setEmbeddedICCToOriginalImage( tmpSpacePath );
+ DDebug() << k_funcinfo << QFile::encodeName(tmpSpacePath) << endl;
+ }
+
+ //-- Calculate and apply the curve on image after transformation -------------
+
+ Digikam::DImg img2(w, h, sb, a, 0, false);
+ m_curves->curvesLutSetup(Digikam::ImageHistogram::AlphaChannel);
+ m_curves->curvesLutProcess(img.bits(), img2.bits(), w, h);
+
+ //-- Adjust contrast ---------------------------------------------------------
+
+ Digikam::BCGModifier cmod;
+ cmod.setContrast((double)(m_cInput->value()/100.0) + 1.00);
+ cmod.applyBCG(img2);
+
+ iface->putOriginalImage("Color Management", img2.bits());
+ delete [] data;
+ }
+
+ kapp->restoreOverrideCursor();
+ }
+
+ accept();
+}
+
+void ImageEffect_ICCProof::slotToggledWidgets( bool t)
+{
+ m_useInDefaultProfile->setEnabled(t);
+ m_useProofDefaultProfile->setEnabled(t);
+ m_useSpaceDefaultProfile->setEnabled(t);
+}
+
+void ImageEffect_ICCProof::slotInICCInfo()
+{
+ if (useEmbeddedProfile())
+ {
+ getICCInfo(m_embeddedICC);
+ }
+ else if(useBuiltinProfile())
+ {
+ QString message = i18n("<p>You have selected the \"Default builtin sRGB profile\"</p>");
+ message.append(i18n("<p>This profile is built on the fly, so there is no relevant information "
+ "about it.</p>"));
+ KMessageBox::information(this, message);
+ }
+ else if (useDefaultInProfile())
+ {
+ getICCInfo(m_inPath);
+ }
+ else if (useSelectedInProfile())
+ {
+ getICCInfo(m_inProfilesPath->url());
+ }
+}
+
+void ImageEffect_ICCProof::slotProofICCInfo()
+{
+ if (useDefaultProofProfile())
+ {
+ getICCInfo(m_proofPath);
+ }
+ else
+ {
+ getICCInfo(m_proofProfilePath->url());
+ }
+}
+
+void ImageEffect_ICCProof::slotSpaceICCInfo()
+{
+ if (useDefaultSpaceProfile())
+ {
+ getICCInfo(m_spacePath);
+ }
+ else
+ {
+ getICCInfo(m_spaceProfilePath->url());
+ }
+}
+
+void ImageEffect_ICCProof::getICCInfo(const QString& profile)
+{
+ if (profile.isEmpty())
+ {
+ KMessageBox::error(this, i18n("Sorry, there is no selected profile"), i18n("Profile Error"));
+ return;
+ }
+
+ Digikam::ICCProfileInfoDlg infoDlg(this, profile);
+ infoDlg.exec();
+}
+
+void ImageEffect_ICCProof::getICCInfo(const QByteArray& profile)
+{
+ if (profile.isNull())
+ {
+ KMessageBox::error(this, i18n("Sorry, it seems there is no embedded profile"), i18n("Profile Error"));
+ return;
+ }
+
+ Digikam::ICCProfileInfoDlg infoDlg(this, QString(), profile);
+ infoDlg.exec();
+}
+
+void ImageEffect_ICCProof::slotCMDisabledWarning()
+{
+ if (!m_cmEnabled)
+ {
+ QString message = i18n("<p>You have not enabled Color Management in the digiKam preferences.</p>");
+ message.append( i18n("<p>\"Use of default profile\" options will be disabled now.</p>"));
+ KMessageBox::information(this, message);
+ slotToggledWidgets(false);
+ }
+}
+
+//-- General Tab ---------------------------
+
+bool ImageEffect_ICCProof::useBPC()
+{
+ return m_BPCBox->isChecked();
+}
+
+bool ImageEffect_ICCProof::doProof()
+{
+ return m_doSoftProofBox->isChecked();
+}
+
+bool ImageEffect_ICCProof::checkGamut()
+{
+ return m_checkGamutBox->isChecked();
+}
+
+bool ImageEffect_ICCProof::embedProfile()
+{
+ return m_embeddProfileBox->isChecked();
+}
+
+//-- Input Tab ---------------------------
+
+bool ImageEffect_ICCProof::useEmbeddedProfile()
+{
+ return m_useEmbeddedProfile->isChecked();
+}
+
+bool ImageEffect_ICCProof::useBuiltinProfile()
+{
+ return m_useSRGBDefaultProfile->isChecked();
+}
+
+bool ImageEffect_ICCProof::useDefaultInProfile()
+{
+ return m_useInDefaultProfile->isChecked();
+}
+
+bool ImageEffect_ICCProof::useSelectedInProfile()
+{
+ return m_useInSelectedProfile->isChecked();
+}
+
+//-- Workspace Tab ---------------------------
+
+bool ImageEffect_ICCProof::useDefaultSpaceProfile()
+{
+ return m_useSpaceDefaultProfile->isChecked();
+}
+
+//-- Proofing Tab ---------------------------
+
+bool ImageEffect_ICCProof::useDefaultProofProfile()
+{
+ return m_useProofDefaultProfile->isChecked();
+}
+
+//-- Load all settings from file --------------------------------------
+
+void ImageEffect_ICCProof::slotUser3()
+{
+ KURL loadColorManagementFile = KFileDialog::getOpenURL(KGlobalSettings::documentPath(),
+ QString( "*" ), this,
+ QString( i18n("Color Management Settings File to Load")) );
+ if( loadColorManagementFile.isEmpty() )
+ return;
+
+ QFile file(loadColorManagementFile.path());
+
+ if ( file.open(IO_ReadOnly) )
+ {
+ QTextStream stream( &file );
+
+ if ( stream.readLine() != "# Color Management Configuration File" )
+ {
+ KMessageBox::error(this,
+ i18n("\"%1\" is not a Color Management settings text file.")
+ .arg(loadColorManagementFile.fileName()));
+ file.close();
+ return;
+ }
+
+ blockSignals(true);
+
+ m_renderingIntentsCB->setCurrentItem( stream.readLine().toInt() );
+ m_doSoftProofBox->setChecked( (bool)(stream.readLine().toUInt()) );
+ m_checkGamutBox->setChecked( (bool)(stream.readLine().toUInt()) );
+ m_embeddProfileBox->setChecked( (bool)(stream.readLine().toUInt()) );
+ m_BPCBox->setChecked( (bool)(stream.readLine().toUInt()) );
+ m_inProfileBG->setButton( stream.readLine().toInt() );
+ m_spaceProfileBG->setButton( stream.readLine().toInt() );
+ m_proofProfileBG->setButton( stream.readLine().toInt() );
+ m_inProfilesPath->setURL( stream.readLine() );
+ m_proofProfilePath->setURL( stream.readLine() );
+ m_spaceProfilePath->setURL( stream.readLine() );
+ m_cInput->setValue( stream.readLine().toInt() );
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curves->curvesChannelReset(i);
+
+ m_curves->setCurveType(m_curvesWidget->m_channelType, Digikam::ImageCurves::CURVE_SMOOTH);
+ m_curvesWidget->reset();
+
+ for (int j = 0 ; j < 17 ; j++)
+ {
+ QPoint disable(-1, -1);
+ QPoint p;
+ p.setX( stream.readLine().toInt() );
+ p.setY( stream.readLine().toInt() );
+
+ if (m_originalImage->sixteenBit() && p != disable)
+ {
+ p.setX(p.x()*255);
+ p.setY(p.y()*255);
+ }
+
+ m_curves->setCurvePoint(Digikam::ImageHistogram::ValueChannel, j, p);
+ }
+
+ blockSignals(false);
+
+ for (int i = 0 ; i < 5 ; i++)
+ m_curves->curvesCalculateCurve(i);
+
+ m_histogramWidget->reset();
+ slotEffect();
+ }
+ else
+ KMessageBox::error(this, i18n("Cannot load settings from the Color Management text file."));
+
+ file.close();
+}
+
+//-- Save all settings to file ---------------------------------------
+
+void ImageEffect_ICCProof::slotUser2()
+{
+ KURL saveColorManagementFile = KFileDialog::getSaveURL(KGlobalSettings::documentPath(),
+ QString( "*" ), this,
+ QString( i18n("Color Management Settings File to Save")) );
+ if( saveColorManagementFile.isEmpty() )
+ return;
+
+ QFile file(saveColorManagementFile.path());
+
+ if ( file.open(IO_WriteOnly) )
+ {
+ QTextStream stream( &file );
+ stream << "# Color Management Configuration File\n";
+ stream << m_renderingIntentsCB->currentItem() << "\n";
+ stream << m_doSoftProofBox->isChecked() << "\n";
+ stream << m_checkGamutBox->isChecked() << "\n";
+ stream << m_embeddProfileBox->isChecked() << "\n";
+ stream << m_BPCBox->isChecked() << "\n";
+ stream << m_inProfileBG->selectedId() << "\n";
+ stream << m_spaceProfileBG->selectedId() << "\n";
+ stream << m_proofProfileBG->selectedId() << "\n";
+ stream << m_inProfilesPath->url() << "\n";
+ stream << m_proofProfilePath->url() << "\n";
+ stream << m_spaceProfilePath->url() << "\n";
+ stream << m_cInput->value() << "\n";
+
+ for (int j = 0 ; j < 17 ; j++)
+ {
+ QPoint p = m_curves->getCurvePoint(Digikam::ImageHistogram::ValueChannel, j);
+ if (m_originalImage->sixteenBit())
+ {
+ p.setX(p.x()/255);
+ p.setY(p.y()/255);
+ }
+ stream << p.x() << "\n";
+ stream << p.y() << "\n";
+ }
+ }
+ else
+ KMessageBox::error(this, i18n("Cannot save settings to the Color Management text file."));
+
+ file.close();
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/imageeffect_iccproof.h b/digikam/imageplugins/coreplugin/imageeffect_iccproof.h
new file mode 100644
index 0000000..08a8a50
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_iccproof.h
@@ -0,0 +1,203 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-12-21
+ * Description : digiKam image editor tool to correct picture
+ * colors using an ICC color profile
+ *
+ * Copyright (C) 2005-2006 by F.J. Cruz <fj.cruz@supercable.es>
+ * Copyright (C) 2006-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 IMAGEEFFECT_ICCPROOF_H
+#define IMAGEEFFECT_ICCPROOF_H
+
+// Digikam include.
+
+#include "imagedlgbase.h"
+
+class QCheckBox;
+class QComboBox;
+class QVButtonGroup;
+class QButtonGroup;
+class QHButtonGroup;
+class QRadioButton;
+class QPushButton;
+class QToolBox;
+
+class KURLRequester;
+class KIntNumInput;
+
+namespace Digikam
+{
+class ICCTransform;
+class ImageWidget;
+class HistogramWidget;
+class ColorGradientWidget;
+class DColor;
+class ICCPreviewWidget;
+class ImageCurves;
+class CurvesWidget;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class ImageEffect_ICCProof : public Digikam::ImageDlgBase
+{
+ Q_OBJECT
+
+public:
+
+ ImageEffect_ICCProof(QWidget* parent);
+ ~ImageEffect_ICCProof();
+
+protected:
+
+ void finalRendering();
+
+private:
+
+ void readUserSettings();
+ void writeUserSettings();
+ void resetValues();
+
+ void getICCInfo(const QString&);
+ void getICCInfo(const QByteArray&);
+
+ bool useBPC();
+ bool doProof();
+ bool checkGamut();
+ bool embedProfile();
+
+ bool useEmbeddedProfile();
+ bool useBuiltinProfile();
+ bool useDefaultInProfile();
+ bool useSelectedInProfile();
+
+ bool useDefaultSpaceProfile();
+ bool useSelectedSpaceProfile();
+
+ bool useDefaultProofProfile();
+ bool useSelectedProofProfile();
+
+private slots:
+
+ void slotUser2();
+ void slotUser3();
+ void slotEffect();
+ void slotChannelChanged(int);
+ void slotScaleChanged(int);
+ void slotSpotColorChanged(const Digikam::DColor &);
+ void slotColorSelectedFromTarget(const Digikam::DColor &);
+ void slotToggledWidgets(bool);
+ void slotInICCInfo();
+ void slotProofICCInfo();
+ void slotSpaceICCInfo();
+ void slotCMDisabledWarning();
+ void processLCMSURL(const QString&);
+
+private:
+
+ enum HistogramScale
+ {
+ Linear = 0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel = 0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ enum ICCSettingsTab
+ {
+ GENERALPAGE=0,
+ INPUTPAGE,
+ WORKSPACEPAGE,
+ PROOFINGPAGE,
+ LIGHTNESSPAGE
+ };
+
+ bool m_cmEnabled;
+ bool m_hasICC;
+
+ uchar *m_destinationPreviewData;
+
+ QComboBox *m_channelCB;
+ QComboBox *m_renderingIntentsCB;
+
+ QCheckBox *m_doSoftProofBox;
+ QCheckBox *m_checkGamutBox;
+ QCheckBox *m_embeddProfileBox;
+ QCheckBox *m_BPCBox;
+
+ QRadioButton *m_useEmbeddedProfile;
+ QRadioButton *m_useInDefaultProfile;
+ QRadioButton *m_useInSelectedProfile;
+ QRadioButton *m_useProofDefaultProfile;
+ QRadioButton *m_useProofSelectedProfile;
+ QRadioButton *m_useSpaceDefaultProfile;
+ QRadioButton *m_useSpaceSelectedProfile;
+ QRadioButton *m_useSRGBDefaultProfile;
+
+ QString m_inPath;
+ QString m_spacePath;
+ QString m_proofPath;
+
+ QButtonGroup *m_optionsBG;
+ QButtonGroup *m_inProfileBG;
+ QButtonGroup *m_spaceProfileBG;
+ QButtonGroup *m_proofProfileBG;
+
+ QHButtonGroup *m_scaleBG;
+ QVButtonGroup *m_renderingIntentBG;
+ QVButtonGroup *m_profilesBG;
+
+ QByteArray m_embeddedICC;
+
+ QToolBox *m_toolBoxWidgets;
+
+ KIntNumInput *m_cInput;
+
+ KURLRequester *m_inProfilesPath;
+ KURLRequester *m_spaceProfilePath;
+ KURLRequester *m_proofProfilePath;
+
+ Digikam::DImg *m_originalImage;
+
+ Digikam::CurvesWidget *m_curvesWidget;
+
+ Digikam::ImageCurves *m_curves;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+
+ Digikam::ICCPreviewWidget *m_iccInPreviewWidget;
+ Digikam::ICCPreviewWidget *m_iccSpacePreviewWidget;
+ Digikam::ICCPreviewWidget *m_iccProofPreviewWidget;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif // IMAGEEFFECT_ICCPROOF_H
diff --git a/digikam/imageplugins/coreplugin/imageeffect_redeye.cpp b/digikam/imageplugins/coreplugin/imageeffect_redeye.cpp
new file mode 100644
index 0000000..ad5054d
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_redeye.cpp
@@ -0,0 +1,574 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-06-06
+ * Description : Red eyes correction tool for image editor
+ *
+ * Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qcolor.h>
+#include <qhbox.h>
+#include <qhgroupbox.h>
+#include <qvgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qcombobox.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+
+// KDE includes.
+
+#include <kcolordialog.h>
+#include <knuminput.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kstandarddirs.h>
+#include <kcolordialog.h>
+
+// Digikam includes.
+
+#include "imageiface.h"
+#include "imagewidget.h"
+#include "histogramwidget.h"
+#include "colorgradientwidget.h"
+#include "bcgmodifier.h"
+#include "dimg.h"
+#include "dimgimagefilters.h"
+
+// Local includes.
+
+#include "imageeffect_redeye.h"
+#include "imageeffect_redeye.moc"
+
+namespace DigikamImagesPluginCore
+{
+
+ImageEffect_RedEye::ImageEffect_RedEye(QWidget* parent)
+ : Digikam::ImageDlgBase(parent, i18n("Red Eye Reduction"), "redeye", false)
+{
+ m_destinationPreviewData = 0;
+ setHelp("redeyecorrectiontool.anchor", "digikam");
+
+ m_previewWidget = new Digikam::ImageWidget("redeye Tool Dialog", plainPage(),
+ i18n("<p>Here you can see the image selection preview with "
+ "red eye reduction applied."),
+ true, Digikam::ImageGuideWidget::PickColorMode, true, true);
+ setPreviewAreaWidget(m_previewWidget);
+
+ // -------------------------------------------------------------
+
+ QWidget *gboxSettings = new QWidget(plainPage());
+ QGridLayout* gridSettings = new QGridLayout(gboxSettings, 11, 4, spacingHint());
+
+ QLabel *label1 = new QLabel(i18n("Channel:"), gboxSettings);
+ label1->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ m_channelCB = new QComboBox( false, gboxSettings );
+ m_channelCB->insertItem( i18n("Luminosity") );
+ m_channelCB->insertItem( i18n("Red") );
+ m_channelCB->insertItem( i18n("Green") );
+ m_channelCB->insertItem( i18n("Blue") );
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red image channel values.<p>"
+ "<b>Green</b>: display the green image channel values.<p>"
+ "<b>Blue</b>: display the blue image channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(gboxSettings);
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin(0);
+ QWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximum counts are small, you can use the linear scale.<p>"
+ "The logarithmic scale can be used when the maximal counts are big "
+ "to show all values (small and large) on the graph."));
+
+ QPushButton *linHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( linHistoButton, i18n( "<p>Linear" ) );
+ m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap( QPixmap( directory + "histogram-lin.png" ) );
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) );
+ m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap( QPixmap( directory + "histogram-log.png" ) );
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(gboxSettings);
+ m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram "
+ "of the selected image channel. It is "
+ "updated upon setting changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new Digikam::ColorGradientWidget(Digikam::ColorGradientWidget::Horizontal, 10, histoBox);
+ m_hGradient->setColors(QColor("black"), QColor("white"));
+
+ // -------------------------------------------------------------
+
+ m_thresholdLabel = new QLabel(i18n("Sensitivity:"), gboxSettings);
+ m_redThreshold = new KIntNumInput(gboxSettings);
+ m_redThreshold->setRange(10, 90, 1, true);
+ m_redThreshold->setValue(20);
+ QWhatsThis::add(m_redThreshold, i18n("<p>Sets the red color pixels selection threshold. "
+ "Low values will select more red color pixels (agressive correction), high "
+ "values less (mild correction). Use low value if eye have been selected "
+ "exactly. Use high value if other parts of the face are also selected."));
+
+ m_smoothLabel = new QLabel(i18n("Smooth:"), gboxSettings);
+ m_smoothLevel = new KIntNumInput(gboxSettings);
+ m_smoothLevel->setRange(0, 5, 1, true);
+ m_smoothLevel->setValue(1);
+ QWhatsThis::add(m_smoothLevel, i18n("<p>Sets the smoothness value when blurring the border "
+ "of the changed pixels. "
+ "This leads to a more naturally looking pupil."));
+
+ QLabel *label3 = new QLabel(i18n("Coloring Tint:"), gboxSettings);
+ m_HSSelector = new KHSSelector(gboxSettings);
+ m_VSelector = new KValueSelector(gboxSettings);
+ m_HSSelector->setMinimumSize(200, 142);
+ m_VSelector->setMinimumSize(26, 142);
+ QWhatsThis::add(m_HSSelector, i18n("<p>Sets a custom color to re-colorize the eyes."));
+
+ QLabel *label4 = new QLabel(i18n("Tint Level:"), gboxSettings);
+ m_tintLevel = new KIntNumInput(gboxSettings);
+ m_tintLevel->setRange(1, 200, 1, true);
+ m_tintLevel->setValue(128);
+ QWhatsThis::add(m_tintLevel, i18n("<p>Set the tint level to adjust the luminosity of "
+ "the new color of the pupil."));
+
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4);
+ gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4);
+ gridSettings->addMultiCellWidget(m_thresholdLabel, 3, 3, 0, 4);
+ gridSettings->addMultiCellWidget(m_redThreshold, 4, 4, 0, 4);
+ gridSettings->addMultiCellWidget(m_smoothLabel, 5, 5, 0, 4);
+ gridSettings->addMultiCellWidget(m_smoothLevel, 6, 6, 0, 4);
+ gridSettings->addMultiCellWidget(label3, 7, 7, 0, 4);
+ gridSettings->addMultiCellWidget(m_HSSelector, 8, 8, 0, 3);
+ gridSettings->addMultiCellWidget(m_VSelector, 8, 8, 4, 4);
+ gridSettings->addMultiCellWidget(label4, 9, 9, 0, 4);
+ gridSettings->addMultiCellWidget(m_tintLevel, 10, 10, 0, 4);
+ gridSettings->setRowStretch(11, 10);
+ gridSettings->setColStretch(3, 10);
+ setUserAreaWidget(gboxSettings);
+
+ // -------------------------------------------------------------
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget(const Digikam::DColor&, const QPoint&)),
+ this, SLOT(slotColorSelectedFromTarget(const Digikam::DColor&)));
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+
+ connect(m_redThreshold, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_smoothLevel, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_HSSelector, SIGNAL(valueChanged(int, int)),
+ this, SLOT(slotHSChanged(int, int)));
+
+ connect(m_VSelector, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_tintLevel, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+}
+
+ImageEffect_RedEye::~ImageEffect_RedEye()
+{
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ delete m_histogramWidget;
+ delete m_previewWidget;
+}
+
+void ImageEffect_RedEye::slotHSChanged(int h, int s)
+{
+ m_VSelector->blockSignals(true);
+ m_VSelector->setHue(h);
+ m_VSelector->setSaturation(s);
+ m_VSelector->updateContents();
+ m_VSelector->repaint(false);
+ m_VSelector->blockSignals(false);
+ slotTimer();
+}
+
+void ImageEffect_RedEye::slotChannelChanged(int channel)
+{
+ switch(channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::ValueHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "red" ) );
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "green" ) );
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "blue" ) );
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_RedEye::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_RedEye::slotColorSelectedFromTarget(const Digikam::DColor& color)
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void ImageEffect_RedEye::readUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("redeye Tool Dialog");
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", Digikam::HistogramWidget::LogScaleHistogram));
+ m_redThreshold->setValue(config->readNumEntry("RedThreshold", 20));
+ m_smoothLevel->setValue(config->readNumEntry("SmoothLevel", 1));
+ m_HSSelector->setXValue(config->readNumEntry("HueColoringTint", 0));
+ m_HSSelector->setYValue(config->readNumEntry("SatColoringTint", 0));
+ m_VSelector->setValue(config->readNumEntry("ValColoringTint", 0));
+ m_tintLevel->setValue(config->readNumEntry("TintLevel", 128));
+
+ slotHSChanged(m_HSSelector->xValue(), m_HSSelector->yValue());
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+}
+
+void ImageEffect_RedEye::writeUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("redeye Tool Dialog");
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writeEntry("RedThreshold", m_redThreshold->value());
+ config->writeEntry("SmoothLevel", m_smoothLevel->value());
+ config->writeEntry("HueColoringTint", m_HSSelector->xValue());
+ config->writeEntry("SatColoringTint", m_HSSelector->yValue());
+ config->writeEntry("ValColoringTint", m_VSelector->value());
+ config->writeEntry("TintLevel", m_tintLevel->value());
+ config->sync();
+}
+
+void ImageEffect_RedEye::resetValues()
+{
+ m_redThreshold->blockSignals(true);
+ m_HSSelector->blockSignals(true);
+ m_VSelector->blockSignals(true);
+ m_tintLevel->blockSignals(true);
+
+ m_redThreshold->setValue(20);
+ m_smoothLevel->setValue(1);
+
+ // Black color by default
+ m_HSSelector->setXValue(0);
+ m_HSSelector->setYValue(0);
+ m_VSelector->setValue(0);
+
+ m_tintLevel->setValue(128);
+
+ m_redThreshold->blockSignals(false);
+ m_HSSelector->blockSignals(false);
+ m_VSelector->blockSignals(false);
+ m_tintLevel->blockSignals(false);
+}
+
+void ImageEffect_RedEye::slotEffect()
+{
+ kapp->setOverrideCursor(KCursor::waitCursor());
+
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ // Here, we need to use the real selection image data because we will apply
+ // a Gaussian blur filter on pixels and we cannot use directly the preview scaled image
+ // else the blur radius will not give the same result between preview and final rendering.
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ m_destinationPreviewData = iface->getImageSelection();
+ int w = iface->selectedWidth();
+ int h = iface->selectedHeight();
+ bool sb = iface->originalSixteenBit();
+ bool a = iface->originalHasAlpha();
+ Digikam::DImg selection(w, h, sb, a, m_destinationPreviewData);
+
+ redEyeFilter(selection);
+
+ Digikam::DImg preview = selection.smoothScale(iface->previewWidth(), iface->previewHeight());
+
+ iface->putPreviewImage(preview.bits());
+ m_previewWidget->updatePreview();
+
+ // Update histogram.
+
+ memcpy(m_destinationPreviewData, selection.bits(), selection.numBytes());
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false);
+
+ kapp->restoreOverrideCursor();
+}
+
+void ImageEffect_RedEye::finalRendering()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ uchar *data = iface->getImageSelection();
+ int w = iface->selectedWidth();
+ int h = iface->selectedHeight();
+ bool sixteenBit = iface->originalSixteenBit();
+ bool hasAlpha = iface->originalHasAlpha();
+ Digikam::DImg selection(w, h, sixteenBit, hasAlpha, data);
+ delete [] data;
+
+ redEyeFilter(selection);
+
+ iface->putImageSelection(i18n("Red Eyes Correction"), selection.bits());
+
+ kapp->restoreOverrideCursor();
+ accept();
+}
+
+void ImageEffect_RedEye::redEyeFilter(Digikam::DImg& selection)
+{
+ Digikam::DImg mask(selection.width(), selection.height(), selection.sixteenBit(), true,
+ selection.bits(), true);
+
+ selection = mask.copy();
+ float redThreshold = m_redThreshold->value()/10.0;
+ int hue = m_HSSelector->xValue();
+ int sat = m_HSSelector->yValue();
+ int val = m_VSelector->value();
+ KColor coloring;
+ coloring.setHsv(hue, sat, val);
+
+ struct channel
+ {
+ float red_gain;
+ float green_gain;
+ float blue_gain;
+ };
+
+ channel red_chan, green_chan, blue_chan;
+
+ red_chan.red_gain = 0.1;
+ red_chan.green_gain = 0.6;
+ red_chan.blue_gain = 0.3;
+
+ green_chan.red_gain = 0.0;
+ green_chan.green_gain = 1.0;
+ green_chan.blue_gain = 0.0;
+
+ blue_chan.red_gain = 0.0;
+ blue_chan.green_gain = 0.0;
+ blue_chan.blue_gain = 1.0;
+
+ float red_norm, green_norm, blue_norm;
+ int level = 201 - m_tintLevel->value();
+
+ red_norm = 1.0 / (red_chan.red_gain + red_chan.green_gain + red_chan.blue_gain);
+ green_norm = 1.0 / (green_chan.red_gain + green_chan.green_gain + green_chan.blue_gain);
+ blue_norm = 1.0 / (blue_chan.red_gain + blue_chan.green_gain + blue_chan.blue_gain);
+
+ red_norm *= coloring.red() / level;
+ green_norm *= coloring.green() / level;
+ blue_norm *= coloring.blue() / level;
+
+ // Perform a red color pixels detection in selection image and create a correction mask using an alpha channel.
+
+ if (!selection.sixteenBit()) // 8 bits image.
+ {
+ uchar* ptr = selection.bits();
+ uchar* mptr = mask.bits();
+ uchar r, g, b, r1, g1, b1;
+
+ for (uint i = 0 ; i < selection.width() * selection.height() ; i++)
+ {
+ b = ptr[0];
+ g = ptr[1];
+ r = ptr[2];
+ mptr[3] = 255;
+
+ if (r >= ( redThreshold * g))
+ {
+ r1 = QMIN(255, (int)(red_norm * (red_chan.red_gain * r +
+ red_chan.green_gain * g +
+ red_chan.blue_gain * b)));
+
+ g1 = QMIN(255, (int)(green_norm * (green_chan.red_gain * r +
+ green_chan.green_gain * g +
+ green_chan.blue_gain * b)));
+
+ b1 = QMIN(255, (int)(blue_norm * (blue_chan.red_gain * r +
+ blue_chan.green_gain * g +
+ blue_chan.blue_gain * b)));
+
+ mptr[0] = b1;
+ mptr[1] = g1;
+ mptr[2] = r1;
+ mptr[3] = QMIN( (int)((r-g) / 150.0 * 255.0), 255);
+ }
+
+ ptr += 4;
+ mptr+= 4;
+ }
+ }
+ else // 16 bits image.
+ {
+ unsigned short* ptr = (unsigned short*)selection.bits();
+ unsigned short* mptr = (unsigned short*)mask.bits();
+ unsigned short r, g, b, r1, g1, b1;
+
+ for (uint i = 0 ; i < selection.width() * selection.height() ; i++)
+ {
+ b = ptr[0];
+ g = ptr[1];
+ r = ptr[2];
+ mptr[3] = 65535;
+
+ if (r >= ( redThreshold * g))
+ {
+ r1 = QMIN(65535, (int)(red_norm * (red_chan.red_gain * r +
+ red_chan.green_gain * g +
+ red_chan.blue_gain * b)));
+
+ g1 = QMIN(65535, (int)(green_norm * (green_chan.red_gain * r +
+ green_chan.green_gain * g +
+ green_chan.blue_gain * b)));
+
+ b1 = QMIN(65535, (int)(blue_norm * (blue_chan.red_gain * r +
+ blue_chan.green_gain * g +
+ blue_chan.blue_gain * b)));
+
+ mptr[0] = b1;
+ mptr[1] = g1;
+ mptr[2] = r1;
+ mptr[3] = QMIN( (int)((r-g) / 38400.0 * 65535.0), 65535);;
+ }
+
+ ptr += 4;
+ mptr+= 4;
+ }
+ }
+
+ // Now, we will blur only the transparency pixels from the mask.
+
+ Digikam::DImg mask2 = mask.copy();
+ Digikam::DImgImageFilters filter;
+ filter.gaussianBlurImage(mask2.bits(), mask2.width(), mask2.height(),
+ mask2.sixteenBit(), m_smoothLevel->value());
+
+ if (!selection.sixteenBit()) // 8 bits image.
+ {
+ uchar* mptr = mask.bits();
+ uchar* mptr2 = mask2.bits();
+
+ for (uint i = 0 ; i < mask2.width() * mask2.height() ; i++)
+ {
+ if (mptr2[3] < 255)
+ {
+ mptr[0] = mptr2[0];
+ mptr[1] = mptr2[1];
+ mptr[2] = mptr2[2];
+ mptr[3] = mptr2[3];
+ }
+
+ mptr += 4;
+ mptr2+= 4;
+ }
+ }
+ else // 16 bits image.
+ {
+ unsigned short* mptr = (unsigned short*)mask.bits();
+ unsigned short* mptr2 = (unsigned short*)mask2.bits();
+
+ for (uint i = 0 ; i < mask2.width() * mask2.height() ; i++)
+ {
+ if (mptr2[3] < 65535)
+ {
+ mptr[0] = mptr2[0];
+ mptr[1] = mptr2[1];
+ mptr[2] = mptr2[2];
+ mptr[3] = mptr2[3];
+ }
+
+ mptr += 4;
+ mptr2+= 4;
+ }
+ }
+
+ // - Perform pixels blending using alpha channel between the mask and the selection.
+
+ Digikam::DColorComposer *composer = Digikam::DColorComposer::getComposer(Digikam::DColorComposer::PorterDuffSrcOver);
+
+ // NOTE: 'mask' is the Source image, 'selection' is the Destination image.
+
+ selection.bitBlendImage(composer, &mask,
+ 0, 0, mask.width(), mask.height(),
+ 0, 0);
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/imageeffect_redeye.h b/digikam/imageplugins/coreplugin/imageeffect_redeye.h
new file mode 100644
index 0000000..3300be3
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_redeye.h
@@ -0,0 +1,152 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-06-06
+ * Description : Red eyes correction tool for image editor
+ *
+ * Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * 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 IMAGEEFFECT_REDEYE_H
+#define IMAGEEFFECT_REDEYE_H
+
+// KDE includes.
+
+#include <kpassivepopup.h>
+
+// Digikam include.
+
+#include "imagedlgbase.h"
+
+class QLabel;
+class QComboBox;
+class QHButtonGroup;
+
+class KHSSelector;
+class KValueSelector;
+class KIntNumInput;
+
+namespace Digikam
+{
+class HistogramWidget;
+class ColorGradientWidget;
+class ImageWidget;
+class DColor;
+class DImg;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class RedEyePassivePopup : public KPassivePopup
+{
+public:
+
+ RedEyePassivePopup(QWidget* parent)
+ : KPassivePopup(parent), m_parent(parent)
+ {
+ }
+
+protected:
+
+ virtual void positionSelf()
+ {
+ move(m_parent->x() + 30, m_parent->y() + 30);
+ }
+
+private:
+
+ QWidget* m_parent;
+};
+
+// ----------------------------------------------------------------
+
+class ImageEffect_RedEye : public Digikam::ImageDlgBase
+{
+ Q_OBJECT
+
+public:
+
+ ImageEffect_RedEye(QWidget *parent);
+ ~ImageEffect_RedEye();
+
+private slots:
+
+ void slotEffect();
+ void slotChannelChanged(int channel);
+ void slotScaleChanged(int scale);
+ void slotColorSelectedFromTarget(const Digikam::DColor &color);
+ void slotHSChanged(int h, int s);
+
+private:
+
+ void readUserSettings();
+ void writeUserSettings();
+ void resetValues();
+ void finalRendering();
+ void redEyeFilter(Digikam::DImg& selection);
+
+private:
+
+ enum HistogramScale
+ {
+ Linear=0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel=0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ enum RedThresold
+ {
+ Mild=0,
+ Aggressive
+ };
+
+ uchar *m_destinationPreviewData;
+
+ QLabel *m_thresholdLabel;
+ QLabel *m_smoothLabel;
+
+ QComboBox *m_channelCB;
+
+ QHButtonGroup *m_scaleBG;
+
+ KIntNumInput *m_tintLevel;
+ KIntNumInput *m_redThreshold;
+ KIntNumInput *m_smoothLevel;
+
+ KHSSelector *m_HSSelector;
+ KValueSelector *m_VSelector;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* IMAGEEFFECT_REDEYE_H */
diff --git a/digikam/imageplugins/coreplugin/imageeffect_rgb.cpp b/digikam/imageplugins/coreplugin/imageeffect_rgb.cpp
new file mode 100644
index 0000000..6101134
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_rgb.cpp
@@ -0,0 +1,419 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-11
+ * Description : digiKam image editor Color Balance tool.
+ *
+ * Copyright (C) 2004-2007 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qspinbox.h>
+#include <qslider.h>
+#include <qcolor.h>
+#include <qgroupbox.h>
+#include <qhgroupbox.h>
+#include <qvgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+
+// KDE includes.
+
+#include <kconfig.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kcursor.h>
+#include <kstandarddirs.h>
+
+// Digikam includes.
+
+#include "imageiface.h"
+#include "imagewidget.h"
+#include "histogramwidget.h"
+#include "colorgradientwidget.h"
+#include "colormodifier.h"
+#include "dimg.h"
+
+// Local includes.
+
+#include "imageeffect_rgb.h"
+#include "imageeffect_rgb.moc"
+
+namespace DigikamImagesPluginCore
+{
+
+ImageEffect_RGB::ImageEffect_RGB(QWidget* parent)
+ : Digikam::ImageDlgBase(parent, i18n("Color Balance"), "colorbalance", false)
+{
+ m_destinationPreviewData = 0L;
+ setHelp("colorbalancetool.anchor", "digikam");
+
+ m_previewWidget = new Digikam::ImageWidget("colorbalance Tool Dialog", plainPage(),
+ i18n("<p>Here you can see the image "
+ "color-balance adjustments preview. "
+ "You can pick color on image "
+ "to see the color level corresponding on histogram."));
+ setPreviewAreaWidget(m_previewWidget);
+
+ // -------------------------------------------------------------
+
+ QWidget *gboxSettings = new QWidget(plainPage());
+ QGridLayout* gridSettings = new QGridLayout( gboxSettings, 7, 4, spacingHint());
+
+ QLabel *label1 = new QLabel(i18n("Channel:"), gboxSettings);
+ label1->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ m_channelCB = new QComboBox( false, gboxSettings );
+ m_channelCB->insertItem( i18n("Luminosity") );
+ m_channelCB->insertItem( i18n("Red") );
+ m_channelCB->insertItem( i18n("Green") );
+ m_channelCB->insertItem( i18n("Blue") );
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red image-channel values.<p>"
+ "<b>Green</b>: display the green image-channel values.<p>"
+ "<b>Blue</b>: display the blue image-channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(gboxSettings);
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin( 0 );
+ QWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximal counts are small, you can use the linear scale.<p>"
+ "Logarithmic scale can be used when the maximal counts are big; "
+ "if it is used, all values (small and large) will be visible on the graph."));
+
+ QPushButton *linHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( linHistoButton, i18n( "<p>Linear" ) );
+ m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap( QPixmap( directory + "histogram-lin.png" ) );
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton( m_scaleBG );
+ QToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) );
+ m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap( QPixmap( directory + "histogram-log.png" ) );
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(gboxSettings);
+ m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram drawing "
+ "of the selected image channel. This one is re-computed at any "
+ "settings changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new Digikam::ColorGradientWidget( Digikam::ColorGradientWidget::Horizontal, 10, histoBox );
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+
+ gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4);
+
+ // -------------------------------------------------------------
+
+ QLabel *labelLeft = new QLabel(i18n("Cyan"), gboxSettings);
+ labelLeft->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ m_rSlider = new QSlider(-100, 100, 1, 0, Qt::Horizontal, gboxSettings, "m_rSlider");
+ m_rSlider->setTickmarks(QSlider::Below);
+ m_rSlider->setTickInterval(20);
+ QWhatsThis::add( m_rSlider, i18n("<p>Set here the cyan/red color adjustment of the image."));
+ QLabel *labelRight = new QLabel(i18n("Red"), gboxSettings);
+ labelRight->setAlignment ( Qt::AlignLeft | Qt::AlignVCenter );
+ m_rInput = new QSpinBox(-100, 100, 1, gboxSettings, "m_rInput");
+
+ gridSettings->addMultiCellWidget(labelLeft, 3, 3, 0, 0);
+ gridSettings->addMultiCellWidget(m_rSlider, 3, 3, 1, 1);
+ gridSettings->addMultiCellWidget(labelRight, 3, 3, 2, 2);
+ gridSettings->addMultiCellWidget(m_rInput, 3, 3, 3, 3);
+
+ // -------------------------------------------------------------
+
+ labelLeft = new QLabel(i18n("Magenta"), gboxSettings);
+ labelLeft->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ m_gSlider = new QSlider(-100, 100, 1, 0, Qt::Horizontal, gboxSettings, "m_gSlider");
+ m_gSlider->setTickmarks(QSlider::Below);
+ m_gSlider->setTickInterval(20);
+ QWhatsThis::add( m_gSlider, i18n("<p>Set here the magenta/green color adjustment of the image."));
+ labelRight = new QLabel(i18n("Green"), gboxSettings);
+ labelRight->setAlignment ( Qt::AlignLeft | Qt::AlignVCenter );
+ m_gInput = new QSpinBox(-100, 100, 1, gboxSettings, "m_gInput");
+
+ gridSettings->addMultiCellWidget(labelLeft, 4, 4, 0, 0);
+ gridSettings->addMultiCellWidget(m_gSlider, 4, 4, 1, 1);
+ gridSettings->addMultiCellWidget(labelRight, 4, 4, 2, 2);
+ gridSettings->addMultiCellWidget(m_gInput, 4, 4, 3, 3);
+
+ // -------------------------------------------------------------
+
+ labelLeft = new QLabel(i18n("Yellow"), gboxSettings);
+ labelLeft->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ m_bSlider = new QSlider(-100, 100, 1, 0, Qt::Horizontal, gboxSettings, "m_bSlider");
+ m_bSlider->setTickmarks(QSlider::Below);
+ m_bSlider->setTickInterval(20);
+ QWhatsThis::add( m_bSlider, i18n("<p>Set here the yellow/blue color adjustment of the image."));
+ labelRight = new QLabel(i18n("Blue"), gboxSettings);
+ labelRight->setAlignment ( Qt::AlignLeft | Qt::AlignVCenter );
+ m_bInput = new QSpinBox(-100, 100, 1, gboxSettings, "m_bInput");
+
+ gridSettings->addMultiCellWidget(labelLeft, 5, 5, 0, 0);
+ gridSettings->addMultiCellWidget(m_bSlider, 5, 5, 1, 1);
+ gridSettings->addMultiCellWidget(labelRight, 5, 5, 2, 2);
+ gridSettings->addMultiCellWidget(m_bInput, 5, 5, 3, 3);
+
+ m_rInput->setValue(0);
+ m_gInput->setValue(0);
+ m_bInput->setValue(0);
+
+ gridSettings->setRowStretch(6, 10);
+ setUserAreaWidget(gboxSettings);
+
+ // -------------------------------------------------------------
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const QPoint & )),
+ this, SLOT(slotColorSelectedFromTarget( const Digikam::DColor & )));
+
+ connect(m_rSlider, SIGNAL(valueChanged(int)),
+ m_rInput, SLOT(setValue(int)));
+ connect(m_rInput, SIGNAL(valueChanged (int)),
+ m_rSlider, SLOT(setValue(int)));
+ connect(m_rInput, SIGNAL(valueChanged (int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_gSlider, SIGNAL(valueChanged(int)),
+ m_gInput, SLOT(setValue(int)));
+ connect(m_gInput, SIGNAL(valueChanged (int)),
+ m_gSlider, SLOT(setValue(int)));
+ connect(m_gInput, SIGNAL(valueChanged (int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_bSlider, SIGNAL(valueChanged(int)),
+ m_bInput, SLOT(setValue(int)));
+ connect(m_bInput, SIGNAL(valueChanged (int)),
+ m_bSlider, SLOT(setValue(int)));
+ connect(m_bInput, SIGNAL(valueChanged (int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+
+ // -------------------------------------------------------------
+
+ enableButtonOK( false );
+}
+
+ImageEffect_RGB::~ImageEffect_RGB()
+{
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ delete m_histogramWidget;
+ delete m_previewWidget;
+}
+
+void ImageEffect_RGB::slotChannelChanged(int channel)
+{
+ switch(channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::ValueHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "white" ) );
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "red" ) );
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "green" ) );
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors( QColor( "black" ), QColor( "blue" ) );
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_RGB::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_RGB::slotColorSelectedFromTarget( const Digikam::DColor &color )
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void ImageEffect_RGB::readUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("colorbalance Tool Dialog");
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", Digikam::HistogramWidget::LogScaleHistogram));
+ int r = config->readNumEntry("RedAjustment", 0);
+ int g = config->readNumEntry("GreenAjustment", 0);
+ int b = config->readNumEntry("BlueAjustment", 0);
+ adjustSliders(r, g, b);
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+}
+
+void ImageEffect_RGB::writeUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("colorbalance Tool Dialog");
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writeEntry("RedAjustment", m_rSlider->value());
+ config->writeEntry("GreenAjustment", m_gInput->value());
+ config->writeEntry("BlueAjustment", m_bInput->value());
+ config->sync();
+}
+
+void ImageEffect_RGB::resetValues()
+{
+ adjustSliders(0, 0, 0);
+}
+
+void ImageEffect_RGB::adjustSliders(int r, int g, int b)
+{
+ m_rSlider->blockSignals(true);
+ m_gSlider->blockSignals(true);
+ m_bSlider->blockSignals(true);
+ m_rInput->blockSignals(true);
+ m_gInput->blockSignals(true);
+ m_bInput->blockSignals(true);
+
+ m_rSlider->setValue(r);
+ m_gSlider->setValue(g);
+ m_bSlider->setValue(b);
+ m_rInput->setValue(r);
+ m_gInput->setValue(g);
+ m_bInput->setValue(b);
+
+ m_rSlider->blockSignals(false);
+ m_gSlider->blockSignals(false);
+ m_bSlider->blockSignals(false);
+ m_rInput->blockSignals(false);
+ m_gInput->blockSignals(false);
+ m_bInput->blockSignals(false);
+
+ slotEffect();
+}
+
+void ImageEffect_RGB::slotEffect()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ enableButtonOK(m_rInput->value() != 0 ||
+ m_gInput->value() != 0 ||
+ m_bInput->value() != 0);
+
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ m_destinationPreviewData = iface->getPreviewImage();
+ int w = iface->previewWidth();
+ int h = iface->previewHeight();
+ bool alpha = iface->previewHasAlpha();
+ bool sixteenBit = iface->previewSixteenBit();
+
+ double r = ((double)m_rInput->value() + 100.0)/100.0;
+ double g = ((double)m_gInput->value() + 100.0)/100.0;
+ double b = ((double)m_bInput->value() + 100.0)/100.0;
+ double a = 1.0;
+
+ Digikam::DImg preview(w, h, sixteenBit, alpha, m_destinationPreviewData);
+ Digikam::ColorModifier cmod;
+ cmod.applyColorModifier(preview, r, g, b, a);
+ iface->putPreviewImage(preview.bits());
+
+ m_previewWidget->updatePreview();
+
+ // Update histogram.
+
+ memcpy(m_destinationPreviewData, preview.bits(), preview.numBytes());
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sixteenBit, 0, 0, 0, false);
+
+ kapp->restoreOverrideCursor();
+}
+
+void ImageEffect_RGB::finalRendering()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ double r = ((double)m_rInput->value() + 100.0)/100.0;
+ double g = ((double)m_gInput->value() + 100.0)/100.0;
+ double b = ((double)m_bInput->value() + 100.0)/100.0;
+ double a = 1.0;
+
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int w = iface->originalWidth();
+ int h = iface->originalHeight();
+ bool alpha = iface->originalHasAlpha();
+ bool sixteenBit = iface->originalSixteenBit();
+ Digikam::DImg original(w, h, sixteenBit, alpha, data);
+ delete [] data;
+
+ Digikam::ColorModifier cmod;
+ cmod.applyColorModifier(original, r, g, b, a);
+
+ iface->putOriginalImage(i18n("Color Balance"), original.bits());
+ kapp->restoreOverrideCursor();
+ accept();
+}
+
+} // NameSpace DigikamImagesPluginCore
+
diff --git a/digikam/imageplugins/coreplugin/imageeffect_rgb.h b/digikam/imageplugins/coreplugin/imageeffect_rgb.h
new file mode 100644
index 0000000..4327764
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageeffect_rgb.h
@@ -0,0 +1,112 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-11
+ * Description : digiKam image editor Color Balance tool.
+ *
+ * Copyright (C) 2004-2007 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 IMAGEEFFECT_RGB_H
+#define IMAGEEFFECT_RGB_H
+
+// Digikam include.
+
+#include "imagedlgbase.h"
+
+class QComboBox;
+class QHButtonGroup;
+
+class QSpinBox;
+class QSlider;
+
+namespace Digikam
+{
+class HistogramWidget;
+class ColorGradientWidget;
+class ImageWidget;
+class DColor;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class ImageEffect_RGB : public Digikam::ImageDlgBase
+{
+ Q_OBJECT
+
+public:
+
+ ImageEffect_RGB(QWidget *parent);
+ ~ImageEffect_RGB();
+
+private:
+
+ void writeUserSettings();
+ void readUserSettings();
+ void resetValues();
+ void adjustSliders(int r, int g, int b);
+ void finalRendering();
+
+private slots:
+
+ void slotEffect();
+ void slotChannelChanged(int channel);
+ void slotScaleChanged(int scale);
+ void slotColorSelectedFromTarget( const Digikam::DColor &color );
+
+private:
+
+ enum HistogramScale
+ {
+ Linear=0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel=0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ uchar *m_destinationPreviewData;
+
+ QComboBox *m_channelCB;
+
+ QHButtonGroup *m_scaleBG;
+
+ QSpinBox *m_rInput;
+ QSpinBox *m_gInput;
+ QSpinBox *m_bInput;
+
+ QSlider *m_rSlider;
+ QSlider *m_gSlider;
+ QSlider *m_bSlider;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* IMAGEEFFECT_RGB_H */
diff --git a/digikam/imageplugins/coreplugin/imageplugin_core.cpp b/digikam/imageplugins/coreplugin/imageplugin_core.cpp
new file mode 100644
index 0000000..cf9a459
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageplugin_core.cpp
@@ -0,0 +1,295 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-06-04
+ * Description : digiKam image editor plugin core
+ *
+ * Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * Copyright (C) 2005-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.
+ *
+ * ============================================================ */
+
+#include <config.h>
+
+// KDE includes.
+
+#include <klocale.h>
+#include <kgenericfactory.h>
+#include <klibloader.h>
+#include <kaction.h>
+#include <kcursor.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "dimg.h"
+#include "dimgimagefilters.h"
+#include "imageiface.h"
+#include "rgbtool.h"
+#include "hsltool.h"
+#include "bcgtool.h"
+#include "bwsepiatool.h"
+#include "redeyetool.h"
+#include "blurtool.h"
+#include "sharpentool.h"
+#include "ratiocroptool.h"
+#include "autocorrectiontool.h"
+#include "iccprooftool.h"
+#include "imageplugin_core.h"
+#include "imageplugin_core.moc"
+
+using namespace DigikamImagesPluginCore;
+using namespace Digikam;
+
+K_EXPORT_COMPONENT_FACTORY(digikamimageplugin_core,
+ KGenericFactory<ImagePlugin_Core>("digikam"));
+
+ImagePlugin_Core::ImagePlugin_Core(QObject *parent, const char*, const QStringList&)
+ : ImagePlugin(parent, "ImagePlugin_Core")
+{
+ //-------------------------------
+ // Fix and Colors menu actions
+
+ m_blurAction = new KAction(i18n("Blur..."), "blurimage", 0,
+ this, SLOT(slotBlur()),
+ actionCollection(), "implugcore_blur");
+
+ m_sharpenAction = new KAction(i18n("Sharpen..."), "sharpenimage", 0,
+ this, SLOT(slotSharpen()),
+ actionCollection(), "implugcore_sharpen");
+
+ m_redeyeAction = new KAction(i18n("Red Eye..."), "redeyes", 0,
+ this, SLOT(slotRedEye()),
+ actionCollection(), "implugcore_redeye");
+ m_redeyeAction->setWhatsThis( i18n( "This filter can be used to correct red eyes in a photo. "
+ "Select a region including the eyes to use this option.") );
+
+ m_BCGAction = new KAction(i18n("Brightness/Contrast/Gamma..."), "contrast", 0,
+ this, SLOT(slotBCG()),
+ actionCollection(), "implugcore_bcg");
+
+ m_HSLAction = new KAction(i18n("Hue/Saturation/Lightness..."), "adjusthsl",
+ CTRL+Key_U, // NOTE: Photoshop 7 use CTRL+U.
+ this, SLOT(slotHSL()),
+ actionCollection(), "implugcore_hsl");
+
+ m_RGBAction = new KAction(i18n("Color Balance..."), "adjustrgb",
+ CTRL+Key_B, // NOTE: Photoshop 7 use CTRL+B.
+ this, SLOT(slotRGB()),
+ actionCollection(), "implugcore_rgb");
+
+ m_autoCorrectionAction = new KAction(i18n("Auto-Correction..."), "autocorrection",
+ CTRL+SHIFT+Key_B, // NOTE: Photoshop 7 use CTRL+SHIFT+B with 'Auto-Color' option.
+ this, SLOT(slotAutoCorrection()),
+ actionCollection(), "implugcore_autocorrection");
+
+ m_invertAction = new KAction(i18n("Invert"), "invertimage",
+ CTRL+Key_I, // NOTE: Photoshop 7 use CTRL+I.
+ this, SLOT(slotInvert()),
+ actionCollection(), "implugcore_invert");
+
+ m_convertTo8Bits = new KAction(i18n("8 bits"), "depth16to8", 0,
+ this, SLOT(slotConvertTo8Bits()),
+ actionCollection(), "implugcore_convertto8bits");
+
+ m_convertTo16Bits = new KAction(i18n("16 bits"), "depth8to16", 0,
+ this, SLOT(slotConvertTo16Bits()),
+ actionCollection(), "implugcore_convertto16bits");
+
+ m_colorManagementAction = new KAction(i18n("Color Management..."), "colormanagement", 0,
+ this, SLOT(slotColorManagement()),
+ actionCollection(), "implugcore_colormanagement");
+ //-------------------------------
+ // Filters menu actions.
+
+ m_BWAction = new KAction(i18n("Black && White..."), "bwtonal", 0,
+ this, SLOT(slotBW()),
+ actionCollection(), "implugcore_blackwhite");
+
+ //-------------------------------
+ // Transform menu actions.
+
+ m_aspectRatioCropAction = new KAction(i18n("Aspect Ratio Crop..."), "ratiocrop", 0,
+ this, SLOT(slotRatioCrop()),
+ actionCollection(), "implugcore_ratiocrop");
+
+ //-------------------------------
+ // Init. menu actions.
+
+ setXMLFile("digikamimageplugin_core_ui.rc");
+
+ DDebug() << "ImagePlugin_Core plugin loaded" << endl;
+}
+
+ImagePlugin_Core::~ImagePlugin_Core()
+{
+}
+
+void ImagePlugin_Core::setEnabledSelectionActions(bool)
+{
+}
+
+void ImagePlugin_Core::setEnabledActions(bool enable)
+{
+ m_redeyeAction->setEnabled(enable);
+ m_BCGAction->setEnabled(enable);
+ m_HSLAction->setEnabled(enable);
+ m_RGBAction->setEnabled(enable);
+ m_autoCorrectionAction->setEnabled(enable);
+ m_invertAction->setEnabled(enable);
+ m_BWAction->setEnabled(enable);
+ m_aspectRatioCropAction->setEnabled(enable);
+ m_sharpenAction->setEnabled(enable);
+ m_blurAction->setEnabled(enable);
+ m_colorManagementAction->setEnabled(enable);
+ m_convertTo8Bits->setEnabled(enable);
+ m_convertTo16Bits->setEnabled(enable);
+}
+
+void ImagePlugin_Core::slotBlur()
+{
+ BlurTool *tool = new BlurTool(this);
+ loadTool(tool);
+}
+
+void ImagePlugin_Core::slotSharpen()
+{
+ SharpenTool *tool = new SharpenTool(this);
+ loadTool(tool);
+}
+
+void ImagePlugin_Core::slotBCG()
+{
+ BCGTool *bcg = new BCGTool(this);
+ loadTool(bcg);
+}
+
+void ImagePlugin_Core::slotRGB()
+{
+ RGBTool *rgb = new RGBTool(this);
+ loadTool(rgb);
+}
+
+void ImagePlugin_Core::slotHSL()
+{
+ HSLTool *hsl = new HSLTool(this);
+ loadTool(hsl);
+}
+
+void ImagePlugin_Core::slotAutoCorrection()
+{
+ AutoCorrectionTool *autocorrection = new AutoCorrectionTool(this);
+ loadTool(autocorrection);
+}
+
+void ImagePlugin_Core::slotInvert()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ ImageIface iface(0, 0);
+
+ uchar *data = iface.getOriginalImage();
+ int w = iface.originalWidth();
+ int h = iface.originalHeight();
+ bool sixteenBit = iface.originalSixteenBit();
+
+ DImgImageFilters filter;
+ filter.invertImage(data, w, h, sixteenBit);
+ iface.putOriginalImage(i18n("Invert"), data);
+ delete [] data;
+
+ kapp->restoreOverrideCursor();
+}
+
+void ImagePlugin_Core::slotBW()
+{
+ BWSepiaTool *bwsepia = new BWSepiaTool(this);
+ loadTool(bwsepia);
+}
+
+void ImagePlugin_Core::slotRedEye()
+{
+ ImageIface iface(0, 0);
+
+ if (!iface.selectedWidth() || !iface.selectedHeight())
+ {
+ RedEyePassivePopup* popup = new RedEyePassivePopup(kapp->activeWindow());
+ popup->setView(i18n("Red-Eye Correction Tool"),
+ i18n("You need to select a region including the eyes to use "
+ "the red-eye correction tool"));
+ popup->setAutoDelete(true);
+ popup->setTimeout(2500);
+ popup->show();
+ return;
+ }
+
+ RedEyeTool *redeye = new RedEyeTool(this);
+ loadTool(redeye);
+}
+
+void ImagePlugin_Core::slotColorManagement()
+{
+ ICCProofTool *tool = new ICCProofTool(this);
+ loadTool(tool);
+}
+
+void ImagePlugin_Core::slotRatioCrop()
+{
+ RatioCropTool *ratiocrop = new RatioCropTool(this);
+ loadTool(ratiocrop);
+}
+
+void ImagePlugin_Core::slotConvertTo8Bits()
+{
+ ImageIface iface(0, 0);
+
+ if (!iface.originalSixteenBit())
+ {
+ KMessageBox::error(kapp->activeWindow(), i18n("This image is already using a depth of 8 bits / color / pixel."));
+ return;
+ }
+ else
+ {
+ if (KMessageBox::warningContinueCancel(
+ kapp->activeWindow(),
+ i18n("Performing this operation will reduce image color quality. "
+ "Do you want to continue?"), QString(),
+ KStdGuiItem::cont(),
+ QString("ImagePluginCore16To8Bits")) == KMessageBox::Cancel)
+ return;
+ }
+
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+ iface.convertOriginalColorDepth(32);
+ kapp->restoreOverrideCursor();
+}
+
+void ImagePlugin_Core::slotConvertTo16Bits()
+{
+ ImageIface iface(0, 0);
+
+ if (iface.originalSixteenBit())
+ {
+ KMessageBox::error(kapp->activeWindow(), i18n("This image is already using a depth of 16 bits / color / pixel."));
+ return;
+ }
+
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+ iface.convertOriginalColorDepth(64);
+ kapp->restoreOverrideCursor();
+}
diff --git a/digikam/imageplugins/coreplugin/imageplugin_core.h b/digikam/imageplugins/coreplugin/imageplugin_core.h
new file mode 100644
index 0000000..55f0ebe
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/imageplugin_core.h
@@ -0,0 +1,84 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-06-04
+ * Description : digiKam image editor plugin core
+ *
+ * Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * Copyright (C) 2005-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_CORE_H
+#define IMAGEPLUGIN_CORE_H
+
+// Digikam includes.
+
+#include "imageplugin.h"
+#include "digikam_export.h"
+
+class KAction;
+
+class DIGIKAMIMAGEPLUGINS_EXPORT ImagePlugin_Core : public Digikam::ImagePlugin
+{
+ Q_OBJECT
+
+public:
+
+ ImagePlugin_Core(QObject *parent, const char* name, const QStringList &args);
+ ~ImagePlugin_Core();
+
+ void setEnabledSelectionActions(bool enable);
+ void setEnabledActions(bool enable);
+
+private slots:
+
+ void slotBlur();
+ void slotSharpen();
+ void slotBCG();
+ void slotRGB();
+ void slotHSL();
+ void slotAutoCorrection();
+ void slotInvert();
+
+ void slotBW();
+
+ void slotRedEye();
+ void slotRatioCrop();
+
+ void slotConvertTo8Bits();
+ void slotConvertTo16Bits();
+
+ void slotColorManagement();
+
+private:
+
+ KAction *m_redeyeAction;
+ KAction *m_BCGAction;
+ KAction *m_HSLAction;
+ KAction *m_RGBAction;
+ KAction *m_autoCorrectionAction;
+ KAction *m_invertAction;
+ KAction *m_BWAction;
+ KAction *m_aspectRatioCropAction;
+ KAction *m_sharpenAction;
+ KAction *m_blurAction;
+ KAction *m_colorManagementAction;
+ KAction *m_convertTo8Bits;
+ KAction *m_convertTo16Bits;
+};
+
+#endif /* IMAGEPLUGIN_CORE_H */
diff --git a/digikam/imageplugins/coreplugin/ratiocrop/Makefile.am b/digikam/imageplugins/coreplugin/ratiocrop/Makefile.am
new file mode 100644
index 0000000..d65a4a3
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/ratiocrop/Makefile.am
@@ -0,0 +1,26 @@
+noinst_LTLIBRARIES = libratiocrop.la
+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)
+
+libratiocrop_la_SOURCES = ratiocroptool.cpp imageselectionwidget.cpp
+
+libratiocrop_la_LDFLAGS = $(all_libraries)
+
+noinst_HEADERS = ratiocroptool.h imageselectionwidget.h
+
diff --git a/digikam/imageplugins/coreplugin/ratiocrop/imageeffect_ratiocrop.cpp b/digikam/imageplugins/coreplugin/ratiocrop/imageeffect_ratiocrop.cpp
new file mode 100644
index 0000000..f138e25
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/ratiocrop/imageeffect_ratiocrop.cpp
@@ -0,0 +1,799 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-12-06
+ * Description : digiKam image editor Ratio Crop tool
+ *
+ * Copyright (C) 2007 by Jaromir Malenko <malenko at email dot cz>
+ * Copyright (C) 2008 by Roberto Castagnola <roberto dot castagnola at gmail dot com>
+ * 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qlayout.h>
+#include <qframe.h>
+#include <qrect.h>
+#include <qvgroupbox.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+#include <qcombobox.h>
+#include <qspinbox.h>
+#include <qimage.h>
+#include <qpushbutton.h>
+#include <qtimer.h>
+#include <qcheckbox.h>
+
+// KDE includes.
+
+#include <kcursor.h>
+#include <klocale.h>
+#include <knuminput.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
+#include <kcolorbutton.h>
+
+// Digikam includes.
+
+#include "imageiface.h"
+#include "imageselectionwidget.h"
+
+// Local includes.
+
+#include "imageeffect_ratiocrop.h"
+#include "imageeffect_ratiocrop.moc"
+
+namespace DigikamImagesPluginCore
+{
+
+ImageEffect_RatioCrop::ImageEffect_RatioCrop(QWidget* parent)
+ : Digikam::ImageDlgBase(parent, i18n("Aspect Ratio Crop & Composition Guide"),
+ "aspectratiocrop", false)
+{
+ setHelp("ratiocroptool.anchor", "digikam");
+ setButtonWhatsThis ( User1, i18n("<p>Set selection area to the maximum size according "
+ "to the current ratio.") );
+ setButtonText(User1, i18n("&Max. Aspect"));
+ showButton(User1, true);
+
+ // -------------------------------------------------------------
+
+ QFrame *frame = new QFrame(plainPage());
+ frame->setFrameStyle(QFrame::Panel|QFrame::Sunken);
+ QVBoxLayout* l = new QVBoxLayout(frame, 5, 0);
+ m_imageSelectionWidget = new ImageSelectionWidget(480, 320, frame);
+ l->addWidget(m_imageSelectionWidget);
+ QWhatsThis::add( m_imageSelectionWidget, i18n("<p>Here you can see the aspect ratio selection preview "
+ "used for cropping. You can use the mouse to move and "
+ "resize the crop area. "
+ "Press and hold the CTRL key to move the opposite corner too. "
+ "Press and hold the SHIFT key to move the closest corner to the "
+ "mouse pointer."));
+ setPreviewAreaWidget(frame);
+
+ m_originalIsLandscape = m_imageSelectionWidget->getOriginalImageWidth() >
+ m_imageSelectionWidget->getOriginalImageHeight();
+
+ // -------------------------------------------------------------
+
+ QWidget *gbox2 = new QWidget(plainPage());
+ QGridLayout *gridBox2 = new QGridLayout( gbox2, 2, 0);
+
+ QFrame *cropSelection = new QFrame( gbox2 );
+ cropSelection->setFrameStyle(QFrame::Panel|QFrame::Sunken);
+ QGridLayout* grid = new QGridLayout( cropSelection, 6, 4, spacingHint());
+
+ QLabel *label = new QLabel(i18n("Aspect ratio:"), cropSelection);
+ m_ratioCB = new QComboBox( false, cropSelection );
+ setRatioCBText(ImageSelectionWidget::Landscape);
+ QWhatsThis::add( m_ratioCB, i18n("<p>Select your constrained aspect ratio for cropping. "
+ "Aspect Ratio Crop tool uses a relative ratio. That means it "
+ "is the same if you use centimeters or inches and it doesn't "
+ "specify the physical size.<p>"
+ "You can see below a correspondence list of traditional photographic "
+ "paper sizes and aspect ratio crop:<p>"
+ "<b>2:3</b>: 10x15cm, 20x30cm, 30x45cm, 4x6\", 8x12\", "
+ "12x18\", 16x24\", 20x30\"<p>"
+ "<b>3:4</b>: 6x8cm, 15x20cm, 18x24cm, 30x40cm, 3.75x5\", 4.5x6\", "
+ "6x8\", 7.5x10\", 9x12\"<p>"
+ "<b>4:5</b>: 20x25cm, 40x50cm, 8x10\", 16x20\"<p>"
+ "<b>5:7</b>: 15x21cm, 30x42cm, 5x7\"<p>"
+ "<b>7:10</b>: 21x30cm, 42x60cm, 3.5x5\"<p>"
+ "The <b>Golden Ratio</b> is 1:1.618. A composition following this rule "
+ "is considered visually harmonious but can be unadapted to print on "
+ "standard photographic paper."));
+
+ m_preciseCrop = new QCheckBox(i18n("Exact"), cropSelection);
+ QWhatsThis::add( m_preciseCrop, i18n("<p>Enable this option to force exact aspect ratio crop."));
+
+ m_orientLabel = new QLabel(i18n("Orientation:"), cropSelection);
+ m_orientCB = new QComboBox( false, cropSelection );
+ m_orientCB->insertItem( i18n("Landscape") );
+ m_orientCB->insertItem( i18n("Portrait") );
+ QWhatsThis::add( m_orientCB, i18n("<p>Select constrained aspect ratio orientation."));
+
+ m_autoOrientation = new QCheckBox(i18n("Auto"), cropSelection);
+ QWhatsThis::add( m_autoOrientation, i18n("<p>Enable this option to automatically set the orientation."));
+
+ grid->addMultiCellWidget(label, 0, 0, 0, 0);
+ grid->addMultiCellWidget(m_ratioCB, 0, 0, 1, 3);
+ grid->addMultiCellWidget(m_preciseCrop, 0, 0, 4, 4);
+ grid->addMultiCellWidget(m_orientLabel, 2, 2, 0, 0);
+ grid->addMultiCellWidget(m_orientCB, 2, 2, 1, 3);
+ grid->addMultiCellWidget(m_autoOrientation, 2, 2, 4, 4);
+
+ // -------------------------------------------------------------
+
+ m_customLabel1 = new QLabel(i18n("Custom ratio:"), cropSelection);
+ m_customLabel1->setAlignment(AlignLeft|AlignVCenter);
+ m_customRatioNInput = new KIntSpinBox(1, 10000, 1, 1, 10, cropSelection);
+ QWhatsThis::add( m_customRatioNInput, i18n("<p>Set here the desired custom aspect numerator value."));
+ m_customLabel2 = new QLabel(" : ", cropSelection);
+ m_customLabel2->setAlignment(AlignCenter|AlignVCenter);
+ m_customRatioDInput = new KIntSpinBox(1, 10000, 1, 1, 10, cropSelection);
+ QWhatsThis::add( m_customRatioDInput, i18n("<p>Set here the desired custom aspect denominator value."));
+
+ grid->addMultiCellWidget(m_customLabel1, 1, 1, 0, 0);
+ grid->addMultiCellWidget(m_customRatioNInput, 1, 1, 1, 1);
+ grid->addMultiCellWidget(m_customLabel2, 1, 1, 2, 2);
+ grid->addMultiCellWidget(m_customRatioDInput, 1, 1, 3, 3);
+
+ // -------------------------------------------------------------
+
+ m_xInput = new KIntNumInput(cropSelection);
+ QWhatsThis::add( m_xInput, i18n("<p>Set here the top left selection corner position for cropping."));
+ m_xInput->setLabel(i18n("X:"), AlignLeft|AlignVCenter);
+ m_xInput->setRange(0, m_imageSelectionWidget->getOriginalImageWidth(), 1, true);
+
+ m_widthInput = new KIntNumInput(cropSelection);
+ m_widthInput->setLabel(i18n("Width:"), AlignLeft|AlignVCenter);
+ QWhatsThis::add( m_widthInput, i18n("<p>Set here the width selection for cropping."));
+ m_widthInput->setRange(m_imageSelectionWidget->getMinWidthRange(),
+ m_imageSelectionWidget->getMaxWidthRange(),
+ m_imageSelectionWidget->getWidthStep(), true);
+
+ m_centerWidth = new QPushButton(cropSelection);
+ KGlobal::dirs()->addResourceType("centerwidth", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("centerwidth", "centerwidth.png");
+ m_centerWidth->setPixmap( QPixmap( directory + "centerwidth.png" ) );
+ QWhatsThis::add( m_centerWidth, i18n("<p>Set width position to center."));
+
+ grid->addMultiCellWidget(m_xInput, 3, 3, 0, 3);
+ grid->addMultiCellWidget(m_widthInput, 4, 4, 0, 3);
+ grid->addMultiCellWidget(m_centerWidth, 3, 3, 4, 4);
+
+ // -------------------------------------------------------------
+
+ m_yInput = new KIntNumInput(cropSelection);
+ m_yInput->setLabel(i18n("Y:"), AlignLeft|AlignVCenter);
+ QWhatsThis::add( m_yInput, i18n("<p>Set here the top left selection corner position for cropping."));
+ m_yInput->setRange(0, m_imageSelectionWidget->getOriginalImageHeight(), 1, true);
+
+ m_heightInput = new KIntNumInput(cropSelection);
+ m_heightInput->setLabel(i18n("Height:"), AlignLeft|AlignVCenter);
+ QWhatsThis::add( m_heightInput, i18n("<p>Set here the height selection for cropping."));
+ m_heightInput->setRange(m_imageSelectionWidget->getMinHeightRange(),
+ m_imageSelectionWidget->getMaxHeightRange(),
+ m_imageSelectionWidget->getHeightStep(), true);
+
+ m_centerHeight = new QPushButton(cropSelection);
+ KGlobal::dirs()->addResourceType("centerheight", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("centerheight", "centerheight.png");
+ m_centerHeight->setPixmap( QPixmap( directory + "centerheight.png" ) );
+ QWhatsThis::add( m_centerHeight, i18n("<p>Set height position to center."));
+
+ grid->addMultiCellWidget(m_yInput, 5, 5, 0, 3);
+ grid->addMultiCellWidget(m_heightInput, 6, 6, 0, 3);
+ grid->addMultiCellWidget(m_centerHeight, 5, 5, 4, 4);
+
+ gridBox2->addMultiCellWidget(cropSelection, 0, 0, 0, 0);
+
+ // -------------------------------------------------------------
+
+ QFrame* compositionGuide = new QFrame( gbox2 );
+ QGridLayout* grid2 = new QGridLayout( compositionGuide, 7, 2, spacingHint());
+ compositionGuide->setFrameStyle(QFrame::Panel|QFrame::Sunken);
+
+ QLabel *labelGuideLines = new QLabel(i18n("Composition guide:"), compositionGuide);
+ m_guideLinesCB = new QComboBox( false, compositionGuide );
+ m_guideLinesCB->insertItem( i18n("Rules of Thirds") );
+ m_guideLinesCB->insertItem( i18n("Harmonious Triangles") );
+ m_guideLinesCB->insertItem( i18n("Golden Mean") );
+ m_guideLinesCB->insertItem( i18n("None") );
+ m_guideLinesCB->setCurrentText( i18n("None") );
+ QWhatsThis::add( m_guideLinesCB, i18n("<p>With this option, you can display guide lines "
+ "which help you to compose your photograph."));
+
+ m_goldenSectionBox = new QCheckBox(i18n("Golden sections"), compositionGuide);
+ QWhatsThis::add( m_goldenSectionBox, i18n("<p>Enable this option to show golden sections."));
+
+ m_goldenSpiralSectionBox = new QCheckBox(i18n("Golden spiral sections"), compositionGuide);
+ QWhatsThis::add( m_goldenSpiralSectionBox, i18n("<p>Enable this option to show golden spiral sections."));
+
+ m_goldenSpiralBox = new QCheckBox(i18n("Golden spiral"), compositionGuide);
+ QWhatsThis::add( m_goldenSpiralBox, i18n("<p>Enable this option to show golden spiral guide."));
+
+ m_goldenTriangleBox = new QCheckBox(i18n("Golden triangles"), compositionGuide);
+ QWhatsThis::add( m_goldenTriangleBox, i18n("<p>Enable this option to show golden triangles."));
+
+ m_flipHorBox = new QCheckBox(i18n("Flip horizontally"), compositionGuide);
+ QWhatsThis::add( m_flipHorBox, i18n("<p>Enable this option to flip horizontally guidelines."));
+
+ m_flipVerBox = new QCheckBox(i18n("Flip vertically"), compositionGuide);
+ QWhatsThis::add( m_flipVerBox, i18n("<p>Enable this option to flip vertically guidelines."));
+
+ m_colorGuideLabel = new QLabel(i18n("Color and width:"), compositionGuide);
+ m_guideColorBt = new KColorButton( QColor( 250, 250, 255 ), compositionGuide );
+ m_guideSize = new QSpinBox( 1, 5, 1, compositionGuide);
+ QWhatsThis::add( m_guideColorBt, i18n("<p>Set here the color used to draw composition guides."));
+ QWhatsThis::add( m_guideSize, i18n("<p>Set here the width in pixels used to draw composition guides."));
+
+ grid2->addMultiCellWidget(labelGuideLines, 0, 0, 0, 0);
+ grid2->addMultiCellWidget(m_guideLinesCB, 0, 0, 1, 2);
+ grid2->addMultiCellWidget(m_goldenSectionBox, 1, 1, 0, 2);
+ grid2->addMultiCellWidget(m_goldenSpiralSectionBox, 2, 2, 0, 2);
+ grid2->addMultiCellWidget(m_goldenSpiralBox, 3, 3, 0, 2);
+ grid2->addMultiCellWidget(m_goldenTriangleBox, 4, 4, 0, 2);
+ grid2->addMultiCellWidget(m_flipHorBox, 5, 5, 0, 2);
+ grid2->addMultiCellWidget(m_flipVerBox, 6, 6, 0, 2);
+ grid2->addMultiCellWidget(m_colorGuideLabel, 7, 7, 0, 0);
+ grid2->addMultiCellWidget(m_guideColorBt, 7, 7, 1, 1);
+ grid2->addMultiCellWidget(m_guideSize, 7, 7, 2, 2);
+
+ gridBox2->addMultiCellWidget(compositionGuide, 1, 1, 0, 0);
+ gridBox2->setRowStretch(2, 10);
+
+ setUserAreaWidget(gbox2);
+
+ // -------------------------------------------------------------
+
+ connect(m_ratioCB, SIGNAL(activated(int)),
+ this, SLOT(slotRatioChanged(int)));
+
+ connect(m_preciseCrop, SIGNAL(toggled(bool)),
+ this, SLOT(slotPreciseCropChanged(bool)));
+
+ connect(m_orientCB, SIGNAL(activated(int)),
+ this, SLOT(slotOrientChanged(int)));
+
+ connect(m_autoOrientation, SIGNAL(toggled(bool)),
+ this, SLOT(slotAutoOrientChanged(bool)));
+
+ connect(m_xInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotXChanged(int)));
+
+ connect(m_yInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotYChanged(int)));
+
+ connect(m_customRatioNInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotCustomNRatioChanged(int)));
+
+ connect(m_customRatioDInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotCustomDRatioChanged(int)));
+
+ connect(m_guideLinesCB, SIGNAL(activated(int)),
+ this, SLOT(slotGuideTypeChanged(int)));
+
+ connect(m_goldenSectionBox, SIGNAL(toggled(bool)),
+ this, SLOT(slotGoldenGuideTypeChanged()));
+
+ connect(m_goldenSpiralSectionBox, SIGNAL(toggled(bool)),
+ this, SLOT(slotGoldenGuideTypeChanged()));
+
+ connect(m_goldenSpiralBox, SIGNAL(toggled(bool)),
+ this, SLOT(slotGoldenGuideTypeChanged()));
+
+ connect(m_goldenTriangleBox, SIGNAL(toggled(bool)),
+ this, SLOT(slotGoldenGuideTypeChanged()));
+
+ connect(m_flipHorBox, SIGNAL(toggled(bool)),
+ this, SLOT(slotGoldenGuideTypeChanged()));
+
+ connect(m_flipVerBox, SIGNAL(toggled(bool)),
+ this, SLOT(slotGoldenGuideTypeChanged()));
+
+ connect(m_guideColorBt, SIGNAL(changed(const QColor &)),
+ m_imageSelectionWidget, SLOT(slotChangeGuideColor(const QColor &)));
+
+ connect(m_guideSize, SIGNAL(valueChanged(int)),
+ m_imageSelectionWidget, SLOT(slotChangeGuideSize(int)));
+
+ connect(m_widthInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotWidthChanged(int)));
+
+ connect(m_heightInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotHeightChanged(int)));
+
+ connect(m_imageSelectionWidget, SIGNAL(signalSelectionChanged(QRect)),
+ this, SLOT(slotSelectionChanged(QRect)));
+
+ connect(m_imageSelectionWidget, SIGNAL(signalSelectionMoved(QRect)),
+ this, SLOT(slotSelectionChanged(QRect)));
+
+ connect(m_imageSelectionWidget, SIGNAL(signalSelectionOrientationChanged(int)),
+ this, SLOT(slotSelectionOrientationChanged(int)));
+
+ connect(m_centerWidth, SIGNAL(clicked()),
+ this, SLOT(slotCenterWidth()));
+
+ connect(m_centerHeight, SIGNAL(clicked()),
+ this, SLOT(slotCenterHeight()));
+
+ // -------------------------------------------------------------
+
+ // Sets current region selection
+ slotSelectionChanged(m_imageSelectionWidget->getRegionSelection());
+
+ readSettings();
+}
+
+ImageEffect_RatioCrop::~ImageEffect_RatioCrop()
+{
+}
+
+void ImageEffect_RatioCrop::readSettings()
+{
+ QColor defaultGuideColor(250, 250, 255);
+ KConfig *config = kapp->config();
+ config->setGroup("aspectratiocrop Tool Dialog");
+
+ // No guide lines per default.
+ m_guideLinesCB->setCurrentItem( config->readNumEntry("Guide Lines Type",
+ ImageSelectionWidget::GuideNone) );
+ m_goldenSectionBox->setChecked( config->readBoolEntry("Golden Section", true) );
+ m_goldenSpiralSectionBox->setChecked( config->readBoolEntry("Golden Spiral Section", false) );
+ m_goldenSpiralBox->setChecked( config->readBoolEntry("Golden Spiral", false) );
+ m_goldenTriangleBox->setChecked( config->readBoolEntry("Golden Triangle", false) );
+ m_flipHorBox->setChecked( config->readBoolEntry("Golden Flip Horizontal", false) );
+ m_flipVerBox->setChecked( config->readBoolEntry("Golden Flip Vertical", false) );
+ m_guideColorBt->setColor(config->readColorEntry("Guide Color", &defaultGuideColor));
+ m_guideSize->setValue(config->readNumEntry("Guide Width", 1));
+ m_imageSelectionWidget->slotGuideLines(m_guideLinesCB->currentItem());
+ m_imageSelectionWidget->slotChangeGuideColor(m_guideColorBt->color());
+
+ m_preciseCrop->setChecked( config->readBoolEntry("Precise Aspect Ratio Crop", false) );
+ m_imageSelectionWidget->setPreciseCrop( m_preciseCrop->isChecked() );
+
+ if (m_originalIsLandscape)
+ {
+ m_orientCB->setCurrentItem( config->readNumEntry("Hor.Oriented Aspect Ratio Orientation",
+ ImageSelectionWidget::Landscape) );
+
+ m_imageSelectionWidget->setSelectionOrientation(m_orientCB->currentItem());
+
+ m_customRatioNInput->setValue( config->readNumEntry("Hor.Oriented Custom Aspect Ratio Num", 1) );
+ m_customRatioDInput->setValue( config->readNumEntry("Hor.Oriented Custom Aspect Ratio Den", 1) );
+ m_ratioCB->setCurrentItem( config->readNumEntry("Hor.Oriented Aspect Ratio",
+ ImageSelectionWidget::RATIO03X04) );
+
+ applyRatioChanges(m_ratioCB->currentItem());
+
+ // Empty selection so it can be moved w/out size constraint
+ m_widthInput->setValue( 0 );
+ m_heightInput->setValue( 0 );
+
+ m_xInput->setValue( config->readNumEntry("Hor.Oriented Custom Aspect Ratio Xpos", 50) );
+ m_yInput->setValue( config->readNumEntry("Hor.Oriented Custom Aspect Ratio Ypos", 50) );
+
+ m_widthInput->setValue( config->readNumEntry("Hor.Oriented Custom Aspect Ratio Width", 800) );
+ m_heightInput->setValue( config->readNumEntry("Hor.Oriented Custom Aspect Ratio Height", 600) );
+ }
+ else
+ {
+ m_orientCB->setCurrentItem( config->readNumEntry("Ver.Oriented Aspect Ratio Orientation",
+ ImageSelectionWidget::Portrait) );
+
+ m_imageSelectionWidget->setSelectionOrientation(m_orientCB->currentItem());
+
+ m_customRatioNInput->setValue( config->readNumEntry("Ver.Oriented Custom Aspect Ratio Num", 1) );
+ m_customRatioDInput->setValue( config->readNumEntry("Ver.Oriented Custom Aspect Ratio Den", 1) );
+ m_ratioCB->setCurrentItem( config->readNumEntry("Ver.Oriented Aspect Ratio",
+ ImageSelectionWidget::RATIO03X04) );
+
+ applyRatioChanges(m_ratioCB->currentItem());
+
+ // Empty selection so it can be moved w/out size constraint
+ m_widthInput->setValue( 0 );
+ m_heightInput->setValue( 0 );
+
+ m_xInput->setValue( config->readNumEntry("Ver.Oriented Custom Aspect Ratio Xpos", 50) );
+ m_yInput->setValue( config->readNumEntry("Ver.Oriented Custom Aspect Ratio Ypos", 50) );
+
+ m_widthInput->setValue( config->readNumEntry("Ver.Oriented Custom Aspect Ratio Width", 800) );
+ m_heightInput->setValue( config->readNumEntry("Ver.Oriented Custom Aspect Ratio Height", 600) );
+ }
+
+ m_autoOrientation->setChecked( config->readBoolEntry("Auto Orientation", false) );
+ slotAutoOrientChanged( m_autoOrientation->isChecked() );
+}
+
+void ImageEffect_RatioCrop::writeSettings()
+{
+ KConfig *config = kapp->config();
+ config->setGroup("aspectratiocrop Tool Dialog");
+
+ if (m_originalIsLandscape)
+ {
+ config->writeEntry( "Hor.Oriented Aspect Ratio", m_ratioCB->currentItem() );
+ config->writeEntry( "Hor.Oriented Aspect Ratio Orientation", m_orientCB->currentItem() );
+ config->writeEntry( "Hor.Oriented Custom Aspect Ratio Num", m_customRatioNInput->value() );
+ config->writeEntry( "Hor.Oriented Custom Aspect Ratio Den", m_customRatioDInput->value() );
+
+ config->writeEntry( "Hor.Oriented Custom Aspect Ratio Xpos", m_xInput->value() );
+ config->writeEntry( "Hor.Oriented Custom Aspect Ratio Ypos", m_yInput->value() );
+ config->writeEntry( "Hor.Oriented Custom Aspect Ratio Width", m_widthInput->value() );
+ config->writeEntry( "Hor.Oriented Custom Aspect Ratio Height", m_heightInput->value() );
+ }
+ else
+ {
+ config->writeEntry( "Ver.Oriented Aspect Ratio", m_ratioCB->currentItem() );
+ config->writeEntry( "Ver.Oriented Aspect Ratio Orientation", m_orientCB->currentItem() );
+ config->writeEntry( "Ver.Oriented Custom Aspect Ratio Num", m_customRatioNInput->value() );
+ config->writeEntry( "Ver.Oriented Custom Aspect Ratio Den", m_customRatioDInput->value() );
+
+ config->writeEntry( "Ver.Oriented Custom Aspect Ratio Xpos", m_xInput->value() );
+ config->writeEntry( "Ver.Oriented Custom Aspect Ratio Ypos", m_yInput->value() );
+ config->writeEntry( "Ver.Oriented Custom Aspect Ratio Width", m_widthInput->value() );
+ config->writeEntry( "Ver.Oriented Custom Aspect Ratio Height", m_heightInput->value() );
+ }
+
+ config->writeEntry( "Precise Aspect Ratio Crop", m_preciseCrop->isChecked() );
+ config->writeEntry( "Auto Orientation", m_autoOrientation->isChecked() );
+ config->writeEntry( "Guide Lines Type", m_guideLinesCB->currentItem() );
+ config->writeEntry( "Golden Section", m_goldenSectionBox->isChecked() );
+ config->writeEntry( "Golden Spiral Section", m_goldenSpiralSectionBox->isChecked() );
+ config->writeEntry( "Golden Spiral", m_goldenSpiralBox->isChecked() );
+ config->writeEntry( "Golden Triangle", m_goldenTriangleBox->isChecked() );
+ config->writeEntry( "Golden Flip Horizontal", m_flipHorBox->isChecked() );
+ config->writeEntry( "Golden Flip Vertical", m_flipVerBox->isChecked() );
+ config->writeEntry( "Guide Color", m_guideColorBt->color() );
+ config->writeEntry( "Guide Width", m_guideSize->value() );
+ config->sync();
+}
+
+void ImageEffect_RatioCrop::slotDefault()
+{
+ m_imageSelectionWidget->resetSelection();
+}
+
+void ImageEffect_RatioCrop::slotUser1()
+{
+ m_imageSelectionWidget->maxAspectSelection();
+}
+
+void ImageEffect_RatioCrop::slotCenterWidth()
+{
+ m_imageSelectionWidget->setCenterSelection(ImageSelectionWidget::CenterWidth);
+}
+
+void ImageEffect_RatioCrop::slotCenterHeight()
+{
+ m_imageSelectionWidget->setCenterSelection(ImageSelectionWidget::CenterHeight);
+}
+
+void ImageEffect_RatioCrop::slotSelectionChanged(QRect rect)
+{
+ m_xInput->blockSignals(true);
+ m_yInput->blockSignals(true);
+ m_widthInput->blockSignals(true);
+ m_heightInput->blockSignals(true);
+
+ m_xInput->setRange(0, m_imageSelectionWidget->getOriginalImageWidth() - rect.width(), 1, true);
+ m_yInput->setRange(0, m_imageSelectionWidget->getOriginalImageHeight() - rect.height(), 1, true);
+ m_widthInput->setRange(m_imageSelectionWidget->getMinWidthRange(),
+ m_imageSelectionWidget->getMaxWidthRange(),
+ m_imageSelectionWidget->getWidthStep(), true);
+ m_heightInput->setRange(m_imageSelectionWidget->getMinHeightRange(),
+ m_imageSelectionWidget->getMaxHeightRange(),
+ m_imageSelectionWidget->getHeightStep(), true);
+
+ m_xInput->setValue(rect.x());
+ m_yInput->setValue(rect.y());
+ m_widthInput->setValue(rect.width());
+ m_heightInput->setValue(rect.height());
+
+ enableButtonOK( rect.isValid() );
+ m_preciseCrop->setEnabled(m_imageSelectionWidget->preciseCropAvailable());
+
+ m_xInput->blockSignals(false);
+ m_yInput->blockSignals(false);
+ m_widthInput->blockSignals(false);
+ m_heightInput->blockSignals(false);
+}
+
+void ImageEffect_RatioCrop::setRatioCBText(int orientation)
+{
+ int item = m_ratioCB->currentItem();
+
+ m_ratioCB->blockSignals(true);
+ m_ratioCB->clear();
+ m_ratioCB->insertItem( i18n("Custom") );
+ m_ratioCB->insertItem( "1:1" );
+ if ( orientation == ImageSelectionWidget::Landscape )
+ {
+ m_ratioCB->insertItem( "3:2" );
+ m_ratioCB->insertItem( "4:3" );
+ m_ratioCB->insertItem( "5:4" );
+ m_ratioCB->insertItem( "7:5" );
+ m_ratioCB->insertItem( "10:7" );
+ }
+ else
+ {
+ m_ratioCB->insertItem( "2:3" );
+ m_ratioCB->insertItem( "3:4" );
+ m_ratioCB->insertItem( "4:5" );
+ m_ratioCB->insertItem( "5:7" );
+ m_ratioCB->insertItem( "7:10" );
+ }
+ m_ratioCB->insertItem( i18n("Golden Ratio") );
+ m_ratioCB->insertItem( i18n("None") );
+ m_ratioCB->setCurrentItem( item );
+ m_ratioCB->blockSignals(false);
+}
+
+void ImageEffect_RatioCrop::slotSelectionOrientationChanged(int newOrientation)
+{
+ // Change text for Aspect ratio ComboBox
+
+ setRatioCBText(newOrientation);
+
+ // Change Orientation ComboBox
+
+ m_orientCB->setCurrentItem(newOrientation);
+
+ // Reverse custom values
+
+ if ( ( m_customRatioNInput->value() < m_customRatioDInput->value() &&
+ newOrientation == ImageSelectionWidget::Landscape ) ||
+ ( m_customRatioNInput->value() > m_customRatioDInput->value() &&
+ newOrientation == ImageSelectionWidget::Portrait ) )
+ {
+ m_customRatioNInput->blockSignals(true);
+ m_customRatioDInput->blockSignals(true);
+
+ int tmp = m_customRatioNInput->value();
+ m_customRatioNInput->setValue( m_customRatioDInput->value() );
+ m_customRatioDInput->setValue( tmp );
+
+ m_customRatioNInput->blockSignals(false);
+ m_customRatioDInput->blockSignals(false);
+ }
+}
+
+void ImageEffect_RatioCrop::slotXChanged(int x)
+{
+ m_imageSelectionWidget->setSelectionX(x);
+}
+
+void ImageEffect_RatioCrop::slotYChanged(int y)
+{
+ m_imageSelectionWidget->setSelectionY(y);
+}
+
+void ImageEffect_RatioCrop::slotWidthChanged(int w)
+{
+ m_imageSelectionWidget->setSelectionWidth(w);
+}
+
+void ImageEffect_RatioCrop::slotHeightChanged(int h)
+{
+ m_imageSelectionWidget->setSelectionHeight(h);
+}
+
+void ImageEffect_RatioCrop::slotPreciseCropChanged(bool a)
+{
+ m_imageSelectionWidget->setPreciseCrop(a);
+}
+
+void ImageEffect_RatioCrop::slotOrientChanged(int o)
+{
+ m_imageSelectionWidget->setSelectionOrientation(o);
+
+ // Reset selection area.
+ slotDefault();
+}
+
+void ImageEffect_RatioCrop::slotAutoOrientChanged(bool a)
+{
+ m_orientCB->setEnabled(!a /*|| m_ratioCB->currentItem() == ImageSelectionWidget::RATIONONE*/);
+ m_imageSelectionWidget->setAutoOrientation(a);
+}
+
+void ImageEffect_RatioCrop::slotRatioChanged(int a)
+{
+ applyRatioChanges(a);
+
+ // Reset selection area.
+ slotDefault();
+}
+
+void ImageEffect_RatioCrop::applyRatioChanges(int a)
+{
+ m_imageSelectionWidget->setSelectionAspectRatioType(a);
+
+ if ( a == ImageSelectionWidget::RATIOCUSTOM )
+ {
+ m_customLabel1->setEnabled(true);
+ m_customLabel2->setEnabled(true);
+ m_customRatioNInput->setEnabled(true);
+ m_customRatioDInput->setEnabled(true);
+ m_orientLabel->setEnabled(true);
+ m_orientCB->setEnabled(! m_autoOrientation->isChecked());
+ m_autoOrientation->setEnabled(true);
+ slotCustomRatioChanged();
+ }
+ else if ( a == ImageSelectionWidget::RATIONONE )
+ {
+ m_orientLabel->setEnabled(false);
+ m_orientCB->setEnabled(false);
+ m_autoOrientation->setEnabled(false);
+ m_customLabel1->setEnabled(false);
+ m_customLabel2->setEnabled(false);
+ m_customRatioNInput->setEnabled(false);
+ m_customRatioDInput->setEnabled(false);
+ }
+ else // Pre-config ratio selected.
+ {
+ m_orientLabel->setEnabled(true);
+ m_orientCB->setEnabled(! m_autoOrientation->isChecked());
+ m_autoOrientation->setEnabled(true);
+ m_customLabel1->setEnabled(false);
+ m_customLabel2->setEnabled(false);
+ m_customRatioNInput->setEnabled(false);
+ m_customRatioDInput->setEnabled(false);
+ }
+}
+
+void ImageEffect_RatioCrop::slotGuideTypeChanged(int t)
+{
+ if ( t == ImageSelectionWidget::GuideNone )
+ {
+ m_goldenSectionBox->setEnabled(false);
+ m_goldenSpiralSectionBox->setEnabled(false);
+ m_goldenSpiralBox->setEnabled(false);
+ m_goldenTriangleBox->setEnabled(false);
+ m_flipHorBox->setEnabled(false);
+ m_flipVerBox->setEnabled(false);
+ m_colorGuideLabel->setEnabled(false);
+ m_guideColorBt->setEnabled(false);
+ m_guideSize->setEnabled(false);
+ }
+ else if ( t == ImageSelectionWidget::RulesOfThirds )
+ {
+ m_goldenSectionBox->setEnabled(false);
+ m_goldenSpiralSectionBox->setEnabled(false);
+ m_goldenSpiralBox->setEnabled(false);
+ m_goldenTriangleBox->setEnabled(false);
+ m_flipHorBox->setEnabled(false);
+ m_flipVerBox->setEnabled(false);
+ m_colorGuideLabel->setEnabled(true);
+ m_guideColorBt->setEnabled(true);
+ m_guideSize->setEnabled(true);
+ }
+ else if ( t == ImageSelectionWidget::HarmoniousTriangles )
+ {
+ m_goldenSectionBox->setEnabled(false);
+ m_goldenSpiralSectionBox->setEnabled(false);
+ m_goldenSpiralBox->setEnabled(false);
+ m_goldenTriangleBox->setEnabled(false);
+ m_flipHorBox->setEnabled(true);
+ m_flipVerBox->setEnabled(true);
+ m_colorGuideLabel->setEnabled(true);
+ m_guideColorBt->setEnabled(true);
+ m_guideSize->setEnabled(true);
+ }
+ else
+ {
+ m_goldenSectionBox->setEnabled(true);
+ m_goldenSpiralSectionBox->setEnabled(true);
+ m_goldenSpiralBox->setEnabled(true);
+ m_goldenTriangleBox->setEnabled(true);
+ m_flipHorBox->setEnabled(true);
+ m_flipVerBox->setEnabled(true);
+ m_colorGuideLabel->setEnabled(true);
+ m_guideColorBt->setEnabled(true);
+ m_guideSize->setEnabled(true);
+ }
+
+ m_imageSelectionWidget->setGoldenGuideTypes(m_goldenSectionBox->isChecked(),
+ m_goldenSpiralSectionBox->isChecked(),
+ m_goldenSpiralBox->isChecked(),
+ m_goldenTriangleBox->isChecked(),
+ m_flipHorBox->isChecked(),
+ m_flipVerBox->isChecked());
+ m_imageSelectionWidget->slotGuideLines(t);
+}
+
+void ImageEffect_RatioCrop::slotGoldenGuideTypeChanged()
+{
+ slotGuideTypeChanged(m_guideLinesCB->currentItem());
+}
+
+void ImageEffect_RatioCrop::slotCustomNRatioChanged(int a)
+{
+ if ( ! m_autoOrientation->isChecked() )
+ {
+ if ( ( m_orientCB->currentItem() == ImageSelectionWidget::Portrait &&
+ m_customRatioDInput->value() < a ) ||
+ ( m_orientCB->currentItem() == ImageSelectionWidget::Landscape &&
+ m_customRatioDInput->value() > a ) )
+ {
+ m_customRatioDInput->blockSignals(true);
+ m_customRatioDInput->setValue(a);
+ m_customRatioDInput->blockSignals(false);
+ }
+ }
+
+ slotCustomRatioChanged();
+}
+
+void ImageEffect_RatioCrop::slotCustomDRatioChanged(int a)
+{
+ if ( ! m_autoOrientation->isChecked() )
+ {
+ if ( ( m_orientCB->currentItem() == ImageSelectionWidget::Landscape &&
+ m_customRatioNInput->value() < a ) ||
+ ( m_orientCB->currentItem() == ImageSelectionWidget::Portrait &&
+ m_customRatioNInput->value() > a ) )
+ {
+ m_customRatioNInput->blockSignals(true);
+ m_customRatioNInput->setValue(a);
+ m_customRatioNInput->blockSignals(false);
+ }
+ }
+
+ slotCustomRatioChanged();
+}
+
+void ImageEffect_RatioCrop::slotCustomRatioChanged()
+{
+ m_imageSelectionWidget->setSelectionAspectRatioValue(
+ m_customRatioNInput->value(), m_customRatioDInput->value() );
+
+ // Reset selection area.
+ slotDefault();
+}
+
+void ImageEffect_RatioCrop::slotOk()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ QRect currentRegion = m_imageSelectionWidget->getRegionSelection();
+ Digikam::ImageIface* iface = m_imageSelectionWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int w = iface->originalWidth();
+ int h = iface->originalHeight();
+ bool a = iface->originalHasAlpha();
+ bool sb = iface->originalSixteenBit();
+
+ QRect normalizedRegion = currentRegion.normalize();
+ if (normalizedRegion.right() > w) normalizedRegion.setRight(w);
+ if (normalizedRegion.bottom() > h) normalizedRegion.setBottom(h);
+
+ Digikam::DImg imOrg(w, h, sb, a, data);
+ delete [] data;
+ imOrg.crop(normalizedRegion);
+
+ iface->putOriginalImage(i18n("Aspect Ratio Crop"), imOrg.bits(), imOrg.width(), imOrg.height());
+
+ kapp->restoreOverrideCursor();
+ writeSettings();
+ accept();
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/ratiocrop/imageeffect_ratiocrop.h b/digikam/imageplugins/coreplugin/ratiocrop/imageeffect_ratiocrop.h
new file mode 100644
index 0000000..ec16321
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/ratiocrop/imageeffect_ratiocrop.h
@@ -0,0 +1,131 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-12-06
+ * Description : digiKam image editor Ratio Crop tool
+ *
+ * Copyright (C) 2007 by Jaromir Malenko <malenko at email dot cz>
+ * Copyright (C) 2008 by Roberto Castagnola <roberto dot castagnola at gmail dot com>
+ * 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 IMAGEEFFECT_RATIOCROP_H
+#define IMAGEEFFECT_RATIOCROP_H
+
+// Digikam include.
+
+#include "imagedlgbase.h"
+
+class QLabel;
+class QComboBox;
+class QPushButton;
+class QCheckBox;
+class QSpinBox;
+
+class KIntNumInput;
+class KIntSpinBox;
+class KColorButton;
+
+namespace DigikamImagesPluginCore
+{
+
+class ImageSelectionWidget;
+
+class ImageEffect_RatioCrop : public Digikam::ImageDlgBase
+{
+ Q_OBJECT
+
+public:
+
+ ImageEffect_RatioCrop(QWidget *parent);
+ ~ImageEffect_RatioCrop();
+
+private:
+
+ void readSettings();
+ void writeSettings();
+
+ void applyRatioChanges(int a);
+ void setRatioCBText(int orientation);
+
+private slots:
+
+ void slotUser1();
+ void slotDefault();
+ void slotOk();
+
+ void slotCenterWidth();
+ void slotCenterHeight();
+ void slotXChanged(int x);
+ void slotYChanged(int y);
+ void slotWidthChanged(int w);
+ void slotHeightChanged(int h);
+ void slotCustomRatioChanged();
+ void slotCustomNRatioChanged(int a);
+ void slotCustomDRatioChanged(int a);
+ void slotPreciseCropChanged(bool a);
+ void slotOrientChanged(int o);
+ void slotAutoOrientChanged(bool a);
+ void slotRatioChanged(int a);
+ void slotSelectionChanged(QRect rect );
+ void slotSelectionOrientationChanged(int);
+ void slotGuideTypeChanged(int t);
+ void slotGoldenGuideTypeChanged();
+
+private:
+
+ bool m_originalIsLandscape;
+
+ QLabel *m_customLabel1;
+ QLabel *m_customLabel2;
+ QLabel *m_orientLabel;
+ QLabel *m_colorGuideLabel;
+
+ QComboBox *m_ratioCB;
+ QComboBox *m_orientCB;
+ QComboBox *m_guideLinesCB;
+
+ QPushButton *m_centerWidth;
+ QPushButton *m_centerHeight;
+
+ QCheckBox *m_goldenSectionBox;
+ QCheckBox *m_goldenSpiralSectionBox;
+ QCheckBox *m_goldenSpiralBox;
+ QCheckBox *m_goldenTriangleBox;
+ QCheckBox *m_flipHorBox;
+ QCheckBox *m_flipVerBox;
+ QCheckBox *m_autoOrientation;
+ QCheckBox *m_preciseCrop;
+
+ QSpinBox *m_guideSize;
+
+ KIntNumInput *m_widthInput;
+ KIntNumInput *m_heightInput;
+ KIntNumInput *m_xInput;
+ KIntNumInput *m_yInput;
+
+ KIntSpinBox *m_customRatioNInput;
+ KIntSpinBox *m_customRatioDInput;
+
+ KColorButton *m_guideColorBt;
+
+ ImageSelectionWidget *m_imageSelectionWidget;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* IMAGEEFFECT_RATIOCROP_H */
diff --git a/digikam/imageplugins/coreplugin/ratiocrop/imageselectionwidget.cpp b/digikam/imageplugins/coreplugin/ratiocrop/imageselectionwidget.cpp
new file mode 100644
index 0000000..b43544e
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/ratiocrop/imageselectionwidget.cpp
@@ -0,0 +1,1422 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-12-09
+ * Description : image selection widget used by ratio crop tool.
+ *
+ * Copyright (C) 2007 by Jaromir Malenko <malenko at email.cz>
+ * Copyright (C) 2008 by Roberto Castagnola <roberto dot castagnola at gmail dot com>
+ * Copyright (C) 2004-2009 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.
+ *
+ * ============================================================ */
+
+#define OPACITY 0.7
+#define RCOL 0xAA
+#define GCOL 0xAA
+#define BCOL 0xAA
+
+#define MINRANGE 0
+
+// Golden number (1+sqrt(5))/2
+#define PHI 1.61803398874989479
+// 1/PHI
+#define INVPHI 0.61803398874989479
+
+// C++ includes.
+
+#include <iostream>
+#include <cstdio>
+#include <cmath>
+#include <cstdlib>
+
+// Qt includes.
+
+#include <qregion.h>
+#include <qcolor.h>
+#include <qpainter.h>
+#include <qbrush.h>
+#include <qpixmap.h>
+#include <qimage.h>
+#include <qpen.h>
+#include <qpoint.h>
+#include <qtimer.h>
+#include <qsizepolicy.h>
+
+// KDE includes.
+
+#include <kstandarddirs.h>
+#include <kcursor.h>
+#include <kglobal.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "imageiface.h"
+#include "dimg.h"
+#include "imageselectionwidget.h"
+#include "imageselectionwidget.moc"
+
+namespace DigikamImagesPluginCore
+{
+
+class ImageSelectionWidgetPriv
+{
+public:
+
+ enum ResizingMode
+ {
+ ResizingNone = 0,
+ ResizingTopLeft,
+ ResizingTopRight,
+ ResizingBottomLeft,
+ ResizingBottomRight
+ };
+
+ ImageSelectionWidgetPriv()
+ {
+ currentResizing = ResizingNone;
+ iface = 0;
+ pixmap = 0;
+ guideSize = 1;
+ }
+
+ // Golden guide types.
+ bool drawGoldenSection;
+ bool drawGoldenSpiralSection;
+ bool drawGoldenSpiral;
+ bool drawGoldenTriangle;
+
+ // Golden guide translations.
+ bool flipHorGoldenGuide;
+ bool flipVerGoldenGuide;
+
+ bool moving;
+ bool autoOrientation;
+ bool preciseCrop;
+
+ int guideLinesType;
+ int guideSize;
+
+ int currentAspectRatioType;
+ int currentResizing;
+ int currentOrientation;
+
+ float currentWidthRatioValue;
+ float currentHeightRatioValue;
+
+ QPoint lastPos;
+
+ QRect rect;
+ QRect image; // Real image dimension.
+ QRect regionSelection; // Real size image selection.
+ QRect localRegionSelection; // Local size selection.
+
+ // Draggable local region selection corners.
+ QRect localTopLeftCorner;
+ QRect localBottomLeftCorner;
+ QRect localTopRightCorner;
+ QRect localBottomRightCorner;
+
+ QPixmap *pixmap;
+
+ QColor guideColor;
+
+ Digikam::DImg preview;
+
+ Digikam::ImageIface *iface;
+};
+
+ImageSelectionWidget::ImageSelectionWidget(int w, int h, QWidget *parent,
+ int widthRatioValue, int heightRatioValue,
+ int aspectRatioType, int orient, int guideLinesType)
+ : QWidget(parent, 0, Qt::WDestructiveClose)
+{
+ d = new ImageSelectionWidgetPriv;
+ d->currentAspectRatioType = aspectRatioType;
+ d->currentWidthRatioValue = widthRatioValue;
+ d->currentHeightRatioValue = heightRatioValue;
+ d->currentOrientation = orient;
+ d->guideLinesType = guideLinesType;
+ d->autoOrientation = false;
+ d->preciseCrop = false;
+ d->moving = true;
+ reverseRatioValues();
+
+ setBackgroundMode(Qt::NoBackground);
+ setMinimumSize(w, h);
+ setMouseTracking(true);
+
+ d->iface = new Digikam::ImageIface(w, h);
+ uchar *data = d->iface->getPreviewImage();
+ int width = d->iface->previewWidth();
+ int height = d->iface->previewHeight();
+ bool sixteenBit = d->iface->previewSixteenBit();
+ bool hasAlpha = d->iface->previewHasAlpha();
+ d->preview = Digikam::DImg(width, height, sixteenBit, hasAlpha, data);
+ delete [] data;
+ d->preview.convertToEightBit();
+ d->pixmap = new QPixmap(w, h);
+
+ d->image = QRect(0, 0, d->iface->originalWidth(), d->iface->originalHeight());
+ d->rect = QRect(w/2-d->preview.width()/2, h/2-d->preview.height()/2,
+ d->preview.width(), d->preview.height());
+ updatePixmap();
+ setGoldenGuideTypes(true, false, false, false, false, false);
+}
+
+ImageSelectionWidget::~ImageSelectionWidget()
+{
+ delete d->iface;
+ delete d->pixmap;
+ delete d;
+}
+
+Digikam::ImageIface* ImageSelectionWidget::imageIface()
+{
+ return d->iface;
+}
+
+void ImageSelectionWidget::resizeEvent(QResizeEvent *e)
+{
+ delete d->pixmap;
+
+ int w = e->size().width();
+ int h = e->size().height();
+
+ uchar *data = d->iface->setPreviewImageSize(w, h);
+ int width = d->iface->previewWidth();
+ int height = d->iface->previewHeight();
+ bool sixteenBit = d->iface->previewSixteenBit();
+ bool hasAlpha = d->iface->previewHasAlpha();
+ d->preview = Digikam::DImg(width, height, sixteenBit, hasAlpha, data);
+ delete [] data;
+ d->preview.convertToEightBit();
+
+ d->pixmap = new QPixmap(w, h);
+
+ d->rect = QRect(w/2-d->preview.width()/2, h/2-d->preview.height()/2,
+ d->preview.width(), d->preview.height());
+ updatePixmap();
+}
+
+int ImageSelectionWidget::getOriginalImageWidth()
+{
+ return d->image.width();
+}
+
+int ImageSelectionWidget::getOriginalImageHeight()
+{
+ return d->image.height();
+}
+
+QRect ImageSelectionWidget::getRegionSelection()
+{
+ return d->regionSelection;
+}
+
+int ImageSelectionWidget::getMinWidthRange()
+{
+ return MINRANGE;
+}
+
+int ImageSelectionWidget::getMinHeightRange()
+{
+ return MINRANGE;
+}
+
+int ImageSelectionWidget::getMaxWidthRange()
+{
+ int maxW = d->image.width() - d->regionSelection.left();
+
+ if (d->currentAspectRatioType != RATIONONE)
+ {
+ // Compute max width taking aspect ratio into account
+ int t = d->currentWidthRatioValue > d->currentHeightRatioValue ? 1 : 0;
+ int h = d->image.height() - d->regionSelection.top();
+ int w = rint( ( h + t ) * d->currentWidthRatioValue /
+ d->currentHeightRatioValue ) - t;
+ if ( w < maxW )
+ maxW = w;
+ }
+
+ // Return max width adjusted if a precise crop is wanted
+ return computePreciseSize(maxW, d->currentWidthRatioValue);
+}
+
+int ImageSelectionWidget::getMaxHeightRange()
+{
+ int maxH = d->image.height() - d->regionSelection.top();
+
+ if (d->currentAspectRatioType != RATIONONE)
+ {
+ // Compute max height taking aspect ratio into account
+ int t = d->currentHeightRatioValue > d->currentWidthRatioValue ? 1 : 0;
+ int w = d->image.width() - d->regionSelection.left();
+ int h = rint( ( w + t ) * d->currentHeightRatioValue /
+ d->currentWidthRatioValue ) - t;
+ if ( h < maxH )
+ maxH = h;
+ }
+
+ // Return max height adjusted if a precise crop is wanted
+ return computePreciseSize(maxH, d->currentHeightRatioValue);
+}
+
+int ImageSelectionWidget::getWidthStep()
+{
+ if ( d->preciseCrop && preciseCropAvailable() )
+ return d->currentWidthRatioValue;
+ else
+ return 1;
+}
+
+int ImageSelectionWidget::getHeightStep()
+{
+ if ( d->preciseCrop && preciseCropAvailable() )
+ return d->currentHeightRatioValue;
+ else
+ return 1;
+}
+
+// Draw a new centered selection with half width (if orientation = Landscape)
+// or with half height (if orientation = Portrait)
+void ImageSelectionWidget::resetSelection()
+{
+ d->regionSelection.setWidth(d->image.width()/2);
+ d->regionSelection.setHeight(d->image.height()/2);
+ applyAspectRatio(d->currentOrientation == Portrait, false);
+
+ setCenterSelection(CenterImage);
+}
+
+void ImageSelectionWidget::setCenterSelection(int centerType)
+{
+ // Adjust selection size if bigger than real image
+ if ( d->regionSelection.height() > d->image.height() )
+ {
+ d->regionSelection.setHeight(d->image.height());
+ applyAspectRatio(true, false);
+ }
+ if ( d->regionSelection.width() > d->image.width() )
+ {
+ d->regionSelection.setWidth(d->image.width());
+ applyAspectRatio(false, false);
+ }
+
+ // Set center point for selection
+ QPoint center = d->image.center();
+ switch (centerType)
+ {
+ case CenterWidth:
+ center.setY(d->regionSelection.center().y());
+ break;
+
+ case CenterHeight:
+ center.setX(d->regionSelection.center().x());
+ break;
+ }
+ d->regionSelection.moveCenter(center);
+
+ // Repaint
+ updatePixmap();
+ repaint(false);
+ regionSelectionChanged();
+}
+
+// Draw a new centered selection with max size
+void ImageSelectionWidget::maxAspectSelection()
+{
+ d->regionSelection.setWidth(d->image.width());
+ d->regionSelection.setHeight(d->image.height());
+ if ( d->currentAspectRatioType != RATIONONE )
+ applyAspectRatio(d->currentOrientation == Portrait, false);
+
+ setCenterSelection(CenterImage);
+}
+
+void ImageSelectionWidget::setGoldenGuideTypes(bool drawGoldenSection, bool drawGoldenSpiralSection,
+ bool drawGoldenSpiral, bool drawGoldenTriangle,
+ bool flipHorGoldenGuide, bool flipVerGoldenGuide)
+{
+ d->drawGoldenSection = drawGoldenSection;
+ d->drawGoldenSpiralSection = drawGoldenSpiralSection;
+ d->drawGoldenSpiral = drawGoldenSpiral;
+ d->drawGoldenTriangle = drawGoldenTriangle;
+ d->flipHorGoldenGuide = flipHorGoldenGuide;
+ d->flipVerGoldenGuide = flipVerGoldenGuide;
+}
+
+void ImageSelectionWidget::slotGuideLines(int guideLinesType)
+{
+ d->guideLinesType = guideLinesType;
+ updatePixmap();
+ repaint(false);
+}
+
+void ImageSelectionWidget::slotChangeGuideColor(const QColor &color)
+{
+ d->guideColor = color;
+ updatePixmap();
+ repaint(false);
+}
+
+void ImageSelectionWidget::slotChangeGuideSize(int size)
+{
+ d->guideSize = size;
+ updatePixmap();
+ repaint(false);
+}
+
+void ImageSelectionWidget::setSelectionOrientation(int orient)
+{
+ d->currentOrientation = orient;
+ reverseRatioValues();
+ applyAspectRatio(true);
+ emit signalSelectionOrientationChanged( d->currentOrientation );
+}
+
+void ImageSelectionWidget::setSelectionAspectRatioType(int aspectRatioType)
+{
+ d->currentAspectRatioType = aspectRatioType;
+
+ // Set ratio values
+ switch(aspectRatioType)
+ {
+ case RATIO01X01:
+ d->currentWidthRatioValue = 1.0;
+ d->currentHeightRatioValue = 1.0;
+ break;
+
+ case RATIO03X04:
+ d->currentWidthRatioValue = 4.0;
+ d->currentHeightRatioValue = 3.0;
+ break;
+
+ case RATIO02x03:
+ d->currentWidthRatioValue = 3.0;
+ d->currentHeightRatioValue = 2.0;
+ break;
+
+ case RATIO05x07:
+ d->currentWidthRatioValue = 7.0;
+ d->currentHeightRatioValue = 5.0;
+ break;
+
+ case RATIO07x10:
+ d->currentWidthRatioValue = 10.0;
+ d->currentHeightRatioValue = 7.0;
+ break;
+
+ case RATIO04X05:
+ d->currentWidthRatioValue = 5.0;
+ d->currentHeightRatioValue = 4.0;
+ break;
+
+ case RATIOGOLDEN:
+ d->currentWidthRatioValue = PHI;
+ d->currentHeightRatioValue = 1.0;
+ break;
+ }
+
+ reverseRatioValues();
+ applyAspectRatio(false);
+}
+
+void ImageSelectionWidget::setSelectionAspectRatioValue(int widthRatioValue,
+ int heightRatioValue)
+{
+ int gdc = widthRatioValue;
+
+ // Compute greatest common divisor using Euclidean algorithm
+ for (int tmp, mod = heightRatioValue; mod != 0; mod = tmp % mod)
+ {
+ tmp = gdc;
+ gdc = mod;
+ }
+
+ d->currentWidthRatioValue = widthRatioValue / gdc;
+ d->currentHeightRatioValue = heightRatioValue / gdc;
+ d->currentAspectRatioType = RATIOCUSTOM;
+
+ // Fix orientation
+ if ( d->autoOrientation )
+ {
+ if ( heightRatioValue > widthRatioValue &&
+ d->currentOrientation == Landscape )
+ {
+ d->currentOrientation = Portrait;
+ emit signalSelectionOrientationChanged( d->currentOrientation );
+ }
+ else if ( widthRatioValue > heightRatioValue &&
+ d->currentOrientation == Portrait )
+ {
+ d->currentOrientation = Landscape;
+ emit signalSelectionOrientationChanged( d->currentOrientation );
+ }
+ }
+ else
+ reverseRatioValues();
+
+ applyAspectRatio(false);
+}
+
+void ImageSelectionWidget::reverseRatioValues()
+{
+ // Reverse ratio values if needed
+ if ( ( d->currentWidthRatioValue > d->currentHeightRatioValue &&
+ d->currentOrientation == Portrait ) ||
+ ( d->currentHeightRatioValue > d->currentWidthRatioValue &&
+ d->currentOrientation == Landscape ) )
+ {
+ float tmp = d->currentWidthRatioValue;
+ d->currentWidthRatioValue = d->currentHeightRatioValue;
+ d->currentHeightRatioValue = tmp;
+ }
+}
+
+bool ImageSelectionWidget::preciseCropAvailable()
+{
+ // Define when precise crop feature can be used
+ // No needed when aspect ratio is 1:1
+ switch(d->currentAspectRatioType)
+ {
+ case RATIONONE:
+ case RATIO01X01:
+ case RATIOGOLDEN:
+ return false;
+
+ case RATIOCUSTOM:
+ return ( d->currentWidthRatioValue != d->currentHeightRatioValue );
+
+ default:
+ return true;
+ }
+}
+
+void ImageSelectionWidget::setPreciseCrop(bool precise)
+{
+ d->preciseCrop = precise;
+ applyAspectRatio(false, true);
+ regionSelectionChanged();
+}
+
+void ImageSelectionWidget::setAutoOrientation(bool orientation)
+{
+ d->autoOrientation = orientation;
+}
+
+void ImageSelectionWidget::setSelectionX(int x)
+{
+ d->regionSelection.moveLeft(x);
+ regionSelectionMoved();
+}
+
+void ImageSelectionWidget::setSelectionY(int y)
+{
+ d->regionSelection.moveTop(y);
+ regionSelectionMoved();
+}
+
+void ImageSelectionWidget::setSelectionWidth(int w)
+{
+ d->regionSelection.setWidth(w);
+ applyAspectRatio(false, true);
+
+ regionSelectionChanged();
+}
+
+void ImageSelectionWidget::setSelectionHeight(int h)
+{
+ d->regionSelection.setHeight(h);
+ applyAspectRatio(true, true);
+
+ regionSelectionChanged();
+}
+
+QPoint ImageSelectionWidget::convertPoint(const QPoint pm, bool localToReal)
+{
+ return convertPoint(pm.x(), pm.y(), localToReal);
+}
+
+QPoint ImageSelectionWidget::convertPoint(int x, int y, bool localToReal)
+{
+ int pmX, pmY;
+
+ if (localToReal)
+ {
+ pmX = ( x - d->rect.left() ) * (float)d->image.width() /
+ (float)d->preview.width();
+
+ pmY = ( y - d->rect.top() ) * (float)d->image.height() /
+ (float)d->preview.height();
+ }
+ else
+ {
+ pmX = d->rect.left() + ( x * (float)d->preview.width() /
+ (float)d->image.width() );
+
+ pmY = d->rect.top() + ( y * (float)d->preview.height() /
+ (float)d->image.height() );
+ }
+
+ return QPoint(pmX, pmY);
+}
+
+int ImageSelectionWidget::computePreciseSize(int size, int step)
+{
+ // Adjust size if precise crop is wanted
+ if ( d->preciseCrop && preciseCropAvailable() )
+ size = int(size / step) * step;
+
+ return size;
+}
+
+void ImageSelectionWidget::applyAspectRatio(bool useHeight, bool repaintWidget)
+{
+ // Save selection area for re-adjustment after changing width and height.
+ QRect oldRegionSelection = d->regionSelection;
+
+ if ( !useHeight ) // Width changed.
+ {
+ int w = computePreciseSize(d->regionSelection.width(),
+ d->currentWidthRatioValue);
+
+ d->regionSelection.setWidth(w);
+ switch(d->currentAspectRatioType)
+ {
+ case RATIONONE:
+ break;
+
+ default:
+ d->regionSelection.setHeight(rint( w * d->currentHeightRatioValue /
+ d->currentWidthRatioValue ) );
+ break;
+ }
+ }
+ else // Height changed.
+ {
+ int h = computePreciseSize(d->regionSelection.height(),
+ d->currentHeightRatioValue);
+
+ d->regionSelection.setHeight(h);
+ switch(d->currentAspectRatioType)
+ {
+ case RATIONONE:
+ break;
+
+ default:
+ d->regionSelection.setWidth(rint( h * d->currentWidthRatioValue /
+ d->currentHeightRatioValue ) );
+ break;
+ }
+ }
+
+ // If we change selection size by a corner, re-adjust the oposite corner position.
+ switch(d->currentResizing)
+ {
+ case ImageSelectionWidgetPriv::ResizingTopLeft:
+ d->regionSelection.moveBottomRight( oldRegionSelection.bottomRight() );
+ break;
+
+ case ImageSelectionWidgetPriv::ResizingTopRight:
+ d->regionSelection.moveBottomLeft( oldRegionSelection.bottomLeft() );
+ break;
+
+ case ImageSelectionWidgetPriv::ResizingBottomLeft:
+ d->regionSelection.moveTopRight( oldRegionSelection.topRight() );
+ break;
+
+ case ImageSelectionWidgetPriv::ResizingBottomRight:
+ d->regionSelection.moveTopLeft( oldRegionSelection.topLeft() );
+ break;
+ }
+
+ if (repaintWidget)
+ {
+ updatePixmap();
+ repaint(false);
+ }
+}
+
+void ImageSelectionWidget::normalizeRegion()
+{
+ // Perform normalization of selection area.
+
+ if (d->regionSelection.left() < d->image.left())
+ d->regionSelection.moveLeft(d->image.left());
+
+ if (d->regionSelection.top() < d->image.top())
+ d->regionSelection.moveTop(d->image.top());
+
+ if (d->regionSelection.right() > d->image.right())
+ d->regionSelection.moveRight(d->image.right());
+
+ if (d->regionSelection.bottom() > d->image.bottom())
+ d->regionSelection.moveBottom(d->image.bottom());
+}
+
+void ImageSelectionWidget::regionSelectionMoved()
+{
+ normalizeRegion();
+
+ updatePixmap();
+ repaint(false);
+
+ emit signalSelectionMoved( d->regionSelection );
+}
+
+void ImageSelectionWidget::regionSelectionChanged()
+{
+ // Compute the intersection of selection region and image region
+ QRect cut = d->regionSelection & d->image;
+
+ // Adjust selection size if it was cropped
+ if ( d->regionSelection.width() > cut.width() )
+ {
+ d->regionSelection = cut;
+ applyAspectRatio(false);
+ }
+ if ( d->regionSelection.height() > cut.height() )
+ {
+ d->regionSelection = cut;
+ applyAspectRatio(true);
+ }
+
+ emit signalSelectionChanged( d->regionSelection );
+}
+
+void ImageSelectionWidget::updatePixmap()
+{
+ // Updated local selection region.
+ d->localRegionSelection.setTopLeft(
+ convertPoint(d->regionSelection.topLeft(), false));
+ d->localRegionSelection.setBottomRight(
+ convertPoint(d->regionSelection.bottomRight(), false));
+
+ // Updated dragging corners region.
+ d->localTopLeftCorner.setRect(d->localRegionSelection.left(),
+ d->localRegionSelection.top(), 8, 8);
+ d->localBottomLeftCorner.setRect(d->localRegionSelection.left(),
+ d->localRegionSelection.bottom() - 7, 8, 8);
+ d->localTopRightCorner.setRect(d->localRegionSelection.right() - 7,
+ d->localRegionSelection.top(), 8, 8);
+ d->localBottomRightCorner.setRect(d->localRegionSelection.right() - 7,
+ d->localRegionSelection.bottom() - 7, 8, 8);
+
+ // Drawing background and image.
+ d->pixmap->fill(colorGroup().background());
+
+ if (d->preview.isNull())
+ return;
+
+ // Drawing region outside selection grayed.
+
+ Digikam::DImg image = d->preview.copy();
+
+ uchar* ptr = image.bits();
+ uchar r, g, b;
+
+ for (int y=d->rect.top() ; y <= d->rect.bottom() ; y++)
+ {
+ for (int x=d->rect.left() ; x <= d->rect.right() ; x++)
+ {
+ if (! d->localRegionSelection.contains(x, y, true) )
+ {
+ b = ptr[0];
+ g = ptr[1];
+ r = ptr[2];
+
+ r += (uchar)((RCOL - r) * OPACITY);
+ g += (uchar)((GCOL - g) * OPACITY);
+ b += (uchar)((BCOL - b) * OPACITY);
+
+ ptr[0] = b;
+ ptr[1] = g;
+ ptr[2] = r;
+ }
+
+ ptr+=4;
+ }
+ }
+
+ QPixmap pix = d->iface->convertToPixmap(image);
+ bitBlt(d->pixmap, d->rect.x(), d->rect.y(), &pix);
+
+ // Stop here if no selection to draw
+ if ( d->regionSelection.isEmpty() )
+ return;
+
+ QPainter p(d->pixmap);
+
+ // Drawing selection borders.
+
+ p.setPen(QPen(QColor(250, 250, 255), 1, Qt::SolidLine));
+ p.drawRect(d->localRegionSelection);
+
+ // Drawing selection corners.
+
+ p.drawRect(d->localTopLeftCorner);
+ p.drawRect(d->localBottomLeftCorner);
+ p.drawRect(d->localTopRightCorner);
+ p.drawRect(d->localBottomRightCorner);
+
+ // Drawing guide lines.
+
+ // Constraint drawing only on local selection region.
+ // This is needed because arcs and incurved lines can draw
+ // outside a little of local selection region.
+ p.setClipping(true);
+ p.setClipRect(d->localRegionSelection);
+
+ switch (d->guideLinesType)
+ {
+ case RulesOfThirds:
+ {
+ int xThird = d->localRegionSelection.width() / 3;
+ int yThird = d->localRegionSelection.height() / 3;
+
+ p.setPen(QPen(Qt::white, d->guideSize, Qt::SolidLine));
+ p.drawLine( d->localRegionSelection.left() + xThird, d->localRegionSelection.top(),
+ d->localRegionSelection.left() + xThird, d->localRegionSelection.bottom() );
+ p.drawLine( d->localRegionSelection.left() + 2*xThird, d->localRegionSelection.top(),
+ d->localRegionSelection.left() + 2*xThird, d->localRegionSelection.bottom() );
+
+ p.drawLine( d->localRegionSelection.left(), d->localRegionSelection.top() + yThird,
+ d->localRegionSelection.right(), d->localRegionSelection.top() + yThird );
+ p.drawLine( d->localRegionSelection.left(), d->localRegionSelection.top() + 2*yThird,
+ d->localRegionSelection.right(), d->localRegionSelection.top() + 2*yThird );
+
+ p.setPen(QPen(d->guideColor, d->guideSize, Qt::DotLine));
+ p.drawLine( d->localRegionSelection.left() + xThird, d->localRegionSelection.top(),
+ d->localRegionSelection.left() + xThird, d->localRegionSelection.bottom() );
+ p.drawLine( d->localRegionSelection.left() + 2*xThird, d->localRegionSelection.top(),
+ d->localRegionSelection.left() + 2*xThird, d->localRegionSelection.bottom() );
+
+ p.drawLine( d->localRegionSelection.left(), d->localRegionSelection.top() + yThird,
+ d->localRegionSelection.right(), d->localRegionSelection.top() + yThird );
+ p.drawLine( d->localRegionSelection.left(), d->localRegionSelection.top() + 2*yThird,
+ d->localRegionSelection.right(), d->localRegionSelection.top() + 2*yThird );
+ break;
+ }
+
+ case DiagonalMethod:
+ {
+ // Move coordinates to top, left
+ p.translate(d->localRegionSelection.topLeft().x(), d->localRegionSelection.topLeft().y());
+
+ float w = (float)d->localRegionSelection.width();
+ float h = (float)d->localRegionSelection.height();
+
+ p.setPen(QPen(Qt::white, d->guideSize, Qt::SolidLine));
+ if (w > h)
+ {
+ p.drawLine( 0, 0, h, h);
+ p.drawLine( 0, h, h, 0);
+ p.drawLine( w-h, 0, w, h);
+ p.drawLine( w-h, h, w, 0);
+
+ }
+ else
+ {
+ p.drawLine( 0, 0, w, w);
+ p.drawLine( 0, w, w, 0);
+ p.drawLine( 0, h-w, w, h);
+ p.drawLine( 0, h, w, h-w);
+ }
+
+ p.setPen(QPen(d->guideColor, d->guideSize, Qt::DotLine));
+ if (w > h)
+ {
+ p.drawLine( 0, 0, h, h);
+ p.drawLine( 0, h, h, 0);
+ p.drawLine( w-h, 0, w, h);
+ p.drawLine( w-h, h, w, 0);
+
+ }
+ else
+ {
+ p.drawLine( 0, 0, w, w);
+ p.drawLine( 0, w, w, 0);
+ p.drawLine( 0, h-w, w, h);
+ p.drawLine( 0, h, w, h-w);
+ }
+ break;
+ }
+
+ case HarmoniousTriangles:
+ {
+ // Move coordinates to local center selection.
+ p.translate(d->localRegionSelection.center().x(), d->localRegionSelection.center().y());
+
+ // Flip horizontal.
+ if (d->flipHorGoldenGuide)
+ p.scale(-1, 1);
+
+ // Flip verical.
+ if (d->flipVerGoldenGuide)
+ p.scale(1, -1);
+
+ float w = (float)d->localRegionSelection.width();
+ float h = (float)d->localRegionSelection.height();
+ int dst = (int)((h*cos(atan(w/h)) / (cos(atan(h/w)))));
+
+ p.setPen(QPen(Qt::white, d->guideSize, Qt::SolidLine));
+ p.drawLine( -d->localRegionSelection.width()/2, -d->localRegionSelection.height()/2,
+ d->localRegionSelection.width()/2, d->localRegionSelection.height()/2);
+
+ p.drawLine( -d->localRegionSelection.width()/2 + dst, -d->localRegionSelection.height()/2,
+ -d->localRegionSelection.width()/2, d->localRegionSelection.height()/2);
+
+ p.drawLine( d->localRegionSelection.width()/2, -d->localRegionSelection.height()/2,
+ d->localRegionSelection.width()/2 - dst, d->localRegionSelection.height()/2);
+
+ p.setPen(QPen(d->guideColor, d->guideSize, Qt::DotLine));
+ p.drawLine( -d->localRegionSelection.width()/2, -d->localRegionSelection.height()/2,
+ d->localRegionSelection.width()/2, d->localRegionSelection.height()/2);
+
+ p.drawLine( -d->localRegionSelection.width()/2 + dst, -d->localRegionSelection.height()/2,
+ -d->localRegionSelection.width()/2, d->localRegionSelection.height()/2);
+
+ p.drawLine( d->localRegionSelection.width()/2, -d->localRegionSelection.height()/2,
+ d->localRegionSelection.width()/2 - dst, d->localRegionSelection.height()/2);
+ break;
+ }
+
+ case GoldenMean:
+ {
+ // Move coordinates to local center selection.
+ p.translate(d->localRegionSelection.center().x(), d->localRegionSelection.center().y());
+
+ // Flip horizontal.
+ if (d->flipHorGoldenGuide)
+ p.scale(-1, 1);
+
+ // Flip vertical.
+ if (d->flipVerGoldenGuide)
+ p.scale(1, -1);
+
+ int w = d->localRegionSelection.width();
+ int h = d->localRegionSelection.height();
+
+ // lengths for the golden mean and half the sizes of the region:
+ int w_g = (int)(w*INVPHI);
+ int h_g = (int)(h*INVPHI);
+ int w_2 = w/2;
+ int h_2 = h/2;
+
+ QRect R1(-w_2, -h_2, w_g, h);
+ // w - 2*w_2 corrects for one-pixel difference
+ // so that R2.right() is really at the right end of the region
+ QRect R2(w_g-w_2, h_2-h_g, w-w_g+1-(w - 2*w_2), h_g);
+
+ QRect R3((int)(w_2 - R2.width()*INVPHI), -h_2,
+ (int)(R2.width()*INVPHI), h - R2.height());
+ QRect R4(R2.x(), R1.y(), R3.x() - R2.x(),
+ (int)(R3.height()*INVPHI));
+ QRect R5(R4.x(), R4.bottom(), (int)(R4.width()*INVPHI),
+ R3.height() - R4.height());
+ QRect R6(R5.x() + R5.width(), R5.bottom() - (int)(R5.height()*INVPHI),
+ R3.x() - R5.right(), (int)(R5.height()*INVPHI));
+ QRect R7(R6.right() - (int)(R6.width()*INVPHI), R4.bottom(),
+ (int)(R6.width()*INVPHI), R5.height() - R6.height());
+
+ p.setPen(QPen(Qt::white, d->guideSize, Qt::SolidLine));
+
+ // Drawing Golden sections.
+ if (d->drawGoldenSection)
+ {
+ // horizontal lines:
+ p.drawLine( R1.left(), R2.top(),
+ R2.right(), R2.top());
+
+ p.drawLine( R1.left(), R1.top() + R2.height(),
+ R2.right(), R1.top() + R2.height());
+
+ // vertical lines:
+ p.drawLine( R1.right(), R1.top(),
+ R1.right(), R1.bottom() );
+
+ p.drawLine( R1.left()+R2.width(), R1.top(),
+ R1.left()+R2.width(), R1.bottom() );
+ }
+
+ // Drawing Golden triangle guides.
+ if (d->drawGoldenTriangle)
+ {
+ p.drawLine( R1.left(), R1.bottom(),
+ R2.right(), R1.top() );
+
+ p.drawLine( R1.left(), R1.top(),
+ R2.right() - R1.width(), R1.bottom());
+
+ p.drawLine( R1.left() + R1.width(), R1.top(),
+ R2.right(), R1.bottom() );
+ }
+
+ // Drawing Golden spiral sections.
+ if (d->drawGoldenSpiralSection)
+ {
+ p.drawLine( R1.topRight(), R1.bottomRight() );
+ p.drawLine( R2.topLeft(), R2.topRight() );
+ p.drawLine( R3.topLeft(), R3.bottomLeft() );
+ p.drawLine( R4.bottomLeft(), R4.bottomRight() );
+ p.drawLine( R5.topRight(), R5.bottomRight() );
+ p.drawLine( R6.topLeft(), R6.topRight() );
+ p.drawLine( R7.topLeft(), R7.bottomLeft() );
+ }
+
+ // Drawing Golden Spiral.
+ if (d->drawGoldenSpiral)
+ {
+ p.drawArc ( R1.left(),
+ R1.top() - R1.height(),
+ 2*R1.width(), 2*R1.height(),
+ 180*16, 90*16);
+
+ p.drawArc ( R2.right() - 2*R2.width(),
+ R1.bottom() - 2*R2.height(),
+ 2*R2.width(), 2*R2.height(),
+ 270*16, 90*16);
+
+ p.drawArc ( R2.right() - 2*R3.width(),
+ R3.top(),
+ 2*R3.width(), 2*R3.height(),
+ 0, 90*16);
+
+ p.drawArc ( R4.left(),
+ R4.top(),
+ 2*R4.width(), 2*R4.height(),
+ 90*16, 90*16);
+
+ p.drawArc ( R5.left(),
+ R5.top()-R5.height(),
+ 2*R5.width(), 2*R5.height(),
+ 180*16, 90*16);
+
+ p.drawArc ( R6.left()-R6.width(),
+ R6.top()-R6.height(),
+ 2*R6.width(), 2*R6.height(),
+ 270*16, 90*16);
+
+ p.drawArc ( R7.left()-R7.width(),
+ R7.top(),
+ 2*R7.width(), 2*R7.height(),
+ 0, 90*16);
+ }
+
+ p.setPen(QPen(d->guideColor, d->guideSize, Qt::DotLine));
+
+ // Drawing Golden sections.
+ if (d->drawGoldenSection)
+ {
+ // horizontal lines:
+ p.drawLine( R1.left(), R2.top(),
+ R2.right(), R2.top());
+
+ p.drawLine( R1.left(), R1.top() + R2.height(),
+ R2.right(), R1.top() + R2.height());
+
+ // vertical lines:
+ p.drawLine( R1.right(), R1.top(),
+ R1.right(), R1.bottom() );
+
+ p.drawLine( R1.left()+R2.width(), R1.top(),
+ R1.left()+R2.width(), R1.bottom() );
+ }
+
+ // Drawing Golden triangle guides.
+ if (d->drawGoldenTriangle)
+ {
+ p.drawLine( R1.left(), R1.bottom(),
+ R2.right(), R1.top() );
+
+ p.drawLine( R1.left(), R1.top(),
+ R2.right() - R1.width(), R1.bottom());
+
+ p.drawLine( R1.left() + R1.width(), R1.top(),
+ R2.right(), R1.bottom() );
+ }
+
+ // Drawing Golden spiral sections.
+ if (d->drawGoldenSpiralSection)
+ {
+ p.drawLine( R1.topRight(), R1.bottomRight() );
+ p.drawLine( R2.topLeft(), R2.topRight() );
+ p.drawLine( R3.topLeft(), R3.bottomLeft() );
+ p.drawLine( R4.bottomLeft(), R4.bottomRight() );
+ p.drawLine( R5.topRight(), R5.bottomRight() );
+ p.drawLine( R6.topLeft(), R6.topRight() );
+ p.drawLine( R7.topLeft(), R7.bottomLeft() );
+ }
+
+ // Drawing Golden Spiral.
+ if (d->drawGoldenSpiral)
+ {
+ p.drawArc ( R1.left(),
+ R1.top() - R1.height(),
+ 2*R1.width(), 2*R1.height(),
+ 180*16, 90*16);
+
+ p.drawArc ( R2.right() - 2*R2.width(),
+ R1.bottom() - 2*R2.height(),
+ 2*R2.width(), 2*R2.height(),
+ 270*16, 90*16);
+
+ p.drawArc ( R2.right() - 2*R3.width(),
+ R3.top(),
+ 2*R3.width(), 2*R3.height(),
+ 0, 90*16);
+
+ p.drawArc ( R4.left(),
+ R4.top(),
+ 2*R4.width(), 2*R4.height(),
+ 90*16, 90*16);
+
+ p.drawArc ( R5.left(),
+ R5.top()-R5.height(),
+ 2*R5.width(), 2*R5.height(),
+ 180*16, 90*16);
+
+ p.drawArc ( R6.left()-R6.width(),
+ R6.top()-R6.height(),
+ 2*R6.width(), 2*R6.height(),
+ 270*16, 90*16);
+
+ p.drawArc ( R7.left()-R7.width(),
+ R7.top(),
+ 2*R7.width(), 2*R7.height(),
+ 0, 90*16);
+ }
+
+ break;
+ }
+ }
+
+ p.setClipping(false);
+
+ p.end();
+}
+
+void ImageSelectionWidget::paintEvent( QPaintEvent * )
+{
+ bitBlt(this, 0, 0, d->pixmap);
+}
+
+QPoint ImageSelectionWidget::opposite()
+{
+ QPoint opp;
+
+ switch(d->currentResizing)
+ {
+ case ImageSelectionWidgetPriv::ResizingTopRight:
+ opp = d->regionSelection.bottomLeft();
+ break;
+
+ case ImageSelectionWidgetPriv::ResizingBottomLeft:
+ opp = d->regionSelection.topRight();
+ break;
+
+ case ImageSelectionWidgetPriv::ResizingBottomRight:
+ opp = d->regionSelection.topLeft();
+ break;
+
+ case ImageSelectionWidgetPriv::ResizingTopLeft:
+ default:
+ opp = d->regionSelection.bottomRight();
+ break;
+ }
+
+ return opp;
+}
+
+float ImageSelectionWidget::distance(QPoint a, QPoint b)
+{
+ return sqrt(pow(a.x() - b.x(), 2) + pow(a.y() - b.y(), 2));
+}
+
+void ImageSelectionWidget::setCursorResizing()
+{
+ switch(d->currentResizing)
+ {
+ case ImageSelectionWidgetPriv::ResizingTopLeft:
+ setCursor( KCursor::sizeFDiagCursor() );
+ break;
+
+ case ImageSelectionWidgetPriv::ResizingTopRight:
+ setCursor( KCursor::sizeBDiagCursor() );
+ break;
+
+ case ImageSelectionWidgetPriv::ResizingBottomLeft:
+ setCursor( KCursor::sizeBDiagCursor() );
+ break;
+
+ case ImageSelectionWidgetPriv::ResizingBottomRight:
+ setCursor( KCursor::sizeFDiagCursor() );
+ break;
+ }
+}
+
+void ImageSelectionWidget::placeSelection(QPoint pm, bool symmetric, QPoint center)
+{
+ // Set orientation
+ if ( d->autoOrientation )
+ {
+ QPoint rel = pm - opposite();
+
+ if ( abs(rel.x()) > abs(rel.y()) )
+ {
+ if ( d->currentOrientation == Portrait )
+ {
+ d->currentOrientation = Landscape;
+ reverseRatioValues();
+ emit signalSelectionOrientationChanged( d->currentOrientation );
+ }
+ }
+ else
+ {
+ if ( d->currentOrientation == Landscape )
+ {
+ d->currentOrientation = Portrait;
+ reverseRatioValues();
+ emit signalSelectionOrientationChanged( d->currentOrientation );
+ }
+ }
+ }
+
+ // Place the corner at the mouse
+ // If a symmetric selection is wanted, place opposite corner to
+ // the center, double selection size and move it to old center after
+ // computing aspect ratio.
+ switch(d->currentResizing)
+ {
+ case ImageSelectionWidgetPriv::ResizingTopLeft:
+ // Place corners to the proper position
+ d->regionSelection.setTopLeft(pm);
+ if ( symmetric )
+ d->regionSelection.setBottomRight(center);
+ break;
+
+ case ImageSelectionWidgetPriv::ResizingTopRight:
+ d->regionSelection.setTopRight(pm);
+ if ( symmetric )
+ d->regionSelection.setBottomLeft(center);
+ break;
+
+ case ImageSelectionWidgetPriv::ResizingBottomLeft:
+ d->regionSelection.setBottomLeft(pm);
+ if ( symmetric )
+ d->regionSelection.setTopRight(center);
+ break;
+
+ case ImageSelectionWidgetPriv::ResizingBottomRight:
+ d->regionSelection.setBottomRight(pm);
+ if ( symmetric )
+ d->regionSelection.setTopLeft(center);
+ break;
+ }
+
+ if ( symmetric )
+ d->regionSelection.setSize(d->regionSelection.size()*2);
+ applyAspectRatio(d->currentOrientation == Portrait, false);
+ if ( symmetric )
+ d->regionSelection.moveCenter(center);
+
+ // Repaint
+ updatePixmap();
+ repaint(false);
+}
+
+void ImageSelectionWidget::mousePressEvent ( QMouseEvent * e )
+{
+ if ( e->button() == Qt::LeftButton )
+ {
+ QPoint pm = QPoint(e->x(), e->y());
+ QPoint pmVirtual = convertPoint(pm);
+ d->moving = false;
+
+ if ( (e->state() & Qt::ShiftButton) == Qt::ShiftButton )
+ {
+ bool symmetric = (e->state() & Qt::ControlButton ) == Qt::ControlButton;
+ QPoint center = d->regionSelection.center();
+
+ // Find the closest corner
+
+ QPoint points[] = { d->regionSelection.topLeft(),
+ d->regionSelection.topRight(),
+ d->regionSelection.bottomLeft(),
+ d->regionSelection.bottomRight() };
+ int resizings[] = { ImageSelectionWidgetPriv::ResizingTopLeft,
+ ImageSelectionWidgetPriv::ResizingTopRight,
+ ImageSelectionWidgetPriv::ResizingBottomLeft,
+ ImageSelectionWidgetPriv::ResizingBottomRight };
+ float dist = -1;
+ for (int i = 0 ; i < 4 ; i++)
+ {
+ QPoint point = points[i];
+ float dist2 = distance(pmVirtual, point);
+ if (dist2 < dist || d->currentResizing == ImageSelectionWidgetPriv::ResizingNone)
+ {
+ dist = dist2;
+ d->currentResizing = resizings[i];
+ }
+ }
+
+ setCursorResizing();
+
+ placeSelection(pmVirtual, symmetric, center);
+ }
+ else
+ {
+ if ( d->localTopLeftCorner.contains( pm ) )
+ d->currentResizing = ImageSelectionWidgetPriv::ResizingTopLeft;
+ else if ( d->localTopRightCorner.contains( pm ) )
+ d->currentResizing = ImageSelectionWidgetPriv::ResizingTopRight;
+ else if ( d->localBottomLeftCorner.contains( pm ) )
+ d->currentResizing = ImageSelectionWidgetPriv::ResizingBottomLeft;
+ else if ( d->localBottomRightCorner.contains( pm ) )
+ d->currentResizing = ImageSelectionWidgetPriv::ResizingBottomRight;
+ else
+ {
+ d->lastPos = pmVirtual;
+ setCursor( KCursor::sizeAllCursor() );
+
+ if (d->regionSelection.contains( pmVirtual ) )
+ {
+ d->moving = true;
+ }
+ else
+ {
+ d->regionSelection.moveCenter( pmVirtual );
+ normalizeRegion();
+ updatePixmap();
+ repaint(false);
+ }
+ }
+ }
+ }
+}
+
+void ImageSelectionWidget::mouseReleaseEvent ( QMouseEvent * )
+{
+ if ( d->currentResizing != ImageSelectionWidgetPriv::ResizingNone )
+ {
+ setCursor( KCursor::arrowCursor() );
+ regionSelectionChanged();
+ d->currentResizing = ImageSelectionWidgetPriv::ResizingNone;
+ }
+ else if ( d->regionSelection.contains( d->lastPos ) )
+ {
+ setCursor( KCursor::handCursor() );
+ regionSelectionMoved();
+ }
+ else
+ {
+ setCursor( KCursor::arrowCursor() );
+ regionSelectionMoved();
+ }
+}
+
+void ImageSelectionWidget::mouseMoveEvent ( QMouseEvent * e )
+{
+ if ( ( e->state() & Qt::LeftButton ) == Qt::LeftButton )
+ {
+ if ( d->moving )
+ {
+ setCursor( KCursor::sizeAllCursor() );
+ QPoint newPos = convertPoint(e->x(), e->y());
+
+ d->regionSelection.moveBy( newPos.x() - d->lastPos.x(),
+ newPos.y() - d->lastPos.y() );
+
+ d->lastPos = newPos;
+
+ normalizeRegion();
+
+ updatePixmap();
+ repaint(false);
+ }
+ else
+ {
+ QPoint pmVirtual = convertPoint(e->x(), e->y());
+
+ if ( d->currentResizing == ImageSelectionWidgetPriv::ResizingNone )
+ {
+ d->regionSelection.setTopLeft( pmVirtual );
+ d->regionSelection.setBottomRight( pmVirtual );
+ d->currentResizing = ImageSelectionWidgetPriv::ResizingTopLeft; // set to anything
+ }
+
+ QPoint center = d->regionSelection.center();
+ bool symmetric = (e->state() & Qt::ControlButton ) == Qt::ControlButton;
+
+ // Change resizing mode
+
+ QPoint opp = symmetric ? center : opposite();
+ QPoint dir = pmVirtual - opp;
+
+ if ( dir.x() > 0 && dir.y() > 0 && d->currentResizing != ImageSelectionWidgetPriv::ResizingBottomRight)
+ {
+ d->currentResizing = ImageSelectionWidgetPriv::ResizingBottomRight;
+ d->regionSelection.setTopLeft( opp );
+ setCursor( KCursor::sizeFDiagCursor() );
+ }
+ else if ( dir.x() > 0 && dir.y() < 0 && d->currentResizing != ImageSelectionWidgetPriv::ResizingTopRight)
+ {
+ d->currentResizing = ImageSelectionWidgetPriv::ResizingTopRight;
+ d->regionSelection.setBottomLeft( opp );
+ setCursor( KCursor::sizeBDiagCursor() );
+ }
+ else if ( dir.x() < 0 && dir.y() > 0 && d->currentResizing != ImageSelectionWidgetPriv::ResizingBottomLeft)
+ {
+ d->currentResizing = ImageSelectionWidgetPriv::ResizingBottomLeft;
+ d->regionSelection.setTopRight( opp );
+ setCursor( KCursor::sizeBDiagCursor() );
+ }
+ else if ( dir.x() < 0 && dir.y() < 0 && d->currentResizing != ImageSelectionWidgetPriv::ResizingTopLeft)
+ {
+ d->currentResizing = ImageSelectionWidgetPriv::ResizingTopLeft;
+ d->regionSelection.setBottomRight( opp );
+ setCursor( KCursor::sizeFDiagCursor() );
+ }
+ else
+ {
+ if ( dir.x() == 0 && dir.y() == 0 )
+ setCursor( KCursor::sizeAllCursor() );
+ else if ( dir.x() == 0 )
+ setCursor( KCursor::sizeHorCursor() );
+ else if ( dir.y() == 0 )
+ setCursor( KCursor::sizeVerCursor() );
+ }
+
+ placeSelection(pmVirtual, symmetric, center);
+ }
+ }
+ else
+ {
+ if ( d->localTopLeftCorner.contains( e->x(), e->y() ) ||
+ d->localBottomRightCorner.contains( e->x(), e->y() ) )
+ setCursor( KCursor::sizeFDiagCursor() );
+ else if ( d->localTopRightCorner.contains( e->x(), e->y() ) ||
+ d->localBottomLeftCorner.contains( e->x(), e->y() ) )
+ setCursor( KCursor::sizeBDiagCursor() );
+ else if ( d->localRegionSelection.contains( e->x(), e->y() ) )
+ setCursor( KCursor::handCursor() );
+ else
+ setCursor( KCursor::arrowCursor() );
+ }
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/ratiocrop/imageselectionwidget.h b/digikam/imageplugins/coreplugin/ratiocrop/imageselectionwidget.h
new file mode 100644
index 0000000..5b4a576
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/ratiocrop/imageselectionwidget.h
@@ -0,0 +1,175 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-12-09
+ * Description : image selection widget used by ratio crop tool.
+ *
+ * Copyright (C) 2007 by Jaromir Malenko <malenko at email.cz>
+ * Copyright (C) 2008 by Roberto Castagnola <roberto dot castagnola at gmail dot com>
+ * Copyright (C) 2004-2009 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 IMAGESELECTIONWIDGET_H
+#define IMAGESELECTIONWIDGET_H
+
+// Qt includes.
+
+#include <qwidget.h>
+#include <qrect.h>
+#include <qcolor.h>
+
+namespace Digikam
+{
+class ImageIface;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class ImageSelectionWidgetPriv;
+
+class ImageSelectionWidget : public QWidget
+{
+
+Q_OBJECT
+
+public:
+
+ enum RatioAspect // Constrained Aspect Ratio list.
+ {
+ RATIOCUSTOM=0, // Custom aspect ratio.
+ RATIO01X01, // 1:1
+ RATIO02x03, // 2:3
+ RATIO03X04, // 3:4
+ RATIO04X05, // 4:5
+ RATIO05x07, // 5:7
+ RATIO07x10, // 7:10
+ RATIOGOLDEN, // Golden ratio : 1:1.618
+ RATIONONE // No aspect ratio.
+ };
+
+ enum Orient
+ {
+ Landscape = 0,
+ Portrait
+ };
+
+ enum CenterType
+ {
+ CenterWidth = 0, // Center selection to the center of image width.
+ CenterHeight, // Center selection to the center of image height.
+ CenterImage // Center selection to the center of image.
+ };
+
+ // Proportion : Golden Ratio and Rule of Thirds. More information at this url:
+ // http://photoinf.com/General/Robert_Berdan/Composition_and_the_Elements_of_Visual_Design.htm
+
+ enum GuideLineType
+ {
+ RulesOfThirds = 0, // Line guides position to 1/3 width and height.
+ DiagonalMethod, // Diagonal Method to improve composition.
+ HarmoniousTriangles, // Harmonious Triangle to improve composition.
+ GoldenMean, // Guides tools using Phi ratio (1.618).
+ GuideNone // No guide line.
+ };
+
+public:
+
+ ImageSelectionWidget(int width, int height, QWidget *parent=0,
+ int widthRatioValue=1, int heightRatioValue=1,
+ int aspectRatio=RATIO01X01, int orient=Landscape,
+ int guideLinesType=GuideNone);
+ ~ImageSelectionWidget();
+
+ void setCenterSelection(int centerType=CenterImage);
+ void setSelectionX(int x);
+ void setSelectionY(int y);
+ void setSelectionWidth(int w);
+ void setSelectionHeight(int h);
+ void setSelectionOrientation(int orient);
+ void setPreciseCrop(bool precise);
+ void setAutoOrientation(bool orientation);
+ void setSelectionAspectRatioType(int aspectRatioType);
+ void setSelectionAspectRatioValue(int widthRatioValue, int heightRatioValue);
+ void setGoldenGuideTypes(bool drawGoldenSection, bool drawGoldenSpiralSection,
+ bool drawGoldenSpiral, bool drawGoldenTriangle,
+ bool flipHorGoldenGuide, bool flipVerGoldenGuide);
+
+ int getOriginalImageWidth();
+ int getOriginalImageHeight();
+ QRect getRegionSelection();
+
+ int getMinWidthRange();
+ int getMinHeightRange();
+ int getMaxWidthRange();
+ int getMaxHeightRange();
+ int getWidthStep();
+ int getHeightStep();
+
+ bool preciseCropAvailable();
+
+ void resetSelection();
+ void maxAspectSelection();
+
+ Digikam::ImageIface* imageIface();
+
+public slots:
+
+ void slotGuideLines(int guideLinesType);
+ void slotChangeGuideColor(const QColor &color);
+ void slotChangeGuideSize(int size);
+
+signals:
+
+ void signalSelectionMoved( QRect rect );
+ void signalSelectionChanged( QRect rect );
+ void signalSelectionOrientationChanged( int newOrientation );
+
+protected:
+
+ void paintEvent( QPaintEvent *e );
+ void mousePressEvent ( QMouseEvent * e );
+ void mouseReleaseEvent ( QMouseEvent * e );
+ void mouseMoveEvent ( QMouseEvent * e );
+ void resizeEvent(QResizeEvent * e);
+
+private:
+
+ // Recalculate the target selection position and emit 'signalSelectionMoved'.
+ void regionSelectionMoved();
+
+ void regionSelectionChanged();
+ QPoint convertPoint(const QPoint pm, bool localToReal=true);
+ QPoint convertPoint(int x, int y, bool localToReal=true);
+ void normalizeRegion();
+ void reverseRatioValues();
+ int computePreciseSize(int size, int step);
+ void applyAspectRatio(bool useHeight, bool repaintWidget=true);
+ void updatePixmap();
+ QPoint opposite();
+ float distance(QPoint a, QPoint b);
+ void placeSelection(QPoint pm, bool symetric, QPoint center);
+ void setCursorResizing();
+
+private:
+
+ ImageSelectionWidgetPriv* d;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* IMAGESELECTIONWIDGET_H */
diff --git a/digikam/imageplugins/coreplugin/ratiocrop/ratiocroptool.cpp b/digikam/imageplugins/coreplugin/ratiocrop/ratiocroptool.cpp
new file mode 100644
index 0000000..e869137
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/ratiocrop/ratiocroptool.cpp
@@ -0,0 +1,853 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-12-06
+ * Description : digiKam image editor Ratio Crop tool
+ *
+ * Copyright (C) 2007 by Jaromir Malenko <malenko at email dot cz>
+ * Copyright (C) 2008 by Roberto Castagnola <roberto dot castagnola at gmail dot com>
+ * Copyright (C) 2004-2009 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qcheckbox.h>
+#include <qframe.h>
+#include <qimage.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qrect.h>
+#include <qspinbox.h>
+#include <qtimer.h>
+#include <qtoolbutton.h>
+#include <qtooltip.h>
+#include <qvgroupbox.h>
+#include <qwhatsthis.h>
+
+// KDE includes.
+
+#include <kapplication.h>
+#include <kcolorbutton.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kpushbutton.h>
+#include <kstandarddirs.h>
+
+// LibKDcraw includes.
+
+#include <libkdcraw/rnuminput.h>
+#include <libkdcraw/rcombobox.h>
+
+// Digikam includes.
+
+#include "editortoolsettings.h"
+#include "imageiface.h"
+#include "imageselectionwidget.h"
+
+// Local includes.
+
+#include "ratiocroptool.h"
+#include "ratiocroptool.moc"
+
+using namespace KDcrawIface;
+using namespace Digikam;
+
+namespace DigikamImagesPluginCore
+{
+
+RatioCropTool::RatioCropTool(QObject* parent)
+ : EditorTool(parent)
+{
+ setName("aspectratiocrop");
+ setToolName(i18n("Aspect Ratio Crop"));
+ setToolIcon(SmallIcon("ratiocrop"));
+ setToolHelp("ratiocroptool.anchor");
+
+ // -------------------------------------------------------------
+
+ m_imageSelectionWidget = new ImageSelectionWidget(480, 320);
+ QWhatsThis::add(m_imageSelectionWidget,
+ i18n("<p>Here you can see the aspect ratio selection preview "
+ "used for cropping. You can use the mouse to move and "
+ "resize the crop area. "
+ "Press and hold the CTRL key to move the opposite corner too. "
+ "Press and hold the SHIFT key to move the closest corner to the "
+ "mouse pointer."));
+
+ m_originalIsLandscape = ((m_imageSelectionWidget->getOriginalImageWidth()) >
+ (m_imageSelectionWidget->getOriginalImageHeight()));
+
+ setToolView(m_imageSelectionWidget);
+
+ // -------------------------------------------------------------
+
+ m_gboxSettings = new EditorToolSettings(EditorToolSettings::Default|
+ EditorToolSettings::Ok|
+ EditorToolSettings::Try|
+ EditorToolSettings::Cancel);
+
+ // -------------------------------------------------------------
+
+ // need to set the button to a KStdGuiItem that has no icon
+ m_gboxSettings->button(EditorToolSettings::Try)->setGuiItem(KStdGuiItem::Test);
+ // now we can set the correct text for the button
+ m_gboxSettings->button(EditorToolSettings::Try)->setText(i18n("Max. Aspect"));
+
+ QToolTip::add(m_gboxSettings->button(EditorToolSettings::Try),
+ i18n("<p>Set selection area to the maximum size according "
+ "to the current ratio."));
+
+ // -------------------------------------------------------------
+
+ QGridLayout *gboxLayout = new QGridLayout(m_gboxSettings->plainPage(), 3, 2);
+
+ QFrame *cropSelection = new QFrame(m_gboxSettings->plainPage());
+ cropSelection->setFrameStyle(QFrame::Panel | QFrame::Sunken);
+
+ QGridLayout* grid = new QGridLayout(cropSelection, 7, 5);
+
+ QLabel *label = new QLabel(i18n("Ratio:"), cropSelection);
+ m_ratioCB = new RComboBox(cropSelection);
+ m_ratioCB->setDefaultItem(ImageSelectionWidget::RATIO03X04);
+ setRatioCBText(ImageSelectionWidget::Landscape);
+ QWhatsThis::add( m_ratioCB, i18n("<p>Select your constrained aspect ratio for cropping. "
+ "Aspect Ratio Crop tool uses a relative ratio. That means it "
+ "is the same if you use centimeters or inches and it doesn't "
+ "specify the physical size.<p>"
+ "You can see below a correspondence list of traditional photographic "
+ "paper sizes and aspect ratio crop:<p>"
+ "<b>2:3</b>: 10x15cm, 20x30cm, 30x45cm, 4x6\", 8x12\", "
+ "12x18\", 16x24\", 20x30\"<p>"
+ "<b>3:4</b>: 6x8cm, 15x20cm, 18x24cm, 30x40cm, 3.75x5\", 4.5x6\", "
+ "6x8\", 7.5x10\", 9x12\"<p>"
+ "<b>4:5</b>: 20x25cm, 40x50cm, 8x10\", 16x20\"<p>"
+ "<b>5:7</b>: 15x21cm, 30x42cm, 5x7\"<p>"
+ "<b>7:10</b>: 21x30cm, 42x60cm, 3.5x5\"<p>"
+ "The <b>Golden Ratio</b> is 1:1.618. A composition following this rule "
+ "is considered visually harmonious but can be unadapted to print on "
+ "standard photographic paper."));
+
+ m_preciseCrop = new QCheckBox(i18n("Exact"), cropSelection);
+ QWhatsThis::add( m_preciseCrop, i18n("<p>Enable this option to force exact aspect ratio crop."));
+
+ m_orientLabel = new QLabel(i18n("Orientation:"), cropSelection);
+ m_orientCB = new RComboBox(cropSelection);
+ m_orientCB->insertItem( i18n("Landscape"));
+ m_orientCB->insertItem( i18n("Portrait"));
+ m_orientCB->setDefaultItem(ImageSelectionWidget::Landscape);
+ QWhatsThis::add( m_orientCB, i18n("<p>Select constrained aspect ratio orientation."));
+
+ m_autoOrientation = new QCheckBox(i18n("Auto"), cropSelection);
+ QWhatsThis::add( m_autoOrientation, i18n("<p>Enable this option to automatically set the orientation."));
+
+ // -------------------------------------------------------------
+
+ m_customLabel1 = new QLabel(i18n("Custom:"), cropSelection);
+ m_customLabel1->setAlignment(AlignLeft|AlignVCenter);
+ m_customRatioNInput = new RIntNumInput(cropSelection);
+ m_customRatioNInput->input()->setRange(1, 10000, 1, false);
+ m_customRatioNInput->setDefaultValue(1);
+ QWhatsThis::add( m_customRatioNInput, i18n("<p>Set here the desired custom aspect numerator value."));
+
+ m_customLabel2 = new QLabel(" : ", cropSelection);
+ m_customLabel2->setAlignment(AlignCenter|AlignVCenter);
+ m_customRatioDInput = new RIntNumInput(cropSelection);
+ m_customRatioDInput->input()->setRange(1, 10000, 1, false);
+ m_customRatioDInput->setDefaultValue(1);
+ QWhatsThis::add( m_customRatioDInput, i18n("<p>Set here the desired custom aspect denominator value."));
+
+ // -------------------------------------------------------------
+
+ m_xInput = new RIntNumInput(cropSelection);
+ m_xInput->input()->setLabel(i18n("X:"), AlignLeft|AlignVCenter);
+ m_xInput->setRange(0, m_imageSelectionWidget->getOriginalImageWidth(), 1);
+ m_xInput->setDefaultValue(50);
+ QWhatsThis::add( m_xInput, i18n("<p>Set here the top left selection corner position for cropping."));
+
+ m_widthInput = new RIntNumInput(cropSelection);
+ m_widthInput->input()->setLabel(i18n("Width:"), AlignLeft|AlignVCenter);
+ m_widthInput->setRange(m_imageSelectionWidget->getMinWidthRange(),
+ m_imageSelectionWidget->getMaxWidthRange(),
+ m_imageSelectionWidget->getWidthStep());
+ m_widthInput->setDefaultValue(800);
+ QWhatsThis::add( m_widthInput, i18n("<p>Set here the width selection for cropping."));
+
+ m_centerWidth = new QToolButton(cropSelection);
+ KGlobal::dirs()->addResourceType("centerwidth", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("centerwidth", "centerwidth.png");
+ m_centerWidth->setPixmap(QPixmap(directory + "centerwidth.png"));
+ QWhatsThis::add(m_centerWidth, i18n("<p>Set width position to center."));
+
+ // -------------------------------------------------------------
+
+ m_yInput = new RIntNumInput(cropSelection);
+ m_yInput->input()->setLabel(i18n("Y:"), AlignLeft | AlignVCenter);
+ m_yInput->setRange(0, m_imageSelectionWidget->getOriginalImageHeight(), 1);
+ m_yInput->setDefaultValue(50);
+ QWhatsThis::add(m_yInput, i18n("<p>Set here the top left selection corner position for cropping."));
+
+ m_heightInput = new RIntNumInput(cropSelection);
+ m_heightInput->input()->setLabel(i18n("Height:"), AlignLeft | AlignVCenter);
+ m_heightInput->setRange(m_imageSelectionWidget->getMinHeightRange(),
+ m_imageSelectionWidget->getMaxHeightRange(),
+ m_imageSelectionWidget->getHeightStep());
+ m_heightInput->setDefaultValue(600);
+ QWhatsThis::add( m_heightInput, i18n("<p>Set here the height selection for cropping."));
+
+ m_centerHeight = new QToolButton(cropSelection);
+ KGlobal::dirs()->addResourceType("centerheight", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("centerheight", "centerheight.png");
+ m_centerHeight->setPixmap(QPixmap(directory + "centerheight.png"));
+ QWhatsThis::add(m_centerHeight, i18n("<p>Set height position to center."));
+
+ grid->addMultiCellWidget(label, 0, 0, 0, 0);
+ grid->addMultiCellWidget(m_ratioCB, 0, 0, 1, 3);
+ grid->addMultiCellWidget(m_preciseCrop, 0, 0, 4, 4);
+ grid->addMultiCellWidget(m_customLabel1, 1, 1, 0, 0);
+ grid->addMultiCellWidget(m_customRatioNInput, 1, 1, 1, 1);
+ grid->addMultiCellWidget(m_customLabel2, 1, 1, 2, 2);
+ grid->addMultiCellWidget(m_customRatioDInput, 1, 1, 3, 3);
+ grid->addMultiCellWidget(m_orientLabel, 2, 2, 0, 0);
+ grid->addMultiCellWidget(m_orientCB, 2, 2, 1, 3);
+ grid->addMultiCellWidget(m_autoOrientation, 2, 2, 4, 4);
+ grid->addMultiCellWidget(m_xInput, 3, 3, 0, 3);
+ grid->addMultiCellWidget(m_widthInput, 4, 4, 0, 3);
+ grid->addMultiCellWidget(m_centerWidth, 4, 4, 4, 4);
+ grid->addMultiCellWidget(m_yInput, 5, 5, 0, 3);
+ grid->addMultiCellWidget(m_heightInput, 6, 6, 0, 3);
+ grid->addMultiCellWidget(m_centerHeight, 6, 6, 4, 4);
+ grid->setMargin(m_gboxSettings->spacingHint());
+ grid->setSpacing(m_gboxSettings->spacingHint());
+
+ // -------------------------------------------------------------
+
+ QFrame* compositionGuide = new QFrame(m_gboxSettings->plainPage());
+ QGridLayout* grid2 = new QGridLayout(compositionGuide, 8, 3);
+ compositionGuide->setFrameStyle(QFrame::Panel|QFrame::Sunken);
+
+ QLabel *labelGuideLines = new QLabel(i18n("Composition guide:"), compositionGuide);
+ m_guideLinesCB = new RComboBox(compositionGuide);
+ m_guideLinesCB->insertItem( i18n("Rules of Thirds"));
+ m_guideLinesCB->insertItem( i18n("Diagonal Method"));
+ m_guideLinesCB->insertItem( i18n("Harmonious Triangles"));
+ m_guideLinesCB->insertItem( i18n("Golden Mean"));
+ m_guideLinesCB->insertItem( i18n("None"));
+ m_guideLinesCB->setDefaultItem(ImageSelectionWidget::GuideNone);
+ QWhatsThis::add( m_guideLinesCB, i18n("<p>With this option, you can display guide lines "
+ "which help you to compose your photograph."));
+
+ m_goldenSectionBox = new QCheckBox(i18n("Golden sections"), compositionGuide);
+ QWhatsThis::add( m_goldenSectionBox, i18n("<p>Enable this option to show golden sections."));
+
+ m_goldenSpiralSectionBox = new QCheckBox(i18n("Golden spiral sections"), compositionGuide);
+ QWhatsThis::add( m_goldenSpiralSectionBox, i18n("<p>Enable this option to show golden spiral sections."));
+
+ m_goldenSpiralBox = new QCheckBox(i18n("Golden spiral"), compositionGuide);
+ QWhatsThis::add( m_goldenSpiralBox, i18n("<p>Enable this option to show golden spiral guide."));
+
+ m_goldenTriangleBox = new QCheckBox(i18n("Golden triangles"), compositionGuide);
+ QWhatsThis::add( m_goldenTriangleBox, i18n("<p>Enable this option to show golden triangles."));
+
+ m_flipHorBox = new QCheckBox(i18n("Flip horizontally"), compositionGuide);
+ QWhatsThis::add( m_flipHorBox, i18n("<p>Enable this option to flip horizontally guidelines."));
+
+ m_flipVerBox = new QCheckBox(i18n("Flip vertically"), compositionGuide);
+ QWhatsThis::add( m_flipVerBox, i18n("<p>Enable this option to flip vertically guidelines."));
+
+ m_colorGuideLabel = new QLabel(i18n("Color and width:"), compositionGuide);
+ m_guideColorBt = new KColorButton(QColor(250, 250, 255), compositionGuide);
+ m_guideSize = new RIntNumInput(compositionGuide);
+ m_guideSize->input()->setRange(1, 5, 1, false);
+ m_guideSize->setDefaultValue(1);
+ QWhatsThis::add( m_guideColorBt, i18n("<p>Set here the color used to draw composition guides."));
+ QWhatsThis::add( m_guideSize, i18n("<p>Set here the width in pixels used to draw composition guides."));
+
+ grid2->addMultiCellWidget(labelGuideLines, 0, 0, 0, 0);
+ grid2->addMultiCellWidget(m_guideLinesCB, 0, 0, 1, 2);
+ grid2->addMultiCellWidget(m_goldenSectionBox, 1, 1, 0, 2);
+ grid2->addMultiCellWidget(m_goldenSpiralSectionBox, 2, 2, 0, 2);
+ grid2->addMultiCellWidget(m_goldenSpiralBox, 3, 3, 0, 2);
+ grid2->addMultiCellWidget(m_goldenTriangleBox, 4, 4, 0, 2);
+ grid2->addMultiCellWidget(m_flipHorBox, 5, 5, 0, 2);
+ grid2->addMultiCellWidget(m_flipVerBox, 6, 6, 0, 2);
+ grid2->addMultiCellWidget(m_colorGuideLabel, 7, 7, 0, 0);
+ grid2->addMultiCellWidget(m_guideColorBt, 7, 7, 1, 1);
+ grid2->addMultiCellWidget(m_guideSize, 7, 7, 2, 2);
+ grid2->setMargin(m_gboxSettings->spacingHint());
+ grid2->setSpacing(m_gboxSettings->spacingHint());
+
+
+ // -------------------------------------------------------------
+
+ gboxLayout->addMultiCellWidget(cropSelection, 0, 0, 0, 1);
+ gboxLayout->addMultiCellWidget(compositionGuide, 1, 1, 0, 1);
+ gboxLayout->setRowStretch(2, 10);
+ gboxLayout->setMargin(m_gboxSettings->spacingHint());
+ gboxLayout->setSpacing(m_gboxSettings->spacingHint());
+
+ setToolSettings(m_gboxSettings);
+ init();
+
+ // -------------------------------------------------------------
+
+ connect(m_ratioCB, SIGNAL(activated(int)),
+ this, SLOT(slotRatioChanged(int)));
+
+ connect(m_preciseCrop, SIGNAL(toggled(bool)),
+ this, SLOT(slotPreciseCropChanged(bool)));
+
+ connect(m_orientCB, SIGNAL(activated(int)),
+ this, SLOT(slotOrientChanged(int)));
+
+ connect(m_autoOrientation, SIGNAL(toggled(bool)),
+ this, SLOT(slotAutoOrientChanged(bool)));
+
+ connect(m_xInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotXChanged(int)));
+
+ connect(m_yInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotYChanged(int)));
+
+ connect(m_customRatioNInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotCustomNRatioChanged(int)));
+
+ connect(m_customRatioDInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotCustomDRatioChanged(int)));
+
+ connect(m_guideLinesCB, SIGNAL(activated(int)),
+ this, SLOT(slotGuideTypeChanged(int)));
+
+ connect(m_goldenSectionBox, SIGNAL(toggled(bool)),
+ this, SLOT(slotGoldenGuideTypeChanged()));
+
+ connect(m_goldenSpiralSectionBox, SIGNAL(toggled(bool)),
+ this, SLOT(slotGoldenGuideTypeChanged()));
+
+ connect(m_goldenSpiralBox, SIGNAL(toggled(bool)),
+ this, SLOT(slotGoldenGuideTypeChanged()));
+
+ connect(m_goldenTriangleBox, SIGNAL(toggled(bool)),
+ this, SLOT(slotGoldenGuideTypeChanged()));
+
+ connect(m_flipHorBox, SIGNAL(toggled(bool)),
+ this, SLOT(slotGoldenGuideTypeChanged()));
+
+ connect(m_flipVerBox, SIGNAL(toggled(bool)),
+ this, SLOT(slotGoldenGuideTypeChanged()));
+
+ connect(m_guideColorBt, SIGNAL(changed(const QColor&)),
+ m_imageSelectionWidget, SLOT(slotChangeGuideColor(const QColor&)));
+
+ connect(m_guideSize, SIGNAL(valueChanged(int)),
+ m_imageSelectionWidget, SLOT(slotChangeGuideSize(int)));
+
+ connect(m_widthInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotWidthChanged(int)));
+
+ connect(m_heightInput, SIGNAL(valueChanged(int)),
+ this, SLOT(slotHeightChanged(int)));
+
+ connect(m_imageSelectionWidget, SIGNAL(signalSelectionChanged(QRect)),
+ this, SLOT(slotSelectionChanged(QRect)));
+
+ connect(m_imageSelectionWidget, SIGNAL(signalSelectionMoved(QRect)),
+ this, SLOT(slotSelectionChanged(QRect)));
+
+ connect(m_imageSelectionWidget, SIGNAL(signalSelectionOrientationChanged(int)),
+ this, SLOT(slotSelectionOrientationChanged(int)));
+
+ connect(m_centerWidth, SIGNAL(clicked()),
+ this, SLOT(slotCenterWidth()));
+
+ connect(m_centerHeight, SIGNAL(clicked()),
+ this, SLOT(slotCenterHeight()));
+
+ // we need to disconnect the standard connection of the Try button first
+ disconnect(m_gboxSettings, SIGNAL(signalTryClicked()),
+ this, SLOT(slotEffect()));
+
+ connect(m_gboxSettings, SIGNAL(signalTryClicked()),
+ this, SLOT(slotMaxAspectRatio()));
+
+ // -------------------------------------------------------------
+
+ // Sets current region selection
+ slotSelectionChanged(m_imageSelectionWidget->getRegionSelection());
+}
+
+RatioCropTool::~RatioCropTool()
+{
+}
+
+void RatioCropTool::readSettings()
+{
+ QColor defaultGuideColor(250, 250, 255);
+ KConfig *config = kapp->config();
+ config->setGroup("aspectratiocrop Tool");
+
+ // No guide lines per default.
+ m_guideLinesCB->setCurrentItem(config->readNumEntry("Guide Lines Type", ImageSelectionWidget::GuideNone));
+ m_goldenSectionBox->setChecked(config->readBoolEntry("Golden Section", true));
+ m_goldenSpiralSectionBox->setChecked(config->readBoolEntry("Golden Spiral Section", false));
+ m_goldenSpiralBox->setChecked(config->readBoolEntry("Golden Spiral", false));
+ m_goldenTriangleBox->setChecked(config->readBoolEntry("Golden Triangle", false));
+ m_flipHorBox->setChecked(config->readBoolEntry("Golden Flip Horizontal", false));
+ m_flipVerBox->setChecked(config->readBoolEntry("Golden Flip Vertical", false));
+ m_guideColorBt->setColor(config->readColorEntry("Guide Color", &defaultGuideColor));
+ m_guideSize->setValue(config->readNumEntry("Guide Width", m_guideSize->defaultValue()));
+ m_imageSelectionWidget->slotGuideLines(m_guideLinesCB->currentItem());
+ m_imageSelectionWidget->slotChangeGuideColor(m_guideColorBt->color());
+
+ m_preciseCrop->setChecked(config->readBoolEntry("Precise Aspect Ratio Crop", false));
+ m_imageSelectionWidget->setPreciseCrop(m_preciseCrop->isChecked());
+
+ // Empty selection so it can be moved w/out size constraint
+ m_widthInput->setValue(0);
+ m_heightInput->setValue(0);
+
+ m_xInput->setValue(config->readNumEntry("Hor.Oriented Custom Aspect Ratio Xpos",
+ m_xInput->defaultValue()));
+ m_yInput->setValue(config->readNumEntry("Hor.Oriented Custom Aspect Ratio Ypos",
+ m_yInput->defaultValue()));
+
+ m_widthInput->setValue(config->readNumEntry("Hor.Oriented Custom Aspect Ratio Width",
+ m_widthInput->defaultValue()));
+ m_heightInput->setValue(config->readNumEntry("Hor.Oriented Custom Aspect Ratio Height",
+ m_heightInput->defaultValue()));
+
+ m_imageSelectionWidget->setSelectionOrientation(m_orientCB->currentItem());
+
+ m_customRatioNInput->setValue(config->readNumEntry("Hor.Oriented Custom Aspect Ratio Num",
+ m_customRatioNInput->defaultValue()));
+ m_customRatioDInput->setValue(config->readNumEntry("Hor.Oriented Custom Aspect Ratio Den",
+ m_customRatioDInput->defaultValue()));
+
+ m_ratioCB->setCurrentItem(config->readNumEntry("Hor.Oriented Aspect Ratio",
+ m_ratioCB->defaultItem()));
+
+ if (m_originalIsLandscape)
+ {
+ m_orientCB->setCurrentItem(config->readNumEntry("Hor.Oriented Aspect Ratio Orientation",
+ ImageSelectionWidget::Landscape));
+ m_orientCB->setDefaultItem(ImageSelectionWidget::Landscape);
+ }
+ else
+ {
+ m_orientCB->setCurrentItem(config->readNumEntry("Ver.Oriented Aspect Ratio Orientation",
+ ImageSelectionWidget::Portrait));
+ m_orientCB->setDefaultItem(ImageSelectionWidget::Portrait);
+ }
+
+ applyRatioChanges(m_ratioCB->currentItem());
+
+ m_autoOrientation->setChecked( config->readBoolEntry("Auto Orientation", false) );
+ slotAutoOrientChanged( m_autoOrientation->isChecked() );
+}
+
+void RatioCropTool::writeSettings()
+{
+ KConfig *config = kapp->config();
+ config->setGroup("aspectratiocrop Tool");
+
+ if (m_originalIsLandscape)
+ {
+ config->writeEntry("Hor.Oriented Aspect Ratio", m_ratioCB->currentItem());
+ config->writeEntry("Hor.Oriented Aspect Ratio Orientation", m_orientCB->currentItem());
+ config->writeEntry("Hor.Oriented Custom Aspect Ratio Num", m_customRatioNInput->value());
+ config->writeEntry("Hor.Oriented Custom Aspect Ratio Den", m_customRatioDInput->value());
+
+ config->writeEntry("Hor.Oriented Custom Aspect Ratio Xpos", m_xInput->value());
+ config->writeEntry("Hor.Oriented Custom Aspect Ratio Ypos", m_yInput->value());
+ config->writeEntry("Hor.Oriented Custom Aspect Ratio Width", m_widthInput->value());
+ config->writeEntry("Hor.Oriented Custom Aspect Ratio Height", m_heightInput->value());
+ }
+ else
+ {
+ config->writeEntry("Ver.Oriented Aspect Ratio", m_ratioCB->currentItem());
+ config->writeEntry("Ver.Oriented Aspect Ratio Orientation", m_orientCB->currentItem());
+ config->writeEntry("Ver.Oriented Custom Aspect Ratio Num", m_customRatioNInput->value());
+ config->writeEntry("Ver.Oriented Custom Aspect Ratio Den", m_customRatioDInput->value());
+
+ config->writeEntry("Ver.Oriented Custom Aspect Ratio Xpos", m_xInput->value());
+ config->writeEntry("Ver.Oriented Custom Aspect Ratio Ypos", m_yInput->value());
+ config->writeEntry("Ver.Oriented Custom Aspect Ratio Width", m_widthInput->value());
+ config->writeEntry("Ver.Oriented Custom Aspect Ratio Height", m_heightInput->value());
+ }
+
+ config->writeEntry("Precise Aspect Ratio Crop", m_preciseCrop->isChecked());
+ config->writeEntry("Auto Orientation", m_autoOrientation->isChecked());
+ config->writeEntry("Guide Lines Type", m_guideLinesCB->currentItem());
+ config->writeEntry("Golden Section", m_goldenSectionBox->isChecked());
+ config->writeEntry("Golden Spiral Section", m_goldenSpiralSectionBox->isChecked());
+ config->writeEntry("Golden Spiral", m_goldenSpiralBox->isChecked());
+ config->writeEntry("Golden Triangle", m_goldenTriangleBox->isChecked());
+ config->writeEntry("Golden Flip Horizontal", m_flipHorBox->isChecked());
+ config->writeEntry("Golden Flip Vertical", m_flipVerBox->isChecked());
+ config->writeEntry("Guide Color", m_guideColorBt->color());
+ config->writeEntry("Guide Width", m_guideSize->value());
+ config->sync();
+}
+
+void RatioCropTool::slotResetSettings()
+{
+ m_imageSelectionWidget->resetSelection();
+}
+
+void RatioCropTool::slotMaxAspectRatio()
+{
+ m_imageSelectionWidget->maxAspectSelection();
+}
+
+void RatioCropTool::slotCenterWidth()
+{
+ m_imageSelectionWidget->setCenterSelection(ImageSelectionWidget::CenterWidth);
+}
+
+void RatioCropTool::slotCenterHeight()
+{
+ m_imageSelectionWidget->setCenterSelection(ImageSelectionWidget::CenterHeight);
+}
+
+void RatioCropTool::slotSelectionChanged(QRect rect)
+{
+ m_xInput->blockSignals(true);
+ m_yInput->blockSignals(true);
+ m_widthInput->blockSignals(true);
+ m_heightInput->blockSignals(true);
+
+ m_xInput->setRange(0, m_imageSelectionWidget->getOriginalImageWidth() - rect.width(), 1);
+ m_yInput->setRange(0, m_imageSelectionWidget->getOriginalImageHeight() - rect.height(), 1);
+
+ m_widthInput->setRange(m_imageSelectionWidget->getMinWidthRange(),
+ m_imageSelectionWidget->getMaxWidthRange(),
+ m_imageSelectionWidget->getWidthStep());
+
+ m_heightInput->setRange(m_imageSelectionWidget->getMinHeightRange(),
+ m_imageSelectionWidget->getMaxHeightRange(),
+ m_imageSelectionWidget->getHeightStep());
+
+ m_xInput->setValue(rect.x());
+ m_yInput->setValue(rect.y());
+ m_widthInput->setValue(rect.width());
+ m_heightInput->setValue(rect.height());
+
+ m_gboxSettings->enableButton(EditorToolSettings::Ok, rect.isValid());
+ m_preciseCrop->setEnabled(m_imageSelectionWidget->preciseCropAvailable());
+
+ m_xInput->blockSignals(false);
+ m_yInput->blockSignals(false);
+ m_widthInput->blockSignals(false);
+ m_heightInput->blockSignals(false);
+}
+
+void RatioCropTool::setRatioCBText(int orientation)
+{
+ int item = m_ratioCB->currentItem();
+
+ m_ratioCB->blockSignals(true);
+ m_ratioCB->combo()->clear();
+ m_ratioCB->insertItem(i18n("Custom"));
+ m_ratioCB->insertItem("1:1");
+ if (orientation == ImageSelectionWidget::Landscape)
+ {
+ m_ratioCB->insertItem("3:2");
+ m_ratioCB->insertItem("4:3");
+ m_ratioCB->insertItem("5:4");
+ m_ratioCB->insertItem("7:5");
+ m_ratioCB->insertItem("10:7");
+ }
+ else
+ {
+ m_ratioCB->insertItem("2:3");
+ m_ratioCB->insertItem("3:4");
+ m_ratioCB->insertItem("4:5");
+ m_ratioCB->insertItem("5:7");
+ m_ratioCB->insertItem("7:10");
+ }
+ m_ratioCB->insertItem(i18n("Golden Ratio"));
+ m_ratioCB->insertItem(i18n("None"));
+ m_ratioCB->setCurrentItem(item);
+ m_ratioCB->blockSignals(false);
+}
+
+void RatioCropTool::slotSelectionOrientationChanged(int newOrientation)
+{
+ // Change text for Aspect ratio ComboBox
+
+ setRatioCBText(newOrientation);
+
+ // Change Orientation ComboBox
+
+ m_orientCB->setCurrentItem(newOrientation);
+
+ // Reverse custom values
+
+ if ( ( m_customRatioNInput->value() < m_customRatioDInput->value() &&
+ newOrientation == ImageSelectionWidget::Landscape) ||
+ ( m_customRatioNInput->value() > m_customRatioDInput->value() &&
+ newOrientation == ImageSelectionWidget::Portrait))
+ {
+ m_customRatioNInput->blockSignals(true);
+ m_customRatioDInput->blockSignals(true);
+
+ int tmp = m_customRatioNInput->value();
+ m_customRatioNInput->setValue(m_customRatioDInput->value());
+ m_customRatioDInput->setValue(tmp);
+
+ m_customRatioNInput->blockSignals(false);
+ m_customRatioDInput->blockSignals(false);
+ }
+}
+
+void RatioCropTool::slotXChanged(int x)
+{
+ m_imageSelectionWidget->setSelectionX(x);
+}
+
+void RatioCropTool::slotYChanged(int y)
+{
+ m_imageSelectionWidget->setSelectionY(y);
+}
+
+void RatioCropTool::slotWidthChanged(int w)
+{
+ m_imageSelectionWidget->setSelectionWidth(w);
+}
+
+void RatioCropTool::slotHeightChanged(int h)
+{
+ m_imageSelectionWidget->setSelectionHeight(h);
+}
+
+void RatioCropTool::slotPreciseCropChanged(bool a)
+{
+ m_imageSelectionWidget->setPreciseCrop(a);
+}
+
+void RatioCropTool::slotOrientChanged(int o)
+{
+ m_imageSelectionWidget->setSelectionOrientation(o);
+
+ // Reset selection area.
+ slotResetSettings();
+}
+
+void RatioCropTool::slotAutoOrientChanged(bool a)
+{
+ m_orientCB->setEnabled(!a /*|| m_ratioCB->currentItem() == ImageSelectionWidget::RATIONONE*/);
+ m_imageSelectionWidget->setAutoOrientation(a);
+}
+
+void RatioCropTool::slotRatioChanged(int a)
+{
+ applyRatioChanges(a);
+
+ // Reset selection area.
+ slotResetSettings();
+}
+
+void RatioCropTool::applyRatioChanges(int a)
+{
+ m_imageSelectionWidget->setSelectionAspectRatioType(a);
+
+ if (a == ImageSelectionWidget::RATIOCUSTOM)
+ {
+ m_customLabel1->setEnabled(true);
+ m_customLabel2->setEnabled(true);
+ m_customRatioNInput->setEnabled(true);
+ m_customRatioDInput->setEnabled(true);
+ m_orientLabel->setEnabled(true);
+ m_orientCB->setEnabled(!m_autoOrientation->isChecked());
+ m_autoOrientation->setEnabled(true);
+ slotCustomRatioChanged();
+ }
+ else if (a == ImageSelectionWidget::RATIONONE)
+ {
+ m_orientLabel->setEnabled(false);
+ m_orientCB->setEnabled(false);
+ m_autoOrientation->setEnabled(false);
+ m_customLabel1->setEnabled(false);
+ m_customLabel2->setEnabled(false);
+ m_customRatioNInput->setEnabled(false);
+ m_customRatioDInput->setEnabled(false);
+ }
+ else // Pre-config ratio selected.
+ {
+ m_orientLabel->setEnabled(true);
+ m_orientCB->setEnabled(!m_autoOrientation->isChecked());
+ m_autoOrientation->setEnabled(true);
+ m_customLabel1->setEnabled(false);
+ m_customLabel2->setEnabled(false);
+ m_customRatioNInput->setEnabled(false);
+ m_customRatioDInput->setEnabled(false);
+ }
+}
+
+void RatioCropTool::slotGuideTypeChanged(int t)
+{
+ if (t == ImageSelectionWidget::GuideNone)
+ {
+ m_goldenSectionBox->setEnabled(false);
+ m_goldenSpiralSectionBox->setEnabled(false);
+ m_goldenSpiralBox->setEnabled(false);
+ m_goldenTriangleBox->setEnabled(false);
+ m_flipHorBox->setEnabled(false);
+ m_flipVerBox->setEnabled(false);
+ m_colorGuideLabel->setEnabled(false);
+ m_guideColorBt->setEnabled(false);
+ m_guideSize->setEnabled(false);
+ }
+ else if (t == ImageSelectionWidget::RulesOfThirds)
+ {
+ m_goldenSectionBox->setEnabled(false);
+ m_goldenSpiralSectionBox->setEnabled(false);
+ m_goldenSpiralBox->setEnabled(false);
+ m_goldenTriangleBox->setEnabled(false);
+ m_flipHorBox->setEnabled(false);
+ m_flipVerBox->setEnabled(false);
+ m_colorGuideLabel->setEnabled(true);
+ m_guideColorBt->setEnabled(true);
+ m_guideSize->setEnabled(true);
+ }
+ else if (t == ImageSelectionWidget::DiagonalMethod)
+ {
+ m_goldenSectionBox->setEnabled(false);
+ m_goldenSpiralSectionBox->setEnabled(false);
+ m_goldenSpiralBox->setEnabled(false);
+ m_goldenTriangleBox->setEnabled(false);
+ m_flipHorBox->setEnabled(false);
+ m_flipVerBox->setEnabled(false);
+ m_colorGuideLabel->setEnabled(true);
+ m_guideColorBt->setEnabled(true);
+ m_guideSize->setEnabled(true);
+ }
+ else if (t == ImageSelectionWidget::HarmoniousTriangles)
+ {
+ m_goldenSectionBox->setEnabled(false);
+ m_goldenSpiralSectionBox->setEnabled(false);
+ m_goldenSpiralBox->setEnabled(false);
+ m_goldenTriangleBox->setEnabled(false);
+ m_flipHorBox->setEnabled(true);
+ m_flipVerBox->setEnabled(true);
+ m_colorGuideLabel->setEnabled(true);
+ m_guideColorBt->setEnabled(true);
+ m_guideSize->setEnabled(true);
+ }
+ else
+ {
+ m_goldenSectionBox->setEnabled(true);
+ m_goldenSpiralSectionBox->setEnabled(true);
+ m_goldenSpiralBox->setEnabled(true);
+ m_goldenTriangleBox->setEnabled(true);
+ m_flipHorBox->setEnabled(true);
+ m_flipVerBox->setEnabled(true);
+ m_colorGuideLabel->setEnabled(true);
+ m_guideColorBt->setEnabled(true);
+ m_guideSize->setEnabled(true);
+ }
+
+ m_imageSelectionWidget->setGoldenGuideTypes(m_goldenSectionBox->isChecked(),
+ m_goldenSpiralSectionBox->isChecked(),
+ m_goldenSpiralBox->isChecked(),
+ m_goldenTriangleBox->isChecked(),
+ m_flipHorBox->isChecked(),
+ m_flipVerBox->isChecked());
+ m_imageSelectionWidget->slotGuideLines(t);
+}
+
+void RatioCropTool::slotGoldenGuideTypeChanged()
+{
+ slotGuideTypeChanged(m_guideLinesCB->currentItem());
+}
+
+void RatioCropTool::slotCustomNRatioChanged(int a)
+{
+ if ( ! m_autoOrientation->isChecked() )
+ {
+ if ( ( m_orientCB->currentItem() == ImageSelectionWidget::Portrait &&
+ m_customRatioDInput->value() < a) ||
+ ( m_orientCB->currentItem() == ImageSelectionWidget::Landscape &&
+ m_customRatioDInput->value() > a))
+ {
+ m_customRatioDInput->blockSignals(true);
+ m_customRatioDInput->setValue(a);
+ m_customRatioDInput->blockSignals(false);
+ }
+ }
+
+ slotCustomRatioChanged();
+}
+
+void RatioCropTool::slotCustomDRatioChanged(int a)
+{
+ if ( ! m_autoOrientation->isChecked() )
+ {
+ if ( ( m_orientCB->currentItem() == ImageSelectionWidget::Landscape &&
+ m_customRatioNInput->value() < a) ||
+ ( m_orientCB->currentItem() == ImageSelectionWidget::Portrait &&
+ m_customRatioNInput->value() > a))
+ {
+ m_customRatioNInput->blockSignals(true);
+ m_customRatioNInput->setValue(a);
+ m_customRatioNInput->blockSignals(false);
+ }
+ }
+
+ slotCustomRatioChanged();
+}
+
+void RatioCropTool::slotCustomRatioChanged()
+{
+ m_imageSelectionWidget->setSelectionAspectRatioValue(m_customRatioNInput->value(),
+ m_customRatioDInput->value());
+
+ // Reset selection area.
+ slotResetSettings();
+}
+
+void RatioCropTool::finalRendering()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ QRect currentRegion = m_imageSelectionWidget->getRegionSelection();
+ ImageIface* iface = m_imageSelectionWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int w = iface->originalWidth();
+ int h = iface->originalHeight();
+ bool a = iface->originalHasAlpha();
+ bool sb = iface->originalSixteenBit();
+
+ QRect normalizedRegion = currentRegion.normalize();
+ if (normalizedRegion.right() > w)
+ normalizedRegion.setRight(w);
+
+ if (normalizedRegion.bottom() > h)
+ normalizedRegion.setBottom(h);
+
+ DImg imOrg(w, h, sb, a, data);
+ delete [] data;
+ imOrg.crop(normalizedRegion);
+
+ iface->putOriginalImage(i18n("Aspect Ratio Crop"), imOrg.bits(), imOrg.width(), imOrg.height());
+
+ kapp->restoreOverrideCursor();
+ writeSettings();
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/ratiocrop/ratiocroptool.h b/digikam/imageplugins/coreplugin/ratiocrop/ratiocroptool.h
new file mode 100644
index 0000000..d2adf3b
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/ratiocrop/ratiocroptool.h
@@ -0,0 +1,134 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-12-06
+ * Description : digiKam image editor Ratio Crop tool
+ *
+ * Copyright (C) 2007 by Jaromir Malenko <malenko at email dot cz>
+ * Copyright (C) 2008 by Roberto Castagnola <roberto dot castagnola at gmail dot com>
+ * Copyright (C) 2004-2009 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 RATIOCROPTOOL_H
+#define RATIOCROPTOOL_H
+
+// Digikam includes.
+
+#include "editortool.h"
+
+class QCheckBox;
+class QLabel;
+class QToolButton;
+
+class KColorButton;
+
+namespace KDcrawIface
+{
+class RComboBox;
+class RIntNumInput;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class ImageSelectionWidget;
+
+class RatioCropTool : public Digikam::EditorTool
+{
+ Q_OBJECT
+
+public:
+
+ RatioCropTool(QObject *parent);
+ ~RatioCropTool();
+
+private:
+
+ void readSettings();
+ void writeSettings();
+ void finalRendering();
+
+ void applyRatioChanges(int a);
+ void setRatioCBText(int orientation);
+
+private slots:
+
+ void slotMaxAspectRatio();
+ void slotResetSettings();
+
+ void slotCenterWidth();
+ void slotCenterHeight();
+ void slotXChanged(int x);
+ void slotYChanged(int y);
+ void slotWidthChanged(int w);
+ void slotHeightChanged(int h);
+ void slotCustomRatioChanged();
+ void slotCustomNRatioChanged(int a);
+ void slotCustomDRatioChanged(int a);
+ void slotPreciseCropChanged(bool a);
+ void slotOrientChanged(int o);
+ void slotAutoOrientChanged(bool a);
+ void slotRatioChanged(int a);
+ void slotSelectionChanged(QRect rect );
+ void slotSelectionOrientationChanged(int);
+ void slotGuideTypeChanged(int t);
+ void slotGoldenGuideTypeChanged();
+
+private:
+
+ bool m_originalIsLandscape;
+
+ QLabel *m_customLabel1;
+ QLabel *m_customLabel2;
+ QLabel *m_orientLabel;
+ QLabel *m_colorGuideLabel;
+
+
+ QToolButton *m_centerWidth;
+ QToolButton *m_centerHeight;
+
+ QCheckBox *m_goldenSectionBox;
+ QCheckBox *m_goldenSpiralSectionBox;
+ QCheckBox *m_goldenSpiralBox;
+ QCheckBox *m_goldenTriangleBox;
+ QCheckBox *m_flipHorBox;
+ QCheckBox *m_flipVerBox;
+ QCheckBox *m_autoOrientation;
+ QCheckBox *m_preciseCrop;
+
+ KDcrawIface::RComboBox *m_guideLinesCB;
+ KDcrawIface::RComboBox *m_orientCB;
+ KDcrawIface::RComboBox *m_ratioCB;
+
+ KDcrawIface::RIntNumInput *m_customRatioDInput;
+ KDcrawIface::RIntNumInput *m_customRatioNInput;
+ KDcrawIface::RIntNumInput *m_guideSize;
+ KDcrawIface::RIntNumInput *m_heightInput;
+ KDcrawIface::RIntNumInput *m_widthInput;
+ KDcrawIface::RIntNumInput *m_xInput;
+ KDcrawIface::RIntNumInput *m_yInput;
+
+ KColorButton *m_guideColorBt;
+
+ ImageSelectionWidget *m_imageSelectionWidget;
+
+ Digikam::EditorToolSettings *m_gboxSettings;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* RATIOCROPTOOL_H */
diff --git a/digikam/imageplugins/coreplugin/redeyetool.cpp b/digikam/imageplugins/coreplugin/redeyetool.cpp
new file mode 100644
index 0000000..937ba1c
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/redeyetool.cpp
@@ -0,0 +1,587 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-06-06
+ * Description : Red eyes correction tool for image editor
+ *
+ * Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qcolor.h>
+#include <qhbox.h>
+#include <qhgroupbox.h>
+#include <qvgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qcombobox.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+
+// KDE includes.
+
+#include <kapplication.h>
+#include <kcolordialog.h>
+#include <kcolordialog.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+// Digikam includes.
+
+#include "bcgmodifier.h"
+#include "colorgradientwidget.h"
+#include "dimg.h"
+#include "dimgimagefilters.h"
+#include "editortoolsettings.h"
+#include "histogramwidget.h"
+#include "imageiface.h"
+#include "imagewidget.h"
+
+// LibKDcraw includes.
+
+#include <libkdcraw/rnuminput.h>
+
+// Local includes.
+
+#include "redeyetool.h"
+#include "redeyetool.moc"
+
+using namespace KDcrawIface;
+using namespace Digikam;
+
+namespace DigikamImagesPluginCore
+{
+
+RedEyeTool::RedEyeTool(QObject* parent)
+ : EditorTool(parent)
+{
+ setName("redeye");
+ setToolName(i18n("Red Eye"));
+ setToolIcon(SmallIcon("redeyes"));
+ setToolHelp("redeyecorrectiontool.anchor");
+
+ m_destinationPreviewData = 0;
+
+ m_previewWidget = new ImageWidget("redeye Tool", 0,
+ i18n("<p>Here you can see the image selection preview with "
+ "red eye reduction applied."),
+ true, ImageGuideWidget::PickColorMode, true, true);
+ setToolView(m_previewWidget);
+
+ // -------------------------------------------------------------
+
+ EditorToolSettings *gboxSettings = new EditorToolSettings(EditorToolSettings::Default|
+ EditorToolSettings::Ok|
+ EditorToolSettings::Cancel);
+
+ QGridLayout* gridSettings = new QGridLayout(gboxSettings->plainPage(), 11, 4);
+
+ QLabel *label1 = new QLabel(i18n("Channel:"), gboxSettings->plainPage());
+ label1->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ m_channelCB = new QComboBox(false, gboxSettings->plainPage());
+ m_channelCB->insertItem(i18n("Luminosity"));
+ m_channelCB->insertItem(i18n("Red"));
+ m_channelCB->insertItem(i18n("Green"));
+ m_channelCB->insertItem(i18n("Blue"));
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red image channel values.<p>"
+ "<b>Green</b>: display the green image channel values.<p>"
+ "<b>Blue</b>: display the blue image channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(gboxSettings->plainPage());
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin(0);
+ QWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximum counts are small, you can use the linear scale.<p>"
+ "The logarithmic scale can be used when the maximal counts are big "
+ "to show all values (small and large) on the graph."));
+
+ QPushButton *linHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(linHistoButton, i18n("<p>Linear"));
+ m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap(QPixmap(directory + "histogram-lin.png"));
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(logHistoButton, i18n("<p>Logarithmic"));
+ m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap(QPixmap(directory + "histogram-log.png"));
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(gboxSettings->plainPage());
+ m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram "
+ "of the selected image channel. It is "
+ "updated upon setting changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, histoBox);
+ m_hGradient->setColors(QColor("black"), QColor("white"));
+
+ // -------------------------------------------------------------
+
+ m_thresholdLabel = new QLabel(i18n("Sensitivity:"), gboxSettings->plainPage());
+ m_redThreshold = new RIntNumInput(gboxSettings->plainPage());
+ m_redThreshold->setRange(10, 90, 1);
+ m_redThreshold->setDefaultValue(20);
+ QWhatsThis::add(m_redThreshold, i18n("<p>Sets the red color pixels selection threshold. "
+ "Low values will select more red color pixels (agressive correction), high "
+ "values less (mild correction). Use low value if eye have been selected "
+ "exactly. Use high value if other parts of the face are also selected."));
+
+ m_smoothLabel = new QLabel(i18n("Smooth:"), gboxSettings->plainPage());
+ m_smoothLevel = new RIntNumInput(gboxSettings->plainPage());
+ m_smoothLevel->setRange(0, 5, 1);
+ m_smoothLevel->setDefaultValue(1);
+ QWhatsThis::add(m_smoothLevel, i18n("<p>Sets the smoothness value when blurring the border "
+ "of the changed pixels. "
+ "This leads to a more naturally looking pupil."));
+
+ QLabel *label3 = new QLabel(i18n("Coloring Tint:"), gboxSettings->plainPage());
+ m_HSSelector = new KHSSelector(gboxSettings->plainPage());
+ m_VSelector = new KValueSelector(gboxSettings->plainPage());
+ m_HSSelector->setMinimumSize(200, 142);
+ m_VSelector->setMinimumSize(26, 142);
+ QWhatsThis::add(m_HSSelector, i18n("<p>Sets a custom color to re-colorize the eyes."));
+
+ QLabel *label4 = new QLabel(i18n("Tint Level:"), gboxSettings->plainPage());
+ m_tintLevel = new RIntNumInput(gboxSettings->plainPage());
+ m_tintLevel->setRange(1, 200, 1);
+ m_tintLevel->setDefaultValue(128);
+ QWhatsThis::add(m_tintLevel, i18n("<p>Set the tint level to adjust the luminosity of "
+ "the new color of the pupil."));
+
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4);
+ gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4);
+ gridSettings->addMultiCellWidget(m_thresholdLabel, 3, 3, 0, 4);
+ gridSettings->addMultiCellWidget(m_redThreshold, 4, 4, 0, 4);
+ gridSettings->addMultiCellWidget(m_smoothLabel, 5, 5, 0, 4);
+ gridSettings->addMultiCellWidget(m_smoothLevel, 6, 6, 0, 4);
+ gridSettings->addMultiCellWidget(label3, 7, 7, 0, 4);
+ gridSettings->addMultiCellWidget(m_HSSelector, 8, 8, 0, 3);
+ gridSettings->addMultiCellWidget(m_VSelector, 8, 8, 4, 4);
+ gridSettings->addMultiCellWidget(label4, 9, 9, 0, 4);
+ gridSettings->addMultiCellWidget(m_tintLevel, 10, 10, 0, 4);
+ gridSettings->setRowStretch(11, 10);
+ gridSettings->setColStretch(3, 10);
+
+ setToolSettings(gboxSettings);
+ init();
+
+ // -------------------------------------------------------------
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget(const Digikam::DColor&, const QPoint&)),
+ this, SLOT(slotColorSelectedFromTarget(const Digikam::DColor&)));
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+
+ connect(m_redThreshold, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_smoothLevel, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_HSSelector, SIGNAL(valueChanged(int, int)),
+ this, SLOT(slotHSChanged(int, int)));
+
+ connect(m_VSelector, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_tintLevel, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTimer()));
+}
+
+RedEyeTool::~RedEyeTool()
+{
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+}
+
+void RedEyeTool::slotHSChanged(int h, int s)
+{
+ m_VSelector->blockSignals(true);
+ m_VSelector->setHue(h);
+ m_VSelector->setSaturation(s);
+ m_VSelector->updateContents();
+ m_VSelector->repaint(false);
+ m_VSelector->blockSignals(false);
+ slotTimer();
+}
+
+void RedEyeTool::slotChannelChanged(int channel)
+{
+ switch (channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::ValueHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("white"));
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("red"));
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("green"));
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("blue"));
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void RedEyeTool::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+}
+
+void RedEyeTool::slotColorSelectedFromTarget(const DColor& color)
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void RedEyeTool::readSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("redeye Tool");
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", HistogramWidget::LogScaleHistogram));
+ m_redThreshold->setValue(config->readNumEntry("RedThreshold", m_redThreshold->defaultValue()));
+ m_smoothLevel->setValue(config->readNumEntry("SmoothLevel", m_smoothLevel->defaultValue()));
+ m_HSSelector->setXValue(config->readNumEntry("HueColoringTint", 0));
+ m_HSSelector->setYValue(config->readNumEntry("SatColoringTint", 0));
+ m_VSelector->setValue(config->readNumEntry("ValColoringTint", 0));
+ m_tintLevel->setValue(config->readNumEntry("TintLevel", m_tintLevel->defaultValue()));
+
+ slotHSChanged(m_HSSelector->xValue(), m_HSSelector->yValue());
+ m_histogramWidget->reset();
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+}
+
+void RedEyeTool::writeSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("redeye Tool");
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writeEntry("RedThreshold", m_redThreshold->value());
+ config->writeEntry("SmoothLevel", m_smoothLevel->value());
+ config->writeEntry("HueColoringTint", m_HSSelector->xValue());
+ config->writeEntry("SatColoringTint", m_HSSelector->yValue());
+ config->writeEntry("ValColoringTint", m_VSelector->value());
+ config->writeEntry("TintLevel", m_tintLevel->value());
+ m_previewWidget->writeSettings();
+ config->sync();
+}
+
+void RedEyeTool::slotResetSettings()
+{
+ m_redThreshold->blockSignals(true);
+ m_HSSelector->blockSignals(true);
+ m_VSelector->blockSignals(true);
+ m_tintLevel->blockSignals(true);
+
+ m_redThreshold->slotReset();
+ m_smoothLevel->slotReset();
+
+ // Black color by default
+ m_HSSelector->setXValue(0);
+ m_HSSelector->setYValue(0);
+ m_VSelector->setValue(0);
+
+ m_tintLevel->slotReset();
+
+ m_redThreshold->blockSignals(false);
+ m_HSSelector->blockSignals(false);
+ m_VSelector->blockSignals(false);
+ m_tintLevel->blockSignals(false);
+}
+
+void RedEyeTool::slotEffect()
+{
+ kapp->setOverrideCursor(KCursor::waitCursor());
+
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ // Here, we need to use the real selection image data because we will apply
+ // a Gaussian blur filter on pixels and we cannot use directly the preview scaled image
+ // else the blur radius will not give the same result between preview and final rendering.
+ ImageIface* iface = m_previewWidget->imageIface();
+ m_destinationPreviewData = iface->getImageSelection();
+ int w = iface->selectedWidth();
+ int h = iface->selectedHeight();
+ bool sb = iface->originalSixteenBit();
+ bool a = iface->originalHasAlpha();
+ DImg selection(w, h, sb, a, m_destinationPreviewData);
+
+ redEyeFilter(selection);
+
+ DImg preview = selection.smoothScale(iface->previewWidth(), iface->previewHeight());
+
+ iface->putPreviewImage(preview.bits());
+ m_previewWidget->updatePreview();
+
+ // Update histogram.
+
+ memcpy(m_destinationPreviewData, selection.bits(), selection.numBytes());
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false);
+
+ kapp->restoreOverrideCursor();
+}
+
+void RedEyeTool::finalRendering()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ ImageIface* iface = m_previewWidget->imageIface();
+ uchar *data = iface->getImageSelection();
+ int w = iface->selectedWidth();
+ int h = iface->selectedHeight();
+ bool sixteenBit = iface->originalSixteenBit();
+ bool hasAlpha = iface->originalHasAlpha();
+ DImg selection(w, h, sixteenBit, hasAlpha, data);
+ delete [] data;
+
+ redEyeFilter(selection);
+
+ iface->putImageSelection(i18n("Red Eyes Correction"), selection.bits());
+
+ kapp->restoreOverrideCursor();
+}
+
+void RedEyeTool::redEyeFilter(DImg& selection)
+{
+ DImg mask(selection.width(), selection.height(), selection.sixteenBit(), true,
+ selection.bits(), true);
+
+ selection = mask.copy();
+ float redThreshold = m_redThreshold->value()/10.0;
+ int hue = m_HSSelector->xValue();
+ int sat = m_HSSelector->yValue();
+ int val = m_VSelector->value();
+ KColor coloring;
+ coloring.setHsv(hue, sat, val);
+
+ struct channel
+ {
+ float red_gain;
+ float green_gain;
+ float blue_gain;
+ };
+
+ channel red_chan, green_chan, blue_chan;
+
+ red_chan.red_gain = 0.1;
+ red_chan.green_gain = 0.6;
+ red_chan.blue_gain = 0.3;
+
+ green_chan.red_gain = 0.0;
+ green_chan.green_gain = 1.0;
+ green_chan.blue_gain = 0.0;
+
+ blue_chan.red_gain = 0.0;
+ blue_chan.green_gain = 0.0;
+ blue_chan.blue_gain = 1.0;
+
+ float red_norm, green_norm, blue_norm;
+ int level = 201 - m_tintLevel->value();
+
+ red_norm = 1.0 / (red_chan.red_gain + red_chan.green_gain + red_chan.blue_gain);
+ green_norm = 1.0 / (green_chan.red_gain + green_chan.green_gain + green_chan.blue_gain);
+ blue_norm = 1.0 / (blue_chan.red_gain + blue_chan.green_gain + blue_chan.blue_gain);
+
+ red_norm *= coloring.red() / level;
+ green_norm *= coloring.green() / level;
+ blue_norm *= coloring.blue() / level;
+
+ // Perform a red color pixels detection in selection image and create a correction mask using an alpha channel.
+
+ if (!selection.sixteenBit()) // 8 bits image.
+ {
+ uchar* ptr = selection.bits();
+ uchar* mptr = mask.bits();
+ uchar r, g, b, r1, g1, b1;
+
+ for (uint i = 0 ; i < selection.width() * selection.height() ; i++)
+ {
+ b = ptr[0];
+ g = ptr[1];
+ r = ptr[2];
+ mptr[3] = 255;
+
+ if (r >= ( redThreshold * g))
+ {
+ r1 = QMIN(255, (int)(red_norm * (red_chan.red_gain * r +
+ red_chan.green_gain * g +
+ red_chan.blue_gain * b)));
+
+ g1 = QMIN(255, (int)(green_norm * (green_chan.red_gain * r +
+ green_chan.green_gain * g +
+ green_chan.blue_gain * b)));
+
+ b1 = QMIN(255, (int)(blue_norm * (blue_chan.red_gain * r +
+ blue_chan.green_gain * g +
+ blue_chan.blue_gain * b)));
+
+ mptr[0] = b1;
+ mptr[1] = g1;
+ mptr[2] = r1;
+ mptr[3] = QMIN( (int)((r-g) / 150.0 * 255.0), 255);
+ }
+
+ ptr += 4;
+ mptr+= 4;
+ }
+ }
+ else // 16 bits image.
+ {
+ unsigned short* ptr = (unsigned short*)selection.bits();
+ unsigned short* mptr = (unsigned short*)mask.bits();
+ unsigned short r, g, b, r1, g1, b1;
+
+ for (uint i = 0 ; i < selection.width() * selection.height() ; i++)
+ {
+ b = ptr[0];
+ g = ptr[1];
+ r = ptr[2];
+ mptr[3] = 65535;
+
+ if (r >= ( redThreshold * g))
+ {
+ r1 = QMIN(65535, (int)(red_norm * (red_chan.red_gain * r +
+ red_chan.green_gain * g +
+ red_chan.blue_gain * b)));
+
+ g1 = QMIN(65535, (int)(green_norm * (green_chan.red_gain * r +
+ green_chan.green_gain * g +
+ green_chan.blue_gain * b)));
+
+ b1 = QMIN(65535, (int)(blue_norm * (blue_chan.red_gain * r +
+ blue_chan.green_gain * g +
+ blue_chan.blue_gain * b)));
+
+ mptr[0] = b1;
+ mptr[1] = g1;
+ mptr[2] = r1;
+ mptr[3] = QMIN( (int)((r-g) / 38400.0 * 65535.0), 65535);;
+ }
+
+ ptr += 4;
+ mptr+= 4;
+ }
+ }
+
+ // Now, we will blur only the transparency pixels from the mask.
+
+ DImg mask2 = mask.copy();
+ DImgImageFilters filter;
+ filter.gaussianBlurImage(mask2.bits(), mask2.width(), mask2.height(),
+ mask2.sixteenBit(), m_smoothLevel->value());
+
+ if (!selection.sixteenBit()) // 8 bits image.
+ {
+ uchar* mptr = mask.bits();
+ uchar* mptr2 = mask2.bits();
+
+ for (uint i = 0 ; i < mask2.width() * mask2.height() ; i++)
+ {
+ if (mptr2[3] < 255)
+ {
+ mptr[0] = mptr2[0];
+ mptr[1] = mptr2[1];
+ mptr[2] = mptr2[2];
+ mptr[3] = mptr2[3];
+ }
+
+ mptr += 4;
+ mptr2+= 4;
+ }
+ }
+ else // 16 bits image.
+ {
+ unsigned short* mptr = (unsigned short*)mask.bits();
+ unsigned short* mptr2 = (unsigned short*)mask2.bits();
+
+ for (uint i = 0 ; i < mask2.width() * mask2.height() ; i++)
+ {
+ if (mptr2[3] < 65535)
+ {
+ mptr[0] = mptr2[0];
+ mptr[1] = mptr2[1];
+ mptr[2] = mptr2[2];
+ mptr[3] = mptr2[3];
+ }
+
+ mptr += 4;
+ mptr2+= 4;
+ }
+ }
+
+ // - Perform pixels blending using alpha channel between the mask and the selection.
+
+ DColorComposer *composer = DColorComposer::getComposer(DColorComposer::PorterDuffSrcOver);
+
+ // NOTE: 'mask' is the Source image, 'selection' is the Destination image.
+
+ selection.bitBlendImage(composer, &mask,
+ 0, 0, mask.width(), mask.height(),
+ 0, 0);
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/redeyetool.h b/digikam/imageplugins/coreplugin/redeyetool.h
new file mode 100644
index 0000000..aa9d048
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/redeyetool.h
@@ -0,0 +1,156 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-06-06
+ * Description : Red eyes correction tool for image editor
+ *
+ * Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * 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 REDEYETOOL_H
+#define REDEYETOOL_H
+
+// KDE includes.
+
+#include <kpassivepopup.h>
+
+// Digikam includes.
+
+#include "editortool.h"
+
+class QLabel;
+class QComboBox;
+class QHButtonGroup;
+
+class KHSSelector;
+class KValueSelector;
+
+namespace KDcrawIface
+{
+class RIntNumInput;
+}
+
+namespace Digikam
+{
+class HistogramWidget;
+class ColorGradientWidget;
+class ImageWidget;
+class DColor;
+class DImg;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class RedEyePassivePopup : public KPassivePopup
+{
+public:
+
+ RedEyePassivePopup(QWidget* parent)
+ : KPassivePopup(parent), m_parent(parent)
+ {
+ }
+
+protected:
+
+ virtual void positionSelf()
+ {
+ move(m_parent->x() + 30, m_parent->y() + 30);
+ }
+
+private:
+
+ QWidget* m_parent;
+};
+
+// ----------------------------------------------------------------
+
+class RedEyeTool : public Digikam::EditorTool
+{
+ Q_OBJECT
+
+public:
+
+ RedEyeTool(QObject *parent);
+ ~RedEyeTool();
+
+private slots:
+
+ void slotEffect();
+ void slotResetSettings();
+ void slotChannelChanged(int channel);
+ void slotScaleChanged(int scale);
+ void slotColorSelectedFromTarget(const Digikam::DColor &color);
+ void slotHSChanged(int h, int s);
+
+private:
+
+ void readSettings();
+ void writeSettings();
+ void finalRendering();
+ void redEyeFilter(Digikam::DImg& selection);
+
+private:
+
+ enum HistogramScale
+ {
+ Linear=0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel=0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ enum RedThresold
+ {
+ Mild=0,
+ Aggressive
+ };
+
+ uchar *m_destinationPreviewData;
+
+ QLabel *m_thresholdLabel;
+ QLabel *m_smoothLabel;
+
+ QComboBox *m_channelCB;
+
+ QHButtonGroup *m_scaleBG;
+
+ KDcrawIface::RIntNumInput *m_tintLevel;
+ KDcrawIface::RIntNumInput *m_redThreshold;
+ KDcrawIface::RIntNumInput *m_smoothLevel;
+
+ KHSSelector *m_HSSelector;
+ KValueSelector *m_VSelector;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* REDEYETOOL_H */
diff --git a/digikam/imageplugins/coreplugin/rgbtool.cpp b/digikam/imageplugins/coreplugin/rgbtool.cpp
new file mode 100644
index 0000000..629d65e
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/rgbtool.cpp
@@ -0,0 +1,440 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-11
+ * Description : digiKam image editor Color Balance tool.
+ *
+ * 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.
+ *
+ * ============================================================ */
+
+// Qt includes.
+
+#include <qcheckbox.h>
+#include <qcolor.h>
+#include <qcombobox.h>
+#include <qframe.h>
+#include <qgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qhgroupbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qslider.h>
+#include <qtooltip.h>
+#include <qvbox.h>
+#include <qvgroupbox.h>
+#include <qwhatsthis.h>
+
+// KDE includes.
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kcursor.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+// LibKDcraw includes.
+
+#include <libkdcraw/rnuminput.h>
+
+// Digikam includes.
+
+#include "colorgradientwidget.h"
+#include "colormodifier.h"
+#include "dimg.h"
+#include "editortoolsettings.h"
+#include "histogramwidget.h"
+#include "imageiface.h"
+#include "imagewidget.h"
+
+// Local includes.
+
+#include "rgbtool.h"
+#include "rgbtool.moc"
+
+using namespace KDcrawIface;
+using namespace Digikam;
+
+namespace DigikamImagesPluginCore
+{
+
+RGBTool::RGBTool(QObject* parent)
+ : EditorTool(parent)
+{
+ setName("colorbalance");
+ setToolName(i18n("Color Balance"));
+ setToolIcon(SmallIcon("adjustrgb"));
+
+ m_destinationPreviewData = 0;
+
+ m_previewWidget = new ImageWidget("colorbalance Tool", 0,
+ i18n("<p>Here you can see the image "
+ "color-balance adjustments preview. "
+ "You can pick color on image "
+ "to see the color level corresponding on histogram."));
+ setToolView(m_previewWidget);
+
+ // -------------------------------------------------------------
+
+ m_gboxSettings = new EditorToolSettings(EditorToolSettings::Default|
+ EditorToolSettings::Ok|
+ EditorToolSettings::Cancel);
+
+ QGridLayout* gridSettings = new QGridLayout(m_gboxSettings->plainPage(), 7, 4);
+
+ QLabel *label1 = new QLabel(i18n("Channel:"), m_gboxSettings->plainPage());
+ label1->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ m_channelCB = new QComboBox(false, m_gboxSettings->plainPage());
+ m_channelCB->insertItem(i18n("Luminosity"));
+ m_channelCB->insertItem(i18n("Red"));
+ m_channelCB->insertItem(i18n("Green"));
+ m_channelCB->insertItem(i18n("Blue"));
+ QWhatsThis::add( m_channelCB, i18n("<p>Select the histogram channel to display here:<p>"
+ "<b>Luminosity</b>: display the image's luminosity values.<p>"
+ "<b>Red</b>: display the red image-channel values.<p>"
+ "<b>Green</b>: display the green image-channel values.<p>"
+ "<b>Blue</b>: display the blue image-channel values.<p>"));
+
+ m_scaleBG = new QHButtonGroup(m_gboxSettings->plainPage());
+ m_scaleBG->setExclusive(true);
+ m_scaleBG->setFrameShape(QFrame::NoFrame);
+ m_scaleBG->setInsideMargin(0);
+ QWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>"
+ "If the image's maximal counts are small, you can use the linear scale.<p>"
+ "Logarithmic scale can be used when the maximal counts are big; "
+ "if it is used, all values (small and large) will be visible on the graph."));
+
+ QPushButton *linHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(linHistoButton, i18n("<p>Linear"));
+ m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-lin", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ QString directory = KGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png");
+ linHistoButton->setPixmap(QPixmap(directory + "histogram-lin.png"));
+ linHistoButton->setToggleButton(true);
+
+ QPushButton *logHistoButton = new QPushButton(m_scaleBG);
+ QToolTip::add(logHistoButton, i18n("<p>Logarithmic"));
+ m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram);
+ KGlobal::dirs()->addResourceType("histogram-log", KGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = KGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png");
+ logHistoButton->setPixmap(QPixmap(directory + "histogram-log.png"));
+ logHistoButton->setToggleButton(true);
+
+ QHBoxLayout* l1 = new QHBoxLayout();
+ l1->addWidget(label1);
+ l1->addWidget(m_channelCB);
+ l1->addStretch(10);
+ l1->addWidget(m_scaleBG);
+
+ gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4);
+
+ // -------------------------------------------------------------
+
+ QVBox *histoBox = new QVBox(m_gboxSettings->plainPage());
+ m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true);
+ QWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram drawing "
+ "of the selected image channel. This one is re-computed at any "
+ "settings changes."));
+ QLabel *space = new QLabel(histoBox);
+ space->setFixedHeight(1);
+ m_hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, histoBox);
+ m_hGradient->setColors(QColor("black"), QColor("white"));
+
+ gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4);
+
+ // -------------------------------------------------------------
+
+ QLabel *labelLeft = new QLabel(i18n("Cyan"), m_gboxSettings->plainPage());
+ labelLeft->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ m_rSlider = new QSlider(-100, 100, 1, 0, Qt::Horizontal, m_gboxSettings->plainPage(), "m_rSlider");
+ m_rSlider->setTickmarks(QSlider::Below);
+ m_rSlider->setTickInterval(20);
+ QWhatsThis::add( m_rSlider, i18n("<p>Set here the cyan/red color adjustment of the image."));
+ QLabel *labelRight = new QLabel(i18n("Red"), m_gboxSettings->plainPage());
+ labelRight->setAlignment ( Qt::AlignLeft | Qt::AlignVCenter );
+ m_rInput = new RIntNumInput(m_gboxSettings->plainPage());
+ m_rInput->setDefaultValue(0);
+ m_rInput->input()->setRange(-100, 100, 1, false);
+
+ gridSettings->addMultiCellWidget(labelLeft, 3, 3, 0, 0);
+ gridSettings->addMultiCellWidget(m_rSlider, 3, 3, 1, 1);
+ gridSettings->addMultiCellWidget(labelRight, 3, 3, 2, 2);
+ gridSettings->addMultiCellWidget(m_rInput, 3, 3, 3, 3);
+
+ // -------------------------------------------------------------
+
+ labelLeft = new QLabel(i18n("Magenta"), m_gboxSettings->plainPage());
+ labelLeft->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ m_gSlider = new QSlider(-100, 100, 1, 0, Qt::Horizontal, m_gboxSettings->plainPage(), "m_gSlider");
+ m_gSlider->setTickmarks(QSlider::Below);
+ m_gSlider->setTickInterval(20);
+ QWhatsThis::add( m_gSlider, i18n("<p>Set here the magenta/green color adjustment of the image."));
+ labelRight = new QLabel(i18n("Green"), m_gboxSettings->plainPage());
+ labelRight->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ m_gInput = new RIntNumInput(m_gboxSettings->plainPage());
+ m_gInput->setDefaultValue(0);
+ m_gInput->input()->setRange(-100, 100, 1, false);
+
+ gridSettings->addMultiCellWidget(labelLeft, 4, 4, 0, 0);
+ gridSettings->addMultiCellWidget(m_gSlider, 4, 4, 1, 1);
+ gridSettings->addMultiCellWidget(labelRight, 4, 4, 2, 2);
+ gridSettings->addMultiCellWidget(m_gInput, 4, 4, 3, 3);
+
+ // -------------------------------------------------------------
+
+ labelLeft = new QLabel(i18n("Yellow"), m_gboxSettings->plainPage());
+ labelLeft->setAlignment ( Qt::AlignRight | Qt::AlignVCenter );
+ m_bSlider = new QSlider(-100, 100, 1, 0, Qt::Horizontal, m_gboxSettings->plainPage(), "m_bSlider");
+ m_bSlider->setTickmarks(QSlider::Below);
+ m_bSlider->setTickInterval(20);
+ QWhatsThis::add( m_bSlider, i18n("<p>Set here the yellow/blue color adjustment of the image."));
+ labelRight = new QLabel(i18n("Blue"), m_gboxSettings->plainPage());
+ labelRight->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ m_bInput = new RIntNumInput(m_gboxSettings->plainPage());
+ m_bInput->setDefaultValue(0);
+ m_bInput->input()->setRange(-100, 100, 1, false);
+
+ gridSettings->addMultiCellWidget(labelLeft, 5, 5, 0, 0);
+ gridSettings->addMultiCellWidget(m_bSlider, 5, 5, 1, 1);
+ gridSettings->addMultiCellWidget(labelRight, 5, 5, 2, 2);
+ gridSettings->addMultiCellWidget(m_bInput, 5, 5, 3, 3);
+
+ m_rInput->setValue(0);
+ m_gInput->setValue(0);
+ m_bInput->setValue(0);
+
+ gridSettings->setRowStretch(6, 10);
+ setToolSettings(m_gboxSettings);
+ init();
+
+ // -------------------------------------------------------------
+
+ connect(m_channelCB, SIGNAL(activated(int)),
+ this, SLOT(slotChannelChanged(int)));
+
+ connect(m_scaleBG, SIGNAL(released(int)),
+ this, SLOT(slotScaleChanged(int)));
+
+ connect(m_previewWidget, SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const QPoint & )),
+ this, SLOT(slotColorSelectedFromTarget( const Digikam::DColor & )));
+
+ connect(m_rSlider, SIGNAL(valueChanged(int)),
+ m_rInput, SLOT(setValue(int)));
+ connect(m_rInput, SIGNAL(valueChanged (int)),
+ m_rSlider, SLOT(setValue(int)));
+ connect(m_rInput, SIGNAL(valueChanged (int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_gSlider, SIGNAL(valueChanged(int)),
+ m_gInput, SLOT(setValue(int)));
+ connect(m_gInput, SIGNAL(valueChanged (int)),
+ m_gSlider, SLOT(setValue(int)));
+ connect(m_gInput, SIGNAL(valueChanged (int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_bSlider, SIGNAL(valueChanged(int)),
+ m_bInput, SLOT(setValue(int)));
+ connect(m_bInput, SIGNAL(valueChanged (int)),
+ m_bSlider, SLOT(setValue(int)));
+ connect(m_bInput, SIGNAL(valueChanged (int)),
+ this, SLOT(slotTimer()));
+
+ connect(m_previewWidget, SIGNAL(signalResized()),
+ this, SLOT(slotEffect()));
+
+ // -------------------------------------------------------------
+
+ m_gboxSettings->enableButton(EditorToolSettings::Ok, false);
+}
+
+RGBTool::~RGBTool()
+{
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+}
+
+void RGBTool::slotChannelChanged(int channel)
+{
+ switch (channel)
+ {
+ case LuminosityChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::ValueHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("white"));
+ break;
+
+ case RedChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("red"));
+ break;
+
+ case GreenChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("green"));
+ break;
+
+ case BlueChannel:
+ m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram;
+ m_hGradient->setColors(QColor("black"), QColor("blue"));
+ break;
+ }
+
+ m_histogramWidget->repaint(false);
+}
+
+void RGBTool::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+}
+
+void RGBTool::slotColorSelectedFromTarget(const DColor &color)
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void RGBTool::readSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("colorbalance Tool");
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", HistogramWidget::LogScaleHistogram));
+ int r = config->readNumEntry("RedAjustment", m_rInput->defaultValue());
+ int g = config->readNumEntry("GreenAjustment", m_gInput->defaultValue());
+ int b = config->readNumEntry("BlueAjustment", m_bInput->defaultValue());
+ adjustSliders(r, g, b);
+ m_histogramWidget->reset();
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+}
+
+void RGBTool::writeSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("colorbalance Tool");
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+ config->writeEntry("RedAjustment", m_rSlider->value());
+ config->writeEntry("GreenAjustment", m_gInput->value());
+ config->writeEntry("BlueAjustment", m_bInput->value());
+ m_previewWidget->writeSettings();
+ config->sync();
+}
+
+void RGBTool::slotResetSettings()
+{
+ int r = m_rInput->defaultValue();
+ int g = m_gInput->defaultValue();
+ int b = m_bInput->defaultValue();
+
+ adjustSliders(r, g, b);
+}
+
+void RGBTool::adjustSliders(int r, int g, int b)
+{
+ m_rSlider->blockSignals(true);
+ m_gSlider->blockSignals(true);
+ m_bSlider->blockSignals(true);
+ m_rInput->blockSignals(true);
+ m_gInput->blockSignals(true);
+ m_bInput->blockSignals(true);
+
+ m_rSlider->setValue(r);
+ m_gSlider->setValue(g);
+ m_bSlider->setValue(b);
+ m_rInput->setValue(r);
+ m_gInput->setValue(g);
+ m_bInput->setValue(b);
+
+ m_rSlider->blockSignals(false);
+ m_gSlider->blockSignals(false);
+ m_bSlider->blockSignals(false);
+ m_rInput->blockSignals(false);
+ m_gInput->blockSignals(false);
+ m_bInput->blockSignals(false);
+
+ slotEffect();
+}
+
+void RGBTool::slotEffect()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ m_gboxSettings->enableButton(EditorToolSettings::Ok,
+ (m_rInput->value() != 0 ||
+ m_gInput->value() != 0 ||
+ m_bInput->value() != 0));
+
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ ImageIface* iface = m_previewWidget->imageIface();
+ m_destinationPreviewData = iface->getPreviewImage();
+ int w = iface->previewWidth();
+ int h = iface->previewHeight();
+ bool alpha = iface->previewHasAlpha();
+ bool sixteenBit = iface->previewSixteenBit();
+
+ double r = ((double) m_rInput->value() + 100.0) / 100.0;
+ double g = ((double) m_gInput->value() + 100.0) / 100.0;
+ double b = ((double) m_bInput->value() + 100.0) / 100.0;
+ double a = 1.0;
+
+ DImg preview(w, h, sixteenBit, alpha, m_destinationPreviewData);
+ ColorModifier cmod;
+ cmod.applyColorModifier(preview, r, g, b, a);
+ iface->putPreviewImage(preview.bits());
+
+ m_previewWidget->updatePreview();
+
+ // Update histogram.
+
+ memcpy(m_destinationPreviewData, preview.bits(), preview.numBytes());
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sixteenBit, 0, 0, 0, false);
+
+ kapp->restoreOverrideCursor();
+}
+
+void RGBTool::finalRendering()
+{
+ kapp->setOverrideCursor( KCursor::waitCursor() );
+
+ double r = ((double) m_rInput->value() + 100.0) / 100.0;
+ double g = ((double) m_gInput->value() + 100.0) / 100.0;
+ double b = ((double) m_bInput->value() + 100.0) / 100.0;
+ double a = 1.0;
+
+ ImageIface* iface = m_previewWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int w = iface->originalWidth();
+ int h = iface->originalHeight();
+ bool alpha = iface->originalHasAlpha();
+ bool sixteenBit = iface->originalSixteenBit();
+ DImg original(w, h, sixteenBit, alpha, data);
+ delete [] data;
+
+ ColorModifier cmod;
+ cmod.applyColorModifier(original, r, g, b, a);
+
+ iface->putOriginalImage(i18n("Color Balance"), original.bits());
+ kapp->restoreOverrideCursor();
+}
+
+} // NameSpace DigikamImagesPluginCore
+
diff --git a/digikam/imageplugins/coreplugin/rgbtool.h b/digikam/imageplugins/coreplugin/rgbtool.h
new file mode 100644
index 0000000..9b635e3
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/rgbtool.h
@@ -0,0 +1,118 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-11
+ * Description : digiKam image editor Color Balance tool.
+ *
+ * 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 RGBTOOL_H
+#define RGBTOOL_H
+
+// Digikam includes.
+
+#include "editortool.h"
+
+class QComboBox;
+class QHButtonGroup;
+
+class QSlider;
+
+namespace KDcrawIface
+{
+class RIntNumInput;
+}
+
+namespace Digikam
+{
+class HistogramWidget;
+class ColorGradientWidget;
+class ImageWidget;
+class DColor;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class RGBTool : public Digikam::EditorTool
+{
+ Q_OBJECT
+
+public:
+
+ RGBTool(QObject *parent);
+ ~RGBTool();
+
+private:
+
+ void writeSettings();
+ void readSettings();
+ void adjustSliders(int r, int g, int b);
+ void finalRendering();
+
+private slots:
+
+ void slotEffect();
+ void slotResetSettings();
+ void slotChannelChanged(int channel);
+ void slotScaleChanged(int scale);
+ void slotColorSelectedFromTarget( const Digikam::DColor &color );
+
+private:
+
+ enum HistogramScale
+ {
+ Linear=0,
+ Logarithmic
+ };
+
+ enum ColorChannel
+ {
+ LuminosityChannel=0,
+ RedChannel,
+ GreenChannel,
+ BlueChannel
+ };
+
+ uchar *m_destinationPreviewData;
+
+ QComboBox *m_channelCB;
+
+ QHButtonGroup *m_scaleBG;
+
+ KDcrawIface::RIntNumInput *m_rInput;
+ KDcrawIface::RIntNumInput *m_gInput;
+ KDcrawIface::RIntNumInput *m_bInput;
+
+ QSlider *m_rSlider;
+ QSlider *m_gSlider;
+ QSlider *m_bSlider;
+
+ Digikam::ImageWidget *m_previewWidget;
+
+ Digikam::ColorGradientWidget *m_hGradient;
+
+ Digikam::HistogramWidget *m_histogramWidget;
+
+ Digikam::EditorToolSettings *m_gboxSettings;
+
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* RGBTOOL_H */
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/Makefile.am b/digikam/imageplugins/coreplugin/sharpnesseditor/Makefile.am
new file mode 100644
index 0000000..39cc3a2
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/Makefile.am
@@ -0,0 +1,32 @@
+SUBDIRS = clapack
+COMPILE_FIRST = clapack
+
+noinst_LTLIBRARIES = libsharpnesseditor.la
+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 \
+ -I$(top_srcdir)/digikam/imageplugins/coreplugin/sharpnesseditor/clapack \
+ $(LIBKDCRAW_CFLAGS) \
+ $(all_includes)
+
+libsharpnesseditor_la_LIBADD = $(top_builddir)/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/liblapack.la
+
+libsharpnesseditor_la_SOURCES = sharpentool.cpp unsharp.cpp matrix.cpp refocus.cpp
+
+libsharpnesseditor_la_LDFLAGS = $(all_libraries)
+
+noinst_HEADERS = sharpentool.h unsharp.h matrix.h refocus.h
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/LICENCE b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/LICENCE
new file mode 100644
index 0000000..a338f86
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/LICENCE
@@ -0,0 +1,12 @@
+REDISTRIBUTABLE
+
+LAPACK is a freely-available software package. It is available from netlib via anonymous ftp and the World Wide Web.
+Thus, it can be included in commercial software packages (and has been). We only ask that proper credit be given to the authors.
+
+Like all software, it is copyrighted. It is not trademarked, but we do ask the following:
+
+If you modify the source for these routines we ask that you change the name of the routine
+and comment the changes made to the original.
+
+We will gladly answer any questions regarding the software. If a modification is done, however,
+it is the responsibility of the person who modified the routine to provide support.
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/Makefile.am b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/Makefile.am
new file mode 100644
index 0000000..bf47855
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/Makefile.am
@@ -0,0 +1,7 @@
+noinst_LTLIBRARIES = liblapack.la
+
+liblapack_la_CFLAGS = -w
+
+noinst_HEADERS = blaswrap.h clapack.h f2c.h fio.h fmt.h fp.h
+
+liblapack_la_SOURCES = abort_.c dgesv.c dlaswp.c endfile.c idamax.c open.c sig_die.c wref.c close.c dgetf2.c dscal.c err.c ieeeck.c s_cmp.c s_stop.c wrtfmt.c dgemm.c dgetrf.c dswap.c fmt.c ilaenv.c s_copy.c wsfe.c dger.c dgetrs.c dtrsm.c fmtlib.c lsame.c sfe.c util.c xerbla.c
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/README b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/README
new file mode 100644
index 0000000..530f73e
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/README
@@ -0,0 +1,2 @@
+The sources in this directory were copied from the CLAPACK
+distribution (see http://www.netlib.org/clapack).
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/abort_.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/abort_.c
new file mode 100644
index 0000000..889c89f
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/abort_.c
@@ -0,0 +1,16 @@
+#include "stdio.h"
+#include "f2c.h"
+
+#ifdef KR_headers
+extern VOID sig_die();
+
+int abort_()
+#else
+extern void sig_die(char*,int);
+
+int abort_(void)
+#endif
+{
+sig_die("Fortran abort routine called", 1);
+return 0; /* not reached */
+}
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/blaswrap.h b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/blaswrap.h
new file mode 100644
index 0000000..84c08d3
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/blaswrap.h
@@ -0,0 +1,158 @@
+/* CLAPACK 3.0 BLAS wrapper macros
+ * Feb 5, 2000
+ */
+
+#ifndef __BLASWRAP_H
+#define __BLASWRAP_H
+
+#ifndef NO_BLAS_WRAP
+
+/* BLAS1 routines */
+#define srotg_ f2c_srotg
+#define drotg_ f2c_drotg
+#define srotmg_ f2c_srotmg
+#define drotmg_ f2c_drotmg
+#define srot_ f2c_srot
+#define drot_ f2c_drot
+#define srotm_ f2c_srotm
+#define drotm_ f2c_drotm
+#define sswap_ f2c_sswap
+#define dswap_ f2c_dswap
+#define cswap_ f2c_cswap
+#define zswap_ f2c_zswap
+#define sscal_ f2c_sscal
+#define dscal_ f2c_dscal
+#define cscal_ f2c_cscal
+#define zscal_ f2c_zscal
+#define csscal_ f2c_csscal
+#define zdscal_ f2c_zdscal
+#define scopy_ f2c_scopy
+#define dcopy_ f2c_dcopy
+#define ccopy_ f2c_ccopy
+#define zcopy_ f2c_zcopy
+#define saxpy_ f2c_saxpy
+#define daxpy_ f2c_daxpy
+#define caxpy_ f2c_caxpy
+#define zaxpy_ f2c_zaxpy
+#define sdot_ f2c_sdot
+#define ddot_ f2c_ddot
+#define cdotu_ f2c_cdotu
+#define zdotu_ f2c_zdotu
+#define cdotc_ f2c_cdotc
+#define zdotc_ f2c_zdotc
+#define snrm2_ f2c_snrm2
+#define dnrm2_ f2c_dnrm2
+#define scnrm2_ f2c_scnrm2
+#define dznrm2_ f2c_dznrm2
+#define sasum_ f2c_sasum
+#define dasum_ f2c_dasum
+#define scasum_ f2c_scasum
+#define dzasum_ f2c_dzasum
+#define isamax_ f2c_isamax
+#define idamax_ f2c_idamax
+#define icamax_ f2c_icamax
+#define izamax_ f2c_izamax
+
+/* BLAS2 routines */
+#define sgemv_ f2c_sgemv
+#define dgemv_ f2c_dgemv
+#define cgemv_ f2c_cgemv
+#define zgemv_ f2c_zgemv
+#define sgbmv_ f2c_sgbmv
+#define dgbmv_ f2c_dgbmv
+#define cgbmv_ f2c_cgbmv
+#define zgbmv_ f2c_zgbmv
+#define chemv_ f2c_chemv
+#define zhemv_ f2c_zhemv
+#define chbmv_ f2c_chbmv
+#define zhbmv_ f2c_zhbmv
+#define chpmv_ f2c_chpmv
+#define zhpmv_ f2c_zhpmv
+#define ssymv_ f2c_ssymv
+#define dsymv_ f2c_dsymv
+#define ssbmv_ f2c_ssbmv
+#define dsbmv_ f2c_dsbmv
+#define sspmv_ f2c_sspmv
+#define dspmv_ f2c_dspmv
+#define strmv_ f2c_strmv
+#define dtrmv_ f2c_dtrmv
+#define ctrmv_ f2c_ctrmv
+#define ztrmv_ f2c_ztrmv
+#define stbmv_ f2c_stbmv
+#define dtbmv_ f2c_dtbmv
+#define ctbmv_ f2c_ctbmv
+#define ztbmv_ f2c_ztbmv
+#define stpmv_ f2c_stpmv
+#define dtpmv_ f2c_dtpmv
+#define ctpmv_ f2c_ctpmv
+#define ztpmv_ f2c_ztpmv
+#define strsv_ f2c_strsv
+#define dtrsv_ f2c_dtrsv
+#define ctrsv_ f2c_ctrsv
+#define ztrsv_ f2c_ztrsv
+#define stbsv_ f2c_stbsv
+#define dtbsv_ f2c_dtbsv
+#define ctbsv_ f2c_ctbsv
+#define ztbsv_ f2c_ztbsv
+#define stpsv_ f2c_stpsv
+#define dtpsv_ f2c_dtpsv
+#define ctpsv_ f2c_ctpsv
+#define ztpsv_ f2c_ztpsv
+#define sger_ f2c_sger
+#define dger_ f2c_dger
+#define cgeru_ f2c_cgeru
+#define zgeru_ f2c_zgeru
+#define cgerc_ f2c_cgerc
+#define zgerc_ f2c_zgerc
+#define cher_ f2c_cher
+#define zher_ f2c_zher
+#define chpr_ f2c_chpr
+#define zhpr_ f2c_zhpr
+#define cher2_ f2c_cher2
+#define zher2_ f2c_zher2
+#define chpr2_ f2c_chpr2
+#define zhpr2_ f2c_zhpr2
+#define ssyr_ f2c_ssyr
+#define dsyr_ f2c_dsyr
+#define sspr_ f2c_sspr
+#define dspr_ f2c_dspr
+#define ssyr2_ f2c_ssyr2
+#define dsyr2_ f2c_dsyr2
+#define sspr2_ f2c_sspr2
+#define dspr2_ f2c_dspr2
+
+/* BLAS3 routines */
+#define sgemm_ f2c_sgemm
+#define dgemm_ f2c_dgemm
+#define cgemm_ f2c_cgemm
+#define zgemm_ f2c_zgemm
+#define ssymm_ f2c_ssymm
+#define dsymm_ f2c_dsymm
+#define csymm_ f2c_csymm
+#define zsymm_ f2c_zsymm
+#define chemm_ f2c_chemm
+#define zhemm_ f2c_zhemm
+#define ssyrk_ f2c_ssyrk
+#define dsyrk_ f2c_dsyrk
+#define csyrk_ f2c_csyrk
+#define zsyrk_ f2c_zsyrk
+#define cherk_ f2c_cherk
+#define zherk_ f2c_zherk
+#define ssyr2k_ f2c_ssyr2k
+#define dsyr2k_ f2c_dsyr2k
+#define csyr2k_ f2c_csyr2k
+#define zsyr2k_ f2c_zsyr2k
+#define cher2k_ f2c_cher2k
+#define zher2k_ f2c_zher2k
+#define strmm_ f2c_strmm
+#define dtrmm_ f2c_dtrmm
+#define ctrmm_ f2c_ctrmm
+#define ztrmm_ f2c_ztrmm
+#define strsm_ f2c_strsm
+#define dtrsm_ f2c_dtrsm
+#define ctrsm_ f2c_ctrsm
+#define ztrsm_ f2c_ztrsm
+
+#endif /* NO_BLAS_WRAP */
+
+#endif /* __BLASWRAP_H */
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/clapack.h b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/clapack.h
new file mode 100644
index 0000000..cad9a4c
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/clapack.h
@@ -0,0 +1,5079 @@
+#ifndef __CLAPACK_H
+#define __CLAPACK_H
+
+/* Subroutine */ int cbdsqr_(char *uplo, integer *n, integer *ncvt, integer *
+ nru, integer *ncc, real *d__, real *e, complex *vt, integer *ldvt,
+ complex *u, integer *ldu, complex *c__, integer *ldc, real *rwork,
+ integer *info);
+
+/* Subroutine */ int cgbbrd_(char *vect, integer *m, integer *n, integer *ncc,
+ integer *kl, integer *ku, complex *ab, integer *ldab, real *d__,
+ real *e, complex *q, integer *ldq, complex *pt, integer *ldpt,
+ complex *c__, integer *ldc, complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int cgbcon_(char *norm, integer *n, integer *kl, integer *ku,
+ complex *ab, integer *ldab, integer *ipiv, real *anorm, real *rcond,
+ complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int cgbequ_(integer *m, integer *n, integer *kl, integer *ku,
+ complex *ab, integer *ldab, real *r__, real *c__, real *rowcnd, real
+ *colcnd, real *amax, integer *info);
+
+/* Subroutine */ int cgbrfs_(char *trans, integer *n, integer *kl, integer *
+ ku, integer *nrhs, complex *ab, integer *ldab, complex *afb, integer *
+ ldafb, integer *ipiv, complex *b, integer *ldb, complex *x, integer *
+ ldx, real *ferr, real *berr, complex *work, real *rwork, integer *
+ info);
+
+/* Subroutine */ int cgbsv_(integer *n, integer *kl, integer *ku, integer *
+ nrhs, complex *ab, integer *ldab, integer *ipiv, complex *b, integer *
+ ldb, integer *info);
+
+/* Subroutine */ int cgbsvx_(char *fact, char *trans, integer *n, integer *kl,
+ integer *ku, integer *nrhs, complex *ab, integer *ldab, complex *afb,
+ integer *ldafb, integer *ipiv, char *equed, real *r__, real *c__,
+ complex *b, integer *ldb, complex *x, integer *ldx, real *rcond, real
+ *ferr, real *berr, complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int cgbtf2_(integer *m, integer *n, integer *kl, integer *ku,
+ complex *ab, integer *ldab, integer *ipiv, integer *info);
+
+/* Subroutine */ int cgbtrf_(integer *m, integer *n, integer *kl, integer *ku,
+ complex *ab, integer *ldab, integer *ipiv, integer *info);
+
+/* Subroutine */ int cgbtrs_(char *trans, integer *n, integer *kl, integer *
+ ku, integer *nrhs, complex *ab, integer *ldab, integer *ipiv, complex
+ *b, integer *ldb, integer *info);
+
+/* Subroutine */ int cgebak_(char *job, char *side, integer *n, integer *ilo,
+ integer *ihi, real *scale, integer *m, complex *v, integer *ldv,
+ integer *info);
+
+/* Subroutine */ int cgebal_(char *job, integer *n, complex *a, integer *lda,
+ integer *ilo, integer *ihi, real *scale, integer *info);
+
+/* Subroutine */ int cgebd2_(integer *m, integer *n, complex *a, integer *lda,
+ real *d__, real *e, complex *tauq, complex *taup, complex *work,
+ integer *info);
+
+/* Subroutine */ int cgebrd_(integer *m, integer *n, complex *a, integer *lda,
+ real *d__, real *e, complex *tauq, complex *taup, complex *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int cgecon_(char *norm, integer *n, complex *a, integer *lda,
+ real *anorm, real *rcond, complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int cgeequ_(integer *m, integer *n, complex *a, integer *lda,
+ real *r__, real *c__, real *rowcnd, real *colcnd, real *amax,
+ integer *info);
+
+/* Subroutine */ int cgees_(char *jobvs, char *sort, L_fp select, integer *n,
+ complex *a, integer *lda, integer *sdim, complex *w, complex *vs,
+ integer *ldvs, complex *work, integer *lwork, real *rwork, logical *
+ bwork, integer *info);
+
+/* Subroutine */ int cgeesx_(char *jobvs, char *sort, L_fp select, char *
+ sense, integer *n, complex *a, integer *lda, integer *sdim, complex *
+ w, complex *vs, integer *ldvs, real *rconde, real *rcondv, complex *
+ work, integer *lwork, real *rwork, logical *bwork, integer *info);
+
+/* Subroutine */ int cgeev_(char *jobvl, char *jobvr, integer *n, complex *a,
+ integer *lda, complex *w, complex *vl, integer *ldvl, complex *vr,
+ integer *ldvr, complex *work, integer *lwork, real *rwork, integer *
+ info);
+
+/* Subroutine */ int cgeevx_(char *balanc, char *jobvl, char *jobvr, char *
+ sense, integer *n, complex *a, integer *lda, complex *w, complex *vl,
+ integer *ldvl, complex *vr, integer *ldvr, integer *ilo, integer *ihi,
+ real *scale, real *abnrm, real *rconde, real *rcondv, complex *work,
+ integer *lwork, real *rwork, integer *info);
+
+/* Subroutine */ int cgegs_(char *jobvsl, char *jobvsr, integer *n, complex *
+ a, integer *lda, complex *b, integer *ldb, complex *alpha, complex *
+ beta, complex *vsl, integer *ldvsl, complex *vsr, integer *ldvsr,
+ complex *work, integer *lwork, real *rwork, integer *info);
+
+/* Subroutine */ int cgegv_(char *jobvl, char *jobvr, integer *n, complex *a,
+ integer *lda, complex *b, integer *ldb, complex *alpha, complex *beta,
+ complex *vl, integer *ldvl, complex *vr, integer *ldvr, complex *
+ work, integer *lwork, real *rwork, integer *info);
+
+/* Subroutine */ int cgehd2_(integer *n, integer *ilo, integer *ihi, complex *
+ a, integer *lda, complex *tau, complex *work, integer *info);
+
+/* Subroutine */ int cgehrd_(integer *n, integer *ilo, integer *ihi, complex *
+ a, integer *lda, complex *tau, complex *work, integer *lwork, integer
+ *info);
+
+/* Subroutine */ int cgelq2_(integer *m, integer *n, complex *a, integer *lda,
+ complex *tau, complex *work, integer *info);
+
+/* Subroutine */ int cgelqf_(integer *m, integer *n, complex *a, integer *lda,
+ complex *tau, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cgels_(char *trans, integer *m, integer *n, integer *
+ nrhs, complex *a, integer *lda, complex *b, integer *ldb, complex *
+ work, integer *lwork, integer *info);
+
+/* Subroutine */ int cgelsx_(integer *m, integer *n, integer *nrhs, complex *
+ a, integer *lda, complex *b, integer *ldb, integer *jpvt, real *rcond,
+ integer *rank, complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int cgelsy_(integer *m, integer *n, integer *nrhs, complex *
+ a, integer *lda, complex *b, integer *ldb, integer *jpvt, real *rcond,
+ integer *rank, complex *work, integer *lwork, real *rwork, integer *
+ info);
+
+/* Subroutine */ int cgeql2_(integer *m, integer *n, complex *a, integer *lda,
+ complex *tau, complex *work, integer *info);
+
+/* Subroutine */ int cgeqlf_(integer *m, integer *n, complex *a, integer *lda,
+ complex *tau, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cgeqp3_(integer *m, integer *n, complex *a, integer *lda,
+ integer *jpvt, complex *tau, complex *work, integer *lwork, real *
+ rwork, integer *info);
+
+/* Subroutine */ int cgeqpf_(integer *m, integer *n, complex *a, integer *lda,
+ integer *jpvt, complex *tau, complex *work, real *rwork, integer *
+ info);
+
+/* Subroutine */ int cgeqr2_(integer *m, integer *n, complex *a, integer *lda,
+ complex *tau, complex *work, integer *info);
+
+/* Subroutine */ int cgeqrf_(integer *m, integer *n, complex *a, integer *lda,
+ complex *tau, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cgerfs_(char *trans, integer *n, integer *nrhs, complex *
+ a, integer *lda, complex *af, integer *ldaf, integer *ipiv, complex *
+ b, integer *ldb, complex *x, integer *ldx, real *ferr, real *berr,
+ complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int cgerq2_(integer *m, integer *n, complex *a, integer *lda,
+ complex *tau, complex *work, integer *info);
+
+/* Subroutine */ int cgerqf_(integer *m, integer *n, complex *a, integer *lda,
+ complex *tau, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cgesc2_(integer *n, complex *a, integer *lda, complex *
+ rhs, integer *ipiv, integer *jpiv, real *scale);
+
+/* Subroutine */ int cgesv_(integer *n, integer *nrhs, complex *a, integer *
+ lda, integer *ipiv, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int cgesvx_(char *fact, char *trans, integer *n, integer *
+ nrhs, complex *a, integer *lda, complex *af, integer *ldaf, integer *
+ ipiv, char *equed, real *r__, real *c__, complex *b, integer *ldb,
+ complex *x, integer *ldx, real *rcond, real *ferr, real *berr,
+ complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int cgetc2_(integer *n, complex *a, integer *lda, integer *
+ ipiv, integer *jpiv, integer *info);
+
+/* Subroutine */ int cgetf2_(integer *m, integer *n, complex *a, integer *lda,
+ integer *ipiv, integer *info);
+
+/* Subroutine */ int cgetrf_(integer *m, integer *n, complex *a, integer *lda,
+ integer *ipiv, integer *info);
+
+/* Subroutine */ int cgetri_(integer *n, complex *a, integer *lda, integer *
+ ipiv, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cgetrs_(char *trans, integer *n, integer *nrhs, complex *
+ a, integer *lda, integer *ipiv, complex *b, integer *ldb, integer *
+ info);
+
+/* Subroutine */ int cggbak_(char *job, char *side, integer *n, integer *ilo,
+ integer *ihi, real *lscale, real *rscale, integer *m, complex *v,
+ integer *ldv, integer *info);
+
+/* Subroutine */ int cggbal_(char *job, integer *n, complex *a, integer *lda,
+ complex *b, integer *ldb, integer *ilo, integer *ihi, real *lscale,
+ real *rscale, real *work, integer *info);
+
+/* Subroutine */ int cgges_(char *jobvsl, char *jobvsr, char *sort, L_fp
+ selctg, integer *n, complex *a, integer *lda, complex *b, integer *
+ ldb, integer *sdim, complex *alpha, complex *beta, complex *vsl,
+ integer *ldvsl, complex *vsr, integer *ldvsr, complex *work, integer *
+ lwork, real *rwork, logical *bwork, integer *info);
+
+/* Subroutine */ int cggesx_(char *jobvsl, char *jobvsr, char *sort, L_fp
+ selctg, char *sense, integer *n, complex *a, integer *lda, complex *b,
+ integer *ldb, integer *sdim, complex *alpha, complex *beta, complex *
+ vsl, integer *ldvsl, complex *vsr, integer *ldvsr, real *rconde, real
+ *rcondv, complex *work, integer *lwork, real *rwork, integer *iwork,
+ integer *liwork, logical *bwork, integer *info);
+
+/* Subroutine */ int cggev_(char *jobvl, char *jobvr, integer *n, complex *a,
+ integer *lda, complex *b, integer *ldb, complex *alpha, complex *beta,
+ complex *vl, integer *ldvl, complex *vr, integer *ldvr, complex *
+ work, integer *lwork, real *rwork, integer *info);
+
+/* Subroutine */ int cggevx_(char *balanc, char *jobvl, char *jobvr, char *
+ sense, integer *n, complex *a, integer *lda, complex *b, integer *ldb,
+ complex *alpha, complex *beta, complex *vl, integer *ldvl, complex *
+ vr, integer *ldvr, integer *ilo, integer *ihi, real *lscale, real *
+ rscale, real *abnrm, real *bbnrm, real *rconde, real *rcondv, complex
+ *work, integer *lwork, real *rwork, integer *iwork, logical *bwork,
+ integer *info);
+
+/* Subroutine */ int cggglm_(integer *n, integer *m, integer *p, complex *a,
+ integer *lda, complex *b, integer *ldb, complex *d__, complex *x,
+ complex *y, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cgghrd_(char *compq, char *compz, integer *n, integer *
+ ilo, integer *ihi, complex *a, integer *lda, complex *b, integer *ldb,
+ complex *q, integer *ldq, complex *z__, integer *ldz, integer *info);
+
+/* Subroutine */ int cgglse_(integer *m, integer *n, integer *p, complex *a,
+ integer *lda, complex *b, integer *ldb, complex *c__, complex *d__,
+ complex *x, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cggqrf_(integer *n, integer *m, integer *p, complex *a,
+ integer *lda, complex *taua, complex *b, integer *ldb, complex *taub,
+ complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cggrqf_(integer *m, integer *p, integer *n, complex *a,
+ integer *lda, complex *taua, complex *b, integer *ldb, complex *taub,
+ complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cggsvd_(char *jobu, char *jobv, char *jobq, integer *m,
+ integer *n, integer *p, integer *k, integer *l, complex *a, integer *
+ lda, complex *b, integer *ldb, real *alpha, real *beta, complex *u,
+ integer *ldu, complex *v, integer *ldv, complex *q, integer *ldq,
+ complex *work, real *rwork, integer *iwork, integer *info);
+
+/* Subroutine */ int cggsvp_(char *jobu, char *jobv, char *jobq, integer *m,
+ integer *p, integer *n, complex *a, integer *lda, complex *b, integer
+ *ldb, real *tola, real *tolb, integer *k, integer *l, complex *u,
+ integer *ldu, complex *v, integer *ldv, complex *q, integer *ldq,
+ integer *iwork, real *rwork, complex *tau, complex *work, integer *
+ info);
+
+/* Subroutine */ int cgtcon_(char *norm, integer *n, complex *dl, complex *
+ d__, complex *du, complex *du2, integer *ipiv, real *anorm, real *
+ rcond, complex *work, integer *info);
+
+/* Subroutine */ int cgtrfs_(char *trans, integer *n, integer *nrhs, complex *
+ dl, complex *d__, complex *du, complex *dlf, complex *df, complex *
+ duf, complex *du2, integer *ipiv, complex *b, integer *ldb, complex *
+ x, integer *ldx, real *ferr, real *berr, complex *work, real *rwork,
+ integer *info);
+
+/* Subroutine */ int cgtsv_(integer *n, integer *nrhs, complex *dl, complex *
+ d__, complex *du, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int cgtsvx_(char *fact, char *trans, integer *n, integer *
+ nrhs, complex *dl, complex *d__, complex *du, complex *dlf, complex *
+ df, complex *duf, complex *du2, integer *ipiv, complex *b, integer *
+ ldb, complex *x, integer *ldx, real *rcond, real *ferr, real *berr,
+ complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int cgttrf_(integer *n, complex *dl, complex *d__, complex *
+ du, complex *du2, integer *ipiv, integer *info);
+
+/* Subroutine */ int cgttrs_(char *trans, integer *n, integer *nrhs, complex *
+ dl, complex *d__, complex *du, complex *du2, integer *ipiv, complex *
+ b, integer *ldb, integer *info);
+
+/* Subroutine */ int cgtts2_(integer *itrans, integer *n, integer *nrhs,
+ complex *dl, complex *d__, complex *du, complex *du2, integer *ipiv,
+ complex *b, integer *ldb);
+
+/* Subroutine */ int chbev_(char *jobz, char *uplo, integer *n, integer *kd,
+ complex *ab, integer *ldab, real *w, complex *z__, integer *ldz,
+ complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int chbevd_(char *jobz, char *uplo, integer *n, integer *kd,
+ complex *ab, integer *ldab, real *w, complex *z__, integer *ldz,
+ complex *work, integer *lwork, real *rwork, integer *lrwork, integer *
+ iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int chbevx_(char *jobz, char *range, char *uplo, integer *n,
+ integer *kd, complex *ab, integer *ldab, complex *q, integer *ldq,
+ real *vl, real *vu, integer *il, integer *iu, real *abstol, integer *
+ m, real *w, complex *z__, integer *ldz, complex *work, real *rwork,
+ integer *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int chbgst_(char *vect, char *uplo, integer *n, integer *ka,
+ integer *kb, complex *ab, integer *ldab, complex *bb, integer *ldbb,
+ complex *x, integer *ldx, complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int chbgv_(char *jobz, char *uplo, integer *n, integer *ka,
+ integer *kb, complex *ab, integer *ldab, complex *bb, integer *ldbb,
+ real *w, complex *z__, integer *ldz, complex *work, real *rwork,
+ integer *info);
+
+/* Subroutine */ int chbgvx_(char *jobz, char *range, char *uplo, integer *n,
+ integer *ka, integer *kb, complex *ab, integer *ldab, complex *bb,
+ integer *ldbb, complex *q, integer *ldq, real *vl, real *vu, integer *
+ il, integer *iu, real *abstol, integer *m, real *w, complex *z__,
+ integer *ldz, complex *work, real *rwork, integer *iwork, integer *
+ ifail, integer *info);
+
+/* Subroutine */ int chbtrd_(char *vect, char *uplo, integer *n, integer *kd,
+ complex *ab, integer *ldab, real *d__, real *e, complex *q, integer *
+ ldq, complex *work, integer *info);
+
+/* Subroutine */ int checon_(char *uplo, integer *n, complex *a, integer *lda,
+ integer *ipiv, real *anorm, real *rcond, complex *work, integer *
+ info);
+
+/* Subroutine */ int cheev_(char *jobz, char *uplo, integer *n, complex *a,
+ integer *lda, real *w, complex *work, integer *lwork, real *rwork,
+ integer *info);
+
+/* Subroutine */ int cheevd_(char *jobz, char *uplo, integer *n, complex *a,
+ integer *lda, real *w, complex *work, integer *lwork, real *rwork,
+ integer *lrwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int cheevr_(char *jobz, char *range, char *uplo, integer *n,
+ complex *a, integer *lda, real *vl, real *vu, integer *il, integer *
+ iu, real *abstol, integer *m, real *w, complex *z__, integer *ldz,
+ integer *isuppz, complex *work, integer *lwork, real *rwork, integer *
+ lrwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int cheevx_(char *jobz, char *range, char *uplo, integer *n,
+ complex *a, integer *lda, real *vl, real *vu, integer *il, integer *
+ iu, real *abstol, integer *m, real *w, complex *z__, integer *ldz,
+ complex *work, integer *lwork, real *rwork, integer *iwork, integer *
+ ifail, integer *info);
+
+/* Subroutine */ int chegs2_(integer *itype, char *uplo, integer *n, complex *
+ a, integer *lda, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int chegst_(integer *itype, char *uplo, integer *n, complex *
+ a, integer *lda, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int chegv_(integer *itype, char *jobz, char *uplo, integer *
+ n, complex *a, integer *lda, complex *b, integer *ldb, real *w,
+ complex *work, integer *lwork, real *rwork, integer *info);
+
+/* Subroutine */ int chegvd_(integer *itype, char *jobz, char *uplo, integer *
+ n, complex *a, integer *lda, complex *b, integer *ldb, real *w,
+ complex *work, integer *lwork, real *rwork, integer *lrwork, integer *
+ iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int chegvx_(integer *itype, char *jobz, char *range, char *
+ uplo, integer *n, complex *a, integer *lda, complex *b, integer *ldb,
+ real *vl, real *vu, integer *il, integer *iu, real *abstol, integer *
+ m, real *w, complex *z__, integer *ldz, complex *work, integer *lwork,
+ real *rwork, integer *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int cherfs_(char *uplo, integer *n, integer *nrhs, complex *
+ a, integer *lda, complex *af, integer *ldaf, integer *ipiv, complex *
+ b, integer *ldb, complex *x, integer *ldx, real *ferr, real *berr,
+ complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int chesv_(char *uplo, integer *n, integer *nrhs, complex *a,
+ integer *lda, integer *ipiv, complex *b, integer *ldb, complex *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int chesvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, complex *a, integer *lda, complex *af, integer *ldaf, integer *
+ ipiv, complex *b, integer *ldb, complex *x, integer *ldx, real *rcond,
+ real *ferr, real *berr, complex *work, integer *lwork, real *rwork,
+ integer *info);
+
+/* Subroutine */ int chetf2_(char *uplo, integer *n, complex *a, integer *lda,
+ integer *ipiv, integer *info);
+
+/* Subroutine */ int chetrd_(char *uplo, integer *n, complex *a, integer *lda,
+ real *d__, real *e, complex *tau, complex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int chetrf_(char *uplo, integer *n, complex *a, integer *lda,
+ integer *ipiv, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int chetri_(char *uplo, integer *n, complex *a, integer *lda,
+ integer *ipiv, complex *work, integer *info);
+
+/* Subroutine */ int chetrs_(char *uplo, integer *n, integer *nrhs, complex *
+ a, integer *lda, integer *ipiv, complex *b, integer *ldb, integer *
+ info);
+
+/* Subroutine */ int chgeqz_(char *job, char *compq, char *compz, integer *n,
+ integer *ilo, integer *ihi, complex *a, integer *lda, complex *b,
+ integer *ldb, complex *alpha, complex *beta, complex *q, integer *ldq,
+ complex *z__, integer *ldz, complex *work, integer *lwork, real *
+ rwork, integer *info);
+
+/* Subroutine */ int chpcon_(char *uplo, integer *n, complex *ap, integer *
+ ipiv, real *anorm, real *rcond, complex *work, integer *info);
+
+/* Subroutine */ int chpev_(char *jobz, char *uplo, integer *n, complex *ap,
+ real *w, complex *z__, integer *ldz, complex *work, real *rwork,
+ integer *info);
+
+/* Subroutine */ int chpevd_(char *jobz, char *uplo, integer *n, complex *ap,
+ real *w, complex *z__, integer *ldz, complex *work, integer *lwork,
+ real *rwork, integer *lrwork, integer *iwork, integer *liwork,
+ integer *info);
+
+/* Subroutine */ int chpevx_(char *jobz, char *range, char *uplo, integer *n,
+ complex *ap, real *vl, real *vu, integer *il, integer *iu, real *
+ abstol, integer *m, real *w, complex *z__, integer *ldz, complex *
+ work, real *rwork, integer *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int chpgst_(integer *itype, char *uplo, integer *n, complex *
+ ap, complex *bp, integer *info);
+
+/* Subroutine */ int chpgv_(integer *itype, char *jobz, char *uplo, integer *
+ n, complex *ap, complex *bp, real *w, complex *z__, integer *ldz,
+ complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int chpgvd_(integer *itype, char *jobz, char *uplo, integer *
+ n, complex *ap, complex *bp, real *w, complex *z__, integer *ldz,
+ complex *work, integer *lwork, real *rwork, integer *lrwork, integer *
+ iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int chpgvx_(integer *itype, char *jobz, char *range, char *
+ uplo, integer *n, complex *ap, complex *bp, real *vl, real *vu,
+ integer *il, integer *iu, real *abstol, integer *m, real *w, complex *
+ z__, integer *ldz, complex *work, real *rwork, integer *iwork,
+ integer *ifail, integer *info);
+
+/* Subroutine */ int chprfs_(char *uplo, integer *n, integer *nrhs, complex *
+ ap, complex *afp, integer *ipiv, complex *b, integer *ldb, complex *x,
+ integer *ldx, real *ferr, real *berr, complex *work, real *rwork,
+ integer *info);
+
+/* Subroutine */ int chpsv_(char *uplo, integer *n, integer *nrhs, complex *
+ ap, integer *ipiv, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int chpsvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, complex *ap, complex *afp, integer *ipiv, complex *b, integer *
+ ldb, complex *x, integer *ldx, real *rcond, real *ferr, real *berr,
+ complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int chptrd_(char *uplo, integer *n, complex *ap, real *d__,
+ real *e, complex *tau, integer *info);
+
+/* Subroutine */ int chptrf_(char *uplo, integer *n, complex *ap, integer *
+ ipiv, integer *info);
+
+/* Subroutine */ int chptri_(char *uplo, integer *n, complex *ap, integer *
+ ipiv, complex *work, integer *info);
+
+/* Subroutine */ int chptrs_(char *uplo, integer *n, integer *nrhs, complex *
+ ap, integer *ipiv, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int chsein_(char *side, char *eigsrc, char *initv, logical *
+ select, integer *n, complex *h__, integer *ldh, complex *w, complex *
+ vl, integer *ldvl, complex *vr, integer *ldvr, integer *mm, integer *
+ m, complex *work, real *rwork, integer *ifaill, integer *ifailr,
+ integer *info);
+
+/* Subroutine */ int chseqr_(char *job, char *compz, integer *n, integer *ilo,
+ integer *ihi, complex *h__, integer *ldh, complex *w, complex *z__,
+ integer *ldz, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int clabrd_(integer *m, integer *n, integer *nb, complex *a,
+ integer *lda, real *d__, real *e, complex *tauq, complex *taup,
+ complex *x, integer *ldx, complex *y, integer *ldy);
+
+/* Subroutine */ int clacgv_(integer *n, complex *x, integer *incx);
+
+/* Subroutine */ int clacon_(integer *n, complex *v, complex *x, real *est,
+ integer *kase);
+
+/* Subroutine */ int clacp2_(char *uplo, integer *m, integer *n, real *a,
+ integer *lda, complex *b, integer *ldb);
+
+/* Subroutine */ int clacpy_(char *uplo, integer *m, integer *n, complex *a,
+ integer *lda, complex *b, integer *ldb);
+
+/* Subroutine */ int clacrm_(integer *m, integer *n, complex *a, integer *lda,
+ real *b, integer *ldb, complex *c__, integer *ldc, real *rwork);
+
+/* Subroutine */ int clacrt_(integer *n, complex *cx, integer *incx, complex *
+ cy, integer *incy, complex *c__, complex *s);
+
+/* Subroutine */ int claed0_(integer *qsiz, integer *n, real *d__, real *e,
+ complex *q, integer *ldq, complex *qstore, integer *ldqs, real *rwork,
+ integer *iwork, integer *info);
+
+/* Subroutine */ int claed7_(integer *n, integer *cutpnt, integer *qsiz,
+ integer *tlvls, integer *curlvl, integer *curpbm, real *d__, complex *
+ q, integer *ldq, real *rho, integer *indxq, real *qstore, integer *
+ qptr, integer *prmptr, integer *perm, integer *givptr, integer *
+ givcol, real *givnum, complex *work, real *rwork, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int claed8_(integer *k, integer *n, integer *qsiz, complex *
+ q, integer *ldq, real *d__, real *rho, integer *cutpnt, real *z__,
+ real *dlamda, complex *q2, integer *ldq2, real *w, integer *indxp,
+ integer *indx, integer *indxq, integer *perm, integer *givptr,
+ integer *givcol, real *givnum, integer *info);
+
+/* Subroutine */ int claein_(logical *rightv, logical *noinit, integer *n,
+ complex *h__, integer *ldh, complex *w, complex *v, complex *b,
+ integer *ldb, real *rwork, real *eps3, real *smlnum, integer *info);
+
+/* Subroutine */ int claesy_(complex *a, complex *b, complex *c__, complex *
+ rt1, complex *rt2, complex *evscal, complex *cs1, complex *sn1);
+
+/* Subroutine */ int claev2_(complex *a, complex *b, complex *c__, real *rt1,
+ real *rt2, real *cs1, complex *sn1);
+
+/* Subroutine */ int clags2_(logical *upper, real *a1, complex *a2, real *a3,
+ real *b1, complex *b2, real *b3, real *csu, complex *snu, real *csv,
+ complex *snv, real *csq, complex *snq);
+
+/* Subroutine */ int clagtm_(char *trans, integer *n, integer *nrhs, real *
+ alpha, complex *dl, complex *d__, complex *du, complex *x, integer *
+ ldx, real *beta, complex *b, integer *ldb);
+
+/* Subroutine */ int clahef_(char *uplo, integer *n, integer *nb, integer *kb,
+ complex *a, integer *lda, integer *ipiv, complex *w, integer *ldw,
+ integer *info);
+
+/* Subroutine */ int clahqr_(logical *wantt, logical *wantz, integer *n,
+ integer *ilo, integer *ihi, complex *h__, integer *ldh, complex *w,
+ integer *iloz, integer *ihiz, complex *z__, integer *ldz, integer *
+ info);
+
+/* Subroutine */ int clahrd_(integer *n, integer *k, integer *nb, complex *a,
+ integer *lda, complex *tau, complex *t, integer *ldt, complex *y,
+ integer *ldy);
+
+/* Subroutine */ int claic1_(integer *job, integer *j, complex *x, real *sest,
+ complex *w, complex *gamma, real *sestpr, complex *s, complex *c__);
+
+/* Subroutine */ int clals0_(integer *icompq, integer *nl, integer *nr,
+ integer *sqre, integer *nrhs, complex *b, integer *ldb, complex *bx,
+ integer *ldbx, integer *perm, integer *givptr, integer *givcol,
+ integer *ldgcol, real *givnum, integer *ldgnum, real *poles, real *
+ difl, real *difr, real *z__, integer *k, real *c__, real *s, real *
+ rwork, integer *info);
+
+/* Subroutine */ int clalsa_(integer *icompq, integer *smlsiz, integer *n,
+ integer *nrhs, complex *b, integer *ldb, complex *bx, integer *ldbx,
+ real *u, integer *ldu, real *vt, integer *k, real *difl, real *difr,
+ real *z__, real *poles, integer *givptr, integer *givcol, integer *
+ ldgcol, integer *perm, real *givnum, real *c__, real *s, real *rwork,
+ integer *iwork, integer *info);
+
+/* Subroutine */ int clapll_(integer *n, complex *x, integer *incx, complex *
+ y, integer *incy, real *ssmin);
+
+/* Subroutine */ int clapmt_(logical *forwrd, integer *m, integer *n, complex
+ *x, integer *ldx, integer *k);
+
+/* Subroutine */ int claqgb_(integer *m, integer *n, integer *kl, integer *ku,
+ complex *ab, integer *ldab, real *r__, real *c__, real *rowcnd, real
+ *colcnd, real *amax, char *equed);
+
+/* Subroutine */ int claqge_(integer *m, integer *n, complex *a, integer *lda,
+ real *r__, real *c__, real *rowcnd, real *colcnd, real *amax, char *
+ equed);
+
+/* Subroutine */ int claqhb_(char *uplo, integer *n, integer *kd, complex *ab,
+ integer *ldab, real *s, real *scond, real *amax, char *equed);
+
+/* Subroutine */ int claqhe_(char *uplo, integer *n, complex *a, integer *lda,
+ real *s, real *scond, real *amax, char *equed);
+
+/* Subroutine */ int claqhp_(char *uplo, integer *n, complex *ap, real *s,
+ real *scond, real *amax, char *equed);
+
+/* Subroutine */ int claqp2_(integer *m, integer *n, integer *offset, complex
+ *a, integer *lda, integer *jpvt, complex *tau, real *vn1, real *vn2,
+ complex *work);
+
+/* Subroutine */ int claqps_(integer *m, integer *n, integer *offset, integer
+ *nb, integer *kb, complex *a, integer *lda, integer *jpvt, complex *
+ tau, real *vn1, real *vn2, complex *auxv, complex *f, integer *ldf);
+
+/* Subroutine */ int claqsb_(char *uplo, integer *n, integer *kd, complex *ab,
+ integer *ldab, real *s, real *scond, real *amax, char *equed);
+
+/* Subroutine */ int claqsp_(char *uplo, integer *n, complex *ap, real *s,
+ real *scond, real *amax, char *equed);
+
+/* Subroutine */ int claqsy_(char *uplo, integer *n, complex *a, integer *lda,
+ real *s, real *scond, real *amax, char *equed);
+
+/* Subroutine */ int clar1v_(integer *n, integer *b1, integer *bn, real *
+ sigma, real *d__, real *l, real *ld, real *lld, real *gersch, complex
+ *z__, real *ztz, real *mingma, integer *r__, integer *isuppz, real *
+ work);
+
+/* Subroutine */ int clar2v_(integer *n, complex *x, complex *y, complex *z__,
+ integer *incx, real *c__, complex *s, integer *incc);
+
+/* Subroutine */ int clarcm_(integer *m, integer *n, real *a, integer *lda,
+ complex *b, integer *ldb, complex *c__, integer *ldc, real *rwork);
+
+/* Subroutine */ int clarf_(char *side, integer *m, integer *n, complex *v,
+ integer *incv, complex *tau, complex *c__, integer *ldc, complex *
+ work);
+
+/* Subroutine */ int clarfb_(char *side, char *trans, char *direct, char *
+ storev, integer *m, integer *n, integer *k, complex *v, integer *ldv,
+ complex *t, integer *ldt, complex *c__, integer *ldc, complex *work,
+ integer *ldwork);
+
+/* Subroutine */ int clarfg_(integer *n, complex *alpha, complex *x, integer *
+ incx, complex *tau);
+
+/* Subroutine */ int clarft_(char *direct, char *storev, integer *n, integer *
+ k, complex *v, integer *ldv, complex *tau, complex *t, integer *ldt);
+
+/* Subroutine */ int clarfx_(char *side, integer *m, integer *n, complex *v,
+ complex *tau, complex *c__, integer *ldc, complex *work);
+
+/* Subroutine */ int clargv_(integer *n, complex *x, integer *incx, complex *
+ y, integer *incy, real *c__, integer *incc);
+
+/* Subroutine */ int clarnv_(integer *idist, integer *iseed, integer *n,
+ complex *x);
+
+/* Subroutine */ int clarrv_(integer *n, real *d__, real *l, integer *isplit,
+ integer *m, real *w, integer *iblock, real *gersch, real *tol,
+ complex *z__, integer *ldz, integer *isuppz, real *work, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int clartg_(complex *f, complex *g, real *cs, complex *sn,
+ complex *r__);
+
+/* Subroutine */ int clartv_(integer *n, complex *x, integer *incx, complex *
+ y, integer *incy, real *c__, complex *s, integer *incc);
+
+/* Subroutine */ int clarz_(char *side, integer *m, integer *n, integer *l,
+ complex *v, integer *incv, complex *tau, complex *c__, integer *ldc,
+ complex *work);
+
+/* Subroutine */ int clarzb_(char *side, char *trans, char *direct, char *
+ storev, integer *m, integer *n, integer *k, integer *l, complex *v,
+ integer *ldv, complex *t, integer *ldt, complex *c__, integer *ldc,
+ complex *work, integer *ldwork);
+
+/* Subroutine */ int clarzt_(char *direct, char *storev, integer *n, integer *
+ k, complex *v, integer *ldv, complex *tau, complex *t, integer *ldt);
+
+/* Subroutine */ int clascl_(char *type__, integer *kl, integer *ku, real *
+ cfrom, real *cto, integer *m, integer *n, complex *a, integer *lda,
+ integer *info);
+
+/* Subroutine */ int claset_(char *uplo, integer *m, integer *n, complex *
+ alpha, complex *beta, complex *a, integer *lda);
+
+/* Subroutine */ int clasr_(char *side, char *pivot, char *direct, integer *m,
+ integer *n, real *c__, real *s, complex *a, integer *lda);
+
+/* Subroutine */ int classq_(integer *n, complex *x, integer *incx, real *
+ scale, real *sumsq);
+
+/* Subroutine */ int claswp_(integer *n, complex *a, integer *lda, integer *
+ k1, integer *k2, integer *ipiv, integer *incx);
+
+/* Subroutine */ int clasyf_(char *uplo, integer *n, integer *nb, integer *kb,
+ complex *a, integer *lda, integer *ipiv, complex *w, integer *ldw,
+ integer *info);
+
+/* Subroutine */ int clatbs_(char *uplo, char *trans, char *diag, char *
+ normin, integer *n, integer *kd, complex *ab, integer *ldab, complex *
+ x, real *scale, real *cnorm, integer *info);
+
+/* Subroutine */ int clatdf_(integer *ijob, integer *n, complex *z__, integer
+ *ldz, complex *rhs, real *rdsum, real *rdscal, integer *ipiv, integer
+ *jpiv);
+
+/* Subroutine */ int clatps_(char *uplo, char *trans, char *diag, char *
+ normin, integer *n, complex *ap, complex *x, real *scale, real *cnorm,
+ integer *info);
+
+/* Subroutine */ int clatrd_(char *uplo, integer *n, integer *nb, complex *a,
+ integer *lda, real *e, complex *tau, complex *w, integer *ldw);
+
+/* Subroutine */ int clatrs_(char *uplo, char *trans, char *diag, char *
+ normin, integer *n, complex *a, integer *lda, complex *x, real *scale,
+ real *cnorm, integer *info);
+
+/* Subroutine */ int clatrz_(integer *m, integer *n, integer *l, complex *a,
+ integer *lda, complex *tau, complex *work);
+
+/* Subroutine */ int clatzm_(char *side, integer *m, integer *n, complex *v,
+ integer *incv, complex *tau, complex *c1, complex *c2, integer *ldc,
+ complex *work);
+
+/* Subroutine */ int clauu2_(char *uplo, integer *n, complex *a, integer *lda,
+ integer *info);
+
+/* Subroutine */ int clauum_(char *uplo, integer *n, complex *a, integer *lda,
+ integer *info);
+
+/* Subroutine */ int cpbcon_(char *uplo, integer *n, integer *kd, complex *ab,
+ integer *ldab, real *anorm, real *rcond, complex *work, real *rwork,
+ integer *info);
+
+/* Subroutine */ int cpbequ_(char *uplo, integer *n, integer *kd, complex *ab,
+ integer *ldab, real *s, real *scond, real *amax, integer *info);
+
+/* Subroutine */ int cpbrfs_(char *uplo, integer *n, integer *kd, integer *
+ nrhs, complex *ab, integer *ldab, complex *afb, integer *ldafb,
+ complex *b, integer *ldb, complex *x, integer *ldx, real *ferr, real *
+ berr, complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int cpbstf_(char *uplo, integer *n, integer *kd, complex *ab,
+ integer *ldab, integer *info);
+
+/* Subroutine */ int cpbsv_(char *uplo, integer *n, integer *kd, integer *
+ nrhs, complex *ab, integer *ldab, complex *b, integer *ldb, integer *
+ info);
+
+/* Subroutine */ int cpbsvx_(char *fact, char *uplo, integer *n, integer *kd,
+ integer *nrhs, complex *ab, integer *ldab, complex *afb, integer *
+ ldafb, char *equed, real *s, complex *b, integer *ldb, complex *x,
+ integer *ldx, real *rcond, real *ferr, real *berr, complex *work,
+ real *rwork, integer *info);
+
+/* Subroutine */ int cpbtf2_(char *uplo, integer *n, integer *kd, complex *ab,
+ integer *ldab, integer *info);
+
+/* Subroutine */ int cpbtrf_(char *uplo, integer *n, integer *kd, complex *ab,
+ integer *ldab, integer *info);
+
+/* Subroutine */ int cpbtrs_(char *uplo, integer *n, integer *kd, integer *
+ nrhs, complex *ab, integer *ldab, complex *b, integer *ldb, integer *
+ info);
+
+/* Subroutine */ int cpocon_(char *uplo, integer *n, complex *a, integer *lda,
+ real *anorm, real *rcond, complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int cpoequ_(integer *n, complex *a, integer *lda, real *s,
+ real *scond, real *amax, integer *info);
+
+/* Subroutine */ int cporfs_(char *uplo, integer *n, integer *nrhs, complex *
+ a, integer *lda, complex *af, integer *ldaf, complex *b, integer *ldb,
+ complex *x, integer *ldx, real *ferr, real *berr, complex *work,
+ real *rwork, integer *info);
+
+/* Subroutine */ int cposv_(char *uplo, integer *n, integer *nrhs, complex *a,
+ integer *lda, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int cposvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, complex *a, integer *lda, complex *af, integer *ldaf, char *
+ equed, real *s, complex *b, integer *ldb, complex *x, integer *ldx,
+ real *rcond, real *ferr, real *berr, complex *work, real *rwork,
+ integer *info);
+
+/* Subroutine */ int cpotf2_(char *uplo, integer *n, complex *a, integer *lda,
+ integer *info);
+
+/* Subroutine */ int cpotrf_(char *uplo, integer *n, complex *a, integer *lda,
+ integer *info);
+
+/* Subroutine */ int cpotri_(char *uplo, integer *n, complex *a, integer *lda,
+ integer *info);
+
+/* Subroutine */ int cpotrs_(char *uplo, integer *n, integer *nrhs, complex *
+ a, integer *lda, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int cppcon_(char *uplo, integer *n, complex *ap, real *anorm,
+ real *rcond, complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int cppequ_(char *uplo, integer *n, complex *ap, real *s,
+ real *scond, real *amax, integer *info);
+
+/* Subroutine */ int cpprfs_(char *uplo, integer *n, integer *nrhs, complex *
+ ap, complex *afp, complex *b, integer *ldb, complex *x, integer *ldx,
+ real *ferr, real *berr, complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int cppsv_(char *uplo, integer *n, integer *nrhs, complex *
+ ap, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int cppsvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, complex *ap, complex *afp, char *equed, real *s, complex *b,
+ integer *ldb, complex *x, integer *ldx, real *rcond, real *ferr, real
+ *berr, complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int cpptrf_(char *uplo, integer *n, complex *ap, integer *
+ info);
+
+/* Subroutine */ int cpptri_(char *uplo, integer *n, complex *ap, integer *
+ info);
+
+/* Subroutine */ int cpptrs_(char *uplo, integer *n, integer *nrhs, complex *
+ ap, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int cptcon_(integer *n, real *d__, complex *e, real *anorm,
+ real *rcond, real *rwork, integer *info);
+
+/* Subroutine */ int cptrfs_(char *uplo, integer *n, integer *nrhs, real *d__,
+ complex *e, real *df, complex *ef, complex *b, integer *ldb, complex
+ *x, integer *ldx, real *ferr, real *berr, complex *work, real *rwork,
+ integer *info);
+
+/* Subroutine */ int cptsv_(integer *n, integer *nrhs, real *d__, complex *e,
+ complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int cptsvx_(char *fact, integer *n, integer *nrhs, real *d__,
+ complex *e, real *df, complex *ef, complex *b, integer *ldb, complex
+ *x, integer *ldx, real *rcond, real *ferr, real *berr, complex *work,
+ real *rwork, integer *info);
+
+/* Subroutine */ int cpttrf_(integer *n, real *d__, complex *e, integer *info);
+
+/* Subroutine */ int cpttrs_(char *uplo, integer *n, integer *nrhs, real *d__,
+ complex *e, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int cptts2_(integer *iuplo, integer *n, integer *nrhs, real *
+ d__, complex *e, complex *b, integer *ldb);
+
+/* Subroutine */ int crot_(integer *n, complex *cx, integer *incx, complex *
+ cy, integer *incy, real *c__, complex *s);
+
+/* Subroutine */ int cspcon_(char *uplo, integer *n, complex *ap, integer *
+ ipiv, real *anorm, real *rcond, complex *work, integer *info);
+
+/* Subroutine */ int cspmv_(char *uplo, integer *n, complex *alpha, complex *
+ ap, complex *x, integer *incx, complex *beta, complex *y, integer *
+ incy);
+
+/* Subroutine */ int cspr_(char *uplo, integer *n, complex *alpha, complex *x,
+ integer *incx, complex *ap);
+
+/* Subroutine */ int csprfs_(char *uplo, integer *n, integer *nrhs, complex *
+ ap, complex *afp, integer *ipiv, complex *b, integer *ldb, complex *x,
+ integer *ldx, real *ferr, real *berr, complex *work, real *rwork,
+ integer *info);
+
+/* Subroutine */ int cspsv_(char *uplo, integer *n, integer *nrhs, complex *
+ ap, integer *ipiv, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int cspsvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, complex *ap, complex *afp, integer *ipiv, complex *b, integer *
+ ldb, complex *x, integer *ldx, real *rcond, real *ferr, real *berr,
+ complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int csptrf_(char *uplo, integer *n, complex *ap, integer *
+ ipiv, integer *info);
+
+/* Subroutine */ int csptri_(char *uplo, integer *n, complex *ap, integer *
+ ipiv, complex *work, integer *info);
+
+/* Subroutine */ int csptrs_(char *uplo, integer *n, integer *nrhs, complex *
+ ap, integer *ipiv, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int csrot_(integer *n, complex *cx, integer *incx, complex *
+ cy, integer *incy, real *c__, real *s);
+
+/* Subroutine */ int csrscl_(integer *n, real *sa, complex *sx, integer *incx);
+
+/* Subroutine */ int cstedc_(char *compz, integer *n, real *d__, real *e,
+ complex *z__, integer *ldz, complex *work, integer *lwork, real *
+ rwork, integer *lrwork, integer *iwork, integer *liwork, integer *
+ info);
+
+/* Subroutine */ int cstein_(integer *n, real *d__, real *e, integer *m, real
+ *w, integer *iblock, integer *isplit, complex *z__, integer *ldz,
+ real *work, integer *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int csteqr_(char *compz, integer *n, real *d__, real *e,
+ complex *z__, integer *ldz, real *work, integer *info);
+
+/* Subroutine */ int csycon_(char *uplo, integer *n, complex *a, integer *lda,
+ integer *ipiv, real *anorm, real *rcond, complex *work, integer *
+ info);
+
+/* Subroutine */ int csymv_(char *uplo, integer *n, complex *alpha, complex *
+ a, integer *lda, complex *x, integer *incx, complex *beta, complex *y,
+ integer *incy);
+
+/* Subroutine */ int csyr_(char *uplo, integer *n, complex *alpha, complex *x,
+ integer *incx, complex *a, integer *lda);
+
+/* Subroutine */ int csyrfs_(char *uplo, integer *n, integer *nrhs, complex *
+ a, integer *lda, complex *af, integer *ldaf, integer *ipiv, complex *
+ b, integer *ldb, complex *x, integer *ldx, real *ferr, real *berr,
+ complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int csysv_(char *uplo, integer *n, integer *nrhs, complex *a,
+ integer *lda, integer *ipiv, complex *b, integer *ldb, complex *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int csysvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, complex *a, integer *lda, complex *af, integer *ldaf, integer *
+ ipiv, complex *b, integer *ldb, complex *x, integer *ldx, real *rcond,
+ real *ferr, real *berr, complex *work, integer *lwork, real *rwork,
+ integer *info);
+
+/* Subroutine */ int csytf2_(char *uplo, integer *n, complex *a, integer *lda,
+ integer *ipiv, integer *info);
+
+/* Subroutine */ int csytrf_(char *uplo, integer *n, complex *a, integer *lda,
+ integer *ipiv, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int csytri_(char *uplo, integer *n, complex *a, integer *lda,
+ integer *ipiv, complex *work, integer *info);
+
+/* Subroutine */ int csytrs_(char *uplo, integer *n, integer *nrhs, complex *
+ a, integer *lda, integer *ipiv, complex *b, integer *ldb, integer *
+ info);
+
+/* Subroutine */ int ctbcon_(char *norm, char *uplo, char *diag, integer *n,
+ integer *kd, complex *ab, integer *ldab, real *rcond, complex *work,
+ real *rwork, integer *info);
+
+/* Subroutine */ int ctbrfs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *kd, integer *nrhs, complex *ab, integer *ldab, complex *b,
+ integer *ldb, complex *x, integer *ldx, real *ferr, real *berr,
+ complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int ctbtrs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *kd, integer *nrhs, complex *ab, integer *ldab, complex *b,
+ integer *ldb, integer *info);
+
+/* Subroutine */ int ctgevc_(char *side, char *howmny, logical *select,
+ integer *n, complex *a, integer *lda, complex *b, integer *ldb,
+ complex *vl, integer *ldvl, complex *vr, integer *ldvr, integer *mm,
+ integer *m, complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int ctgex2_(logical *wantq, logical *wantz, integer *n,
+ complex *a, integer *lda, complex *b, integer *ldb, complex *q,
+ integer *ldq, complex *z__, integer *ldz, integer *j1, integer *info);
+
+/* Subroutine */ int ctgexc_(logical *wantq, logical *wantz, integer *n,
+ complex *a, integer *lda, complex *b, integer *ldb, complex *q,
+ integer *ldq, complex *z__, integer *ldz, integer *ifst, integer *
+ ilst, integer *info);
+
+/* Subroutine */ int ctgsen_(integer *ijob, logical *wantq, logical *wantz,
+ logical *select, integer *n, complex *a, integer *lda, complex *b,
+ integer *ldb, complex *alpha, complex *beta, complex *q, integer *ldq,
+ complex *z__, integer *ldz, integer *m, real *pl, real *pr, real *
+ dif, complex *work, integer *lwork, integer *iwork, integer *liwork,
+ integer *info);
+
+/* Subroutine */ int ctgsja_(char *jobu, char *jobv, char *jobq, integer *m,
+ integer *p, integer *n, integer *k, integer *l, complex *a, integer *
+ lda, complex *b, integer *ldb, real *tola, real *tolb, real *alpha,
+ real *beta, complex *u, integer *ldu, complex *v, integer *ldv,
+ complex *q, integer *ldq, complex *work, integer *ncycle, integer *
+ info);
+
+/* Subroutine */ int ctgsna_(char *job, char *howmny, logical *select,
+ integer *n, complex *a, integer *lda, complex *b, integer *ldb,
+ complex *vl, integer *ldvl, complex *vr, integer *ldvr, real *s, real
+ *dif, integer *mm, integer *m, complex *work, integer *lwork, integer
+ *iwork, integer *info);
+
+/* Subroutine */ int ctgsy2_(char *trans, integer *ijob, integer *m, integer *
+ n, complex *a, integer *lda, complex *b, integer *ldb, complex *c__,
+ integer *ldc, complex *d__, integer *ldd, complex *e, integer *lde,
+ complex *f, integer *ldf, real *scale, real *rdsum, real *rdscal,
+ integer *info);
+
+/* Subroutine */ int ctgsyl_(char *trans, integer *ijob, integer *m, integer *
+ n, complex *a, integer *lda, complex *b, integer *ldb, complex *c__,
+ integer *ldc, complex *d__, integer *ldd, complex *e, integer *lde,
+ complex *f, integer *ldf, real *scale, real *dif, complex *work,
+ integer *lwork, integer *iwork, integer *info);
+
+/* Subroutine */ int ctpcon_(char *norm, char *uplo, char *diag, integer *n,
+ complex *ap, real *rcond, complex *work, real *rwork, integer *info);
+
+/* Subroutine */ int ctprfs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, complex *ap, complex *b, integer *ldb, complex *x,
+ integer *ldx, real *ferr, real *berr, complex *work, real *rwork,
+ integer *info);
+
+/* Subroutine */ int ctptri_(char *uplo, char *diag, integer *n, complex *ap,
+ integer *info);
+
+/* Subroutine */ int ctptrs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, complex *ap, complex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int ctrcon_(char *norm, char *uplo, char *diag, integer *n,
+ complex *a, integer *lda, real *rcond, complex *work, real *rwork,
+ integer *info);
+
+/* Subroutine */ int ctrevc_(char *side, char *howmny, logical *select,
+ integer *n, complex *t, integer *ldt, complex *vl, integer *ldvl,
+ complex *vr, integer *ldvr, integer *mm, integer *m, complex *work,
+ real *rwork, integer *info);
+
+/* Subroutine */ int ctrexc_(char *compq, integer *n, complex *t, integer *
+ ldt, complex *q, integer *ldq, integer *ifst, integer *ilst, integer *
+ info);
+
+/* Subroutine */ int ctrrfs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, complex *a, integer *lda, complex *b, integer *ldb,
+ complex *x, integer *ldx, real *ferr, real *berr, complex *work, real
+ *rwork, integer *info);
+
+/* Subroutine */ int ctrsen_(char *job, char *compq, logical *select, integer
+ *n, complex *t, integer *ldt, complex *q, integer *ldq, complex *w,
+ integer *m, real *s, real *sep, complex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int ctrsna_(char *job, char *howmny, logical *select,
+ integer *n, complex *t, integer *ldt, complex *vl, integer *ldvl,
+ complex *vr, integer *ldvr, real *s, real *sep, integer *mm, integer *
+ m, complex *work, integer *ldwork, real *rwork, integer *info);
+
+/* Subroutine */ int ctrsyl_(char *trana, char *tranb, integer *isgn, integer
+ *m, integer *n, complex *a, integer *lda, complex *b, integer *ldb,
+ complex *c__, integer *ldc, real *scale, integer *info);
+
+/* Subroutine */ int ctrti2_(char *uplo, char *diag, integer *n, complex *a,
+ integer *lda, integer *info);
+
+/* Subroutine */ int ctrtri_(char *uplo, char *diag, integer *n, complex *a,
+ integer *lda, integer *info);
+
+/* Subroutine */ int ctrtrs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, complex *a, integer *lda, complex *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int ctzrqf_(integer *m, integer *n, complex *a, integer *lda,
+ complex *tau, integer *info);
+
+/* Subroutine */ int ctzrzf_(integer *m, integer *n, complex *a, integer *lda,
+ complex *tau, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cung2l_(integer *m, integer *n, integer *k, complex *a,
+ integer *lda, complex *tau, complex *work, integer *info);
+
+/* Subroutine */ int cung2r_(integer *m, integer *n, integer *k, complex *a,
+ integer *lda, complex *tau, complex *work, integer *info);
+
+/* Subroutine */ int cungbr_(char *vect, integer *m, integer *n, integer *k,
+ complex *a, integer *lda, complex *tau, complex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int cunghr_(integer *n, integer *ilo, integer *ihi, complex *
+ a, integer *lda, complex *tau, complex *work, integer *lwork, integer
+ *info);
+
+/* Subroutine */ int cungl2_(integer *m, integer *n, integer *k, complex *a,
+ integer *lda, complex *tau, complex *work, integer *info);
+
+/* Subroutine */ int cunglq_(integer *m, integer *n, integer *k, complex *a,
+ integer *lda, complex *tau, complex *work, integer *lwork, integer *
+ info);
+
+/* Subroutine */ int cungql_(integer *m, integer *n, integer *k, complex *a,
+ integer *lda, complex *tau, complex *work, integer *lwork, integer *
+ info);
+
+/* Subroutine */ int cungqr_(integer *m, integer *n, integer *k, complex *a,
+ integer *lda, complex *tau, complex *work, integer *lwork, integer *
+ info);
+
+/* Subroutine */ int cungr2_(integer *m, integer *n, integer *k, complex *a,
+ integer *lda, complex *tau, complex *work, integer *info);
+
+/* Subroutine */ int cungrq_(integer *m, integer *n, integer *k, complex *a,
+ integer *lda, complex *tau, complex *work, integer *lwork, integer *
+ info);
+
+/* Subroutine */ int cungtr_(char *uplo, integer *n, complex *a, integer *lda,
+ complex *tau, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cunm2l_(char *side, char *trans, integer *m, integer *n,
+ integer *k, complex *a, integer *lda, complex *tau, complex *c__,
+ integer *ldc, complex *work, integer *info);
+
+/* Subroutine */ int cunm2r_(char *side, char *trans, integer *m, integer *n,
+ integer *k, complex *a, integer *lda, complex *tau, complex *c__,
+ integer *ldc, complex *work, integer *info);
+
+/* Subroutine */ int cunmbr_(char *vect, char *side, char *trans, integer *m,
+ integer *n, integer *k, complex *a, integer *lda, complex *tau,
+ complex *c__, integer *ldc, complex *work, integer *lwork, integer *
+ info);
+
+/* Subroutine */ int cunmhr_(char *side, char *trans, integer *m, integer *n,
+ integer *ilo, integer *ihi, complex *a, integer *lda, complex *tau,
+ complex *c__, integer *ldc, complex *work, integer *lwork, integer *
+ info);
+
+/* Subroutine */ int cunml2_(char *side, char *trans, integer *m, integer *n,
+ integer *k, complex *a, integer *lda, complex *tau, complex *c__,
+ integer *ldc, complex *work, integer *info);
+
+/* Subroutine */ int cunmlq_(char *side, char *trans, integer *m, integer *n,
+ integer *k, complex *a, integer *lda, complex *tau, complex *c__,
+ integer *ldc, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cunmql_(char *side, char *trans, integer *m, integer *n,
+ integer *k, complex *a, integer *lda, complex *tau, complex *c__,
+ integer *ldc, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cunmqr_(char *side, char *trans, integer *m, integer *n,
+ integer *k, complex *a, integer *lda, complex *tau, complex *c__,
+ integer *ldc, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cunmr2_(char *side, char *trans, integer *m, integer *n,
+ integer *k, complex *a, integer *lda, complex *tau, complex *c__,
+ integer *ldc, complex *work, integer *info);
+
+/* Subroutine */ int cunmr3_(char *side, char *trans, integer *m, integer *n,
+ integer *k, integer *l, complex *a, integer *lda, complex *tau,
+ complex *c__, integer *ldc, complex *work, integer *info);
+
+/* Subroutine */ int cunmrq_(char *side, char *trans, integer *m, integer *n,
+ integer *k, complex *a, integer *lda, complex *tau, complex *c__,
+ integer *ldc, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cunmrz_(char *side, char *trans, integer *m, integer *n,
+ integer *k, integer *l, complex *a, integer *lda, complex *tau,
+ complex *c__, integer *ldc, complex *work, integer *lwork, integer *
+ info);
+
+/* Subroutine */ int cunmtr_(char *side, char *uplo, char *trans, integer *m,
+ integer *n, complex *a, integer *lda, complex *tau, complex *c__,
+ integer *ldc, complex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int cupgtr_(char *uplo, integer *n, complex *ap, complex *
+ tau, complex *q, integer *ldq, complex *work, integer *info);
+
+/* Subroutine */ int cupmtr_(char *side, char *uplo, char *trans, integer *m,
+ integer *n, complex *ap, complex *tau, complex *c__, integer *ldc,
+ complex *work, integer *info);
+
+/* Subroutine */ int dbdsdc_(char *uplo, char *compq, integer *n, doublereal *
+ d__, doublereal *e, doublereal *u, integer *ldu, doublereal *vt,
+ integer *ldvt, doublereal *q, integer *iq, doublereal *work, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int dbdsqr_(char *uplo, integer *n, integer *ncvt, integer *
+ nru, integer *ncc, doublereal *d__, doublereal *e, doublereal *vt,
+ integer *ldvt, doublereal *u, integer *ldu, doublereal *c__, integer *
+ ldc, doublereal *work, integer *info);
+
+/* Subroutine */ int ddisna_(char *job, integer *m, integer *n, doublereal *
+ d__, doublereal *sep, integer *info);
+
+/* Subroutine */ int dgbbrd_(char *vect, integer *m, integer *n, integer *ncc,
+ integer *kl, integer *ku, doublereal *ab, integer *ldab, doublereal *
+ d__, doublereal *e, doublereal *q, integer *ldq, doublereal *pt,
+ integer *ldpt, doublereal *c__, integer *ldc, doublereal *work,
+ integer *info);
+
+/* Subroutine */ int dgbcon_(char *norm, integer *n, integer *kl, integer *ku,
+ doublereal *ab, integer *ldab, integer *ipiv, doublereal *anorm,
+ doublereal *rcond, doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dgbequ_(integer *m, integer *n, integer *kl, integer *ku,
+ doublereal *ab, integer *ldab, doublereal *r__, doublereal *c__,
+ doublereal *rowcnd, doublereal *colcnd, doublereal *amax, integer *
+ info);
+
+/* Subroutine */ int dgbrfs_(char *trans, integer *n, integer *kl, integer *
+ ku, integer *nrhs, doublereal *ab, integer *ldab, doublereal *afb,
+ integer *ldafb, integer *ipiv, doublereal *b, integer *ldb,
+ doublereal *x, integer *ldx, doublereal *ferr, doublereal *berr,
+ doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dgbsv_(integer *n, integer *kl, integer *ku, integer *
+ nrhs, doublereal *ab, integer *ldab, integer *ipiv, doublereal *b,
+ integer *ldb, integer *info);
+
+/* Subroutine */ int dgbsvx_(char *fact, char *trans, integer *n, integer *kl,
+ integer *ku, integer *nrhs, doublereal *ab, integer *ldab,
+ doublereal *afb, integer *ldafb, integer *ipiv, char *equed,
+ doublereal *r__, doublereal *c__, doublereal *b, integer *ldb,
+ doublereal *x, integer *ldx, doublereal *rcond, doublereal *ferr,
+ doublereal *berr, doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dgbtf2_(integer *m, integer *n, integer *kl, integer *ku,
+ doublereal *ab, integer *ldab, integer *ipiv, integer *info);
+
+/* Subroutine */ int dgbtrf_(integer *m, integer *n, integer *kl, integer *ku,
+ doublereal *ab, integer *ldab, integer *ipiv, integer *info);
+
+/* Subroutine */ int dgbtrs_(char *trans, integer *n, integer *kl, integer *
+ ku, integer *nrhs, doublereal *ab, integer *ldab, integer *ipiv,
+ doublereal *b, integer *ldb, integer *info);
+
+/* Subroutine */ int dgebak_(char *job, char *side, integer *n, integer *ilo,
+ integer *ihi, doublereal *scale, integer *m, doublereal *v, integer *
+ ldv, integer *info);
+
+/* Subroutine */ int dgebal_(char *job, integer *n, doublereal *a, integer *
+ lda, integer *ilo, integer *ihi, doublereal *scale, integer *info);
+
+/* Subroutine */ int dgebd2_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *d__, doublereal *e, doublereal *tauq, doublereal *
+ taup, doublereal *work, integer *info);
+
+/* Subroutine */ int dgebrd_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *d__, doublereal *e, doublereal *tauq, doublereal *
+ taup, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dgecon_(char *norm, integer *n, doublereal *a, integer *
+ lda, doublereal *anorm, doublereal *rcond, doublereal *work, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int dgeequ_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *r__, doublereal *c__, doublereal *rowcnd, doublereal
+ *colcnd, doublereal *amax, integer *info);
+
+/* Subroutine */ int dgees_(char *jobvs, char *sort, L_fp select, integer *n,
+ doublereal *a, integer *lda, integer *sdim, doublereal *wr,
+ doublereal *wi, doublereal *vs, integer *ldvs, doublereal *work,
+ integer *lwork, logical *bwork, integer *info);
+
+/* Subroutine */ int dgeesx_(char *jobvs, char *sort, L_fp select, char *
+ sense, integer *n, doublereal *a, integer *lda, integer *sdim,
+ doublereal *wr, doublereal *wi, doublereal *vs, integer *ldvs,
+ doublereal *rconde, doublereal *rcondv, doublereal *work, integer *
+ lwork, integer *iwork, integer *liwork, logical *bwork, integer *info);
+
+/* Subroutine */ int dgeev_(char *jobvl, char *jobvr, integer *n, doublereal *
+ a, integer *lda, doublereal *wr, doublereal *wi, doublereal *vl,
+ integer *ldvl, doublereal *vr, integer *ldvr, doublereal *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int dgeevx_(char *balanc, char *jobvl, char *jobvr, char *
+ sense, integer *n, doublereal *a, integer *lda, doublereal *wr,
+ doublereal *wi, doublereal *vl, integer *ldvl, doublereal *vr,
+ integer *ldvr, integer *ilo, integer *ihi, doublereal *scale,
+ doublereal *abnrm, doublereal *rconde, doublereal *rcondv, doublereal
+ *work, integer *lwork, integer *iwork, integer *info);
+
+/* Subroutine */ int dgegs_(char *jobvsl, char *jobvsr, integer *n,
+ doublereal *a, integer *lda, doublereal *b, integer *ldb, doublereal *
+ alphar, doublereal *alphai, doublereal *beta, doublereal *vsl,
+ integer *ldvsl, doublereal *vsr, integer *ldvsr, doublereal *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int dgegv_(char *jobvl, char *jobvr, integer *n, doublereal *
+ a, integer *lda, doublereal *b, integer *ldb, doublereal *alphar,
+ doublereal *alphai, doublereal *beta, doublereal *vl, integer *ldvl,
+ doublereal *vr, integer *ldvr, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dgehd2_(integer *n, integer *ilo, integer *ihi,
+ doublereal *a, integer *lda, doublereal *tau, doublereal *work,
+ integer *info);
+
+/* Subroutine */ int dgehrd_(integer *n, integer *ilo, integer *ihi,
+ doublereal *a, integer *lda, doublereal *tau, doublereal *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int dgelq2_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *tau, doublereal *work, integer *info);
+
+/* Subroutine */ int dgelqf_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *tau, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dgels_(char *trans, integer *m, integer *n, integer *
+ nrhs, doublereal *a, integer *lda, doublereal *b, integer *ldb,
+ doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dgelsd_(integer *m, integer *n, integer *nrhs,
+ doublereal *a, integer *lda, doublereal *b, integer *ldb, doublereal *
+ s, doublereal *rcond, integer *rank, doublereal *work, integer *lwork,
+ integer *iwork, integer *info);
+
+/* Subroutine */ int dgelss_(integer *m, integer *n, integer *nrhs,
+ doublereal *a, integer *lda, doublereal *b, integer *ldb, doublereal *
+ s, doublereal *rcond, integer *rank, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dgelsx_(integer *m, integer *n, integer *nrhs,
+ doublereal *a, integer *lda, doublereal *b, integer *ldb, integer *
+ jpvt, doublereal *rcond, integer *rank, doublereal *work, integer *
+ info);
+
+/* Subroutine */ int dgelsy_(integer *m, integer *n, integer *nrhs,
+ doublereal *a, integer *lda, doublereal *b, integer *ldb, integer *
+ jpvt, doublereal *rcond, integer *rank, doublereal *work, integer *
+ lwork, integer *info);
+
+/* Subroutine */ int dgeql2_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *tau, doublereal *work, integer *info);
+
+/* Subroutine */ int dgeqlf_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *tau, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dgeqp3_(integer *m, integer *n, doublereal *a, integer *
+ lda, integer *jpvt, doublereal *tau, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dgeqpf_(integer *m, integer *n, doublereal *a, integer *
+ lda, integer *jpvt, doublereal *tau, doublereal *work, integer *info);
+
+/* Subroutine */ int dgeqr2_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *tau, doublereal *work, integer *info);
+
+/* Subroutine */ int dgeqrf_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *tau, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dgerfs_(char *trans, integer *n, integer *nrhs,
+ doublereal *a, integer *lda, doublereal *af, integer *ldaf, integer *
+ ipiv, doublereal *b, integer *ldb, doublereal *x, integer *ldx,
+ doublereal *ferr, doublereal *berr, doublereal *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int dgerq2_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *tau, doublereal *work, integer *info);
+
+/* Subroutine */ int dgerqf_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *tau, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dgesc2_(integer *n, doublereal *a, integer *lda,
+ doublereal *rhs, integer *ipiv, integer *jpiv, doublereal *scale);
+
+/* Subroutine */ int dgesdd_(char *jobz, integer *m, integer *n, doublereal *
+ a, integer *lda, doublereal *s, doublereal *u, integer *ldu,
+ doublereal *vt, integer *ldvt, doublereal *work, integer *lwork,
+ integer *iwork, integer *info);
+
+/* Subroutine */ int dgesv_(integer *n, integer *nrhs, doublereal *a, integer
+ *lda, integer *ipiv, doublereal *b, integer *ldb, integer *info);
+
+/* Subroutine */ int dgesvd_(char *jobu, char *jobvt, integer *m, integer *n,
+ doublereal *a, integer *lda, doublereal *s, doublereal *u, integer *
+ ldu, doublereal *vt, integer *ldvt, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dgesvx_(char *fact, char *trans, integer *n, integer *
+ nrhs, doublereal *a, integer *lda, doublereal *af, integer *ldaf,
+ integer *ipiv, char *equed, doublereal *r__, doublereal *c__,
+ doublereal *b, integer *ldb, doublereal *x, integer *ldx, doublereal *
+ rcond, doublereal *ferr, doublereal *berr, doublereal *work, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int dgetc2_(integer *n, doublereal *a, integer *lda, integer
+ *ipiv, integer *jpiv, integer *info);
+
+/* Subroutine */ int dgetf2_(integer *m, integer *n, doublereal *a, integer *
+ lda, integer *ipiv, integer *info);
+
+/* Subroutine */ int dgetrf_(integer *m, integer *n, doublereal *a, integer *
+ lda, integer *ipiv, integer *info);
+
+/* Subroutine */ int dgetri_(integer *n, doublereal *a, integer *lda, integer
+ *ipiv, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dgetrs_(char *trans, integer *n, integer *nrhs,
+ doublereal *a, integer *lda, integer *ipiv, doublereal *b, integer *
+ ldb, integer *info);
+
+/* Subroutine */ int dggbak_(char *job, char *side, integer *n, integer *ilo,
+ integer *ihi, doublereal *lscale, doublereal *rscale, integer *m,
+ doublereal *v, integer *ldv, integer *info);
+
+/* Subroutine */ int dggbal_(char *job, integer *n, doublereal *a, integer *
+ lda, doublereal *b, integer *ldb, integer *ilo, integer *ihi,
+ doublereal *lscale, doublereal *rscale, doublereal *work, integer *
+ info);
+
+/* Subroutine */ int dgges_(char *jobvsl, char *jobvsr, char *sort, L_fp
+ delctg, integer *n, doublereal *a, integer *lda, doublereal *b,
+ integer *ldb, integer *sdim, doublereal *alphar, doublereal *alphai,
+ doublereal *beta, doublereal *vsl, integer *ldvsl, doublereal *vsr,
+ integer *ldvsr, doublereal *work, integer *lwork, logical *bwork,
+ integer *info);
+
+/* Subroutine */ int dggesx_(char *jobvsl, char *jobvsr, char *sort, L_fp
+ delctg, char *sense, integer *n, doublereal *a, integer *lda,
+ doublereal *b, integer *ldb, integer *sdim, doublereal *alphar,
+ doublereal *alphai, doublereal *beta, doublereal *vsl, integer *ldvsl,
+ doublereal *vsr, integer *ldvsr, doublereal *rconde, doublereal *
+ rcondv, doublereal *work, integer *lwork, integer *iwork, integer *
+ liwork, logical *bwork, integer *info);
+
+/* Subroutine */ int dggev_(char *jobvl, char *jobvr, integer *n, doublereal *
+ a, integer *lda, doublereal *b, integer *ldb, doublereal *alphar,
+ doublereal *alphai, doublereal *beta, doublereal *vl, integer *ldvl,
+ doublereal *vr, integer *ldvr, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dggevx_(char *balanc, char *jobvl, char *jobvr, char *
+ sense, integer *n, doublereal *a, integer *lda, doublereal *b,
+ integer *ldb, doublereal *alphar, doublereal *alphai, doublereal *
+ beta, doublereal *vl, integer *ldvl, doublereal *vr, integer *ldvr,
+ integer *ilo, integer *ihi, doublereal *lscale, doublereal *rscale,
+ doublereal *abnrm, doublereal *bbnrm, doublereal *rconde, doublereal *
+ rcondv, doublereal *work, integer *lwork, integer *iwork, logical *
+ bwork, integer *info);
+
+/* Subroutine */ int dggglm_(integer *n, integer *m, integer *p, doublereal *
+ a, integer *lda, doublereal *b, integer *ldb, doublereal *d__,
+ doublereal *x, doublereal *y, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dgghrd_(char *compq, char *compz, integer *n, integer *
+ ilo, integer *ihi, doublereal *a, integer *lda, doublereal *b,
+ integer *ldb, doublereal *q, integer *ldq, doublereal *z__, integer *
+ ldz, integer *info);
+
+/* Subroutine */ int dgglse_(integer *m, integer *n, integer *p, doublereal *
+ a, integer *lda, doublereal *b, integer *ldb, doublereal *c__,
+ doublereal *d__, doublereal *x, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dggqrf_(integer *n, integer *m, integer *p, doublereal *
+ a, integer *lda, doublereal *taua, doublereal *b, integer *ldb,
+ doublereal *taub, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dggrqf_(integer *m, integer *p, integer *n, doublereal *
+ a, integer *lda, doublereal *taua, doublereal *b, integer *ldb,
+ doublereal *taub, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dggsvd_(char *jobu, char *jobv, char *jobq, integer *m,
+ integer *n, integer *p, integer *k, integer *l, doublereal *a,
+ integer *lda, doublereal *b, integer *ldb, doublereal *alpha,
+ doublereal *beta, doublereal *u, integer *ldu, doublereal *v, integer
+ *ldv, doublereal *q, integer *ldq, doublereal *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int dggsvp_(char *jobu, char *jobv, char *jobq, integer *m,
+ integer *p, integer *n, doublereal *a, integer *lda, doublereal *b,
+ integer *ldb, doublereal *tola, doublereal *tolb, integer *k, integer
+ *l, doublereal *u, integer *ldu, doublereal *v, integer *ldv,
+ doublereal *q, integer *ldq, integer *iwork, doublereal *tau,
+ doublereal *work, integer *info);
+
+/* Subroutine */ int dgtcon_(char *norm, integer *n, doublereal *dl,
+ doublereal *d__, doublereal *du, doublereal *du2, integer *ipiv,
+ doublereal *anorm, doublereal *rcond, doublereal *work, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int dgtrfs_(char *trans, integer *n, integer *nrhs,
+ doublereal *dl, doublereal *d__, doublereal *du, doublereal *dlf,
+ doublereal *df, doublereal *duf, doublereal *du2, integer *ipiv,
+ doublereal *b, integer *ldb, doublereal *x, integer *ldx, doublereal *
+ ferr, doublereal *berr, doublereal *work, integer *iwork, integer *
+ info);
+
+/* Subroutine */ int dgtsv_(integer *n, integer *nrhs, doublereal *dl,
+ doublereal *d__, doublereal *du, doublereal *b, integer *ldb, integer
+ *info);
+
+/* Subroutine */ int dgtsvx_(char *fact, char *trans, integer *n, integer *
+ nrhs, doublereal *dl, doublereal *d__, doublereal *du, doublereal *
+ dlf, doublereal *df, doublereal *duf, doublereal *du2, integer *ipiv,
+ doublereal *b, integer *ldb, doublereal *x, integer *ldx, doublereal *
+ rcond, doublereal *ferr, doublereal *berr, doublereal *work, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int dgttrf_(integer *n, doublereal *dl, doublereal *d__,
+ doublereal *du, doublereal *du2, integer *ipiv, integer *info);
+
+/* Subroutine */ int dgttrs_(char *trans, integer *n, integer *nrhs,
+ doublereal *dl, doublereal *d__, doublereal *du, doublereal *du2,
+ integer *ipiv, doublereal *b, integer *ldb, integer *info);
+
+/* Subroutine */ int dgtts2_(integer *itrans, integer *n, integer *nrhs,
+ doublereal *dl, doublereal *d__, doublereal *du, doublereal *du2,
+ integer *ipiv, doublereal *b, integer *ldb);
+
+/* Subroutine */ int dhgeqz_(char *job, char *compq, char *compz, integer *n,
+ integer *ilo, integer *ihi, doublereal *a, integer *lda, doublereal *
+ b, integer *ldb, doublereal *alphar, doublereal *alphai, doublereal *
+ beta, doublereal *q, integer *ldq, doublereal *z__, integer *ldz,
+ doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dhsein_(char *side, char *eigsrc, char *initv, logical *
+ select, integer *n, doublereal *h__, integer *ldh, doublereal *wr,
+ doublereal *wi, doublereal *vl, integer *ldvl, doublereal *vr,
+ integer *ldvr, integer *mm, integer *m, doublereal *work, integer *
+ ifaill, integer *ifailr, integer *info);
+
+/* Subroutine */ int dhseqr_(char *job, char *compz, integer *n, integer *ilo,
+ integer *ihi, doublereal *h__, integer *ldh, doublereal *wr,
+ doublereal *wi, doublereal *z__, integer *ldz, doublereal *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int dlabad_(doublereal *small, doublereal *large);
+
+/* Subroutine */ int dlabrd_(integer *m, integer *n, integer *nb, doublereal *
+ a, integer *lda, doublereal *d__, doublereal *e, doublereal *tauq,
+ doublereal *taup, doublereal *x, integer *ldx, doublereal *y, integer
+ *ldy);
+
+/* Subroutine */ int dlacon_(integer *n, doublereal *v, doublereal *x,
+ integer *isgn, doublereal *est, integer *kase);
+
+/* Subroutine */ int dlacpy_(char *uplo, integer *m, integer *n, doublereal *
+ a, integer *lda, doublereal *b, integer *ldb);
+
+/* Subroutine */ int dladiv_(doublereal *a, doublereal *b, doublereal *c__,
+ doublereal *d__, doublereal *p, doublereal *q);
+
+/* Subroutine */ int dlae2_(doublereal *a, doublereal *b, doublereal *c__,
+ doublereal *rt1, doublereal *rt2);
+
+/* Subroutine */ int dlaebz_(integer *ijob, integer *nitmax, integer *n,
+ integer *mmax, integer *minp, integer *nbmin, doublereal *abstol,
+ doublereal *reltol, doublereal *pivmin, doublereal *d__, doublereal *
+ e, doublereal *e2, integer *nval, doublereal *ab, doublereal *c__,
+ integer *mout, integer *nab, doublereal *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int dlaed0_(integer *icompq, integer *qsiz, integer *n,
+ doublereal *d__, doublereal *e, doublereal *q, integer *ldq,
+ doublereal *qstore, integer *ldqs, doublereal *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int dlaed1_(integer *n, doublereal *d__, doublereal *q,
+ integer *ldq, integer *indxq, doublereal *rho, integer *cutpnt,
+ doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dlaed2_(integer *k, integer *n, integer *n1, doublereal *
+ d__, doublereal *q, integer *ldq, integer *indxq, doublereal *rho,
+ doublereal *z__, doublereal *dlamda, doublereal *w, doublereal *q2,
+ integer *indx, integer *indxc, integer *indxp, integer *coltyp,
+ integer *info);
+
+/* Subroutine */ int dlaed3_(integer *k, integer *n, integer *n1, doublereal *
+ d__, doublereal *q, integer *ldq, doublereal *rho, doublereal *dlamda,
+ doublereal *q2, integer *indx, integer *ctot, doublereal *w,
+ doublereal *s, integer *info);
+
+/* Subroutine */ int dlaed4_(integer *n, integer *i__, doublereal *d__,
+ doublereal *z__, doublereal *delta, doublereal *rho, doublereal *dlam,
+ integer *info);
+
+/* Subroutine */ int dlaed5_(integer *i__, doublereal *d__, doublereal *z__,
+ doublereal *delta, doublereal *rho, doublereal *dlam);
+
+/* Subroutine */ int dlaed6_(integer *kniter, logical *orgati, doublereal *
+ rho, doublereal *d__, doublereal *z__, doublereal *finit, doublereal *
+ tau, integer *info);
+
+/* Subroutine */ int dlaed7_(integer *icompq, integer *n, integer *qsiz,
+ integer *tlvls, integer *curlvl, integer *curpbm, doublereal *d__,
+ doublereal *q, integer *ldq, integer *indxq, doublereal *rho, integer
+ *cutpnt, doublereal *qstore, integer *qptr, integer *prmptr, integer *
+ perm, integer *givptr, integer *givcol, doublereal *givnum,
+ doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dlaed8_(integer *icompq, integer *k, integer *n, integer
+ *qsiz, doublereal *d__, doublereal *q, integer *ldq, integer *indxq,
+ doublereal *rho, integer *cutpnt, doublereal *z__, doublereal *dlamda,
+ doublereal *q2, integer *ldq2, doublereal *w, integer *perm, integer
+ *givptr, integer *givcol, doublereal *givnum, integer *indxp, integer
+ *indx, integer *info);
+
+/* Subroutine */ int dlaed9_(integer *k, integer *kstart, integer *kstop,
+ integer *n, doublereal *d__, doublereal *q, integer *ldq, doublereal *
+ rho, doublereal *dlamda, doublereal *w, doublereal *s, integer *lds,
+ integer *info);
+
+/* Subroutine */ int dlaeda_(integer *n, integer *tlvls, integer *curlvl,
+ integer *curpbm, integer *prmptr, integer *perm, integer *givptr,
+ integer *givcol, doublereal *givnum, doublereal *q, integer *qptr,
+ doublereal *z__, doublereal *ztemp, integer *info);
+
+/* Subroutine */ int dlaein_(logical *rightv, logical *noinit, integer *n,
+ doublereal *h__, integer *ldh, doublereal *wr, doublereal *wi,
+ doublereal *vr, doublereal *vi, doublereal *b, integer *ldb,
+ doublereal *work, doublereal *eps3, doublereal *smlnum, doublereal *
+ bignum, integer *info);
+
+/* Subroutine */ int dlaev2_(doublereal *a, doublereal *b, doublereal *c__,
+ doublereal *rt1, doublereal *rt2, doublereal *cs1, doublereal *sn1);
+
+/* Subroutine */ int dlaexc_(logical *wantq, integer *n, doublereal *t,
+ integer *ldt, doublereal *q, integer *ldq, integer *j1, integer *n1,
+ integer *n2, doublereal *work, integer *info);
+
+/* Subroutine */ int dlag2_(doublereal *a, integer *lda, doublereal *b,
+ integer *ldb, doublereal *safmin, doublereal *scale1, doublereal *
+ scale2, doublereal *wr1, doublereal *wr2, doublereal *wi);
+
+/* Subroutine */ int dlags2_(logical *upper, doublereal *a1, doublereal *a2,
+ doublereal *a3, doublereal *b1, doublereal *b2, doublereal *b3,
+ doublereal *csu, doublereal *snu, doublereal *csv, doublereal *snv,
+ doublereal *csq, doublereal *snq);
+
+/* Subroutine */ int dlagtf_(integer *n, doublereal *a, doublereal *lambda,
+ doublereal *b, doublereal *c__, doublereal *tol, doublereal *d__,
+ integer *in, integer *info);
+
+/* Subroutine */ int dlagtm_(char *trans, integer *n, integer *nrhs,
+ doublereal *alpha, doublereal *dl, doublereal *d__, doublereal *du,
+ doublereal *x, integer *ldx, doublereal *beta, doublereal *b, integer
+ *ldb);
+
+/* Subroutine */ int dlagts_(integer *job, integer *n, doublereal *a,
+ doublereal *b, doublereal *c__, doublereal *d__, integer *in,
+ doublereal *y, doublereal *tol, integer *info);
+
+/* Subroutine */ int dlagv2_(doublereal *a, integer *lda, doublereal *b,
+ integer *ldb, doublereal *alphar, doublereal *alphai, doublereal *
+ beta, doublereal *csl, doublereal *snl, doublereal *csr, doublereal *
+ snr);
+
+/* Subroutine */ int dlahqr_(logical *wantt, logical *wantz, integer *n,
+ integer *ilo, integer *ihi, doublereal *h__, integer *ldh, doublereal
+ *wr, doublereal *wi, integer *iloz, integer *ihiz, doublereal *z__,
+ integer *ldz, integer *info);
+
+/* Subroutine */ int dlahrd_(integer *n, integer *k, integer *nb, doublereal *
+ a, integer *lda, doublereal *tau, doublereal *t, integer *ldt,
+ doublereal *y, integer *ldy);
+
+/* Subroutine */ int dlaic1_(integer *job, integer *j, doublereal *x,
+ doublereal *sest, doublereal *w, doublereal *gamma, doublereal *
+ sestpr, doublereal *s, doublereal *c__);
+
+/* Subroutine */ int dlaln2_(logical *ltrans, integer *na, integer *nw,
+ doublereal *smin, doublereal *ca, doublereal *a, integer *lda,
+ doublereal *d1, doublereal *d2, doublereal *b, integer *ldb,
+ doublereal *wr, doublereal *wi, doublereal *x, integer *ldx,
+ doublereal *scale, doublereal *xnorm, integer *info);
+
+/* Subroutine */ int dlals0_(integer *icompq, integer *nl, integer *nr,
+ integer *sqre, integer *nrhs, doublereal *b, integer *ldb, doublereal
+ *bx, integer *ldbx, integer *perm, integer *givptr, integer *givcol,
+ integer *ldgcol, doublereal *givnum, integer *ldgnum, doublereal *
+ poles, doublereal *difl, doublereal *difr, doublereal *z__, integer *
+ k, doublereal *c__, doublereal *s, doublereal *work, integer *info);
+
+/* Subroutine */ int dlalsa_(integer *icompq, integer *smlsiz, integer *n,
+ integer *nrhs, doublereal *b, integer *ldb, doublereal *bx, integer *
+ ldbx, doublereal *u, integer *ldu, doublereal *vt, integer *k,
+ doublereal *difl, doublereal *difr, doublereal *z__, doublereal *
+ poles, integer *givptr, integer *givcol, integer *ldgcol, integer *
+ perm, doublereal *givnum, doublereal *c__, doublereal *s, doublereal *
+ work, integer *iwork, integer *info);
+
+/* Subroutine */ int dlalsd_(char *uplo, integer *smlsiz, integer *n, integer
+ *nrhs, doublereal *d__, doublereal *e, doublereal *b, integer *ldb,
+ doublereal *rcond, integer *rank, doublereal *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int dlamc1_(integer *beta, integer *t, logical *rnd, logical
+ *ieee1);
+
+/* Subroutine */ int dlamc2_(integer *beta, integer *t, logical *rnd,
+ doublereal *eps, integer *emin, doublereal *rmin, integer *emax,
+ doublereal *rmax);
+
+/* Subroutine */ int dlamc4_(integer *emin, doublereal *start, integer *base);
+
+/* Subroutine */ int dlamc5_(integer *beta, integer *p, integer *emin,
+ logical *ieee, integer *emax, doublereal *rmax);
+
+/* Subroutine */ int dlamrg_(integer *n1, integer *n2, doublereal *a, integer
+ *dtrd1, integer *dtrd2, integer *index);
+
+/* Subroutine */ int dlanv2_(doublereal *a, doublereal *b, doublereal *c__,
+ doublereal *d__, doublereal *rt1r, doublereal *rt1i, doublereal *rt2r,
+ doublereal *rt2i, doublereal *cs, doublereal *sn);
+
+/* Subroutine */ int dlapll_(integer *n, doublereal *x, integer *incx,
+ doublereal *y, integer *incy, doublereal *ssmin);
+
+/* Subroutine */ int dlapmt_(logical *forwrd, integer *m, integer *n,
+ doublereal *x, integer *ldx, integer *k);
+
+/* Subroutine */ int dlaqgb_(integer *m, integer *n, integer *kl, integer *ku,
+ doublereal *ab, integer *ldab, doublereal *r__, doublereal *c__,
+ doublereal *rowcnd, doublereal *colcnd, doublereal *amax, char *equed);
+
+/* Subroutine */ int dlaqge_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *r__, doublereal *c__, doublereal *rowcnd, doublereal
+ *colcnd, doublereal *amax, char *equed);
+
+/* Subroutine */ int dlaqp2_(integer *m, integer *n, integer *offset,
+ doublereal *a, integer *lda, integer *jpvt, doublereal *tau,
+ doublereal *vn1, doublereal *vn2, doublereal *work);
+
+/* Subroutine */ int dlaqps_(integer *m, integer *n, integer *offset, integer
+ *nb, integer *kb, doublereal *a, integer *lda, integer *jpvt,
+ doublereal *tau, doublereal *vn1, doublereal *vn2, doublereal *auxv,
+ doublereal *f, integer *ldf);
+
+/* Subroutine */ int dlaqsb_(char *uplo, integer *n, integer *kd, doublereal *
+ ab, integer *ldab, doublereal *s, doublereal *scond, doublereal *amax,
+ char *equed);
+
+/* Subroutine */ int dlaqsp_(char *uplo, integer *n, doublereal *ap,
+ doublereal *s, doublereal *scond, doublereal *amax, char *equed);
+
+/* Subroutine */ int dlaqsy_(char *uplo, integer *n, doublereal *a, integer *
+ lda, doublereal *s, doublereal *scond, doublereal *amax, char *equed);
+
+/* Subroutine */ int dlaqtr_(logical *ltran, logical *lreal, integer *n,
+ doublereal *t, integer *ldt, doublereal *b, doublereal *w, doublereal
+ *scale, doublereal *x, doublereal *work, integer *info);
+
+/* Subroutine */ int dlar1v_(integer *n, integer *b1, integer *bn, doublereal
+ *sigma, doublereal *d__, doublereal *l, doublereal *ld, doublereal *
+ lld, doublereal *gersch, doublereal *z__, doublereal *ztz, doublereal
+ *mingma, integer *r__, integer *isuppz, doublereal *work);
+
+/* Subroutine */ int dlar2v_(integer *n, doublereal *x, doublereal *y,
+ doublereal *z__, integer *incx, doublereal *c__, doublereal *s,
+ integer *incc);
+
+/* Subroutine */ int dlarf_(char *side, integer *m, integer *n, doublereal *v,
+ integer *incv, doublereal *tau, doublereal *c__, integer *ldc,
+ doublereal *work);
+
+/* Subroutine */ int dlarfb_(char *side, char *trans, char *direct, char *
+ storev, integer *m, integer *n, integer *k, doublereal *v, integer *
+ ldv, doublereal *t, integer *ldt, doublereal *c__, integer *ldc,
+ doublereal *work, integer *ldwork);
+
+/* Subroutine */ int dlarfg_(integer *n, doublereal *alpha, doublereal *x,
+ integer *incx, doublereal *tau);
+
+/* Subroutine */ int dlarft_(char *direct, char *storev, integer *n, integer *
+ k, doublereal *v, integer *ldv, doublereal *tau, doublereal *t,
+ integer *ldt);
+
+/* Subroutine */ int dlarfx_(char *side, integer *m, integer *n, doublereal *
+ v, doublereal *tau, doublereal *c__, integer *ldc, doublereal *work);
+
+/* Subroutine */ int dlargv_(integer *n, doublereal *x, integer *incx,
+ doublereal *y, integer *incy, doublereal *c__, integer *incc);
+
+/* Subroutine */ int dlarnv_(integer *idist, integer *iseed, integer *n,
+ doublereal *x);
+
+/* Subroutine */ int dlarrb_(integer *n, doublereal *d__, doublereal *l,
+ doublereal *ld, doublereal *lld, integer *ifirst, integer *ilast,
+ doublereal *sigma, doublereal *reltol, doublereal *w, doublereal *
+ wgap, doublereal *werr, doublereal *work, integer *iwork, integer *
+ info);
+
+/* Subroutine */ int dlarre_(integer *n, doublereal *d__, doublereal *e,
+ doublereal *tol, integer *nsplit, integer *isplit, integer *m,
+ doublereal *w, doublereal *woff, doublereal *gersch, doublereal *work,
+ integer *info);
+
+/* Subroutine */ int dlarrf_(integer *n, doublereal *d__, doublereal *l,
+ doublereal *ld, doublereal *lld, integer *ifirst, integer *ilast,
+ doublereal *w, doublereal *dplus, doublereal *lplus, doublereal *work,
+ integer *iwork, integer *info);
+
+/* Subroutine */ int dlarrv_(integer *n, doublereal *d__, doublereal *l,
+ integer *isplit, integer *m, doublereal *w, integer *iblock,
+ doublereal *gersch, doublereal *tol, doublereal *z__, integer *ldz,
+ integer *isuppz, doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dlartg_(doublereal *f, doublereal *g, doublereal *cs,
+ doublereal *sn, doublereal *r__);
+
+/* Subroutine */ int dlartv_(integer *n, doublereal *x, integer *incx,
+ doublereal *y, integer *incy, doublereal *c__, doublereal *s, integer
+ *incc);
+
+/* Subroutine */ int dlaruv_(integer *iseed, integer *n, doublereal *x);
+
+/* Subroutine */ int dlarz_(char *side, integer *m, integer *n, integer *l,
+ doublereal *v, integer *incv, doublereal *tau, doublereal *c__,
+ integer *ldc, doublereal *work);
+
+/* Subroutine */ int dlarzb_(char *side, char *trans, char *direct, char *
+ storev, integer *m, integer *n, integer *k, integer *l, doublereal *v,
+ integer *ldv, doublereal *t, integer *ldt, doublereal *c__, integer *
+ ldc, doublereal *work, integer *ldwork);
+
+/* Subroutine */ int dlarzt_(char *direct, char *storev, integer *n, integer *
+ k, doublereal *v, integer *ldv, doublereal *tau, doublereal *t,
+ integer *ldt);
+
+/* Subroutine */ int dlas2_(doublereal *f, doublereal *g, doublereal *h__,
+ doublereal *ssmin, doublereal *ssmax);
+
+/* Subroutine */ int dlascl_(char *type__, integer *kl, integer *ku,
+ doublereal *cfrom, doublereal *cto, integer *m, integer *n,
+ doublereal *a, integer *lda, integer *info);
+
+/* Subroutine */ int dlasd0_(integer *n, integer *sqre, doublereal *d__,
+ doublereal *e, doublereal *u, integer *ldu, doublereal *vt, integer *
+ ldvt, integer *smlsiz, integer *iwork, doublereal *work, integer *
+ info);
+
+/* Subroutine */ int dlasd1_(integer *nl, integer *nr, integer *sqre,
+ doublereal *d__, doublereal *alpha, doublereal *beta, doublereal *u,
+ integer *ldu, doublereal *vt, integer *ldvt, integer *idxq, integer *
+ iwork, doublereal *work, integer *info);
+
+/* Subroutine */ int dlasd2_(integer *nl, integer *nr, integer *sqre, integer
+ *k, doublereal *d__, doublereal *z__, doublereal *alpha, doublereal *
+ beta, doublereal *u, integer *ldu, doublereal *vt, integer *ldvt,
+ doublereal *dsigma, doublereal *u2, integer *ldu2, doublereal *vt2,
+ integer *ldvt2, integer *idxp, integer *idx, integer *idxc, integer *
+ idxq, integer *coltyp, integer *info);
+
+/* Subroutine */ int dlasd3_(integer *nl, integer *nr, integer *sqre, integer
+ *k, doublereal *d__, doublereal *q, integer *ldq, doublereal *dsigma,
+ doublereal *u, integer *ldu, doublereal *u2, integer *ldu2,
+ doublereal *vt, integer *ldvt, doublereal *vt2, integer *ldvt2,
+ integer *idxc, integer *ctot, doublereal *z__, integer *info);
+
+/* Subroutine */ int dlasd4_(integer *n, integer *i__, doublereal *d__,
+ doublereal *z__, doublereal *delta, doublereal *rho, doublereal *
+ sigma, doublereal *work, integer *info);
+
+/* Subroutine */ int dlasd5_(integer *i__, doublereal *d__, doublereal *z__,
+ doublereal *delta, doublereal *rho, doublereal *dsigma, doublereal *
+ work);
+
+/* Subroutine */ int dlasd6_(integer *icompq, integer *nl, integer *nr,
+ integer *sqre, doublereal *d__, doublereal *vf, doublereal *vl,
+ doublereal *alpha, doublereal *beta, integer *idxq, integer *perm,
+ integer *givptr, integer *givcol, integer *ldgcol, doublereal *givnum,
+ integer *ldgnum, doublereal *poles, doublereal *difl, doublereal *
+ difr, doublereal *z__, integer *k, doublereal *c__, doublereal *s,
+ doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dlasd7_(integer *icompq, integer *nl, integer *nr,
+ integer *sqre, integer *k, doublereal *d__, doublereal *z__,
+ doublereal *zw, doublereal *vf, doublereal *vfw, doublereal *vl,
+ doublereal *vlw, doublereal *alpha, doublereal *beta, doublereal *
+ dsigma, integer *idx, integer *idxp, integer *idxq, integer *perm,
+ integer *givptr, integer *givcol, integer *ldgcol, doublereal *givnum,
+ integer *ldgnum, doublereal *c__, doublereal *s, integer *info);
+
+/* Subroutine */ int dlasd8_(integer *icompq, integer *k, doublereal *d__,
+ doublereal *z__, doublereal *vf, doublereal *vl, doublereal *difl,
+ doublereal *difr, integer *lddifr, doublereal *dsigma, doublereal *
+ work, integer *info);
+
+/* Subroutine */ int dlasd9_(integer *icompq, integer *ldu, integer *k,
+ doublereal *d__, doublereal *z__, doublereal *vf, doublereal *vl,
+ doublereal *difl, doublereal *difr, doublereal *dsigma, doublereal *
+ work, integer *info);
+
+/* Subroutine */ int dlasda_(integer *icompq, integer *smlsiz, integer *n,
+ integer *sqre, doublereal *d__, doublereal *e, doublereal *u, integer
+ *ldu, doublereal *vt, integer *k, doublereal *difl, doublereal *difr,
+ doublereal *z__, doublereal *poles, integer *givptr, integer *givcol,
+ integer *ldgcol, integer *perm, doublereal *givnum, doublereal *c__,
+ doublereal *s, doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dlasdq_(char *uplo, integer *sqre, integer *n, integer *
+ ncvt, integer *nru, integer *ncc, doublereal *d__, doublereal *e,
+ doublereal *vt, integer *ldvt, doublereal *u, integer *ldu,
+ doublereal *c__, integer *ldc, doublereal *work, integer *info);
+
+/* Subroutine */ int dlasdt_(integer *n, integer *lvl, integer *nd, integer *
+ inode, integer *ndiml, integer *ndimr, integer *msub);
+
+/* Subroutine */ int dlaset_(char *uplo, integer *m, integer *n, doublereal *
+ alpha, doublereal *beta, doublereal *a, integer *lda);
+
+/* Subroutine */ int dlasq1_(integer *n, doublereal *d__, doublereal *e,
+ doublereal *work, integer *info);
+
+/* Subroutine */ int dlasq2_(integer *n, doublereal *z__, integer *info);
+
+/* Subroutine */ int dlasq3_(integer *i0, integer *n0, doublereal *z__,
+ integer *pp, doublereal *dmin__, doublereal *sigma, doublereal *desig,
+ doublereal *qmax, integer *nfail, integer *iter, integer *ndiv,
+ logical *ieee);
+
+/* Subroutine */ int dlasq4_(integer *i0, integer *n0, doublereal *z__,
+ integer *pp, integer *n0in, doublereal *dmin__, doublereal *dmin1,
+ doublereal *dmin2, doublereal *dn, doublereal *dn1, doublereal *dn2,
+ doublereal *tau, integer *ttype);
+
+/* Subroutine */ int dlasq5_(integer *i0, integer *n0, doublereal *z__,
+ integer *pp, doublereal *tau, doublereal *dmin__, doublereal *dmin1,
+ doublereal *dmin2, doublereal *dn, doublereal *dnm1, doublereal *dnm2,
+ logical *ieee);
+
+/* Subroutine */ int dlasq6_(integer *i0, integer *n0, doublereal *z__,
+ integer *pp, doublereal *dmin__, doublereal *dmin1, doublereal *dmin2,
+ doublereal *dn, doublereal *dnm1, doublereal *dnm2);
+
+/* Subroutine */ int dlasr_(char *side, char *pivot, char *direct, integer *m,
+ integer *n, doublereal *c__, doublereal *s, doublereal *a, integer *
+ lda);
+
+/* Subroutine */ int dlasrt_(char *id, integer *n, doublereal *d__, integer *
+ info);
+
+/* Subroutine */ int dlassq_(integer *n, doublereal *x, integer *incx,
+ doublereal *scale, doublereal *sumsq);
+
+/* Subroutine */ int dlasv2_(doublereal *f, doublereal *g, doublereal *h__,
+ doublereal *ssmin, doublereal *ssmax, doublereal *snr, doublereal *
+ csr, doublereal *snl, doublereal *csl);
+
+/* Subroutine */ int dlaswp_(integer *n, doublereal *a, integer *lda, integer
+ *k1, integer *k2, integer *ipiv, integer *incx);
+
+/* Subroutine */ int dlasy2_(logical *ltranl, logical *ltranr, integer *isgn,
+ integer *n1, integer *n2, doublereal *tl, integer *ldtl, doublereal *
+ tr, integer *ldtr, doublereal *b, integer *ldb, doublereal *scale,
+ doublereal *x, integer *ldx, doublereal *xnorm, integer *info);
+
+/* Subroutine */ int dlasyf_(char *uplo, integer *n, integer *nb, integer *kb,
+ doublereal *a, integer *lda, integer *ipiv, doublereal *w, integer *
+ ldw, integer *info);
+
+/* Subroutine */ int dlatbs_(char *uplo, char *trans, char *diag, char *
+ normin, integer *n, integer *kd, doublereal *ab, integer *ldab,
+ doublereal *x, doublereal *scale, doublereal *cnorm, integer *info);
+
+/* Subroutine */ int dlatdf_(integer *ijob, integer *n, doublereal *z__,
+ integer *ldz, doublereal *rhs, doublereal *rdsum, doublereal *rdscal,
+ integer *ipiv, integer *jpiv);
+
+/* Subroutine */ int dlatps_(char *uplo, char *trans, char *diag, char *
+ normin, integer *n, doublereal *ap, doublereal *x, doublereal *scale,
+ doublereal *cnorm, integer *info);
+
+/* Subroutine */ int dlatrd_(char *uplo, integer *n, integer *nb, doublereal *
+ a, integer *lda, doublereal *e, doublereal *tau, doublereal *w,
+ integer *ldw);
+
+/* Subroutine */ int dlatrs_(char *uplo, char *trans, char *diag, char *
+ normin, integer *n, doublereal *a, integer *lda, doublereal *x,
+ doublereal *scale, doublereal *cnorm, integer *info);
+
+/* Subroutine */ int dlatrz_(integer *m, integer *n, integer *l, doublereal *
+ a, integer *lda, doublereal *tau, doublereal *work);
+
+/* Subroutine */ int dlatzm_(char *side, integer *m, integer *n, doublereal *
+ v, integer *incv, doublereal *tau, doublereal *c1, doublereal *c2,
+ integer *ldc, doublereal *work);
+
+/* Subroutine */ int dlauu2_(char *uplo, integer *n, doublereal *a, integer *
+ lda, integer *info);
+
+/* Subroutine */ int dlauum_(char *uplo, integer *n, doublereal *a, integer *
+ lda, integer *info);
+
+/* Subroutine */ int dopgtr_(char *uplo, integer *n, doublereal *ap,
+ doublereal *tau, doublereal *q, integer *ldq, doublereal *work,
+ integer *info);
+
+/* Subroutine */ int dopmtr_(char *side, char *uplo, char *trans, integer *m,
+ integer *n, doublereal *ap, doublereal *tau, doublereal *c__, integer
+ *ldc, doublereal *work, integer *info);
+
+/* Subroutine */ int dorg2l_(integer *m, integer *n, integer *k, doublereal *
+ a, integer *lda, doublereal *tau, doublereal *work, integer *info);
+
+/* Subroutine */ int dorg2r_(integer *m, integer *n, integer *k, doublereal *
+ a, integer *lda, doublereal *tau, doublereal *work, integer *info);
+
+/* Subroutine */ int dorgbr_(char *vect, integer *m, integer *n, integer *k,
+ doublereal *a, integer *lda, doublereal *tau, doublereal *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int dorghr_(integer *n, integer *ilo, integer *ihi,
+ doublereal *a, integer *lda, doublereal *tau, doublereal *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int dorgl2_(integer *m, integer *n, integer *k, doublereal *
+ a, integer *lda, doublereal *tau, doublereal *work, integer *info);
+
+/* Subroutine */ int dorglq_(integer *m, integer *n, integer *k, doublereal *
+ a, integer *lda, doublereal *tau, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dorgql_(integer *m, integer *n, integer *k, doublereal *
+ a, integer *lda, doublereal *tau, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dorgqr_(integer *m, integer *n, integer *k, doublereal *
+ a, integer *lda, doublereal *tau, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dorgr2_(integer *m, integer *n, integer *k, doublereal *
+ a, integer *lda, doublereal *tau, doublereal *work, integer *info);
+
+/* Subroutine */ int dorgrq_(integer *m, integer *n, integer *k, doublereal *
+ a, integer *lda, doublereal *tau, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dorgtr_(char *uplo, integer *n, doublereal *a, integer *
+ lda, doublereal *tau, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dorm2l_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublereal *a, integer *lda, doublereal *tau, doublereal *
+ c__, integer *ldc, doublereal *work, integer *info);
+
+/* Subroutine */ int dorm2r_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublereal *a, integer *lda, doublereal *tau, doublereal *
+ c__, integer *ldc, doublereal *work, integer *info);
+
+/* Subroutine */ int dormbr_(char *vect, char *side, char *trans, integer *m,
+ integer *n, integer *k, doublereal *a, integer *lda, doublereal *tau,
+ doublereal *c__, integer *ldc, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dormhr_(char *side, char *trans, integer *m, integer *n,
+ integer *ilo, integer *ihi, doublereal *a, integer *lda, doublereal *
+ tau, doublereal *c__, integer *ldc, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dorml2_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublereal *a, integer *lda, doublereal *tau, doublereal *
+ c__, integer *ldc, doublereal *work, integer *info);
+
+/* Subroutine */ int dormlq_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublereal *a, integer *lda, doublereal *tau, doublereal *
+ c__, integer *ldc, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dormql_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublereal *a, integer *lda, doublereal *tau, doublereal *
+ c__, integer *ldc, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dormqr_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublereal *a, integer *lda, doublereal *tau, doublereal *
+ c__, integer *ldc, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dormr2_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublereal *a, integer *lda, doublereal *tau, doublereal *
+ c__, integer *ldc, doublereal *work, integer *info);
+
+/* Subroutine */ int dormr3_(char *side, char *trans, integer *m, integer *n,
+ integer *k, integer *l, doublereal *a, integer *lda, doublereal *tau,
+ doublereal *c__, integer *ldc, doublereal *work, integer *info);
+
+/* Subroutine */ int dormrq_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublereal *a, integer *lda, doublereal *tau, doublereal *
+ c__, integer *ldc, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dormrz_(char *side, char *trans, integer *m, integer *n,
+ integer *k, integer *l, doublereal *a, integer *lda, doublereal *tau,
+ doublereal *c__, integer *ldc, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dormtr_(char *side, char *uplo, char *trans, integer *m,
+ integer *n, doublereal *a, integer *lda, doublereal *tau, doublereal *
+ c__, integer *ldc, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dpbcon_(char *uplo, integer *n, integer *kd, doublereal *
+ ab, integer *ldab, doublereal *anorm, doublereal *rcond, doublereal *
+ work, integer *iwork, integer *info);
+
+/* Subroutine */ int dpbequ_(char *uplo, integer *n, integer *kd, doublereal *
+ ab, integer *ldab, doublereal *s, doublereal *scond, doublereal *amax,
+ integer *info);
+
+/* Subroutine */ int dpbrfs_(char *uplo, integer *n, integer *kd, integer *
+ nrhs, doublereal *ab, integer *ldab, doublereal *afb, integer *ldafb,
+ doublereal *b, integer *ldb, doublereal *x, integer *ldx, doublereal *
+ ferr, doublereal *berr, doublereal *work, integer *iwork, integer *
+ info);
+
+/* Subroutine */ int dpbstf_(char *uplo, integer *n, integer *kd, doublereal *
+ ab, integer *ldab, integer *info);
+
+/* Subroutine */ int dpbsv_(char *uplo, integer *n, integer *kd, integer *
+ nrhs, doublereal *ab, integer *ldab, doublereal *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int dpbsvx_(char *fact, char *uplo, integer *n, integer *kd,
+ integer *nrhs, doublereal *ab, integer *ldab, doublereal *afb,
+ integer *ldafb, char *equed, doublereal *s, doublereal *b, integer *
+ ldb, doublereal *x, integer *ldx, doublereal *rcond, doublereal *ferr,
+ doublereal *berr, doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dpbtf2_(char *uplo, integer *n, integer *kd, doublereal *
+ ab, integer *ldab, integer *info);
+
+/* Subroutine */ int dpbtrf_(char *uplo, integer *n, integer *kd, doublereal *
+ ab, integer *ldab, integer *info);
+
+/* Subroutine */ int dpbtrs_(char *uplo, integer *n, integer *kd, integer *
+ nrhs, doublereal *ab, integer *ldab, doublereal *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int dpocon_(char *uplo, integer *n, doublereal *a, integer *
+ lda, doublereal *anorm, doublereal *rcond, doublereal *work, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int dpoequ_(integer *n, doublereal *a, integer *lda,
+ doublereal *s, doublereal *scond, doublereal *amax, integer *info);
+
+/* Subroutine */ int dporfs_(char *uplo, integer *n, integer *nrhs,
+ doublereal *a, integer *lda, doublereal *af, integer *ldaf,
+ doublereal *b, integer *ldb, doublereal *x, integer *ldx, doublereal *
+ ferr, doublereal *berr, doublereal *work, integer *iwork, integer *
+ info);
+
+/* Subroutine */ int dposv_(char *uplo, integer *n, integer *nrhs, doublereal
+ *a, integer *lda, doublereal *b, integer *ldb, integer *info);
+
+/* Subroutine */ int dposvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, doublereal *a, integer *lda, doublereal *af, integer *ldaf,
+ char *equed, doublereal *s, doublereal *b, integer *ldb, doublereal *
+ x, integer *ldx, doublereal *rcond, doublereal *ferr, doublereal *
+ berr, doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dpotf2_(char *uplo, integer *n, doublereal *a, integer *
+ lda, integer *info);
+
+/* Subroutine */ int dpotrf_(char *uplo, integer *n, doublereal *a, integer *
+ lda, integer *info);
+
+/* Subroutine */ int dpotri_(char *uplo, integer *n, doublereal *a, integer *
+ lda, integer *info);
+
+/* Subroutine */ int dpotrs_(char *uplo, integer *n, integer *nrhs,
+ doublereal *a, integer *lda, doublereal *b, integer *ldb, integer *
+ info);
+
+/* Subroutine */ int dppcon_(char *uplo, integer *n, doublereal *ap,
+ doublereal *anorm, doublereal *rcond, doublereal *work, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int dppequ_(char *uplo, integer *n, doublereal *ap,
+ doublereal *s, doublereal *scond, doublereal *amax, integer *info);
+
+/* Subroutine */ int dpprfs_(char *uplo, integer *n, integer *nrhs,
+ doublereal *ap, doublereal *afp, doublereal *b, integer *ldb,
+ doublereal *x, integer *ldx, doublereal *ferr, doublereal *berr,
+ doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dppsv_(char *uplo, integer *n, integer *nrhs, doublereal
+ *ap, doublereal *b, integer *ldb, integer *info);
+
+/* Subroutine */ int dppsvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, doublereal *ap, doublereal *afp, char *equed, doublereal *s,
+ doublereal *b, integer *ldb, doublereal *x, integer *ldx, doublereal *
+ rcond, doublereal *ferr, doublereal *berr, doublereal *work, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int dpptrf_(char *uplo, integer *n, doublereal *ap, integer *
+ info);
+
+/* Subroutine */ int dpptri_(char *uplo, integer *n, doublereal *ap, integer *
+ info);
+
+/* Subroutine */ int dpptrs_(char *uplo, integer *n, integer *nrhs,
+ doublereal *ap, doublereal *b, integer *ldb, integer *info);
+
+/* Subroutine */ int dptcon_(integer *n, doublereal *d__, doublereal *e,
+ doublereal *anorm, doublereal *rcond, doublereal *work, integer *info);
+
+/* Subroutine */ int dpteqr_(char *compz, integer *n, doublereal *d__,
+ doublereal *e, doublereal *z__, integer *ldz, doublereal *work,
+ integer *info);
+
+/* Subroutine */ int dptrfs_(integer *n, integer *nrhs, doublereal *d__,
+ doublereal *e, doublereal *df, doublereal *ef, doublereal *b, integer
+ *ldb, doublereal *x, integer *ldx, doublereal *ferr, doublereal *berr,
+ doublereal *work, integer *info);
+
+/* Subroutine */ int dptsv_(integer *n, integer *nrhs, doublereal *d__,
+ doublereal *e, doublereal *b, integer *ldb, integer *info);
+
+/* Subroutine */ int dptsvx_(char *fact, integer *n, integer *nrhs,
+ doublereal *d__, doublereal *e, doublereal *df, doublereal *ef,
+ doublereal *b, integer *ldb, doublereal *x, integer *ldx, doublereal *
+ rcond, doublereal *ferr, doublereal *berr, doublereal *work, integer *
+ info);
+
+/* Subroutine */ int dpttrf_(integer *n, doublereal *d__, doublereal *e,
+ integer *info);
+
+/* Subroutine */ int dpttrs_(integer *n, integer *nrhs, doublereal *d__,
+ doublereal *e, doublereal *b, integer *ldb, integer *info);
+
+/* Subroutine */ int dptts2_(integer *n, integer *nrhs, doublereal *d__,
+ doublereal *e, doublereal *b, integer *ldb);
+
+/* Subroutine */ int drscl_(integer *n, doublereal *sa, doublereal *sx,
+ integer *incx);
+
+/* Subroutine */ int dsbev_(char *jobz, char *uplo, integer *n, integer *kd,
+ doublereal *ab, integer *ldab, doublereal *w, doublereal *z__,
+ integer *ldz, doublereal *work, integer *info);
+
+/* Subroutine */ int dsbevd_(char *jobz, char *uplo, integer *n, integer *kd,
+ doublereal *ab, integer *ldab, doublereal *w, doublereal *z__,
+ integer *ldz, doublereal *work, integer *lwork, integer *iwork,
+ integer *liwork, integer *info);
+
+/* Subroutine */ int dsbevx_(char *jobz, char *range, char *uplo, integer *n,
+ integer *kd, doublereal *ab, integer *ldab, doublereal *q, integer *
+ ldq, doublereal *vl, doublereal *vu, integer *il, integer *iu,
+ doublereal *abstol, integer *m, doublereal *w, doublereal *z__,
+ integer *ldz, doublereal *work, integer *iwork, integer *ifail,
+ integer *info);
+
+/* Subroutine */ int dsbgst_(char *vect, char *uplo, integer *n, integer *ka,
+ integer *kb, doublereal *ab, integer *ldab, doublereal *bb, integer *
+ ldbb, doublereal *x, integer *ldx, doublereal *work, integer *info);
+
+/* Subroutine */ int dsbgv_(char *jobz, char *uplo, integer *n, integer *ka,
+ integer *kb, doublereal *ab, integer *ldab, doublereal *bb, integer *
+ ldbb, doublereal *w, doublereal *z__, integer *ldz, doublereal *work,
+ integer *info);
+
+/* Subroutine */ int dsbgvd_(char *jobz, char *uplo, integer *n, integer *ka,
+ integer *kb, doublereal *ab, integer *ldab, doublereal *bb, integer *
+ ldbb, doublereal *w, doublereal *z__, integer *ldz, doublereal *work,
+ integer *lwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int dsbgvx_(char *jobz, char *range, char *uplo, integer *n,
+ integer *ka, integer *kb, doublereal *ab, integer *ldab, doublereal *
+ bb, integer *ldbb, doublereal *q, integer *ldq, doublereal *vl,
+ doublereal *vu, integer *il, integer *iu, doublereal *abstol, integer
+ *m, doublereal *w, doublereal *z__, integer *ldz, doublereal *work,
+ integer *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int dsbtrd_(char *vect, char *uplo, integer *n, integer *kd,
+ doublereal *ab, integer *ldab, doublereal *d__, doublereal *e,
+ doublereal *q, integer *ldq, doublereal *work, integer *info);
+
+/* Subroutine */ int dspcon_(char *uplo, integer *n, doublereal *ap, integer *
+ ipiv, doublereal *anorm, doublereal *rcond, doublereal *work, integer
+ *iwork, integer *info);
+
+/* Subroutine */ int dspev_(char *jobz, char *uplo, integer *n, doublereal *
+ ap, doublereal *w, doublereal *z__, integer *ldz, doublereal *work,
+ integer *info);
+
+/* Subroutine */ int dspevd_(char *jobz, char *uplo, integer *n, doublereal *
+ ap, doublereal *w, doublereal *z__, integer *ldz, doublereal *work,
+ integer *lwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int dspevx_(char *jobz, char *range, char *uplo, integer *n,
+ doublereal *ap, doublereal *vl, doublereal *vu, integer *il, integer *
+ iu, doublereal *abstol, integer *m, doublereal *w, doublereal *z__,
+ integer *ldz, doublereal *work, integer *iwork, integer *ifail,
+ integer *info);
+
+/* Subroutine */ int dspgst_(integer *itype, char *uplo, integer *n,
+ doublereal *ap, doublereal *bp, integer *info);
+
+/* Subroutine */ int dspgv_(integer *itype, char *jobz, char *uplo, integer *
+ n, doublereal *ap, doublereal *bp, doublereal *w, doublereal *z__,
+ integer *ldz, doublereal *work, integer *info);
+
+/* Subroutine */ int dspgvd_(integer *itype, char *jobz, char *uplo, integer *
+ n, doublereal *ap, doublereal *bp, doublereal *w, doublereal *z__,
+ integer *ldz, doublereal *work, integer *lwork, integer *iwork,
+ integer *liwork, integer *info);
+
+/* Subroutine */ int dspgvx_(integer *itype, char *jobz, char *range, char *
+ uplo, integer *n, doublereal *ap, doublereal *bp, doublereal *vl,
+ doublereal *vu, integer *il, integer *iu, doublereal *abstol, integer
+ *m, doublereal *w, doublereal *z__, integer *ldz, doublereal *work,
+ integer *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int dsprfs_(char *uplo, integer *n, integer *nrhs,
+ doublereal *ap, doublereal *afp, integer *ipiv, doublereal *b,
+ integer *ldb, doublereal *x, integer *ldx, doublereal *ferr,
+ doublereal *berr, doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dspsv_(char *uplo, integer *n, integer *nrhs, doublereal
+ *ap, integer *ipiv, doublereal *b, integer *ldb, integer *info);
+
+/* Subroutine */ int dspsvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, doublereal *ap, doublereal *afp, integer *ipiv, doublereal *b,
+ integer *ldb, doublereal *x, integer *ldx, doublereal *rcond,
+ doublereal *ferr, doublereal *berr, doublereal *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int dsptrd_(char *uplo, integer *n, doublereal *ap,
+ doublereal *d__, doublereal *e, doublereal *tau, integer *info);
+
+/* Subroutine */ int dsptrf_(char *uplo, integer *n, doublereal *ap, integer *
+ ipiv, integer *info);
+
+/* Subroutine */ int dsptri_(char *uplo, integer *n, doublereal *ap, integer *
+ ipiv, doublereal *work, integer *info);
+
+/* Subroutine */ int dsptrs_(char *uplo, integer *n, integer *nrhs,
+ doublereal *ap, integer *ipiv, doublereal *b, integer *ldb, integer *
+ info);
+
+/* Subroutine */ int dstebz_(char *range, char *order, integer *n, doublereal
+ *vl, doublereal *vu, integer *il, integer *iu, doublereal *abstol,
+ doublereal *d__, doublereal *e, integer *m, integer *nsplit,
+ doublereal *w, integer *iblock, integer *isplit, doublereal *work,
+ integer *iwork, integer *info);
+
+/* Subroutine */ int dstedc_(char *compz, integer *n, doublereal *d__,
+ doublereal *e, doublereal *z__, integer *ldz, doublereal *work,
+ integer *lwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int dstegr_(char *jobz, char *range, integer *n, doublereal *
+ d__, doublereal *e, doublereal *vl, doublereal *vu, integer *il,
+ integer *iu, doublereal *abstol, integer *m, doublereal *w,
+ doublereal *z__, integer *ldz, integer *isuppz, doublereal *work,
+ integer *lwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int dstein_(integer *n, doublereal *d__, doublereal *e,
+ integer *m, doublereal *w, integer *iblock, integer *isplit,
+ doublereal *z__, integer *ldz, doublereal *work, integer *iwork,
+ integer *ifail, integer *info);
+
+/* Subroutine */ int dsteqr_(char *compz, integer *n, doublereal *d__,
+ doublereal *e, doublereal *z__, integer *ldz, doublereal *work,
+ integer *info);
+
+/* Subroutine */ int dsterf_(integer *n, doublereal *d__, doublereal *e,
+ integer *info);
+
+/* Subroutine */ int dstev_(char *jobz, integer *n, doublereal *d__,
+ doublereal *e, doublereal *z__, integer *ldz, doublereal *work,
+ integer *info);
+
+/* Subroutine */ int dstevd_(char *jobz, integer *n, doublereal *d__,
+ doublereal *e, doublereal *z__, integer *ldz, doublereal *work,
+ integer *lwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int dstevr_(char *jobz, char *range, integer *n, doublereal *
+ d__, doublereal *e, doublereal *vl, doublereal *vu, integer *il,
+ integer *iu, doublereal *abstol, integer *m, doublereal *w,
+ doublereal *z__, integer *ldz, integer *isuppz, doublereal *work,
+ integer *lwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int dstevx_(char *jobz, char *range, integer *n, doublereal *
+ d__, doublereal *e, doublereal *vl, doublereal *vu, integer *il,
+ integer *iu, doublereal *abstol, integer *m, doublereal *w,
+ doublereal *z__, integer *ldz, doublereal *work, integer *iwork,
+ integer *ifail, integer *info);
+
+/* Subroutine */ int dsycon_(char *uplo, integer *n, doublereal *a, integer *
+ lda, integer *ipiv, doublereal *anorm, doublereal *rcond, doublereal *
+ work, integer *iwork, integer *info);
+
+/* Subroutine */ int dsyev_(char *jobz, char *uplo, integer *n, doublereal *a,
+ integer *lda, doublereal *w, doublereal *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int dsyevd_(char *jobz, char *uplo, integer *n, doublereal *
+ a, integer *lda, doublereal *w, doublereal *work, integer *lwork,
+ integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int dsyevr_(char *jobz, char *range, char *uplo, integer *n,
+ doublereal *a, integer *lda, doublereal *vl, doublereal *vu, integer *
+ il, integer *iu, doublereal *abstol, integer *m, doublereal *w,
+ doublereal *z__, integer *ldz, integer *isuppz, doublereal *work,
+ integer *lwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int dsyevx_(char *jobz, char *range, char *uplo, integer *n,
+ doublereal *a, integer *lda, doublereal *vl, doublereal *vu, integer *
+ il, integer *iu, doublereal *abstol, integer *m, doublereal *w,
+ doublereal *z__, integer *ldz, doublereal *work, integer *lwork,
+ integer *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int dsygs2_(integer *itype, char *uplo, integer *n,
+ doublereal *a, integer *lda, doublereal *b, integer *ldb, integer *
+ info);
+
+/* Subroutine */ int dsygst_(integer *itype, char *uplo, integer *n,
+ doublereal *a, integer *lda, doublereal *b, integer *ldb, integer *
+ info);
+
+/* Subroutine */ int dsygv_(integer *itype, char *jobz, char *uplo, integer *
+ n, doublereal *a, integer *lda, doublereal *b, integer *ldb,
+ doublereal *w, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dsygvd_(integer *itype, char *jobz, char *uplo, integer *
+ n, doublereal *a, integer *lda, doublereal *b, integer *ldb,
+ doublereal *w, doublereal *work, integer *lwork, integer *iwork,
+ integer *liwork, integer *info);
+
+/* Subroutine */ int dsygvx_(integer *itype, char *jobz, char *range, char *
+ uplo, integer *n, doublereal *a, integer *lda, doublereal *b, integer
+ *ldb, doublereal *vl, doublereal *vu, integer *il, integer *iu,
+ doublereal *abstol, integer *m, doublereal *w, doublereal *z__,
+ integer *ldz, doublereal *work, integer *lwork, integer *iwork,
+ integer *ifail, integer *info);
+
+/* Subroutine */ int dsyrfs_(char *uplo, integer *n, integer *nrhs,
+ doublereal *a, integer *lda, doublereal *af, integer *ldaf, integer *
+ ipiv, doublereal *b, integer *ldb, doublereal *x, integer *ldx,
+ doublereal *ferr, doublereal *berr, doublereal *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int dsysv_(char *uplo, integer *n, integer *nrhs, doublereal
+ *a, integer *lda, integer *ipiv, doublereal *b, integer *ldb,
+ doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dsysvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, doublereal *a, integer *lda, doublereal *af, integer *ldaf,
+ integer *ipiv, doublereal *b, integer *ldb, doublereal *x, integer *
+ ldx, doublereal *rcond, doublereal *ferr, doublereal *berr,
+ doublereal *work, integer *lwork, integer *iwork, integer *info);
+
+/* Subroutine */ int dsytd2_(char *uplo, integer *n, doublereal *a, integer *
+ lda, doublereal *d__, doublereal *e, doublereal *tau, integer *info);
+
+/* Subroutine */ int dsytf2_(char *uplo, integer *n, doublereal *a, integer *
+ lda, integer *ipiv, integer *info);
+
+/* Subroutine */ int dsytrd_(char *uplo, integer *n, doublereal *a, integer *
+ lda, doublereal *d__, doublereal *e, doublereal *tau, doublereal *
+ work, integer *lwork, integer *info);
+
+/* Subroutine */ int dsytrf_(char *uplo, integer *n, doublereal *a, integer *
+ lda, integer *ipiv, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dsytri_(char *uplo, integer *n, doublereal *a, integer *
+ lda, integer *ipiv, doublereal *work, integer *info);
+
+/* Subroutine */ int dsytrs_(char *uplo, integer *n, integer *nrhs,
+ doublereal *a, integer *lda, integer *ipiv, doublereal *b, integer *
+ ldb, integer *info);
+
+/* Subroutine */ int dtbcon_(char *norm, char *uplo, char *diag, integer *n,
+ integer *kd, doublereal *ab, integer *ldab, doublereal *rcond,
+ doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dtbrfs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *kd, integer *nrhs, doublereal *ab, integer *ldab, doublereal
+ *b, integer *ldb, doublereal *x, integer *ldx, doublereal *ferr,
+ doublereal *berr, doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dtbtrs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *kd, integer *nrhs, doublereal *ab, integer *ldab, doublereal
+ *b, integer *ldb, integer *info);
+
+/* Subroutine */ int dtgevc_(char *side, char *howmny, logical *select,
+ integer *n, doublereal *a, integer *lda, doublereal *b, integer *ldb,
+ doublereal *vl, integer *ldvl, doublereal *vr, integer *ldvr, integer
+ *mm, integer *m, doublereal *work, integer *info);
+
+/* Subroutine */ int dtgex2_(logical *wantq, logical *wantz, integer *n,
+ doublereal *a, integer *lda, doublereal *b, integer *ldb, doublereal *
+ q, integer *ldq, doublereal *z__, integer *ldz, integer *j1, integer *
+ n1, integer *n2, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dtgexc_(logical *wantq, logical *wantz, integer *n,
+ doublereal *a, integer *lda, doublereal *b, integer *ldb, doublereal *
+ q, integer *ldq, doublereal *z__, integer *ldz, integer *ifst,
+ integer *ilst, doublereal *work, integer *lwork, integer *info);
+
+/* Subroutine */ int dtgsen_(integer *ijob, logical *wantq, logical *wantz,
+ logical *select, integer *n, doublereal *a, integer *lda, doublereal *
+ b, integer *ldb, doublereal *alphar, doublereal *alphai, doublereal *
+ beta, doublereal *q, integer *ldq, doublereal *z__, integer *ldz,
+ integer *m, doublereal *pl, doublereal *pr, doublereal *dif,
+ doublereal *work, integer *lwork, integer *iwork, integer *liwork,
+ integer *info);
+
+/* Subroutine */ int dtgsja_(char *jobu, char *jobv, char *jobq, integer *m,
+ integer *p, integer *n, integer *k, integer *l, doublereal *a,
+ integer *lda, doublereal *b, integer *ldb, doublereal *tola,
+ doublereal *tolb, doublereal *alpha, doublereal *beta, doublereal *u,
+ integer *ldu, doublereal *v, integer *ldv, doublereal *q, integer *
+ ldq, doublereal *work, integer *ncycle, integer *info);
+
+/* Subroutine */ int dtgsna_(char *job, char *howmny, logical *select,
+ integer *n, doublereal *a, integer *lda, doublereal *b, integer *ldb,
+ doublereal *vl, integer *ldvl, doublereal *vr, integer *ldvr,
+ doublereal *s, doublereal *dif, integer *mm, integer *m, doublereal *
+ work, integer *lwork, integer *iwork, integer *info);
+
+/* Subroutine */ int dtgsy2_(char *trans, integer *ijob, integer *m, integer *
+ n, doublereal *a, integer *lda, doublereal *b, integer *ldb,
+ doublereal *c__, integer *ldc, doublereal *d__, integer *ldd,
+ doublereal *e, integer *lde, doublereal *f, integer *ldf, doublereal *
+ scale, doublereal *rdsum, doublereal *rdscal, integer *iwork, integer
+ *pq, integer *info);
+
+/* Subroutine */ int dtgsyl_(char *trans, integer *ijob, integer *m, integer *
+ n, doublereal *a, integer *lda, doublereal *b, integer *ldb,
+ doublereal *c__, integer *ldc, doublereal *d__, integer *ldd,
+ doublereal *e, integer *lde, doublereal *f, integer *ldf, doublereal *
+ scale, doublereal *dif, doublereal *work, integer *lwork, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int dtpcon_(char *norm, char *uplo, char *diag, integer *n,
+ doublereal *ap, doublereal *rcond, doublereal *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int dtprfs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, doublereal *ap, doublereal *b, integer *ldb,
+ doublereal *x, integer *ldx, doublereal *ferr, doublereal *berr,
+ doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dtptri_(char *uplo, char *diag, integer *n, doublereal *
+ ap, integer *info);
+
+/* Subroutine */ int dtptrs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, doublereal *ap, doublereal *b, integer *ldb, integer *
+ info);
+
+/* Subroutine */ int dtrcon_(char *norm, char *uplo, char *diag, integer *n,
+ doublereal *a, integer *lda, doublereal *rcond, doublereal *work,
+ integer *iwork, integer *info);
+
+/* Subroutine */ int dtrevc_(char *side, char *howmny, logical *select,
+ integer *n, doublereal *t, integer *ldt, doublereal *vl, integer *
+ ldvl, doublereal *vr, integer *ldvr, integer *mm, integer *m,
+ doublereal *work, integer *info);
+
+/* Subroutine */ int dtrexc_(char *compq, integer *n, doublereal *t, integer *
+ ldt, doublereal *q, integer *ldq, integer *ifst, integer *ilst,
+ doublereal *work, integer *info);
+
+/* Subroutine */ int dtrrfs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, doublereal *a, integer *lda, doublereal *b, integer *
+ ldb, doublereal *x, integer *ldx, doublereal *ferr, doublereal *berr,
+ doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int dtrsen_(char *job, char *compq, logical *select, integer
+ *n, doublereal *t, integer *ldt, doublereal *q, integer *ldq,
+ doublereal *wr, doublereal *wi, integer *m, doublereal *s, doublereal
+ *sep, doublereal *work, integer *lwork, integer *iwork, integer *
+ liwork, integer *info);
+
+/* Subroutine */ int dtrsna_(char *job, char *howmny, logical *select,
+ integer *n, doublereal *t, integer *ldt, doublereal *vl, integer *
+ ldvl, doublereal *vr, integer *ldvr, doublereal *s, doublereal *sep,
+ integer *mm, integer *m, doublereal *work, integer *ldwork, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int dtrsyl_(char *trana, char *tranb, integer *isgn, integer
+ *m, integer *n, doublereal *a, integer *lda, doublereal *b, integer *
+ ldb, doublereal *c__, integer *ldc, doublereal *scale, integer *info);
+
+/* Subroutine */ int dtrti2_(char *uplo, char *diag, integer *n, doublereal *
+ a, integer *lda, integer *info);
+
+/* Subroutine */ int dtrtri_(char *uplo, char *diag, integer *n, doublereal *
+ a, integer *lda, integer *info);
+
+/* Subroutine */ int dtrtrs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, doublereal *a, integer *lda, doublereal *b, integer *
+ ldb, integer *info);
+
+/* Subroutine */ int dtzrqf_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *tau, integer *info);
+
+/* Subroutine */ int dtzrzf_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublereal *tau, doublereal *work, integer *lwork, integer *info);
+
+integer icmax1_(integer *n, complex *cx, integer *incx);
+
+integer ieeeck_(integer *ispec, real *zero, real *one);
+
+integer ilaenv_(integer *ispec, char *name__, char *opts, integer *n1,
+ integer *n2, integer *n3, integer *n4, ftnlen name_len, ftnlen
+ opts_len);
+
+integer izmax1_(integer *n, doublecomplex *cx, integer *incx);
+
+/* Subroutine */ int sbdsdc_(char *uplo, char *compq, integer *n, real *d__,
+ real *e, real *u, integer *ldu, real *vt, integer *ldvt, real *q,
+ integer *iq, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int sbdsqr_(char *uplo, integer *n, integer *ncvt, integer *
+ nru, integer *ncc, real *d__, real *e, real *vt, integer *ldvt, real *
+ u, integer *ldu, real *c__, integer *ldc, real *work, integer *info);
+
+/* Subroutine */ int sdisna_(char *job, integer *m, integer *n, real *d__,
+ real *sep, integer *info);
+
+/* Subroutine */ int sgbbrd_(char *vect, integer *m, integer *n, integer *ncc,
+ integer *kl, integer *ku, real *ab, integer *ldab, real *d__, real *
+ e, real *q, integer *ldq, real *pt, integer *ldpt, real *c__, integer
+ *ldc, real *work, integer *info);
+
+/* Subroutine */ int sgbcon_(char *norm, integer *n, integer *kl, integer *ku,
+ real *ab, integer *ldab, integer *ipiv, real *anorm, real *rcond,
+ real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int sgbequ_(integer *m, integer *n, integer *kl, integer *ku,
+ real *ab, integer *ldab, real *r__, real *c__, real *rowcnd, real *
+ colcnd, real *amax, integer *info);
+
+/* Subroutine */ int sgbrfs_(char *trans, integer *n, integer *kl, integer *
+ ku, integer *nrhs, real *ab, integer *ldab, real *afb, integer *ldafb,
+ integer *ipiv, real *b, integer *ldb, real *x, integer *ldx, real *
+ ferr, real *berr, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int sgbsv_(integer *n, integer *kl, integer *ku, integer *
+ nrhs, real *ab, integer *ldab, integer *ipiv, real *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int sgbsvx_(char *fact, char *trans, integer *n, integer *kl,
+ integer *ku, integer *nrhs, real *ab, integer *ldab, real *afb,
+ integer *ldafb, integer *ipiv, char *equed, real *r__, real *c__,
+ real *b, integer *ldb, real *x, integer *ldx, real *rcond, real *ferr,
+ real *berr, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int sgbtf2_(integer *m, integer *n, integer *kl, integer *ku,
+ real *ab, integer *ldab, integer *ipiv, integer *info);
+
+/* Subroutine */ int sgbtrf_(integer *m, integer *n, integer *kl, integer *ku,
+ real *ab, integer *ldab, integer *ipiv, integer *info);
+
+/* Subroutine */ int sgbtrs_(char *trans, integer *n, integer *kl, integer *
+ ku, integer *nrhs, real *ab, integer *ldab, integer *ipiv, real *b,
+ integer *ldb, integer *info);
+
+/* Subroutine */ int sgebak_(char *job, char *side, integer *n, integer *ilo,
+ integer *ihi, real *scale, integer *m, real *v, integer *ldv, integer
+ *info);
+
+/* Subroutine */ int sgebal_(char *job, integer *n, real *a, integer *lda,
+ integer *ilo, integer *ihi, real *scale, integer *info);
+
+/* Subroutine */ int sgebd2_(integer *m, integer *n, real *a, integer *lda,
+ real *d__, real *e, real *tauq, real *taup, real *work, integer *info);
+
+/* Subroutine */ int sgebrd_(integer *m, integer *n, real *a, integer *lda,
+ real *d__, real *e, real *tauq, real *taup, real *work, integer *
+ lwork, integer *info);
+
+/* Subroutine */ int sgecon_(char *norm, integer *n, real *a, integer *lda,
+ real *anorm, real *rcond, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int sgeequ_(integer *m, integer *n, real *a, integer *lda,
+ real *r__, real *c__, real *rowcnd, real *colcnd, real *amax, integer
+ *info);
+
+/* Subroutine */ int sgees_(char *jobvs, char *sort, L_fp select, integer *n,
+ real *a, integer *lda, integer *sdim, real *wr, real *wi, real *vs,
+ integer *ldvs, real *work, integer *lwork, logical *bwork, integer *
+ info);
+
+/* Subroutine */ int sgeesx_(char *jobvs, char *sort, L_fp select, char *
+ sense, integer *n, real *a, integer *lda, integer *sdim, real *wr,
+ real *wi, real *vs, integer *ldvs, real *rconde, real *rcondv, real *
+ work, integer *lwork, integer *iwork, integer *liwork, logical *bwork,
+ integer *info);
+
+/* Subroutine */ int sgeev_(char *jobvl, char *jobvr, integer *n, real *a,
+ integer *lda, real *wr, real *wi, real *vl, integer *ldvl, real *vr,
+ integer *ldvr, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sgeevx_(char *balanc, char *jobvl, char *jobvr, char *
+ sense, integer *n, real *a, integer *lda, real *wr, real *wi, real *
+ vl, integer *ldvl, real *vr, integer *ldvr, integer *ilo, integer *
+ ihi, real *scale, real *abnrm, real *rconde, real *rcondv, real *work,
+ integer *lwork, integer *iwork, integer *info);
+
+/* Subroutine */ int sgegs_(char *jobvsl, char *jobvsr, integer *n, real *a,
+ integer *lda, real *b, integer *ldb, real *alphar, real *alphai, real
+ *beta, real *vsl, integer *ldvsl, real *vsr, integer *ldvsr, real *
+ work, integer *lwork, integer *info);
+
+/* Subroutine */ int sgegv_(char *jobvl, char *jobvr, integer *n, real *a,
+ integer *lda, real *b, integer *ldb, real *alphar, real *alphai, real
+ *beta, real *vl, integer *ldvl, real *vr, integer *ldvr, real *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int sgehd2_(integer *n, integer *ilo, integer *ihi, real *a,
+ integer *lda, real *tau, real *work, integer *info);
+
+/* Subroutine */ int sgehrd_(integer *n, integer *ilo, integer *ihi, real *a,
+ integer *lda, real *tau, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sgelq2_(integer *m, integer *n, real *a, integer *lda,
+ real *tau, real *work, integer *info);
+
+/* Subroutine */ int sgelqf_(integer *m, integer *n, real *a, integer *lda,
+ real *tau, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sgels_(char *trans, integer *m, integer *n, integer *
+ nrhs, real *a, integer *lda, real *b, integer *ldb, real *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int sgelsd_(integer *m, integer *n, integer *nrhs, real *a,
+ integer *lda, real *b, integer *ldb, real *s, real *rcond, integer *
+ rank, real *work, integer *lwork, integer *iwork, integer *info);
+
+/* Subroutine */ int sgelss_(integer *m, integer *n, integer *nrhs, real *a,
+ integer *lda, real *b, integer *ldb, real *s, real *rcond, integer *
+ rank, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sgelsx_(integer *m, integer *n, integer *nrhs, real *a,
+ integer *lda, real *b, integer *ldb, integer *jpvt, real *rcond,
+ integer *rank, real *work, integer *info);
+
+/* Subroutine */ int sgelsy_(integer *m, integer *n, integer *nrhs, real *a,
+ integer *lda, real *b, integer *ldb, integer *jpvt, real *rcond,
+ integer *rank, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sgeql2_(integer *m, integer *n, real *a, integer *lda,
+ real *tau, real *work, integer *info);
+
+/* Subroutine */ int sgeqlf_(integer *m, integer *n, real *a, integer *lda,
+ real *tau, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sgeqp3_(integer *m, integer *n, real *a, integer *lda,
+ integer *jpvt, real *tau, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sgeqpf_(integer *m, integer *n, real *a, integer *lda,
+ integer *jpvt, real *tau, real *work, integer *info);
+
+/* Subroutine */ int sgeqr2_(integer *m, integer *n, real *a, integer *lda,
+ real *tau, real *work, integer *info);
+
+/* Subroutine */ int sgeqrf_(integer *m, integer *n, real *a, integer *lda,
+ real *tau, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sgerfs_(char *trans, integer *n, integer *nrhs, real *a,
+ integer *lda, real *af, integer *ldaf, integer *ipiv, real *b,
+ integer *ldb, real *x, integer *ldx, real *ferr, real *berr, real *
+ work, integer *iwork, integer *info);
+
+/* Subroutine */ int sgerq2_(integer *m, integer *n, real *a, integer *lda,
+ real *tau, real *work, integer *info);
+
+/* Subroutine */ int sgerqf_(integer *m, integer *n, real *a, integer *lda,
+ real *tau, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sgesc2_(integer *n, real *a, integer *lda, real *rhs,
+ integer *ipiv, integer *jpiv, real *scale);
+
+/* Subroutine */ int sgesdd_(char *jobz, integer *m, integer *n, real *a,
+ integer *lda, real *s, real *u, integer *ldu, real *vt, integer *ldvt,
+ real *work, integer *lwork, integer *iwork, integer *info);
+
+/* Subroutine */ int sgesv_(integer *n, integer *nrhs, real *a, integer *lda,
+ integer *ipiv, real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int sgesvd_(char *jobu, char *jobvt, integer *m, integer *n,
+ real *a, integer *lda, real *s, real *u, integer *ldu, real *vt,
+ integer *ldvt, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sgesvx_(char *fact, char *trans, integer *n, integer *
+ nrhs, real *a, integer *lda, real *af, integer *ldaf, integer *ipiv,
+ char *equed, real *r__, real *c__, real *b, integer *ldb, real *x,
+ integer *ldx, real *rcond, real *ferr, real *berr, real *work,
+ integer *iwork, integer *info);
+
+/* Subroutine */ int sgetc2_(integer *n, real *a, integer *lda, integer *ipiv,
+ integer *jpiv, integer *info);
+
+/* Subroutine */ int sgetf2_(integer *m, integer *n, real *a, integer *lda,
+ integer *ipiv, integer *info);
+
+/* Subroutine */ int sgetrf_(integer *m, integer *n, real *a, integer *lda,
+ integer *ipiv, integer *info);
+
+/* Subroutine */ int sgetri_(integer *n, real *a, integer *lda, integer *ipiv,
+ real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sgetrs_(char *trans, integer *n, integer *nrhs, real *a,
+ integer *lda, integer *ipiv, real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int sggbak_(char *job, char *side, integer *n, integer *ilo,
+ integer *ihi, real *lscale, real *rscale, integer *m, real *v,
+ integer *ldv, integer *info);
+
+/* Subroutine */ int sggbal_(char *job, integer *n, real *a, integer *lda,
+ real *b, integer *ldb, integer *ilo, integer *ihi, real *lscale, real
+ *rscale, real *work, integer *info);
+
+/* Subroutine */ int sgges_(char *jobvsl, char *jobvsr, char *sort, L_fp
+ selctg, integer *n, real *a, integer *lda, real *b, integer *ldb,
+ integer *sdim, real *alphar, real *alphai, real *beta, real *vsl,
+ integer *ldvsl, real *vsr, integer *ldvsr, real *work, integer *lwork,
+ logical *bwork, integer *info);
+
+/* Subroutine */ int sggesx_(char *jobvsl, char *jobvsr, char *sort, L_fp
+ selctg, char *sense, integer *n, real *a, integer *lda, real *b,
+ integer *ldb, integer *sdim, real *alphar, real *alphai, real *beta,
+ real *vsl, integer *ldvsl, real *vsr, integer *ldvsr, real *rconde,
+ real *rcondv, real *work, integer *lwork, integer *iwork, integer *
+ liwork, logical *bwork, integer *info);
+
+/* Subroutine */ int sggev_(char *jobvl, char *jobvr, integer *n, real *a,
+ integer *lda, real *b, integer *ldb, real *alphar, real *alphai, real
+ *beta, real *vl, integer *ldvl, real *vr, integer *ldvr, real *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int sggevx_(char *balanc, char *jobvl, char *jobvr, char *
+ sense, integer *n, real *a, integer *lda, real *b, integer *ldb, real
+ *alphar, real *alphai, real *beta, real *vl, integer *ldvl, real *vr,
+ integer *ldvr, integer *ilo, integer *ihi, real *lscale, real *rscale,
+ real *abnrm, real *bbnrm, real *rconde, real *rcondv, real *work,
+ integer *lwork, integer *iwork, logical *bwork, integer *info);
+
+/* Subroutine */ int sggglm_(integer *n, integer *m, integer *p, real *a,
+ integer *lda, real *b, integer *ldb, real *d__, real *x, real *y,
+ real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sgghrd_(char *compq, char *compz, integer *n, integer *
+ ilo, integer *ihi, real *a, integer *lda, real *b, integer *ldb, real
+ *q, integer *ldq, real *z__, integer *ldz, integer *info);
+
+/* Subroutine */ int sgglse_(integer *m, integer *n, integer *p, real *a,
+ integer *lda, real *b, integer *ldb, real *c__, real *d__, real *x,
+ real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sggqrf_(integer *n, integer *m, integer *p, real *a,
+ integer *lda, real *taua, real *b, integer *ldb, real *taub, real *
+ work, integer *lwork, integer *info);
+
+/* Subroutine */ int sggrqf_(integer *m, integer *p, integer *n, real *a,
+ integer *lda, real *taua, real *b, integer *ldb, real *taub, real *
+ work, integer *lwork, integer *info);
+
+/* Subroutine */ int sggsvd_(char *jobu, char *jobv, char *jobq, integer *m,
+ integer *n, integer *p, integer *k, integer *l, real *a, integer *lda,
+ real *b, integer *ldb, real *alpha, real *beta, real *u, integer *
+ ldu, real *v, integer *ldv, real *q, integer *ldq, real *work,
+ integer *iwork, integer *info);
+
+/* Subroutine */ int sggsvp_(char *jobu, char *jobv, char *jobq, integer *m,
+ integer *p, integer *n, real *a, integer *lda, real *b, integer *ldb,
+ real *tola, real *tolb, integer *k, integer *l, real *u, integer *ldu,
+ real *v, integer *ldv, real *q, integer *ldq, integer *iwork, real *
+ tau, real *work, integer *info);
+
+/* Subroutine */ int sgtcon_(char *norm, integer *n, real *dl, real *d__,
+ real *du, real *du2, integer *ipiv, real *anorm, real *rcond, real *
+ work, integer *iwork, integer *info);
+
+/* Subroutine */ int sgtrfs_(char *trans, integer *n, integer *nrhs, real *dl,
+ real *d__, real *du, real *dlf, real *df, real *duf, real *du2,
+ integer *ipiv, real *b, integer *ldb, real *x, integer *ldx, real *
+ ferr, real *berr, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int sgtsv_(integer *n, integer *nrhs, real *dl, real *d__,
+ real *du, real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int sgtsvx_(char *fact, char *trans, integer *n, integer *
+ nrhs, real *dl, real *d__, real *du, real *dlf, real *df, real *duf,
+ real *du2, integer *ipiv, real *b, integer *ldb, real *x, integer *
+ ldx, real *rcond, real *ferr, real *berr, real *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int sgttrf_(integer *n, real *dl, real *d__, real *du, real *
+ du2, integer *ipiv, integer *info);
+
+/* Subroutine */ int sgttrs_(char *trans, integer *n, integer *nrhs, real *dl,
+ real *d__, real *du, real *du2, integer *ipiv, real *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int sgtts2_(integer *itrans, integer *n, integer *nrhs, real
+ *dl, real *d__, real *du, real *du2, integer *ipiv, real *b, integer *
+ ldb);
+
+/* Subroutine */ int shgeqz_(char *job, char *compq, char *compz, integer *n,
+ integer *ilo, integer *ihi, real *a, integer *lda, real *b, integer *
+ ldb, real *alphar, real *alphai, real *beta, real *q, integer *ldq,
+ real *z__, integer *ldz, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int shsein_(char *side, char *eigsrc, char *initv, logical *
+ select, integer *n, real *h__, integer *ldh, real *wr, real *wi, real
+ *vl, integer *ldvl, real *vr, integer *ldvr, integer *mm, integer *m,
+ real *work, integer *ifaill, integer *ifailr, integer *info);
+
+/* Subroutine */ int shseqr_(char *job, char *compz, integer *n, integer *ilo,
+ integer *ihi, real *h__, integer *ldh, real *wr, real *wi, real *z__,
+ integer *ldz, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int slabad_(real *small, real *large);
+
+/* Subroutine */ int slabrd_(integer *m, integer *n, integer *nb, real *a,
+ integer *lda, real *d__, real *e, real *tauq, real *taup, real *x,
+ integer *ldx, real *y, integer *ldy);
+
+/* Subroutine */ int slacon_(integer *n, real *v, real *x, integer *isgn,
+ real *est, integer *kase);
+
+/* Subroutine */ int slacpy_(char *uplo, integer *m, integer *n, real *a,
+ integer *lda, real *b, integer *ldb);
+
+/* Subroutine */ int sladiv_(real *a, real *b, real *c__, real *d__, real *p,
+ real *q);
+
+/* Subroutine */ int slae2_(real *a, real *b, real *c__, real *rt1, real *rt2);
+
+/* Subroutine */ int slaebz_(integer *ijob, integer *nitmax, integer *n,
+ integer *mmax, integer *minp, integer *nbmin, real *abstol, real *
+ reltol, real *pivmin, real *d__, real *e, real *e2, integer *nval,
+ real *ab, real *c__, integer *mout, integer *nab, real *work, integer
+ *iwork, integer *info);
+
+/* Subroutine */ int slaed0_(integer *icompq, integer *qsiz, integer *n, real
+ *d__, real *e, real *q, integer *ldq, real *qstore, integer *ldqs,
+ real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int slaed1_(integer *n, real *d__, real *q, integer *ldq,
+ integer *indxq, real *rho, integer *cutpnt, real *work, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int slaed2_(integer *k, integer *n, integer *n1, real *d__,
+ real *q, integer *ldq, integer *indxq, real *rho, real *z__, real *
+ dlamda, real *w, real *q2, integer *indx, integer *indxc, integer *
+ indxp, integer *coltyp, integer *info);
+
+/* Subroutine */ int slaed3_(integer *k, integer *n, integer *n1, real *d__,
+ real *q, integer *ldq, real *rho, real *dlamda, real *q2, integer *
+ indx, integer *ctot, real *w, real *s, integer *info);
+
+/* Subroutine */ int slaed4_(integer *n, integer *i__, real *d__, real *z__,
+ real *delta, real *rho, real *dlam, integer *info);
+
+/* Subroutine */ int slaed5_(integer *i__, real *d__, real *z__, real *delta,
+ real *rho, real *dlam);
+
+/* Subroutine */ int slaed6_(integer *kniter, logical *orgati, real *rho,
+ real *d__, real *z__, real *finit, real *tau, integer *info);
+
+/* Subroutine */ int slaed7_(integer *icompq, integer *n, integer *qsiz,
+ integer *tlvls, integer *curlvl, integer *curpbm, real *d__, real *q,
+ integer *ldq, integer *indxq, real *rho, integer *cutpnt, real *
+ qstore, integer *qptr, integer *prmptr, integer *perm, integer *
+ givptr, integer *givcol, real *givnum, real *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int slaed8_(integer *icompq, integer *k, integer *n, integer
+ *qsiz, real *d__, real *q, integer *ldq, integer *indxq, real *rho,
+ integer *cutpnt, real *z__, real *dlamda, real *q2, integer *ldq2,
+ real *w, integer *perm, integer *givptr, integer *givcol, real *
+ givnum, integer *indxp, integer *indx, integer *info);
+
+/* Subroutine */ int slaed9_(integer *k, integer *kstart, integer *kstop,
+ integer *n, real *d__, real *q, integer *ldq, real *rho, real *dlamda,
+ real *w, real *s, integer *lds, integer *info);
+
+/* Subroutine */ int slaeda_(integer *n, integer *tlvls, integer *curlvl,
+ integer *curpbm, integer *prmptr, integer *perm, integer *givptr,
+ integer *givcol, real *givnum, real *q, integer *qptr, real *z__,
+ real *ztemp, integer *info);
+
+/* Subroutine */ int slaein_(logical *rightv, logical *noinit, integer *n,
+ real *h__, integer *ldh, real *wr, real *wi, real *vr, real *vi, real
+ *b, integer *ldb, real *work, real *eps3, real *smlnum, real *bignum,
+ integer *info);
+
+/* Subroutine */ int slaev2_(real *a, real *b, real *c__, real *rt1, real *
+ rt2, real *cs1, real *sn1);
+
+/* Subroutine */ int slaexc_(logical *wantq, integer *n, real *t, integer *
+ ldt, real *q, integer *ldq, integer *j1, integer *n1, integer *n2,
+ real *work, integer *info);
+
+/* Subroutine */ int slag2_(real *a, integer *lda, real *b, integer *ldb,
+ real *safmin, real *scale1, real *scale2, real *wr1, real *wr2, real *
+ wi);
+
+/* Subroutine */ int slags2_(logical *upper, real *a1, real *a2, real *a3,
+ real *b1, real *b2, real *b3, real *csu, real *snu, real *csv, real *
+ snv, real *csq, real *snq);
+
+/* Subroutine */ int slagtf_(integer *n, real *a, real *lambda, real *b, real
+ *c__, real *tol, real *d__, integer *in, integer *info);
+
+/* Subroutine */ int slagtm_(char *trans, integer *n, integer *nrhs, real *
+ alpha, real *dl, real *d__, real *du, real *x, integer *ldx, real *
+ beta, real *b, integer *ldb);
+
+/* Subroutine */ int slagts_(integer *job, integer *n, real *a, real *b, real
+ *c__, real *d__, integer *in, real *y, real *tol, integer *info);
+
+/* Subroutine */ int slagv2_(real *a, integer *lda, real *b, integer *ldb,
+ real *alphar, real *alphai, real *beta, real *csl, real *snl, real *
+ csr, real *snr);
+
+/* Subroutine */ int slahqr_(logical *wantt, logical *wantz, integer *n,
+ integer *ilo, integer *ihi, real *h__, integer *ldh, real *wr, real *
+ wi, integer *iloz, integer *ihiz, real *z__, integer *ldz, integer *
+ info);
+
+/* Subroutine */ int slahrd_(integer *n, integer *k, integer *nb, real *a,
+ integer *lda, real *tau, real *t, integer *ldt, real *y, integer *ldy);
+
+/* Subroutine */ int slaic1_(integer *job, integer *j, real *x, real *sest,
+ real *w, real *gamma, real *sestpr, real *s, real *c__);
+
+/* Subroutine */ int slaln2_(logical *ltrans, integer *na, integer *nw, real *
+ smin, real *ca, real *a, integer *lda, real *d1, real *d2, real *b,
+ integer *ldb, real *wr, real *wi, real *x, integer *ldx, real *scale,
+ real *xnorm, integer *info);
+
+/* Subroutine */ int slals0_(integer *icompq, integer *nl, integer *nr,
+ integer *sqre, integer *nrhs, real *b, integer *ldb, real *bx,
+ integer *ldbx, integer *perm, integer *givptr, integer *givcol,
+ integer *ldgcol, real *givnum, integer *ldgnum, real *poles, real *
+ difl, real *difr, real *z__, integer *k, real *c__, real *s, real *
+ work, integer *info);
+
+/* Subroutine */ int slalsa_(integer *icompq, integer *smlsiz, integer *n,
+ integer *nrhs, real *b, integer *ldb, real *bx, integer *ldbx, real *
+ u, integer *ldu, real *vt, integer *k, real *difl, real *difr, real *
+ z__, real *poles, integer *givptr, integer *givcol, integer *ldgcol,
+ integer *perm, real *givnum, real *c__, real *s, real *work, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int slalsd_(char *uplo, integer *smlsiz, integer *n, integer
+ *nrhs, real *d__, real *e, real *b, integer *ldb, real *rcond,
+ integer *rank, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int slamc1_(integer *beta, integer *t, logical *rnd, logical
+ *ieee1);
+
+/* Subroutine */ int slamc2_(integer *beta, integer *t, logical *rnd, real *
+ eps, integer *emin, real *rmin, integer *emax, real *rmax);
+
+/* Subroutine */ int slamc4_(integer *emin, real *start, integer *base);
+
+/* Subroutine */ int slamc5_(integer *beta, integer *p, integer *emin,
+ logical *ieee, integer *emax, real *rmax);
+
+/* Subroutine */ int slamrg_(integer *n1, integer *n2, real *a, integer *
+ strd1, integer *strd2, integer *index);
+
+/* Subroutine */ int slanv2_(real *a, real *b, real *c__, real *d__, real *
+ rt1r, real *rt1i, real *rt2r, real *rt2i, real *cs, real *sn);
+
+/* Subroutine */ int slapll_(integer *n, real *x, integer *incx, real *y,
+ integer *incy, real *ssmin);
+
+/* Subroutine */ int slapmt_(logical *forwrd, integer *m, integer *n, real *x,
+ integer *ldx, integer *k);
+
+/* Subroutine */ int slaqgb_(integer *m, integer *n, integer *kl, integer *ku,
+ real *ab, integer *ldab, real *r__, real *c__, real *rowcnd, real *
+ colcnd, real *amax, char *equed);
+
+/* Subroutine */ int slaqge_(integer *m, integer *n, real *a, integer *lda,
+ real *r__, real *c__, real *rowcnd, real *colcnd, real *amax, char *
+ equed);
+
+/* Subroutine */ int slaqp2_(integer *m, integer *n, integer *offset, real *a,
+ integer *lda, integer *jpvt, real *tau, real *vn1, real *vn2, real *
+ work);
+
+/* Subroutine */ int slaqps_(integer *m, integer *n, integer *offset, integer
+ *nb, integer *kb, real *a, integer *lda, integer *jpvt, real *tau,
+ real *vn1, real *vn2, real *auxv, real *f, integer *ldf);
+
+/* Subroutine */ int slaqsb_(char *uplo, integer *n, integer *kd, real *ab,
+ integer *ldab, real *s, real *scond, real *amax, char *equed);
+
+/* Subroutine */ int slaqsp_(char *uplo, integer *n, real *ap, real *s, real *
+ scond, real *amax, char *equed);
+
+/* Subroutine */ int slaqsy_(char *uplo, integer *n, real *a, integer *lda,
+ real *s, real *scond, real *amax, char *equed);
+
+/* Subroutine */ int slaqtr_(logical *ltran, logical *lreal, integer *n, real
+ *t, integer *ldt, real *b, real *w, real *scale, real *x, real *work,
+ integer *info);
+
+/* Subroutine */ int slar1v_(integer *n, integer *b1, integer *bn, real *
+ sigma, real *d__, real *l, real *ld, real *lld, real *gersch, real *
+ z__, real *ztz, real *mingma, integer *r__, integer *isuppz, real *
+ work);
+
+/* Subroutine */ int slar2v_(integer *n, real *x, real *y, real *z__, integer
+ *incx, real *c__, real *s, integer *incc);
+
+/* Subroutine */ int slarf_(char *side, integer *m, integer *n, real *v,
+ integer *incv, real *tau, real *c__, integer *ldc, real *work);
+
+/* Subroutine */ int slarfb_(char *side, char *trans, char *direct, char *
+ storev, integer *m, integer *n, integer *k, real *v, integer *ldv,
+ real *t, integer *ldt, real *c__, integer *ldc, real *work, integer *
+ ldwork);
+
+/* Subroutine */ int slarfg_(integer *n, real *alpha, real *x, integer *incx,
+ real *tau);
+
+/* Subroutine */ int slarft_(char *direct, char *storev, integer *n, integer *
+ k, real *v, integer *ldv, real *tau, real *t, integer *ldt);
+
+/* Subroutine */ int slarfx_(char *side, integer *m, integer *n, real *v,
+ real *tau, real *c__, integer *ldc, real *work);
+
+/* Subroutine */ int slargv_(integer *n, real *x, integer *incx, real *y,
+ integer *incy, real *c__, integer *incc);
+
+/* Subroutine */ int slarnv_(integer *idist, integer *iseed, integer *n, real
+ *x);
+
+/* Subroutine */ int slarrb_(integer *n, real *d__, real *l, real *ld, real *
+ lld, integer *ifirst, integer *ilast, real *sigma, real *reltol, real
+ *w, real *wgap, real *werr, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int slarre_(integer *n, real *d__, real *e, real *tol,
+ integer *nsplit, integer *isplit, integer *m, real *w, real *woff,
+ real *gersch, real *work, integer *info);
+
+/* Subroutine */ int slarrf_(integer *n, real *d__, real *l, real *ld, real *
+ lld, integer *ifirst, integer *ilast, real *w, real *dplus, real *
+ lplus, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int slarrv_(integer *n, real *d__, real *l, integer *isplit,
+ integer *m, real *w, integer *iblock, real *gersch, real *tol, real *
+ z__, integer *ldz, integer *isuppz, real *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int slartg_(real *f, real *g, real *cs, real *sn, real *r__);
+
+/* Subroutine */ int slartv_(integer *n, real *x, integer *incx, real *y,
+ integer *incy, real *c__, real *s, integer *incc);
+
+/* Subroutine */ int slaruv_(integer *iseed, integer *n, real *x);
+
+/* Subroutine */ int slarz_(char *side, integer *m, integer *n, integer *l,
+ real *v, integer *incv, real *tau, real *c__, integer *ldc, real *
+ work);
+
+/* Subroutine */ int slarzb_(char *side, char *trans, char *direct, char *
+ storev, integer *m, integer *n, integer *k, integer *l, real *v,
+ integer *ldv, real *t, integer *ldt, real *c__, integer *ldc, real *
+ work, integer *ldwork);
+
+/* Subroutine */ int slarzt_(char *direct, char *storev, integer *n, integer *
+ k, real *v, integer *ldv, real *tau, real *t, integer *ldt);
+
+/* Subroutine */ int slas2_(real *f, real *g, real *h__, real *ssmin, real *
+ ssmax);
+
+/* Subroutine */ int slascl_(char *type__, integer *kl, integer *ku, real *
+ cfrom, real *cto, integer *m, integer *n, real *a, integer *lda,
+ integer *info);
+
+/* Subroutine */ int slasd0_(integer *n, integer *sqre, real *d__, real *e,
+ real *u, integer *ldu, real *vt, integer *ldvt, integer *smlsiz,
+ integer *iwork, real *work, integer *info);
+
+/* Subroutine */ int slasd1_(integer *nl, integer *nr, integer *sqre, real *
+ d__, real *alpha, real *beta, real *u, integer *ldu, real *vt,
+ integer *ldvt, integer *idxq, integer *iwork, real *work, integer *
+ info);
+
+/* Subroutine */ int slasd2_(integer *nl, integer *nr, integer *sqre, integer
+ *k, real *d__, real *z__, real *alpha, real *beta, real *u, integer *
+ ldu, real *vt, integer *ldvt, real *dsigma, real *u2, integer *ldu2,
+ real *vt2, integer *ldvt2, integer *idxp, integer *idx, integer *idxc,
+ integer *idxq, integer *coltyp, integer *info);
+
+/* Subroutine */ int slasd3_(integer *nl, integer *nr, integer *sqre, integer
+ *k, real *d__, real *q, integer *ldq, real *dsigma, real *u, integer *
+ ldu, real *u2, integer *ldu2, real *vt, integer *ldvt, real *vt2,
+ integer *ldvt2, integer *idxc, integer *ctot, real *z__, integer *
+ info);
+
+/* Subroutine */ int slasd4_(integer *n, integer *i__, real *d__, real *z__,
+ real *delta, real *rho, real *sigma, real *work, integer *info);
+
+/* Subroutine */ int slasd5_(integer *i__, real *d__, real *z__, real *delta,
+ real *rho, real *dsigma, real *work);
+
+/* Subroutine */ int slasd6_(integer *icompq, integer *nl, integer *nr,
+ integer *sqre, real *d__, real *vf, real *vl, real *alpha, real *beta,
+ integer *idxq, integer *perm, integer *givptr, integer *givcol,
+ integer *ldgcol, real *givnum, integer *ldgnum, real *poles, real *
+ difl, real *difr, real *z__, integer *k, real *c__, real *s, real *
+ work, integer *iwork, integer *info);
+
+/* Subroutine */ int slasd7_(integer *icompq, integer *nl, integer *nr,
+ integer *sqre, integer *k, real *d__, real *z__, real *zw, real *vf,
+ real *vfw, real *vl, real *vlw, real *alpha, real *beta, real *dsigma,
+ integer *idx, integer *idxp, integer *idxq, integer *perm, integer *
+ givptr, integer *givcol, integer *ldgcol, real *givnum, integer *
+ ldgnum, real *c__, real *s, integer *info);
+
+/* Subroutine */ int slasd8_(integer *icompq, integer *k, real *d__, real *
+ z__, real *vf, real *vl, real *difl, real *difr, integer *lddifr,
+ real *dsigma, real *work, integer *info);
+
+/* Subroutine */ int slasd9_(integer *icompq, integer *ldu, integer *k, real *
+ d__, real *z__, real *vf, real *vl, real *difl, real *difr, real *
+ dsigma, real *work, integer *info);
+
+/* Subroutine */ int slasda_(integer *icompq, integer *smlsiz, integer *n,
+ integer *sqre, real *d__, real *e, real *u, integer *ldu, real *vt,
+ integer *k, real *difl, real *difr, real *z__, real *poles, integer *
+ givptr, integer *givcol, integer *ldgcol, integer *perm, real *givnum,
+ real *c__, real *s, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int slasdq_(char *uplo, integer *sqre, integer *n, integer *
+ ncvt, integer *nru, integer *ncc, real *d__, real *e, real *vt,
+ integer *ldvt, real *u, integer *ldu, real *c__, integer *ldc, real *
+ work, integer *info);
+
+/* Subroutine */ int slasdt_(integer *n, integer *lvl, integer *nd, integer *
+ inode, integer *ndiml, integer *ndimr, integer *msub);
+
+/* Subroutine */ int slaset_(char *uplo, integer *m, integer *n, real *alpha,
+ real *beta, real *a, integer *lda);
+
+/* Subroutine */ int slasq1_(integer *n, real *d__, real *e, real *work,
+ integer *info);
+
+/* Subroutine */ int slasq2_(integer *n, real *z__, integer *info);
+
+/* Subroutine */ int slasq3_(integer *i0, integer *n0, real *z__, integer *pp,
+ real *dmin__, real *sigma, real *desig, real *qmax, integer *nfail,
+ integer *iter, integer *ndiv, logical *ieee);
+
+/* Subroutine */ int slasq4_(integer *i0, integer *n0, real *z__, integer *pp,
+ integer *n0in, real *dmin__, real *dmin1, real *dmin2, real *dn,
+ real *dn1, real *dn2, real *tau, integer *ttype);
+
+/* Subroutine */ int slasq5_(integer *i0, integer *n0, real *z__, integer *pp,
+ real *tau, real *dmin__, real *dmin1, real *dmin2, real *dn, real *
+ dnm1, real *dnm2, logical *ieee);
+
+/* Subroutine */ int slasq6_(integer *i0, integer *n0, real *z__, integer *pp,
+ real *dmin__, real *dmin1, real *dmin2, real *dn, real *dnm1, real *
+ dnm2);
+
+/* Subroutine */ int slasr_(char *side, char *pivot, char *direct, integer *m,
+ integer *n, real *c__, real *s, real *a, integer *lda);
+
+/* Subroutine */ int slasrt_(char *id, integer *n, real *d__, integer *info);
+
+/* Subroutine */ int slassq_(integer *n, real *x, integer *incx, real *scale,
+ real *sumsq);
+
+/* Subroutine */ int slasv2_(real *f, real *g, real *h__, real *ssmin, real *
+ ssmax, real *snr, real *csr, real *snl, real *csl);
+
+/* Subroutine */ int slaswp_(integer *n, real *a, integer *lda, integer *k1,
+ integer *k2, integer *ipiv, integer *incx);
+
+/* Subroutine */ int slasy2_(logical *ltranl, logical *ltranr, integer *isgn,
+ integer *n1, integer *n2, real *tl, integer *ldtl, real *tr, integer *
+ ldtr, real *b, integer *ldb, real *scale, real *x, integer *ldx, real
+ *xnorm, integer *info);
+
+/* Subroutine */ int slasyf_(char *uplo, integer *n, integer *nb, integer *kb,
+ real *a, integer *lda, integer *ipiv, real *w, integer *ldw, integer
+ *info);
+
+/* Subroutine */ int slatbs_(char *uplo, char *trans, char *diag, char *
+ normin, integer *n, integer *kd, real *ab, integer *ldab, real *x,
+ real *scale, real *cnorm, integer *info);
+
+/* Subroutine */ int slatdf_(integer *ijob, integer *n, real *z__, integer *
+ ldz, real *rhs, real *rdsum, real *rdscal, integer *ipiv, integer *
+ jpiv);
+
+/* Subroutine */ int slatps_(char *uplo, char *trans, char *diag, char *
+ normin, integer *n, real *ap, real *x, real *scale, real *cnorm,
+ integer *info);
+
+/* Subroutine */ int slatrd_(char *uplo, integer *n, integer *nb, real *a,
+ integer *lda, real *e, real *tau, real *w, integer *ldw);
+
+/* Subroutine */ int slatrs_(char *uplo, char *trans, char *diag, char *
+ normin, integer *n, real *a, integer *lda, real *x, real *scale, real
+ *cnorm, integer *info);
+
+/* Subroutine */ int slatrz_(integer *m, integer *n, integer *l, real *a,
+ integer *lda, real *tau, real *work);
+
+/* Subroutine */ int slatzm_(char *side, integer *m, integer *n, real *v,
+ integer *incv, real *tau, real *c1, real *c2, integer *ldc, real *
+ work);
+
+/* Subroutine */ int slauu2_(char *uplo, integer *n, real *a, integer *lda,
+ integer *info);
+
+/* Subroutine */ int slauum_(char *uplo, integer *n, real *a, integer *lda,
+ integer *info);
+
+/* Subroutine */ int sopgtr_(char *uplo, integer *n, real *ap, real *tau,
+ real *q, integer *ldq, real *work, integer *info);
+
+/* Subroutine */ int sopmtr_(char *side, char *uplo, char *trans, integer *m,
+ integer *n, real *ap, real *tau, real *c__, integer *ldc, real *work,
+ integer *info);
+
+/* Subroutine */ int sorg2l_(integer *m, integer *n, integer *k, real *a,
+ integer *lda, real *tau, real *work, integer *info);
+
+/* Subroutine */ int sorg2r_(integer *m, integer *n, integer *k, real *a,
+ integer *lda, real *tau, real *work, integer *info);
+
+/* Subroutine */ int sorgbr_(char *vect, integer *m, integer *n, integer *k,
+ real *a, integer *lda, real *tau, real *work, integer *lwork, integer
+ *info);
+
+/* Subroutine */ int sorghr_(integer *n, integer *ilo, integer *ihi, real *a,
+ integer *lda, real *tau, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sorgl2_(integer *m, integer *n, integer *k, real *a,
+ integer *lda, real *tau, real *work, integer *info);
+
+/* Subroutine */ int sorglq_(integer *m, integer *n, integer *k, real *a,
+ integer *lda, real *tau, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sorgql_(integer *m, integer *n, integer *k, real *a,
+ integer *lda, real *tau, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sorgqr_(integer *m, integer *n, integer *k, real *a,
+ integer *lda, real *tau, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sorgr2_(integer *m, integer *n, integer *k, real *a,
+ integer *lda, real *tau, real *work, integer *info);
+
+/* Subroutine */ int sorgrq_(integer *m, integer *n, integer *k, real *a,
+ integer *lda, real *tau, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sorgtr_(char *uplo, integer *n, real *a, integer *lda,
+ real *tau, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sorm2l_(char *side, char *trans, integer *m, integer *n,
+ integer *k, real *a, integer *lda, real *tau, real *c__, integer *ldc,
+ real *work, integer *info);
+
+/* Subroutine */ int sorm2r_(char *side, char *trans, integer *m, integer *n,
+ integer *k, real *a, integer *lda, real *tau, real *c__, integer *ldc,
+ real *work, integer *info);
+
+/* Subroutine */ int sormbr_(char *vect, char *side, char *trans, integer *m,
+ integer *n, integer *k, real *a, integer *lda, real *tau, real *c__,
+ integer *ldc, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sormhr_(char *side, char *trans, integer *m, integer *n,
+ integer *ilo, integer *ihi, real *a, integer *lda, real *tau, real *
+ c__, integer *ldc, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sorml2_(char *side, char *trans, integer *m, integer *n,
+ integer *k, real *a, integer *lda, real *tau, real *c__, integer *ldc,
+ real *work, integer *info);
+
+/* Subroutine */ int sormlq_(char *side, char *trans, integer *m, integer *n,
+ integer *k, real *a, integer *lda, real *tau, real *c__, integer *ldc,
+ real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sormql_(char *side, char *trans, integer *m, integer *n,
+ integer *k, real *a, integer *lda, real *tau, real *c__, integer *ldc,
+ real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sormqr_(char *side, char *trans, integer *m, integer *n,
+ integer *k, real *a, integer *lda, real *tau, real *c__, integer *ldc,
+ real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sormr2_(char *side, char *trans, integer *m, integer *n,
+ integer *k, real *a, integer *lda, real *tau, real *c__, integer *ldc,
+ real *work, integer *info);
+
+/* Subroutine */ int sormr3_(char *side, char *trans, integer *m, integer *n,
+ integer *k, integer *l, real *a, integer *lda, real *tau, real *c__,
+ integer *ldc, real *work, integer *info);
+
+/* Subroutine */ int sormrq_(char *side, char *trans, integer *m, integer *n,
+ integer *k, real *a, integer *lda, real *tau, real *c__, integer *ldc,
+ real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sormrz_(char *side, char *trans, integer *m, integer *n,
+ integer *k, integer *l, real *a, integer *lda, real *tau, real *c__,
+ integer *ldc, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int sormtr_(char *side, char *uplo, char *trans, integer *m,
+ integer *n, real *a, integer *lda, real *tau, real *c__, integer *ldc,
+ real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int spbcon_(char *uplo, integer *n, integer *kd, real *ab,
+ integer *ldab, real *anorm, real *rcond, real *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int spbequ_(char *uplo, integer *n, integer *kd, real *ab,
+ integer *ldab, real *s, real *scond, real *amax, integer *info);
+
+/* Subroutine */ int spbrfs_(char *uplo, integer *n, integer *kd, integer *
+ nrhs, real *ab, integer *ldab, real *afb, integer *ldafb, real *b,
+ integer *ldb, real *x, integer *ldx, real *ferr, real *berr, real *
+ work, integer *iwork, integer *info);
+
+/* Subroutine */ int spbstf_(char *uplo, integer *n, integer *kd, real *ab,
+ integer *ldab, integer *info);
+
+/* Subroutine */ int spbsv_(char *uplo, integer *n, integer *kd, integer *
+ nrhs, real *ab, integer *ldab, real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int spbsvx_(char *fact, char *uplo, integer *n, integer *kd,
+ integer *nrhs, real *ab, integer *ldab, real *afb, integer *ldafb,
+ char *equed, real *s, real *b, integer *ldb, real *x, integer *ldx,
+ real *rcond, real *ferr, real *berr, real *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int spbtf2_(char *uplo, integer *n, integer *kd, real *ab,
+ integer *ldab, integer *info);
+
+/* Subroutine */ int spbtrf_(char *uplo, integer *n, integer *kd, real *ab,
+ integer *ldab, integer *info);
+
+/* Subroutine */ int spbtrs_(char *uplo, integer *n, integer *kd, integer *
+ nrhs, real *ab, integer *ldab, real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int spocon_(char *uplo, integer *n, real *a, integer *lda,
+ real *anorm, real *rcond, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int spoequ_(integer *n, real *a, integer *lda, real *s, real
+ *scond, real *amax, integer *info);
+
+/* Subroutine */ int sporfs_(char *uplo, integer *n, integer *nrhs, real *a,
+ integer *lda, real *af, integer *ldaf, real *b, integer *ldb, real *x,
+ integer *ldx, real *ferr, real *berr, real *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int sposv_(char *uplo, integer *n, integer *nrhs, real *a,
+ integer *lda, real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int sposvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, real *a, integer *lda, real *af, integer *ldaf, char *equed,
+ real *s, real *b, integer *ldb, real *x, integer *ldx, real *rcond,
+ real *ferr, real *berr, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int spotf2_(char *uplo, integer *n, real *a, integer *lda,
+ integer *info);
+
+/* Subroutine */ int spotrf_(char *uplo, integer *n, real *a, integer *lda,
+ integer *info);
+
+/* Subroutine */ int spotri_(char *uplo, integer *n, real *a, integer *lda,
+ integer *info);
+
+/* Subroutine */ int spotrs_(char *uplo, integer *n, integer *nrhs, real *a,
+ integer *lda, real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int sppcon_(char *uplo, integer *n, real *ap, real *anorm,
+ real *rcond, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int sppequ_(char *uplo, integer *n, real *ap, real *s, real *
+ scond, real *amax, integer *info);
+
+/* Subroutine */ int spprfs_(char *uplo, integer *n, integer *nrhs, real *ap,
+ real *afp, real *b, integer *ldb, real *x, integer *ldx, real *ferr,
+ real *berr, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int sppsv_(char *uplo, integer *n, integer *nrhs, real *ap,
+ real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int sppsvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, real *ap, real *afp, char *equed, real *s, real *b, integer *
+ ldb, real *x, integer *ldx, real *rcond, real *ferr, real *berr, real
+ *work, integer *iwork, integer *info);
+
+/* Subroutine */ int spptrf_(char *uplo, integer *n, real *ap, integer *info);
+
+/* Subroutine */ int spptri_(char *uplo, integer *n, real *ap, integer *info);
+
+/* Subroutine */ int spptrs_(char *uplo, integer *n, integer *nrhs, real *ap,
+ real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int sptcon_(integer *n, real *d__, real *e, real *anorm,
+ real *rcond, real *work, integer *info);
+
+/* Subroutine */ int spteqr_(char *compz, integer *n, real *d__, real *e,
+ real *z__, integer *ldz, real *work, integer *info);
+
+/* Subroutine */ int sptrfs_(integer *n, integer *nrhs, real *d__, real *e,
+ real *df, real *ef, real *b, integer *ldb, real *x, integer *ldx,
+ real *ferr, real *berr, real *work, integer *info);
+
+/* Subroutine */ int sptsv_(integer *n, integer *nrhs, real *d__, real *e,
+ real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int sptsvx_(char *fact, integer *n, integer *nrhs, real *d__,
+ real *e, real *df, real *ef, real *b, integer *ldb, real *x, integer
+ *ldx, real *rcond, real *ferr, real *berr, real *work, integer *info);
+
+/* Subroutine */ int spttrf_(integer *n, real *d__, real *e, integer *info);
+
+/* Subroutine */ int spttrs_(integer *n, integer *nrhs, real *d__, real *e,
+ real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int sptts2_(integer *n, integer *nrhs, real *d__, real *e,
+ real *b, integer *ldb);
+
+/* Subroutine */ int srscl_(integer *n, real *sa, real *sx, integer *incx);
+
+/* Subroutine */ int ssbev_(char *jobz, char *uplo, integer *n, integer *kd,
+ real *ab, integer *ldab, real *w, real *z__, integer *ldz, real *work,
+ integer *info);
+
+/* Subroutine */ int ssbevd_(char *jobz, char *uplo, integer *n, integer *kd,
+ real *ab, integer *ldab, real *w, real *z__, integer *ldz, real *work,
+ integer *lwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int ssbevx_(char *jobz, char *range, char *uplo, integer *n,
+ integer *kd, real *ab, integer *ldab, real *q, integer *ldq, real *vl,
+ real *vu, integer *il, integer *iu, real *abstol, integer *m, real *
+ w, real *z__, integer *ldz, real *work, integer *iwork, integer *
+ ifail, integer *info);
+
+/* Subroutine */ int ssbgst_(char *vect, char *uplo, integer *n, integer *ka,
+ integer *kb, real *ab, integer *ldab, real *bb, integer *ldbb, real *
+ x, integer *ldx, real *work, integer *info);
+
+/* Subroutine */ int ssbgv_(char *jobz, char *uplo, integer *n, integer *ka,
+ integer *kb, real *ab, integer *ldab, real *bb, integer *ldbb, real *
+ w, real *z__, integer *ldz, real *work, integer *info);
+
+/* Subroutine */ int ssbgvd_(char *jobz, char *uplo, integer *n, integer *ka,
+ integer *kb, real *ab, integer *ldab, real *bb, integer *ldbb, real *
+ w, real *z__, integer *ldz, real *work, integer *lwork, integer *
+ iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int ssbgvx_(char *jobz, char *range, char *uplo, integer *n,
+ integer *ka, integer *kb, real *ab, integer *ldab, real *bb, integer *
+ ldbb, real *q, integer *ldq, real *vl, real *vu, integer *il, integer
+ *iu, real *abstol, integer *m, real *w, real *z__, integer *ldz, real
+ *work, integer *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int ssbtrd_(char *vect, char *uplo, integer *n, integer *kd,
+ real *ab, integer *ldab, real *d__, real *e, real *q, integer *ldq,
+ real *work, integer *info);
+
+/* Subroutine */ int sspcon_(char *uplo, integer *n, real *ap, integer *ipiv,
+ real *anorm, real *rcond, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int sspev_(char *jobz, char *uplo, integer *n, real *ap,
+ real *w, real *z__, integer *ldz, real *work, integer *info);
+
+/* Subroutine */ int sspevd_(char *jobz, char *uplo, integer *n, real *ap,
+ real *w, real *z__, integer *ldz, real *work, integer *lwork, integer
+ *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int sspevx_(char *jobz, char *range, char *uplo, integer *n,
+ real *ap, real *vl, real *vu, integer *il, integer *iu, real *abstol,
+ integer *m, real *w, real *z__, integer *ldz, real *work, integer *
+ iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int sspgst_(integer *itype, char *uplo, integer *n, real *ap,
+ real *bp, integer *info);
+
+/* Subroutine */ int sspgv_(integer *itype, char *jobz, char *uplo, integer *
+ n, real *ap, real *bp, real *w, real *z__, integer *ldz, real *work,
+ integer *info);
+
+/* Subroutine */ int sspgvd_(integer *itype, char *jobz, char *uplo, integer *
+ n, real *ap, real *bp, real *w, real *z__, integer *ldz, real *work,
+ integer *lwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int sspgvx_(integer *itype, char *jobz, char *range, char *
+ uplo, integer *n, real *ap, real *bp, real *vl, real *vu, integer *il,
+ integer *iu, real *abstol, integer *m, real *w, real *z__, integer *
+ ldz, real *work, integer *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int ssprfs_(char *uplo, integer *n, integer *nrhs, real *ap,
+ real *afp, integer *ipiv, real *b, integer *ldb, real *x, integer *
+ ldx, real *ferr, real *berr, real *work, integer *iwork, integer *
+ info);
+
+/* Subroutine */ int sspsv_(char *uplo, integer *n, integer *nrhs, real *ap,
+ integer *ipiv, real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int sspsvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, real *ap, real *afp, integer *ipiv, real *b, integer *ldb, real
+ *x, integer *ldx, real *rcond, real *ferr, real *berr, real *work,
+ integer *iwork, integer *info);
+
+/* Subroutine */ int ssptrd_(char *uplo, integer *n, real *ap, real *d__,
+ real *e, real *tau, integer *info);
+
+/* Subroutine */ int ssptrf_(char *uplo, integer *n, real *ap, integer *ipiv,
+ integer *info);
+
+/* Subroutine */ int ssptri_(char *uplo, integer *n, real *ap, integer *ipiv,
+ real *work, integer *info);
+
+/* Subroutine */ int ssptrs_(char *uplo, integer *n, integer *nrhs, real *ap,
+ integer *ipiv, real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int sstebz_(char *range, char *order, integer *n, real *vl,
+ real *vu, integer *il, integer *iu, real *abstol, real *d__, real *e,
+ integer *m, integer *nsplit, real *w, integer *iblock, integer *
+ isplit, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int sstedc_(char *compz, integer *n, real *d__, real *e,
+ real *z__, integer *ldz, real *work, integer *lwork, integer *iwork,
+ integer *liwork, integer *info);
+
+/* Subroutine */ int sstegr_(char *jobz, char *range, integer *n, real *d__,
+ real *e, real *vl, real *vu, integer *il, integer *iu, real *abstol,
+ integer *m, real *w, real *z__, integer *ldz, integer *isuppz, real *
+ work, integer *lwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int sstein_(integer *n, real *d__, real *e, integer *m, real
+ *w, integer *iblock, integer *isplit, real *z__, integer *ldz, real *
+ work, integer *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int ssteqr_(char *compz, integer *n, real *d__, real *e,
+ real *z__, integer *ldz, real *work, integer *info);
+
+/* Subroutine */ int ssterf_(integer *n, real *d__, real *e, integer *info);
+
+/* Subroutine */ int sstev_(char *jobz, integer *n, real *d__, real *e, real *
+ z__, integer *ldz, real *work, integer *info);
+
+/* Subroutine */ int sstevd_(char *jobz, integer *n, real *d__, real *e, real
+ *z__, integer *ldz, real *work, integer *lwork, integer *iwork,
+ integer *liwork, integer *info);
+
+/* Subroutine */ int sstevr_(char *jobz, char *range, integer *n, real *d__,
+ real *e, real *vl, real *vu, integer *il, integer *iu, real *abstol,
+ integer *m, real *w, real *z__, integer *ldz, integer *isuppz, real *
+ work, integer *lwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int sstevx_(char *jobz, char *range, integer *n, real *d__,
+ real *e, real *vl, real *vu, integer *il, integer *iu, real *abstol,
+ integer *m, real *w, real *z__, integer *ldz, real *work, integer *
+ iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int ssycon_(char *uplo, integer *n, real *a, integer *lda,
+ integer *ipiv, real *anorm, real *rcond, real *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int ssyev_(char *jobz, char *uplo, integer *n, real *a,
+ integer *lda, real *w, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int ssyevd_(char *jobz, char *uplo, integer *n, real *a,
+ integer *lda, real *w, real *work, integer *lwork, integer *iwork,
+ integer *liwork, integer *info);
+
+/* Subroutine */ int ssyevr_(char *jobz, char *range, char *uplo, integer *n,
+ real *a, integer *lda, real *vl, real *vu, integer *il, integer *iu,
+ real *abstol, integer *m, real *w, real *z__, integer *ldz, integer *
+ isuppz, real *work, integer *lwork, integer *iwork, integer *liwork,
+ integer *info);
+
+/* Subroutine */ int ssyevx_(char *jobz, char *range, char *uplo, integer *n,
+ real *a, integer *lda, real *vl, real *vu, integer *il, integer *iu,
+ real *abstol, integer *m, real *w, real *z__, integer *ldz, real *
+ work, integer *lwork, integer *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int ssygs2_(integer *itype, char *uplo, integer *n, real *a,
+ integer *lda, real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int ssygst_(integer *itype, char *uplo, integer *n, real *a,
+ integer *lda, real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int ssygv_(integer *itype, char *jobz, char *uplo, integer *
+ n, real *a, integer *lda, real *b, integer *ldb, real *w, real *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int ssygvd_(integer *itype, char *jobz, char *uplo, integer *
+ n, real *a, integer *lda, real *b, integer *ldb, real *w, real *work,
+ integer *lwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int ssygvx_(integer *itype, char *jobz, char *range, char *
+ uplo, integer *n, real *a, integer *lda, real *b, integer *ldb, real *
+ vl, real *vu, integer *il, integer *iu, real *abstol, integer *m,
+ real *w, real *z__, integer *ldz, real *work, integer *lwork, integer
+ *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int ssyrfs_(char *uplo, integer *n, integer *nrhs, real *a,
+ integer *lda, real *af, integer *ldaf, integer *ipiv, real *b,
+ integer *ldb, real *x, integer *ldx, real *ferr, real *berr, real *
+ work, integer *iwork, integer *info);
+
+/* Subroutine */ int ssysv_(char *uplo, integer *n, integer *nrhs, real *a,
+ integer *lda, integer *ipiv, real *b, integer *ldb, real *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int ssysvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, real *a, integer *lda, real *af, integer *ldaf, integer *ipiv,
+ real *b, integer *ldb, real *x, integer *ldx, real *rcond, real *ferr,
+ real *berr, real *work, integer *lwork, integer *iwork, integer *
+ info);
+
+/* Subroutine */ int ssytd2_(char *uplo, integer *n, real *a, integer *lda,
+ real *d__, real *e, real *tau, integer *info);
+
+/* Subroutine */ int ssytf2_(char *uplo, integer *n, real *a, integer *lda,
+ integer *ipiv, integer *info);
+
+/* Subroutine */ int ssytrd_(char *uplo, integer *n, real *a, integer *lda,
+ real *d__, real *e, real *tau, real *work, integer *lwork, integer *
+ info);
+
+/* Subroutine */ int ssytrf_(char *uplo, integer *n, real *a, integer *lda,
+ integer *ipiv, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int ssytri_(char *uplo, integer *n, real *a, integer *lda,
+ integer *ipiv, real *work, integer *info);
+
+/* Subroutine */ int ssytrs_(char *uplo, integer *n, integer *nrhs, real *a,
+ integer *lda, integer *ipiv, real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int stbcon_(char *norm, char *uplo, char *diag, integer *n,
+ integer *kd, real *ab, integer *ldab, real *rcond, real *work,
+ integer *iwork, integer *info);
+
+/* Subroutine */ int stbrfs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *kd, integer *nrhs, real *ab, integer *ldab, real *b, integer
+ *ldb, real *x, integer *ldx, real *ferr, real *berr, real *work,
+ integer *iwork, integer *info);
+
+/* Subroutine */ int stbtrs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *kd, integer *nrhs, real *ab, integer *ldab, real *b, integer
+ *ldb, integer *info);
+
+/* Subroutine */ int stgevc_(char *side, char *howmny, logical *select,
+ integer *n, real *a, integer *lda, real *b, integer *ldb, real *vl,
+ integer *ldvl, real *vr, integer *ldvr, integer *mm, integer *m, real
+ *work, integer *info);
+
+/* Subroutine */ int stgex2_(logical *wantq, logical *wantz, integer *n, real
+ *a, integer *lda, real *b, integer *ldb, real *q, integer *ldq, real *
+ z__, integer *ldz, integer *j1, integer *n1, integer *n2, real *work,
+ integer *lwork, integer *info);
+
+/* Subroutine */ int stgexc_(logical *wantq, logical *wantz, integer *n, real
+ *a, integer *lda, real *b, integer *ldb, real *q, integer *ldq, real *
+ z__, integer *ldz, integer *ifst, integer *ilst, real *work, integer *
+ lwork, integer *info);
+
+/* Subroutine */ int stgsen_(integer *ijob, logical *wantq, logical *wantz,
+ logical *select, integer *n, real *a, integer *lda, real *b, integer *
+ ldb, real *alphar, real *alphai, real *beta, real *q, integer *ldq,
+ real *z__, integer *ldz, integer *m, real *pl, real *pr, real *dif,
+ real *work, integer *lwork, integer *iwork, integer *liwork, integer *
+ info);
+
+/* Subroutine */ int stgsja_(char *jobu, char *jobv, char *jobq, integer *m,
+ integer *p, integer *n, integer *k, integer *l, real *a, integer *lda,
+ real *b, integer *ldb, real *tola, real *tolb, real *alpha, real *
+ beta, real *u, integer *ldu, real *v, integer *ldv, real *q, integer *
+ ldq, real *work, integer *ncycle, integer *info);
+
+/* Subroutine */ int stgsna_(char *job, char *howmny, logical *select,
+ integer *n, real *a, integer *lda, real *b, integer *ldb, real *vl,
+ integer *ldvl, real *vr, integer *ldvr, real *s, real *dif, integer *
+ mm, integer *m, real *work, integer *lwork, integer *iwork, integer *
+ info);
+
+/* Subroutine */ int stgsy2_(char *trans, integer *ijob, integer *m, integer *
+ n, real *a, integer *lda, real *b, integer *ldb, real *c__, integer *
+ ldc, real *d__, integer *ldd, real *e, integer *lde, real *f, integer
+ *ldf, real *scale, real *rdsum, real *rdscal, integer *iwork, integer
+ *pq, integer *info);
+
+/* Subroutine */ int stgsyl_(char *trans, integer *ijob, integer *m, integer *
+ n, real *a, integer *lda, real *b, integer *ldb, real *c__, integer *
+ ldc, real *d__, integer *ldd, real *e, integer *lde, real *f, integer
+ *ldf, real *scale, real *dif, real *work, integer *lwork, integer *
+ iwork, integer *info);
+
+/* Subroutine */ int stpcon_(char *norm, char *uplo, char *diag, integer *n,
+ real *ap, real *rcond, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int stprfs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, real *ap, real *b, integer *ldb, real *x, integer *ldx,
+ real *ferr, real *berr, real *work, integer *iwork, integer *info);
+
+/* Subroutine */ int stptri_(char *uplo, char *diag, integer *n, real *ap,
+ integer *info);
+
+/* Subroutine */ int stptrs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, real *ap, real *b, integer *ldb, integer *info);
+
+/* Subroutine */ int strcon_(char *norm, char *uplo, char *diag, integer *n,
+ real *a, integer *lda, real *rcond, real *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int strevc_(char *side, char *howmny, logical *select,
+ integer *n, real *t, integer *ldt, real *vl, integer *ldvl, real *vr,
+ integer *ldvr, integer *mm, integer *m, real *work, integer *info);
+
+/* Subroutine */ int strexc_(char *compq, integer *n, real *t, integer *ldt,
+ real *q, integer *ldq, integer *ifst, integer *ilst, real *work,
+ integer *info);
+
+/* Subroutine */ int strrfs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, real *a, integer *lda, real *b, integer *ldb, real *x,
+ integer *ldx, real *ferr, real *berr, real *work, integer *iwork,
+ integer *info);
+
+/* Subroutine */ int strsen_(char *job, char *compq, logical *select, integer
+ *n, real *t, integer *ldt, real *q, integer *ldq, real *wr, real *wi,
+ integer *m, real *s, real *sep, real *work, integer *lwork, integer *
+ iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int strsna_(char *job, char *howmny, logical *select,
+ integer *n, real *t, integer *ldt, real *vl, integer *ldvl, real *vr,
+ integer *ldvr, real *s, real *sep, integer *mm, integer *m, real *
+ work, integer *ldwork, integer *iwork, integer *info);
+
+/* Subroutine */ int strsyl_(char *trana, char *tranb, integer *isgn, integer
+ *m, integer *n, real *a, integer *lda, real *b, integer *ldb, real *
+ c__, integer *ldc, real *scale, integer *info);
+
+/* Subroutine */ int strti2_(char *uplo, char *diag, integer *n, real *a,
+ integer *lda, integer *info);
+
+/* Subroutine */ int strtri_(char *uplo, char *diag, integer *n, real *a,
+ integer *lda, integer *info);
+
+/* Subroutine */ int strtrs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, real *a, integer *lda, real *b, integer *ldb, integer *
+ info);
+
+/* Subroutine */ int stzrqf_(integer *m, integer *n, real *a, integer *lda,
+ real *tau, integer *info);
+
+/* Subroutine */ int stzrzf_(integer *m, integer *n, real *a, integer *lda,
+ real *tau, real *work, integer *lwork, integer *info);
+
+/* Subroutine */ int xerbla_(char *srname, integer *info);
+
+/* Subroutine */ int zbdsqr_(char *uplo, integer *n, integer *ncvt, integer *
+ nru, integer *ncc, doublereal *d__, doublereal *e, doublecomplex *vt,
+ integer *ldvt, doublecomplex *u, integer *ldu, doublecomplex *c__,
+ integer *ldc, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zdrot_(integer *n, doublecomplex *cx, integer *incx,
+ doublecomplex *cy, integer *incy, doublereal *c__, doublereal *s);
+
+/* Subroutine */ int zdrscl_(integer *n, doublereal *sa, doublecomplex *sx,
+ integer *incx);
+
+/* Subroutine */ int zgbbrd_(char *vect, integer *m, integer *n, integer *ncc,
+ integer *kl, integer *ku, doublecomplex *ab, integer *ldab,
+ doublereal *d__, doublereal *e, doublecomplex *q, integer *ldq,
+ doublecomplex *pt, integer *ldpt, doublecomplex *c__, integer *ldc,
+ doublecomplex *work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgbcon_(char *norm, integer *n, integer *kl, integer *ku,
+ doublecomplex *ab, integer *ldab, integer *ipiv, doublereal *anorm,
+ doublereal *rcond, doublecomplex *work, doublereal *rwork, integer *
+ info);
+
+/* Subroutine */ int zgbequ_(integer *m, integer *n, integer *kl, integer *ku,
+ doublecomplex *ab, integer *ldab, doublereal *r__, doublereal *c__,
+ doublereal *rowcnd, doublereal *colcnd, doublereal *amax, integer *
+ info);
+
+/* Subroutine */ int zgbrfs_(char *trans, integer *n, integer *kl, integer *
+ ku, integer *nrhs, doublecomplex *ab, integer *ldab, doublecomplex *
+ afb, integer *ldafb, integer *ipiv, doublecomplex *b, integer *ldb,
+ doublecomplex *x, integer *ldx, doublereal *ferr, doublereal *berr,
+ doublecomplex *work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgbsv_(integer *n, integer *kl, integer *ku, integer *
+ nrhs, doublecomplex *ab, integer *ldab, integer *ipiv, doublecomplex *
+ b, integer *ldb, integer *info);
+
+/* Subroutine */ int zgbsvx_(char *fact, char *trans, integer *n, integer *kl,
+ integer *ku, integer *nrhs, doublecomplex *ab, integer *ldab,
+ doublecomplex *afb, integer *ldafb, integer *ipiv, char *equed,
+ doublereal *r__, doublereal *c__, doublecomplex *b, integer *ldb,
+ doublecomplex *x, integer *ldx, doublereal *rcond, doublereal *ferr,
+ doublereal *berr, doublecomplex *work, doublereal *rwork, integer *
+ info);
+
+/* Subroutine */ int zgbtf2_(integer *m, integer *n, integer *kl, integer *ku,
+ doublecomplex *ab, integer *ldab, integer *ipiv, integer *info);
+
+/* Subroutine */ int zgbtrf_(integer *m, integer *n, integer *kl, integer *ku,
+ doublecomplex *ab, integer *ldab, integer *ipiv, integer *info);
+
+/* Subroutine */ int zgbtrs_(char *trans, integer *n, integer *kl, integer *
+ ku, integer *nrhs, doublecomplex *ab, integer *ldab, integer *ipiv,
+ doublecomplex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int zgebak_(char *job, char *side, integer *n, integer *ilo,
+ integer *ihi, doublereal *scale, integer *m, doublecomplex *v,
+ integer *ldv, integer *info);
+
+/* Subroutine */ int zgebal_(char *job, integer *n, doublecomplex *a, integer
+ *lda, integer *ilo, integer *ihi, doublereal *scale, integer *info);
+
+/* Subroutine */ int zgebd2_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublereal *d__, doublereal *e, doublecomplex *tauq,
+ doublecomplex *taup, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zgebrd_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublereal *d__, doublereal *e, doublecomplex *tauq,
+ doublecomplex *taup, doublecomplex *work, integer *lwork, integer *
+ info);
+
+/* Subroutine */ int zgecon_(char *norm, integer *n, doublecomplex *a,
+ integer *lda, doublereal *anorm, doublereal *rcond, doublecomplex *
+ work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgeequ_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublereal *r__, doublereal *c__, doublereal *rowcnd,
+ doublereal *colcnd, doublereal *amax, integer *info);
+
+/* Subroutine */ int zgees_(char *jobvs, char *sort, L_fp select, integer *n,
+ doublecomplex *a, integer *lda, integer *sdim, doublecomplex *w,
+ doublecomplex *vs, integer *ldvs, doublecomplex *work, integer *lwork,
+ doublereal *rwork, logical *bwork, integer *info);
+
+/* Subroutine */ int zgeesx_(char *jobvs, char *sort, L_fp select, char *
+ sense, integer *n, doublecomplex *a, integer *lda, integer *sdim,
+ doublecomplex *w, doublecomplex *vs, integer *ldvs, doublereal *
+ rconde, doublereal *rcondv, doublecomplex *work, integer *lwork,
+ doublereal *rwork, logical *bwork, integer *info);
+
+/* Subroutine */ int zgeev_(char *jobvl, char *jobvr, integer *n,
+ doublecomplex *a, integer *lda, doublecomplex *w, doublecomplex *vl,
+ integer *ldvl, doublecomplex *vr, integer *ldvr, doublecomplex *work,
+ integer *lwork, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgeevx_(char *balanc, char *jobvl, char *jobvr, char *
+ sense, integer *n, doublecomplex *a, integer *lda, doublecomplex *w,
+ doublecomplex *vl, integer *ldvl, doublecomplex *vr, integer *ldvr,
+ integer *ilo, integer *ihi, doublereal *scale, doublereal *abnrm,
+ doublereal *rconde, doublereal *rcondv, doublecomplex *work, integer *
+ lwork, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgegs_(char *jobvsl, char *jobvsr, integer *n,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ doublecomplex *alpha, doublecomplex *beta, doublecomplex *vsl,
+ integer *ldvsl, doublecomplex *vsr, integer *ldvsr, doublecomplex *
+ work, integer *lwork, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgegv_(char *jobvl, char *jobvr, integer *n,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ doublecomplex *alpha, doublecomplex *beta, doublecomplex *vl, integer
+ *ldvl, doublecomplex *vr, integer *ldvr, doublecomplex *work, integer
+ *lwork, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgehd2_(integer *n, integer *ilo, integer *ihi,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
+ work, integer *info);
+
+/* Subroutine */ int zgehrd_(integer *n, integer *ilo, integer *ihi,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
+ work, integer *lwork, integer *info);
+
+/* Subroutine */ int zgelq2_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublecomplex *tau, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zgelqf_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublecomplex *tau, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zgels_(char *trans, integer *m, integer *n, integer *
+ nrhs, doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ doublecomplex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int zgelsx_(integer *m, integer *n, integer *nrhs,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ integer *jpvt, doublereal *rcond, integer *rank, doublecomplex *work,
+ doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgelsy_(integer *m, integer *n, integer *nrhs,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ integer *jpvt, doublereal *rcond, integer *rank, doublecomplex *work,
+ integer *lwork, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgeql2_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublecomplex *tau, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zgeqlf_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublecomplex *tau, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zgeqp3_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, integer *jpvt, doublecomplex *tau, doublecomplex *work,
+ integer *lwork, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgeqpf_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, integer *jpvt, doublecomplex *tau, doublecomplex *work,
+ doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgeqr2_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublecomplex *tau, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zgeqrf_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublecomplex *tau, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zgerfs_(char *trans, integer *n, integer *nrhs,
+ doublecomplex *a, integer *lda, doublecomplex *af, integer *ldaf,
+ integer *ipiv, doublecomplex *b, integer *ldb, doublecomplex *x,
+ integer *ldx, doublereal *ferr, doublereal *berr, doublecomplex *work,
+ doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgerq2_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublecomplex *tau, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zgerqf_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublecomplex *tau, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zgesc2_(integer *n, doublecomplex *a, integer *lda,
+ doublecomplex *rhs, integer *ipiv, integer *jpiv, doublereal *scale);
+
+/* Subroutine */ int zgesv_(integer *n, integer *nrhs, doublecomplex *a,
+ integer *lda, integer *ipiv, doublecomplex *b, integer *ldb, integer *
+ info);
+
+/* Subroutine */ int zgesvx_(char *fact, char *trans, integer *n, integer *
+ nrhs, doublecomplex *a, integer *lda, doublecomplex *af, integer *
+ ldaf, integer *ipiv, char *equed, doublereal *r__, doublereal *c__,
+ doublecomplex *b, integer *ldb, doublecomplex *x, integer *ldx,
+ doublereal *rcond, doublereal *ferr, doublereal *berr, doublecomplex *
+ work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgetc2_(integer *n, doublecomplex *a, integer *lda,
+ integer *ipiv, integer *jpiv, integer *info);
+
+/* Subroutine */ int zgetf2_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, integer *ipiv, integer *info);
+
+/* Subroutine */ int zgetrf_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, integer *ipiv, integer *info);
+
+/* Subroutine */ int zgetri_(integer *n, doublecomplex *a, integer *lda,
+ integer *ipiv, doublecomplex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int zgetrs_(char *trans, integer *n, integer *nrhs,
+ doublecomplex *a, integer *lda, integer *ipiv, doublecomplex *b,
+ integer *ldb, integer *info);
+
+/* Subroutine */ int zggbak_(char *job, char *side, integer *n, integer *ilo,
+ integer *ihi, doublereal *lscale, doublereal *rscale, integer *m,
+ doublecomplex *v, integer *ldv, integer *info);
+
+/* Subroutine */ int zggbal_(char *job, integer *n, doublecomplex *a, integer
+ *lda, doublecomplex *b, integer *ldb, integer *ilo, integer *ihi,
+ doublereal *lscale, doublereal *rscale, doublereal *work, integer *
+ info);
+
+/* Subroutine */ int zgges_(char *jobvsl, char *jobvsr, char *sort, L_fp
+ delctg, integer *n, doublecomplex *a, integer *lda, doublecomplex *b,
+ integer *ldb, integer *sdim, doublecomplex *alpha, doublecomplex *
+ beta, doublecomplex *vsl, integer *ldvsl, doublecomplex *vsr, integer
+ *ldvsr, doublecomplex *work, integer *lwork, doublereal *rwork,
+ logical *bwork, integer *info);
+
+/* Subroutine */ int zggesx_(char *jobvsl, char *jobvsr, char *sort, L_fp
+ delctg, char *sense, integer *n, doublecomplex *a, integer *lda,
+ doublecomplex *b, integer *ldb, integer *sdim, doublecomplex *alpha,
+ doublecomplex *beta, doublecomplex *vsl, integer *ldvsl,
+ doublecomplex *vsr, integer *ldvsr, doublereal *rconde, doublereal *
+ rcondv, doublecomplex *work, integer *lwork, doublereal *rwork,
+ integer *iwork, integer *liwork, logical *bwork, integer *info);
+
+/* Subroutine */ int zggev_(char *jobvl, char *jobvr, integer *n,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ doublecomplex *alpha, doublecomplex *beta, doublecomplex *vl, integer
+ *ldvl, doublecomplex *vr, integer *ldvr, doublecomplex *work, integer
+ *lwork, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zggevx_(char *balanc, char *jobvl, char *jobvr, char *
+ sense, integer *n, doublecomplex *a, integer *lda, doublecomplex *b,
+ integer *ldb, doublecomplex *alpha, doublecomplex *beta,
+ doublecomplex *vl, integer *ldvl, doublecomplex *vr, integer *ldvr,
+ integer *ilo, integer *ihi, doublereal *lscale, doublereal *rscale,
+ doublereal *abnrm, doublereal *bbnrm, doublereal *rconde, doublereal *
+ rcondv, doublecomplex *work, integer *lwork, doublereal *rwork,
+ integer *iwork, logical *bwork, integer *info);
+
+/* Subroutine */ int zggglm_(integer *n, integer *m, integer *p,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ doublecomplex *d__, doublecomplex *x, doublecomplex *y, doublecomplex
+ *work, integer *lwork, integer *info);
+
+/* Subroutine */ int zgghrd_(char *compq, char *compz, integer *n, integer *
+ ilo, integer *ihi, doublecomplex *a, integer *lda, doublecomplex *b,
+ integer *ldb, doublecomplex *q, integer *ldq, doublecomplex *z__,
+ integer *ldz, integer *info);
+
+/* Subroutine */ int zgglse_(integer *m, integer *n, integer *p,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ doublecomplex *c__, doublecomplex *d__, doublecomplex *x,
+ doublecomplex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int zggqrf_(integer *n, integer *m, integer *p,
+ doublecomplex *a, integer *lda, doublecomplex *taua, doublecomplex *b,
+ integer *ldb, doublecomplex *taub, doublecomplex *work, integer *
+ lwork, integer *info);
+
+/* Subroutine */ int zggrqf_(integer *m, integer *p, integer *n,
+ doublecomplex *a, integer *lda, doublecomplex *taua, doublecomplex *b,
+ integer *ldb, doublecomplex *taub, doublecomplex *work, integer *
+ lwork, integer *info);
+
+/* Subroutine */ int zggsvd_(char *jobu, char *jobv, char *jobq, integer *m,
+ integer *n, integer *p, integer *k, integer *l, doublecomplex *a,
+ integer *lda, doublecomplex *b, integer *ldb, doublereal *alpha,
+ doublereal *beta, doublecomplex *u, integer *ldu, doublecomplex *v,
+ integer *ldv, doublecomplex *q, integer *ldq, doublecomplex *work,
+ doublereal *rwork, integer *iwork, integer *info);
+
+/* Subroutine */ int zggsvp_(char *jobu, char *jobv, char *jobq, integer *m,
+ integer *p, integer *n, doublecomplex *a, integer *lda, doublecomplex
+ *b, integer *ldb, doublereal *tola, doublereal *tolb, integer *k,
+ integer *l, doublecomplex *u, integer *ldu, doublecomplex *v, integer
+ *ldv, doublecomplex *q, integer *ldq, integer *iwork, doublereal *
+ rwork, doublecomplex *tau, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zgtcon_(char *norm, integer *n, doublecomplex *dl,
+ doublecomplex *d__, doublecomplex *du, doublecomplex *du2, integer *
+ ipiv, doublereal *anorm, doublereal *rcond, doublecomplex *work,
+ integer *info);
+
+/* Subroutine */ int zgtrfs_(char *trans, integer *n, integer *nrhs,
+ doublecomplex *dl, doublecomplex *d__, doublecomplex *du,
+ doublecomplex *dlf, doublecomplex *df, doublecomplex *duf,
+ doublecomplex *du2, integer *ipiv, doublecomplex *b, integer *ldb,
+ doublecomplex *x, integer *ldx, doublereal *ferr, doublereal *berr,
+ doublecomplex *work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zgtsv_(integer *n, integer *nrhs, doublecomplex *dl,
+ doublecomplex *d__, doublecomplex *du, doublecomplex *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int zgtsvx_(char *fact, char *trans, integer *n, integer *
+ nrhs, doublecomplex *dl, doublecomplex *d__, doublecomplex *du,
+ doublecomplex *dlf, doublecomplex *df, doublecomplex *duf,
+ doublecomplex *du2, integer *ipiv, doublecomplex *b, integer *ldb,
+ doublecomplex *x, integer *ldx, doublereal *rcond, doublereal *ferr,
+ doublereal *berr, doublecomplex *work, doublereal *rwork, integer *
+ info);
+
+/* Subroutine */ int zgttrf_(integer *n, doublecomplex *dl, doublecomplex *
+ d__, doublecomplex *du, doublecomplex *du2, integer *ipiv, integer *
+ info);
+
+/* Subroutine */ int zgttrs_(char *trans, integer *n, integer *nrhs,
+ doublecomplex *dl, doublecomplex *d__, doublecomplex *du,
+ doublecomplex *du2, integer *ipiv, doublecomplex *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int zgtts2_(integer *itrans, integer *n, integer *nrhs,
+ doublecomplex *dl, doublecomplex *d__, doublecomplex *du,
+ doublecomplex *du2, integer *ipiv, doublecomplex *b, integer *ldb);
+
+/* Subroutine */ int zhbev_(char *jobz, char *uplo, integer *n, integer *kd,
+ doublecomplex *ab, integer *ldab, doublereal *w, doublecomplex *z__,
+ integer *ldz, doublecomplex *work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zhbevd_(char *jobz, char *uplo, integer *n, integer *kd,
+ doublecomplex *ab, integer *ldab, doublereal *w, doublecomplex *z__,
+ integer *ldz, doublecomplex *work, integer *lwork, doublereal *rwork,
+ integer *lrwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int zhbevx_(char *jobz, char *range, char *uplo, integer *n,
+ integer *kd, doublecomplex *ab, integer *ldab, doublecomplex *q,
+ integer *ldq, doublereal *vl, doublereal *vu, integer *il, integer *
+ iu, doublereal *abstol, integer *m, doublereal *w, doublecomplex *z__,
+ integer *ldz, doublecomplex *work, doublereal *rwork, integer *iwork,
+ integer *ifail, integer *info);
+
+/* Subroutine */ int zhbgst_(char *vect, char *uplo, integer *n, integer *ka,
+ integer *kb, doublecomplex *ab, integer *ldab, doublecomplex *bb,
+ integer *ldbb, doublecomplex *x, integer *ldx, doublecomplex *work,
+ doublereal *rwork, integer *info);
+
+/* Subroutine */ int zhbgv_(char *jobz, char *uplo, integer *n, integer *ka,
+ integer *kb, doublecomplex *ab, integer *ldab, doublecomplex *bb,
+ integer *ldbb, doublereal *w, doublecomplex *z__, integer *ldz,
+ doublecomplex *work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zhbgvx_(char *jobz, char *range, char *uplo, integer *n,
+ integer *ka, integer *kb, doublecomplex *ab, integer *ldab,
+ doublecomplex *bb, integer *ldbb, doublecomplex *q, integer *ldq,
+ doublereal *vl, doublereal *vu, integer *il, integer *iu, doublereal *
+ abstol, integer *m, doublereal *w, doublecomplex *z__, integer *ldz,
+ doublecomplex *work, doublereal *rwork, integer *iwork, integer *
+ ifail, integer *info);
+
+/* Subroutine */ int zhbtrd_(char *vect, char *uplo, integer *n, integer *kd,
+ doublecomplex *ab, integer *ldab, doublereal *d__, doublereal *e,
+ doublecomplex *q, integer *ldq, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zhecon_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, integer *ipiv, doublereal *anorm, doublereal *rcond,
+ doublecomplex *work, integer *info);
+
+/* Subroutine */ int zheev_(char *jobz, char *uplo, integer *n, doublecomplex
+ *a, integer *lda, doublereal *w, doublecomplex *work, integer *lwork,
+ doublereal *rwork, integer *info);
+
+/* Subroutine */ int zheevd_(char *jobz, char *uplo, integer *n,
+ doublecomplex *a, integer *lda, doublereal *w, doublecomplex *work,
+ integer *lwork, doublereal *rwork, integer *lrwork, integer *iwork,
+ integer *liwork, integer *info);
+
+/* Subroutine */ int zheevr_(char *jobz, char *range, char *uplo, integer *n,
+ doublecomplex *a, integer *lda, doublereal *vl, doublereal *vu,
+ integer *il, integer *iu, doublereal *abstol, integer *m, doublereal *
+ w, doublecomplex *z__, integer *ldz, integer *isuppz, doublecomplex *
+ work, integer *lwork, doublereal *rwork, integer *lrwork, integer *
+ iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int zheevx_(char *jobz, char *range, char *uplo, integer *n,
+ doublecomplex *a, integer *lda, doublereal *vl, doublereal *vu,
+ integer *il, integer *iu, doublereal *abstol, integer *m, doublereal *
+ w, doublecomplex *z__, integer *ldz, doublecomplex *work, integer *
+ lwork, doublereal *rwork, integer *iwork, integer *ifail, integer *
+ info);
+
+/* Subroutine */ int zhegs2_(integer *itype, char *uplo, integer *n,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int zhegst_(integer *itype, char *uplo, integer *n,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int zhegv_(integer *itype, char *jobz, char *uplo, integer *
+ n, doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ doublereal *w, doublecomplex *work, integer *lwork, doublereal *rwork,
+ integer *info);
+
+/* Subroutine */ int zhegvd_(integer *itype, char *jobz, char *uplo, integer *
+ n, doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ doublereal *w, doublecomplex *work, integer *lwork, doublereal *rwork,
+ integer *lrwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int zhegvx_(integer *itype, char *jobz, char *range, char *
+ uplo, integer *n, doublecomplex *a, integer *lda, doublecomplex *b,
+ integer *ldb, doublereal *vl, doublereal *vu, integer *il, integer *
+ iu, doublereal *abstol, integer *m, doublereal *w, doublecomplex *z__,
+ integer *ldz, doublecomplex *work, integer *lwork, doublereal *rwork,
+ integer *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int zherfs_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *a, integer *lda, doublecomplex *af, integer *ldaf,
+ integer *ipiv, doublecomplex *b, integer *ldb, doublecomplex *x,
+ integer *ldx, doublereal *ferr, doublereal *berr, doublecomplex *work,
+ doublereal *rwork, integer *info);
+
+/* Subroutine */ int zhesv_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *a, integer *lda, integer *ipiv, doublecomplex *b,
+ integer *ldb, doublecomplex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int zhesvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, doublecomplex *a, integer *lda, doublecomplex *af, integer *
+ ldaf, integer *ipiv, doublecomplex *b, integer *ldb, doublecomplex *x,
+ integer *ldx, doublereal *rcond, doublereal *ferr, doublereal *berr,
+ doublecomplex *work, integer *lwork, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zhetf2_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, integer *ipiv, integer *info);
+
+/* Subroutine */ int zhetrd_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, doublereal *d__, doublereal *e, doublecomplex *tau,
+ doublecomplex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int zhetrf_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, integer *ipiv, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zhetri_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, integer *ipiv, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zhetrs_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *a, integer *lda, integer *ipiv, doublecomplex *b,
+ integer *ldb, integer *info);
+
+/* Subroutine */ int zhgeqz_(char *job, char *compq, char *compz, integer *n,
+ integer *ilo, integer *ihi, doublecomplex *a, integer *lda,
+ doublecomplex *b, integer *ldb, doublecomplex *alpha, doublecomplex *
+ beta, doublecomplex *q, integer *ldq, doublecomplex *z__, integer *
+ ldz, doublecomplex *work, integer *lwork, doublereal *rwork, integer *
+ info);
+
+/* Subroutine */ int zhpcon_(char *uplo, integer *n, doublecomplex *ap,
+ integer *ipiv, doublereal *anorm, doublereal *rcond, doublecomplex *
+ work, integer *info);
+
+/* Subroutine */ int zhpev_(char *jobz, char *uplo, integer *n, doublecomplex
+ *ap, doublereal *w, doublecomplex *z__, integer *ldz, doublecomplex *
+ work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zhpevd_(char *jobz, char *uplo, integer *n,
+ doublecomplex *ap, doublereal *w, doublecomplex *z__, integer *ldz,
+ doublecomplex *work, integer *lwork, doublereal *rwork, integer *
+ lrwork, integer *iwork, integer *liwork, integer *info);
+
+/* Subroutine */ int zhpevx_(char *jobz, char *range, char *uplo, integer *n,
+ doublecomplex *ap, doublereal *vl, doublereal *vu, integer *il,
+ integer *iu, doublereal *abstol, integer *m, doublereal *w,
+ doublecomplex *z__, integer *ldz, doublecomplex *work, doublereal *
+ rwork, integer *iwork, integer *ifail, integer *info);
+
+/* Subroutine */ int zhpgst_(integer *itype, char *uplo, integer *n,
+ doublecomplex *ap, doublecomplex *bp, integer *info);
+
+/* Subroutine */ int zhpgv_(integer *itype, char *jobz, char *uplo, integer *
+ n, doublecomplex *ap, doublecomplex *bp, doublereal *w, doublecomplex
+ *z__, integer *ldz, doublecomplex *work, doublereal *rwork, integer *
+ info);
+
+/* Subroutine */ int zhpgvd_(integer *itype, char *jobz, char *uplo, integer *
+ n, doublecomplex *ap, doublecomplex *bp, doublereal *w, doublecomplex
+ *z__, integer *ldz, doublecomplex *work, integer *lwork, doublereal *
+ rwork, integer *lrwork, integer *iwork, integer *liwork, integer *
+ info);
+
+/* Subroutine */ int zhpgvx_(integer *itype, char *jobz, char *range, char *
+ uplo, integer *n, doublecomplex *ap, doublecomplex *bp, doublereal *
+ vl, doublereal *vu, integer *il, integer *iu, doublereal *abstol,
+ integer *m, doublereal *w, doublecomplex *z__, integer *ldz,
+ doublecomplex *work, doublereal *rwork, integer *iwork, integer *
+ ifail, integer *info);
+
+/* Subroutine */ int zhprfs_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *ap, doublecomplex *afp, integer *ipiv, doublecomplex *
+ b, integer *ldb, doublecomplex *x, integer *ldx, doublereal *ferr,
+ doublereal *berr, doublecomplex *work, doublereal *rwork, integer *
+ info);
+
+/* Subroutine */ int zhpsv_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *ap, integer *ipiv, doublecomplex *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int zhpsvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, doublecomplex *ap, doublecomplex *afp, integer *ipiv,
+ doublecomplex *b, integer *ldb, doublecomplex *x, integer *ldx,
+ doublereal *rcond, doublereal *ferr, doublereal *berr, doublecomplex *
+ work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zhptrd_(char *uplo, integer *n, doublecomplex *ap,
+ doublereal *d__, doublereal *e, doublecomplex *tau, integer *info);
+
+/* Subroutine */ int zhptrf_(char *uplo, integer *n, doublecomplex *ap,
+ integer *ipiv, integer *info);
+
+/* Subroutine */ int zhptri_(char *uplo, integer *n, doublecomplex *ap,
+ integer *ipiv, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zhptrs_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *ap, integer *ipiv, doublecomplex *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int zhsein_(char *side, char *eigsrc, char *initv, logical *
+ select, integer *n, doublecomplex *h__, integer *ldh, doublecomplex *
+ w, doublecomplex *vl, integer *ldvl, doublecomplex *vr, integer *ldvr,
+ integer *mm, integer *m, doublecomplex *work, doublereal *rwork,
+ integer *ifaill, integer *ifailr, integer *info);
+
+/* Subroutine */ int zhseqr_(char *job, char *compz, integer *n, integer *ilo,
+ integer *ihi, doublecomplex *h__, integer *ldh, doublecomplex *w,
+ doublecomplex *z__, integer *ldz, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zlabrd_(integer *m, integer *n, integer *nb,
+ doublecomplex *a, integer *lda, doublereal *d__, doublereal *e,
+ doublecomplex *tauq, doublecomplex *taup, doublecomplex *x, integer *
+ ldx, doublecomplex *y, integer *ldy);
+
+/* Subroutine */ int zlacgv_(integer *n, doublecomplex *x, integer *incx);
+
+/* Subroutine */ int zlacon_(integer *n, doublecomplex *v, doublecomplex *x,
+ doublereal *est, integer *kase);
+
+/* Subroutine */ int zlacp2_(char *uplo, integer *m, integer *n, doublereal *
+ a, integer *lda, doublecomplex *b, integer *ldb);
+
+/* Subroutine */ int zlacpy_(char *uplo, integer *m, integer *n,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb);
+
+/* Subroutine */ int zlacrm_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublereal *b, integer *ldb, doublecomplex *c__,
+ integer *ldc, doublereal *rwork);
+
+/* Subroutine */ int zlacrt_(integer *n, doublecomplex *cx, integer *incx,
+ doublecomplex *cy, integer *incy, doublecomplex *c__, doublecomplex *
+ s);
+
+/* Subroutine */ int zlaed0_(integer *qsiz, integer *n, doublereal *d__,
+ doublereal *e, doublecomplex *q, integer *ldq, doublecomplex *qstore,
+ integer *ldqs, doublereal *rwork, integer *iwork, integer *info);
+
+/* Subroutine */ int zlaed7_(integer *n, integer *cutpnt, integer *qsiz,
+ integer *tlvls, integer *curlvl, integer *curpbm, doublereal *d__,
+ doublecomplex *q, integer *ldq, doublereal *rho, integer *indxq,
+ doublereal *qstore, integer *qptr, integer *prmptr, integer *perm,
+ integer *givptr, integer *givcol, doublereal *givnum, doublecomplex *
+ work, doublereal *rwork, integer *iwork, integer *info);
+
+/* Subroutine */ int zlaed8_(integer *k, integer *n, integer *qsiz,
+ doublecomplex *q, integer *ldq, doublereal *d__, doublereal *rho,
+ integer *cutpnt, doublereal *z__, doublereal *dlamda, doublecomplex *
+ q2, integer *ldq2, doublereal *w, integer *indxp, integer *indx,
+ integer *indxq, integer *perm, integer *givptr, integer *givcol,
+ doublereal *givnum, integer *info);
+
+/* Subroutine */ int zlaein_(logical *rightv, logical *noinit, integer *n,
+ doublecomplex *h__, integer *ldh, doublecomplex *w, doublecomplex *v,
+ doublecomplex *b, integer *ldb, doublereal *rwork, doublereal *eps3,
+ doublereal *smlnum, integer *info);
+
+/* Subroutine */ int zlaesy_(doublecomplex *a, doublecomplex *b,
+ doublecomplex *c__, doublecomplex *rt1, doublecomplex *rt2,
+ doublecomplex *evscal, doublecomplex *cs1, doublecomplex *sn1);
+
+/* Subroutine */ int zlaev2_(doublecomplex *a, doublecomplex *b,
+ doublecomplex *c__, doublereal *rt1, doublereal *rt2, doublereal *cs1,
+ doublecomplex *sn1);
+
+/* Subroutine */ int zlags2_(logical *upper, doublereal *a1, doublecomplex *
+ a2, doublereal *a3, doublereal *b1, doublecomplex *b2, doublereal *b3,
+ doublereal *csu, doublecomplex *snu, doublereal *csv, doublecomplex *
+ snv, doublereal *csq, doublecomplex *snq);
+
+/* Subroutine */ int zlagtm_(char *trans, integer *n, integer *nrhs,
+ doublereal *alpha, doublecomplex *dl, doublecomplex *d__,
+ doublecomplex *du, doublecomplex *x, integer *ldx, doublereal *beta,
+ doublecomplex *b, integer *ldb);
+
+/* Subroutine */ int zlahef_(char *uplo, integer *n, integer *nb, integer *kb,
+ doublecomplex *a, integer *lda, integer *ipiv, doublecomplex *w,
+ integer *ldw, integer *info);
+
+/* Subroutine */ int zlahqr_(logical *wantt, logical *wantz, integer *n,
+ integer *ilo, integer *ihi, doublecomplex *h__, integer *ldh,
+ doublecomplex *w, integer *iloz, integer *ihiz, doublecomplex *z__,
+ integer *ldz, integer *info);
+
+/* Subroutine */ int zlahrd_(integer *n, integer *k, integer *nb,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *t,
+ integer *ldt, doublecomplex *y, integer *ldy);
+
+/* Subroutine */ int zlaic1_(integer *job, integer *j, doublecomplex *x,
+ doublereal *sest, doublecomplex *w, doublecomplex *gamma, doublereal *
+ sestpr, doublecomplex *s, doublecomplex *c__);
+
+/* Subroutine */ int zlals0_(integer *icompq, integer *nl, integer *nr,
+ integer *sqre, integer *nrhs, doublecomplex *b, integer *ldb,
+ doublecomplex *bx, integer *ldbx, integer *perm, integer *givptr,
+ integer *givcol, integer *ldgcol, doublereal *givnum, integer *ldgnum,
+ doublereal *poles, doublereal *difl, doublereal *difr, doublereal *
+ z__, integer *k, doublereal *c__, doublereal *s, doublereal *rwork,
+ integer *info);
+
+/* Subroutine */ int zlalsa_(integer *icompq, integer *smlsiz, integer *n,
+ integer *nrhs, doublecomplex *b, integer *ldb, doublecomplex *bx,
+ integer *ldbx, doublereal *u, integer *ldu, doublereal *vt, integer *
+ k, doublereal *difl, doublereal *difr, doublereal *z__, doublereal *
+ poles, integer *givptr, integer *givcol, integer *ldgcol, integer *
+ perm, doublereal *givnum, doublereal *c__, doublereal *s, doublereal *
+ rwork, integer *iwork, integer *info);
+
+/* Subroutine */ int zlapll_(integer *n, doublecomplex *x, integer *incx,
+ doublecomplex *y, integer *incy, doublereal *ssmin);
+
+/* Subroutine */ int zlapmt_(logical *forwrd, integer *m, integer *n,
+ doublecomplex *x, integer *ldx, integer *k);
+
+/* Subroutine */ int zlaqgb_(integer *m, integer *n, integer *kl, integer *ku,
+ doublecomplex *ab, integer *ldab, doublereal *r__, doublereal *c__,
+ doublereal *rowcnd, doublereal *colcnd, doublereal *amax, char *equed);
+
+/* Subroutine */ int zlaqge_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublereal *r__, doublereal *c__, doublereal *rowcnd,
+ doublereal *colcnd, doublereal *amax, char *equed);
+
+/* Subroutine */ int zlaqhb_(char *uplo, integer *n, integer *kd,
+ doublecomplex *ab, integer *ldab, doublereal *s, doublereal *scond,
+ doublereal *amax, char *equed);
+
+/* Subroutine */ int zlaqhe_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, doublereal *s, doublereal *scond, doublereal *amax,
+ char *equed);
+
+/* Subroutine */ int zlaqhp_(char *uplo, integer *n, doublecomplex *ap,
+ doublereal *s, doublereal *scond, doublereal *amax, char *equed);
+
+/* Subroutine */ int zlaqp2_(integer *m, integer *n, integer *offset,
+ doublecomplex *a, integer *lda, integer *jpvt, doublecomplex *tau,
+ doublereal *vn1, doublereal *vn2, doublecomplex *work);
+
+/* Subroutine */ int zlaqps_(integer *m, integer *n, integer *offset, integer
+ *nb, integer *kb, doublecomplex *a, integer *lda, integer *jpvt,
+ doublecomplex *tau, doublereal *vn1, doublereal *vn2, doublecomplex *
+ auxv, doublecomplex *f, integer *ldf);
+
+/* Subroutine */ int zlaqsb_(char *uplo, integer *n, integer *kd,
+ doublecomplex *ab, integer *ldab, doublereal *s, doublereal *scond,
+ doublereal *amax, char *equed);
+
+/* Subroutine */ int zlaqsp_(char *uplo, integer *n, doublecomplex *ap,
+ doublereal *s, doublereal *scond, doublereal *amax, char *equed);
+
+/* Subroutine */ int zlaqsy_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, doublereal *s, doublereal *scond, doublereal *amax,
+ char *equed);
+
+/* Subroutine */ int zlar1v_(integer *n, integer *b1, integer *bn, doublereal
+ *sigma, doublereal *d__, doublereal *l, doublereal *ld, doublereal *
+ lld, doublereal *gersch, doublecomplex *z__, doublereal *ztz,
+ doublereal *mingma, integer *r__, integer *isuppz, doublereal *work);
+
+/* Subroutine */ int zlar2v_(integer *n, doublecomplex *x, doublecomplex *y,
+ doublecomplex *z__, integer *incx, doublereal *c__, doublecomplex *s,
+ integer *incc);
+
+/* Subroutine */ int zlarcm_(integer *m, integer *n, doublereal *a, integer *
+ lda, doublecomplex *b, integer *ldb, doublecomplex *c__, integer *ldc,
+ doublereal *rwork);
+
+/* Subroutine */ int zlarf_(char *side, integer *m, integer *n, doublecomplex
+ *v, integer *incv, doublecomplex *tau, doublecomplex *c__, integer *
+ ldc, doublecomplex *work);
+
+/* Subroutine */ int zlarfb_(char *side, char *trans, char *direct, char *
+ storev, integer *m, integer *n, integer *k, doublecomplex *v, integer
+ *ldv, doublecomplex *t, integer *ldt, doublecomplex *c__, integer *
+ ldc, doublecomplex *work, integer *ldwork);
+
+/* Subroutine */ int zlarfg_(integer *n, doublecomplex *alpha, doublecomplex *
+ x, integer *incx, doublecomplex *tau);
+
+/* Subroutine */ int zlarft_(char *direct, char *storev, integer *n, integer *
+ k, doublecomplex *v, integer *ldv, doublecomplex *tau, doublecomplex *
+ t, integer *ldt);
+
+/* Subroutine */ int zlarfx_(char *side, integer *m, integer *n,
+ doublecomplex *v, doublecomplex *tau, doublecomplex *c__, integer *
+ ldc, doublecomplex *work);
+
+/* Subroutine */ int zlargv_(integer *n, doublecomplex *x, integer *incx,
+ doublecomplex *y, integer *incy, doublereal *c__, integer *incc);
+
+/* Subroutine */ int zlarnv_(integer *idist, integer *iseed, integer *n,
+ doublecomplex *x);
+
+/* Subroutine */ int zlarrv_(integer *n, doublereal *d__, doublereal *l,
+ integer *isplit, integer *m, doublereal *w, integer *iblock,
+ doublereal *gersch, doublereal *tol, doublecomplex *z__, integer *ldz,
+ integer *isuppz, doublereal *work, integer *iwork, integer *info);
+
+/* Subroutine */ int zlartg_(doublecomplex *f, doublecomplex *g, doublereal *
+ cs, doublecomplex *sn, doublecomplex *r__);
+
+/* Subroutine */ int zlartv_(integer *n, doublecomplex *x, integer *incx,
+ doublecomplex *y, integer *incy, doublereal *c__, doublecomplex *s,
+ integer *incc);
+
+/* Subroutine */ int zlarz_(char *side, integer *m, integer *n, integer *l,
+ doublecomplex *v, integer *incv, doublecomplex *tau, doublecomplex *
+ c__, integer *ldc, doublecomplex *work);
+
+/* Subroutine */ int zlarzb_(char *side, char *trans, char *direct, char *
+ storev, integer *m, integer *n, integer *k, integer *l, doublecomplex
+ *v, integer *ldv, doublecomplex *t, integer *ldt, doublecomplex *c__,
+ integer *ldc, doublecomplex *work, integer *ldwork);
+
+/* Subroutine */ int zlarzt_(char *direct, char *storev, integer *n, integer *
+ k, doublecomplex *v, integer *ldv, doublecomplex *tau, doublecomplex *
+ t, integer *ldt);
+
+/* Subroutine */ int zlascl_(char *type__, integer *kl, integer *ku,
+ doublereal *cfrom, doublereal *cto, integer *m, integer *n,
+ doublecomplex *a, integer *lda, integer *info);
+
+/* Subroutine */ int zlaset_(char *uplo, integer *m, integer *n,
+ doublecomplex *alpha, doublecomplex *beta, doublecomplex *a, integer *
+ lda);
+
+/* Subroutine */ int zlasr_(char *side, char *pivot, char *direct, integer *m,
+ integer *n, doublereal *c__, doublereal *s, doublecomplex *a,
+ integer *lda);
+
+/* Subroutine */ int zlassq_(integer *n, doublecomplex *x, integer *incx,
+ doublereal *scale, doublereal *sumsq);
+
+/* Subroutine */ int zlaswp_(integer *n, doublecomplex *a, integer *lda,
+ integer *k1, integer *k2, integer *ipiv, integer *incx);
+
+/* Subroutine */ int zlasyf_(char *uplo, integer *n, integer *nb, integer *kb,
+ doublecomplex *a, integer *lda, integer *ipiv, doublecomplex *w,
+ integer *ldw, integer *info);
+
+/* Subroutine */ int zlatbs_(char *uplo, char *trans, char *diag, char *
+ normin, integer *n, integer *kd, doublecomplex *ab, integer *ldab,
+ doublecomplex *x, doublereal *scale, doublereal *cnorm, integer *info);
+
+/* Subroutine */ int zlatdf_(integer *ijob, integer *n, doublecomplex *z__,
+ integer *ldz, doublecomplex *rhs, doublereal *rdsum, doublereal *
+ rdscal, integer *ipiv, integer *jpiv);
+
+/* Subroutine */ int zlatps_(char *uplo, char *trans, char *diag, char *
+ normin, integer *n, doublecomplex *ap, doublecomplex *x, doublereal *
+ scale, doublereal *cnorm, integer *info);
+
+/* Subroutine */ int zlatrd_(char *uplo, integer *n, integer *nb,
+ doublecomplex *a, integer *lda, doublereal *e, doublecomplex *tau,
+ doublecomplex *w, integer *ldw);
+
+/* Subroutine */ int zlatrs_(char *uplo, char *trans, char *diag, char *
+ normin, integer *n, doublecomplex *a, integer *lda, doublecomplex *x,
+ doublereal *scale, doublereal *cnorm, integer *info);
+
+/* Subroutine */ int zlatrz_(integer *m, integer *n, integer *l,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
+ work);
+
+/* Subroutine */ int zlatzm_(char *side, integer *m, integer *n,
+ doublecomplex *v, integer *incv, doublecomplex *tau, doublecomplex *
+ c1, doublecomplex *c2, integer *ldc, doublecomplex *work);
+
+/* Subroutine */ int zlauu2_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, integer *info);
+
+/* Subroutine */ int zlauum_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, integer *info);
+
+/* Subroutine */ int zpbcon_(char *uplo, integer *n, integer *kd,
+ doublecomplex *ab, integer *ldab, doublereal *anorm, doublereal *
+ rcond, doublecomplex *work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zpbequ_(char *uplo, integer *n, integer *kd,
+ doublecomplex *ab, integer *ldab, doublereal *s, doublereal *scond,
+ doublereal *amax, integer *info);
+
+/* Subroutine */ int zpbrfs_(char *uplo, integer *n, integer *kd, integer *
+ nrhs, doublecomplex *ab, integer *ldab, doublecomplex *afb, integer *
+ ldafb, doublecomplex *b, integer *ldb, doublecomplex *x, integer *ldx,
+ doublereal *ferr, doublereal *berr, doublecomplex *work, doublereal *
+ rwork, integer *info);
+
+/* Subroutine */ int zpbstf_(char *uplo, integer *n, integer *kd,
+ doublecomplex *ab, integer *ldab, integer *info);
+
+/* Subroutine */ int zpbsv_(char *uplo, integer *n, integer *kd, integer *
+ nrhs, doublecomplex *ab, integer *ldab, doublecomplex *b, integer *
+ ldb, integer *info);
+
+/* Subroutine */ int zpbsvx_(char *fact, char *uplo, integer *n, integer *kd,
+ integer *nrhs, doublecomplex *ab, integer *ldab, doublecomplex *afb,
+ integer *ldafb, char *equed, doublereal *s, doublecomplex *b, integer
+ *ldb, doublecomplex *x, integer *ldx, doublereal *rcond, doublereal *
+ ferr, doublereal *berr, doublecomplex *work, doublereal *rwork,
+ integer *info);
+
+/* Subroutine */ int zpbtf2_(char *uplo, integer *n, integer *kd,
+ doublecomplex *ab, integer *ldab, integer *info);
+
+/* Subroutine */ int zpbtrf_(char *uplo, integer *n, integer *kd,
+ doublecomplex *ab, integer *ldab, integer *info);
+
+/* Subroutine */ int zpbtrs_(char *uplo, integer *n, integer *kd, integer *
+ nrhs, doublecomplex *ab, integer *ldab, doublecomplex *b, integer *
+ ldb, integer *info);
+
+/* Subroutine */ int zpocon_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, doublereal *anorm, doublereal *rcond, doublecomplex *
+ work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zpoequ_(integer *n, doublecomplex *a, integer *lda,
+ doublereal *s, doublereal *scond, doublereal *amax, integer *info);
+
+/* Subroutine */ int zporfs_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *a, integer *lda, doublecomplex *af, integer *ldaf,
+ doublecomplex *b, integer *ldb, doublecomplex *x, integer *ldx,
+ doublereal *ferr, doublereal *berr, doublecomplex *work, doublereal *
+ rwork, integer *info);
+
+/* Subroutine */ int zposv_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int zposvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, doublecomplex *a, integer *lda, doublecomplex *af, integer *
+ ldaf, char *equed, doublereal *s, doublecomplex *b, integer *ldb,
+ doublecomplex *x, integer *ldx, doublereal *rcond, doublereal *ferr,
+ doublereal *berr, doublecomplex *work, doublereal *rwork, integer *
+ info);
+
+/* Subroutine */ int zpotf2_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, integer *info);
+
+/* Subroutine */ int zpotrf_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, integer *info);
+
+/* Subroutine */ int zpotri_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, integer *info);
+
+/* Subroutine */ int zpotrs_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int zppcon_(char *uplo, integer *n, doublecomplex *ap,
+ doublereal *anorm, doublereal *rcond, doublecomplex *work, doublereal
+ *rwork, integer *info);
+
+/* Subroutine */ int zppequ_(char *uplo, integer *n, doublecomplex *ap,
+ doublereal *s, doublereal *scond, doublereal *amax, integer *info);
+
+/* Subroutine */ int zpprfs_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *ap, doublecomplex *afp, doublecomplex *b, integer *ldb,
+ doublecomplex *x, integer *ldx, doublereal *ferr, doublereal *berr,
+ doublecomplex *work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zppsv_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *ap, doublecomplex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int zppsvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, doublecomplex *ap, doublecomplex *afp, char *equed, doublereal *
+ s, doublecomplex *b, integer *ldb, doublecomplex *x, integer *ldx,
+ doublereal *rcond, doublereal *ferr, doublereal *berr, doublecomplex *
+ work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zpptrf_(char *uplo, integer *n, doublecomplex *ap,
+ integer *info);
+
+/* Subroutine */ int zpptri_(char *uplo, integer *n, doublecomplex *ap,
+ integer *info);
+
+/* Subroutine */ int zpptrs_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *ap, doublecomplex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int zptcon_(integer *n, doublereal *d__, doublecomplex *e,
+ doublereal *anorm, doublereal *rcond, doublereal *rwork, integer *
+ info);
+
+/* Subroutine */ int zptrfs_(char *uplo, integer *n, integer *nrhs,
+ doublereal *d__, doublecomplex *e, doublereal *df, doublecomplex *ef,
+ doublecomplex *b, integer *ldb, doublecomplex *x, integer *ldx,
+ doublereal *ferr, doublereal *berr, doublecomplex *work, doublereal *
+ rwork, integer *info);
+
+/* Subroutine */ int zptsv_(integer *n, integer *nrhs, doublereal *d__,
+ doublecomplex *e, doublecomplex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int zptsvx_(char *fact, integer *n, integer *nrhs,
+ doublereal *d__, doublecomplex *e, doublereal *df, doublecomplex *ef,
+ doublecomplex *b, integer *ldb, doublecomplex *x, integer *ldx,
+ doublereal *rcond, doublereal *ferr, doublereal *berr, doublecomplex *
+ work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zpttrf_(integer *n, doublereal *d__, doublecomplex *e,
+ integer *info);
+
+/* Subroutine */ int zpttrs_(char *uplo, integer *n, integer *nrhs,
+ doublereal *d__, doublecomplex *e, doublecomplex *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int zptts2_(integer *iuplo, integer *n, integer *nrhs,
+ doublereal *d__, doublecomplex *e, doublecomplex *b, integer *ldb);
+
+/* Subroutine */ int zrot_(integer *n, doublecomplex *cx, integer *incx,
+ doublecomplex *cy, integer *incy, doublereal *c__, doublecomplex *s);
+
+/* Subroutine */ int zspcon_(char *uplo, integer *n, doublecomplex *ap,
+ integer *ipiv, doublereal *anorm, doublereal *rcond, doublecomplex *
+ work, integer *info);
+
+/* Subroutine */ int zspmv_(char *uplo, integer *n, doublecomplex *alpha,
+ doublecomplex *ap, doublecomplex *x, integer *incx, doublecomplex *
+ beta, doublecomplex *y, integer *incy);
+
+/* Subroutine */ int zspr_(char *uplo, integer *n, doublecomplex *alpha,
+ doublecomplex *x, integer *incx, doublecomplex *ap);
+
+/* Subroutine */ int zsprfs_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *ap, doublecomplex *afp, integer *ipiv, doublecomplex *
+ b, integer *ldb, doublecomplex *x, integer *ldx, doublereal *ferr,
+ doublereal *berr, doublecomplex *work, doublereal *rwork, integer *
+ info);
+
+/* Subroutine */ int zspsv_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *ap, integer *ipiv, doublecomplex *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int zspsvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, doublecomplex *ap, doublecomplex *afp, integer *ipiv,
+ doublecomplex *b, integer *ldb, doublecomplex *x, integer *ldx,
+ doublereal *rcond, doublereal *ferr, doublereal *berr, doublecomplex *
+ work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zsptrf_(char *uplo, integer *n, doublecomplex *ap,
+ integer *ipiv, integer *info);
+
+/* Subroutine */ int zsptri_(char *uplo, integer *n, doublecomplex *ap,
+ integer *ipiv, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zsptrs_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *ap, integer *ipiv, doublecomplex *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int zstedc_(char *compz, integer *n, doublereal *d__,
+ doublereal *e, doublecomplex *z__, integer *ldz, doublecomplex *work,
+ integer *lwork, doublereal *rwork, integer *lrwork, integer *iwork,
+ integer *liwork, integer *info);
+
+/* Subroutine */ int zstein_(integer *n, doublereal *d__, doublereal *e,
+ integer *m, doublereal *w, integer *iblock, integer *isplit,
+ doublecomplex *z__, integer *ldz, doublereal *work, integer *iwork,
+ integer *ifail, integer *info);
+
+/* Subroutine */ int zsteqr_(char *compz, integer *n, doublereal *d__,
+ doublereal *e, doublecomplex *z__, integer *ldz, doublereal *work,
+ integer *info);
+
+/* Subroutine */ int zsycon_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, integer *ipiv, doublereal *anorm, doublereal *rcond,
+ doublecomplex *work, integer *info);
+
+/* Subroutine */ int zsymv_(char *uplo, integer *n, doublecomplex *alpha,
+ doublecomplex *a, integer *lda, doublecomplex *x, integer *incx,
+ doublecomplex *beta, doublecomplex *y, integer *incy);
+
+/* Subroutine */ int zsyr_(char *uplo, integer *n, doublecomplex *alpha,
+ doublecomplex *x, integer *incx, doublecomplex *a, integer *lda);
+
+/* Subroutine */ int zsyrfs_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *a, integer *lda, doublecomplex *af, integer *ldaf,
+ integer *ipiv, doublecomplex *b, integer *ldb, doublecomplex *x,
+ integer *ldx, doublereal *ferr, doublereal *berr, doublecomplex *work,
+ doublereal *rwork, integer *info);
+
+/* Subroutine */ int zsysv_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *a, integer *lda, integer *ipiv, doublecomplex *b,
+ integer *ldb, doublecomplex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int zsysvx_(char *fact, char *uplo, integer *n, integer *
+ nrhs, doublecomplex *a, integer *lda, doublecomplex *af, integer *
+ ldaf, integer *ipiv, doublecomplex *b, integer *ldb, doublecomplex *x,
+ integer *ldx, doublereal *rcond, doublereal *ferr, doublereal *berr,
+ doublecomplex *work, integer *lwork, doublereal *rwork, integer *info);
+
+/* Subroutine */ int zsytf2_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, integer *ipiv, integer *info);
+
+/* Subroutine */ int zsytrf_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, integer *ipiv, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zsytri_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, integer *ipiv, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zsytrs_(char *uplo, integer *n, integer *nrhs,
+ doublecomplex *a, integer *lda, integer *ipiv, doublecomplex *b,
+ integer *ldb, integer *info);
+
+/* Subroutine */ int ztbcon_(char *norm, char *uplo, char *diag, integer *n,
+ integer *kd, doublecomplex *ab, integer *ldab, doublereal *rcond,
+ doublecomplex *work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int ztbrfs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *kd, integer *nrhs, doublecomplex *ab, integer *ldab,
+ doublecomplex *b, integer *ldb, doublecomplex *x, integer *ldx,
+ doublereal *ferr, doublereal *berr, doublecomplex *work, doublereal *
+ rwork, integer *info);
+
+/* Subroutine */ int ztbtrs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *kd, integer *nrhs, doublecomplex *ab, integer *ldab,
+ doublecomplex *b, integer *ldb, integer *info);
+
+/* Subroutine */ int ztgevc_(char *side, char *howmny, logical *select,
+ integer *n, doublecomplex *a, integer *lda, doublecomplex *b, integer
+ *ldb, doublecomplex *vl, integer *ldvl, doublecomplex *vr, integer *
+ ldvr, integer *mm, integer *m, doublecomplex *work, doublereal *rwork,
+ integer *info);
+
+/* Subroutine */ int ztgex2_(logical *wantq, logical *wantz, integer *n,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ doublecomplex *q, integer *ldq, doublecomplex *z__, integer *ldz,
+ integer *j1, integer *info);
+
+/* Subroutine */ int ztgexc_(logical *wantq, logical *wantz, integer *n,
+ doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ doublecomplex *q, integer *ldq, doublecomplex *z__, integer *ldz,
+ integer *ifst, integer *ilst, integer *info);
+
+/* Subroutine */ int ztgsen_(integer *ijob, logical *wantq, logical *wantz,
+ logical *select, integer *n, doublecomplex *a, integer *lda,
+ doublecomplex *b, integer *ldb, doublecomplex *alpha, doublecomplex *
+ beta, doublecomplex *q, integer *ldq, doublecomplex *z__, integer *
+ ldz, integer *m, doublereal *pl, doublereal *pr, doublereal *dif,
+ doublecomplex *work, integer *lwork, integer *iwork, integer *liwork,
+ integer *info);
+
+/* Subroutine */ int ztgsja_(char *jobu, char *jobv, char *jobq, integer *m,
+ integer *p, integer *n, integer *k, integer *l, doublecomplex *a,
+ integer *lda, doublecomplex *b, integer *ldb, doublereal *tola,
+ doublereal *tolb, doublereal *alpha, doublereal *beta, doublecomplex *
+ u, integer *ldu, doublecomplex *v, integer *ldv, doublecomplex *q,
+ integer *ldq, doublecomplex *work, integer *ncycle, integer *info);
+
+/* Subroutine */ int ztgsna_(char *job, char *howmny, logical *select,
+ integer *n, doublecomplex *a, integer *lda, doublecomplex *b, integer
+ *ldb, doublecomplex *vl, integer *ldvl, doublecomplex *vr, integer *
+ ldvr, doublereal *s, doublereal *dif, integer *mm, integer *m,
+ doublecomplex *work, integer *lwork, integer *iwork, integer *info);
+
+/* Subroutine */ int ztgsy2_(char *trans, integer *ijob, integer *m, integer *
+ n, doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ doublecomplex *c__, integer *ldc, doublecomplex *d__, integer *ldd,
+ doublecomplex *e, integer *lde, doublecomplex *f, integer *ldf,
+ doublereal *scale, doublereal *rdsum, doublereal *rdscal, integer *
+ info);
+
+/* Subroutine */ int ztgsyl_(char *trans, integer *ijob, integer *m, integer *
+ n, doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
+ doublecomplex *c__, integer *ldc, doublecomplex *d__, integer *ldd,
+ doublecomplex *e, integer *lde, doublecomplex *f, integer *ldf,
+ doublereal *scale, doublereal *dif, doublecomplex *work, integer *
+ lwork, integer *iwork, integer *info);
+
+/* Subroutine */ int ztpcon_(char *norm, char *uplo, char *diag, integer *n,
+ doublecomplex *ap, doublereal *rcond, doublecomplex *work, doublereal
+ *rwork, integer *info);
+
+/* Subroutine */ int ztprfs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, doublecomplex *ap, doublecomplex *b, integer *ldb,
+ doublecomplex *x, integer *ldx, doublereal *ferr, doublereal *berr,
+ doublecomplex *work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int ztptri_(char *uplo, char *diag, integer *n,
+ doublecomplex *ap, integer *info);
+
+/* Subroutine */ int ztptrs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, doublecomplex *ap, doublecomplex *b, integer *ldb,
+ integer *info);
+
+/* Subroutine */ int ztrcon_(char *norm, char *uplo, char *diag, integer *n,
+ doublecomplex *a, integer *lda, doublereal *rcond, doublecomplex *
+ work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int ztrevc_(char *side, char *howmny, logical *select,
+ integer *n, doublecomplex *t, integer *ldt, doublecomplex *vl,
+ integer *ldvl, doublecomplex *vr, integer *ldvr, integer *mm, integer
+ *m, doublecomplex *work, doublereal *rwork, integer *info);
+
+/* Subroutine */ int ztrexc_(char *compq, integer *n, doublecomplex *t,
+ integer *ldt, doublecomplex *q, integer *ldq, integer *ifst, integer *
+ ilst, integer *info);
+
+/* Subroutine */ int ztrrfs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, doublecomplex *a, integer *lda, doublecomplex *b,
+ integer *ldb, doublecomplex *x, integer *ldx, doublereal *ferr,
+ doublereal *berr, doublecomplex *work, doublereal *rwork, integer *
+ info);
+
+/* Subroutine */ int ztrsen_(char *job, char *compq, logical *select, integer
+ *n, doublecomplex *t, integer *ldt, doublecomplex *q, integer *ldq,
+ doublecomplex *w, integer *m, doublereal *s, doublereal *sep,
+ doublecomplex *work, integer *lwork, integer *info);
+
+/* Subroutine */ int ztrsna_(char *job, char *howmny, logical *select,
+ integer *n, doublecomplex *t, integer *ldt, doublecomplex *vl,
+ integer *ldvl, doublecomplex *vr, integer *ldvr, doublereal *s,
+ doublereal *sep, integer *mm, integer *m, doublecomplex *work,
+ integer *ldwork, doublereal *rwork, integer *info);
+
+/* Subroutine */ int ztrsyl_(char *trana, char *tranb, integer *isgn, integer
+ *m, integer *n, doublecomplex *a, integer *lda, doublecomplex *b,
+ integer *ldb, doublecomplex *c__, integer *ldc, doublereal *scale,
+ integer *info);
+
+/* Subroutine */ int ztrti2_(char *uplo, char *diag, integer *n,
+ doublecomplex *a, integer *lda, integer *info);
+
+/* Subroutine */ int ztrtri_(char *uplo, char *diag, integer *n,
+ doublecomplex *a, integer *lda, integer *info);
+
+/* Subroutine */ int ztrtrs_(char *uplo, char *trans, char *diag, integer *n,
+ integer *nrhs, doublecomplex *a, integer *lda, doublecomplex *b,
+ integer *ldb, integer *info);
+
+/* Subroutine */ int ztzrqf_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublecomplex *tau, integer *info);
+
+/* Subroutine */ int ztzrzf_(integer *m, integer *n, doublecomplex *a,
+ integer *lda, doublecomplex *tau, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zung2l_(integer *m, integer *n, integer *k,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
+ work, integer *info);
+
+/* Subroutine */ int zung2r_(integer *m, integer *n, integer *k,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
+ work, integer *info);
+
+/* Subroutine */ int zungbr_(char *vect, integer *m, integer *n, integer *k,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
+ work, integer *lwork, integer *info);
+
+/* Subroutine */ int zunghr_(integer *n, integer *ilo, integer *ihi,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
+ work, integer *lwork, integer *info);
+
+/* Subroutine */ int zungl2_(integer *m, integer *n, integer *k,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
+ work, integer *info);
+
+/* Subroutine */ int zunglq_(integer *m, integer *n, integer *k,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
+ work, integer *lwork, integer *info);
+
+/* Subroutine */ int zungql_(integer *m, integer *n, integer *k,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
+ work, integer *lwork, integer *info);
+
+/* Subroutine */ int zungqr_(integer *m, integer *n, integer *k,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
+ work, integer *lwork, integer *info);
+
+/* Subroutine */ int zungr2_(integer *m, integer *n, integer *k,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
+ work, integer *info);
+
+/* Subroutine */ int zungrq_(integer *m, integer *n, integer *k,
+ doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
+ work, integer *lwork, integer *info);
+
+/* Subroutine */ int zungtr_(char *uplo, integer *n, doublecomplex *a,
+ integer *lda, doublecomplex *tau, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zunm2l_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublecomplex *a, integer *lda, doublecomplex *tau,
+ doublecomplex *c__, integer *ldc, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zunm2r_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublecomplex *a, integer *lda, doublecomplex *tau,
+ doublecomplex *c__, integer *ldc, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zunmbr_(char *vect, char *side, char *trans, integer *m,
+ integer *n, integer *k, doublecomplex *a, integer *lda, doublecomplex
+ *tau, doublecomplex *c__, integer *ldc, doublecomplex *work, integer *
+ lwork, integer *info);
+
+/* Subroutine */ int zunmhr_(char *side, char *trans, integer *m, integer *n,
+ integer *ilo, integer *ihi, doublecomplex *a, integer *lda,
+ doublecomplex *tau, doublecomplex *c__, integer *ldc, doublecomplex *
+ work, integer *lwork, integer *info);
+
+/* Subroutine */ int zunml2_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublecomplex *a, integer *lda, doublecomplex *tau,
+ doublecomplex *c__, integer *ldc, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zunmlq_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublecomplex *a, integer *lda, doublecomplex *tau,
+ doublecomplex *c__, integer *ldc, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zunmql_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublecomplex *a, integer *lda, doublecomplex *tau,
+ doublecomplex *c__, integer *ldc, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zunmqr_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublecomplex *a, integer *lda, doublecomplex *tau,
+ doublecomplex *c__, integer *ldc, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zunmr2_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublecomplex *a, integer *lda, doublecomplex *tau,
+ doublecomplex *c__, integer *ldc, doublecomplex *work, integer *info);
+
+/* Subroutine */ int zunmr3_(char *side, char *trans, integer *m, integer *n,
+ integer *k, integer *l, doublecomplex *a, integer *lda, doublecomplex
+ *tau, doublecomplex *c__, integer *ldc, doublecomplex *work, integer *
+ info);
+
+/* Subroutine */ int zunmrq_(char *side, char *trans, integer *m, integer *n,
+ integer *k, doublecomplex *a, integer *lda, doublecomplex *tau,
+ doublecomplex *c__, integer *ldc, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zunmrz_(char *side, char *trans, integer *m, integer *n,
+ integer *k, integer *l, doublecomplex *a, integer *lda, doublecomplex
+ *tau, doublecomplex *c__, integer *ldc, doublecomplex *work, integer *
+ lwork, integer *info);
+
+/* Subroutine */ int zunmtr_(char *side, char *uplo, char *trans, integer *m,
+ integer *n, doublecomplex *a, integer *lda, doublecomplex *tau,
+ doublecomplex *c__, integer *ldc, doublecomplex *work, integer *lwork,
+ integer *info);
+
+/* Subroutine */ int zupgtr_(char *uplo, integer *n, doublecomplex *ap,
+ doublecomplex *tau, doublecomplex *q, integer *ldq, doublecomplex *
+ work, integer *info);
+
+/* Subroutine */ int zupmtr_(char *side, char *uplo, char *trans, integer *m,
+ integer *n, doublecomplex *ap, doublecomplex *tau, doublecomplex *c__,
+ integer *ldc, doublecomplex *work, integer *info);
+
+#endif /* __CLAPACK_H */
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/close.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/close.c
new file mode 100644
index 0000000..5810059
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/close.c
@@ -0,0 +1,94 @@
+#include "f2c.h"
+#include "fio.h"
+#ifdef KR_headers
+integer f_clos(a) cllist *a;
+#else
+#undef abs
+#undef min
+#undef max
+#include "stdlib.h"
+#ifdef NON_UNIX_STDIO
+#ifndef unlink
+#define unlink remove
+#endif
+#else
+#ifdef MSDOS
+#include "io.h"
+#else
+#ifdef __cplusplus
+extern "C" int unlink(const char*);
+#else
+extern int unlink(const char*);
+#endif
+#endif
+#endif
+
+integer f_clos(cllist *a)
+#endif
+{ unit *b;
+
+ if(a->cunit >= MXUNIT) return(0);
+ b= &f__units[a->cunit];
+ if(b->ufd==NULL)
+ goto done;
+ if (b->uscrtch == 1)
+ goto Delete;
+ if (!a->csta)
+ goto Keep;
+ switch(*a->csta) {
+ default:
+ Keep:
+ case 'k':
+ case 'K':
+ if(b->uwrt == 1)
+ t_runc((alist *)a);
+ if(b->ufnm) {
+ fclose(b->ufd);
+ free(b->ufnm);
+ }
+ break;
+ case 'd':
+ case 'D':
+ Delete:
+ fclose(b->ufd);
+ if(b->ufnm) {
+ unlink(b->ufnm); /*SYSDEP*/
+ free(b->ufnm);
+ }
+ }
+ b->ufd=NULL;
+ done:
+ b->uend=0;
+ b->ufnm=NULL;
+ return(0);
+ }
+ void
+#ifdef KR_headers
+f_exit()
+#else
+f_exit(void)
+#endif
+{ int i;
+ static cllist xx;
+ if (!xx.cerr) {
+ xx.cerr=1;
+ xx.csta=NULL;
+ for(i=0;i<MXUNIT;i++)
+ {
+ xx.cunit=i;
+ (void) f_clos(&xx);
+ }
+ }
+}
+ int
+#ifdef KR_headers
+flush_()
+#else
+flush_(void)
+#endif
+{ int i;
+ for(i=0;i<MXUNIT;i++)
+ if(f__units[i].ufd != NULL && f__units[i].uwrt)
+ fflush(f__units[i].ufd);
+return 0;
+}
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgemm.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgemm.c
new file mode 100644
index 0000000..964a278
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgemm.c
@@ -0,0 +1,313 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+/* Subroutine */ int dgemm_(char *transa, char *transb, integer *m, integer *
+ n, integer *k, doublereal *alpha, doublereal *a, integer *lda,
+ doublereal *b, integer *ldb, doublereal *beta, doublereal *c__,
+ integer *ldc)
+{
+ /* System generated locals */
+ integer a_dim1, a_offset, b_dim1, b_offset, c_dim1, c_offset, i__1, i__2,
+ i__3;
+ /* Local variables */
+ static integer info;
+ static logical nota, notb;
+ static doublereal temp;
+ static integer i__, j, l, ncola;
+ extern logical lsame_(char *, char *);
+ static integer nrowa, nrowb;
+ extern /* Subroutine */ int xerbla_(char *, integer *);
+#define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1]
+#define b_ref(a_1,a_2) b[(a_2)*b_dim1 + a_1]
+#define c___ref(a_1,a_2) c__[(a_2)*c_dim1 + a_1]
+/* Purpose
+ =======
+ DGEMM performs one of the matrix-matrix operations
+ C := alpha*op( A )*op( B ) + beta*C,
+ where op( X ) is one of
+ op( X ) = X or op( X ) = X',
+ alpha and beta are scalars, and A, B and C are matrices, with op( A )
+ an m by k matrix, op( B ) a k by n matrix and C an m by n matrix.
+ Parameters
+ ==========
+ TRANSA - CHARACTER*1.
+ On entry, TRANSA specifies the form of op( A ) to be used in
+ the matrix multiplication as follows:
+ TRANSA = 'N' or 'n', op( A ) = A.
+ TRANSA = 'T' or 't', op( A ) = A'.
+ TRANSA = 'C' or 'c', op( A ) = A'.
+ Unchanged on exit.
+ TRANSB - CHARACTER*1.
+ On entry, TRANSB specifies the form of op( B ) to be used in
+ the matrix multiplication as follows:
+ TRANSB = 'N' or 'n', op( B ) = B.
+ TRANSB = 'T' or 't', op( B ) = B'.
+ TRANSB = 'C' or 'c', op( B ) = B'.
+ Unchanged on exit.
+ M - INTEGER.
+ On entry, M specifies the number of rows of the matrix
+ op( A ) and of the matrix C. M must be at least zero.
+ Unchanged on exit.
+ N - INTEGER.
+ On entry, N specifies the number of columns of the matrix
+ op( B ) and the number of columns of the matrix C. N must be
+ at least zero.
+ Unchanged on exit.
+ K - INTEGER.
+ On entry, K specifies the number of columns of the matrix
+ op( A ) and the number of rows of the matrix op( B ). K must
+ be at least zero.
+ Unchanged on exit.
+ ALPHA - DOUBLE PRECISION.
+ On entry, ALPHA specifies the scalar alpha.
+ Unchanged on exit.
+ A - DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is
+ k when TRANSA = 'N' or 'n', and is m otherwise.
+ Before entry with TRANSA = 'N' or 'n', the leading m by k
+ part of the array A must contain the matrix A, otherwise
+ the leading k by m part of the array A must contain the
+ matrix A.
+ Unchanged on exit.
+ LDA - INTEGER.
+ On entry, LDA specifies the first dimension of A as declared
+ in the calling (sub) program. When TRANSA = 'N' or 'n' then
+ LDA must be at least max( 1, m ), otherwise LDA must be at
+ least max( 1, k ).
+ Unchanged on exit.
+ B - DOUBLE PRECISION array of DIMENSION ( LDB, kb ), where kb is
+ n when TRANSB = 'N' or 'n', and is k otherwise.
+ Before entry with TRANSB = 'N' or 'n', the leading k by n
+ part of the array B must contain the matrix B, otherwise
+ the leading n by k part of the array B must contain the
+ matrix B.
+ Unchanged on exit.
+ LDB - INTEGER.
+ On entry, LDB specifies the first dimension of B as declared
+ in the calling (sub) program. When TRANSB = 'N' or 'n' then
+ LDB must be at least max( 1, k ), otherwise LDB must be at
+ least max( 1, n ).
+ Unchanged on exit.
+ BETA - DOUBLE PRECISION.
+ On entry, BETA specifies the scalar beta. When BETA is
+ supplied as zero then C need not be set on input.
+ Unchanged on exit.
+ C - DOUBLE PRECISION array of DIMENSION ( LDC, n ).
+ Before entry, the leading m by n part of the array C must
+ contain the matrix C, except when beta is zero, in which
+ case C need not be set on entry.
+ On exit, the array C is overwritten by the m by n matrix
+ ( alpha*op( A )*op( B ) + beta*C ).
+ LDC - INTEGER.
+ On entry, LDC specifies the first dimension of C as declared
+ in the calling (sub) program. LDC must be at least
+ max( 1, m ).
+ Unchanged on exit.
+ Level 3 Blas routine.
+ -- Written on 8-February-1989.
+ Jack Dongarra, Argonne National Laboratory.
+ Iain Duff, AERE Harwell.
+ Jeremy Du Croz, Numerical Algorithms Group Ltd.
+ Sven Hammarling, Numerical Algorithms Group Ltd.
+ Set NOTA and NOTB as true if A and B respectively are not
+ transposed and set NROWA, NCOLA and NROWB as the number of rows
+ and columns of A and the number of rows of B respectively.
+ Parameter adjustments */
+ a_dim1 = *lda;
+ a_offset = 1 + a_dim1 * 1;
+ a -= a_offset;
+ b_dim1 = *ldb;
+ b_offset = 1 + b_dim1 * 1;
+ b -= b_offset;
+ c_dim1 = *ldc;
+ c_offset = 1 + c_dim1 * 1;
+ c__ -= c_offset;
+ /* Function Body */
+ nota = lsame_(transa, "N");
+ notb = lsame_(transb, "N");
+ if (nota) {
+ nrowa = *m;
+ ncola = *k;
+ } else {
+ nrowa = *k;
+ ncola = *m;
+ }
+ if (notb) {
+ nrowb = *k;
+ } else {
+ nrowb = *n;
+ }
+/* Test the input parameters. */
+ info = 0;
+ if (! nota && ! lsame_(transa, "C") && ! lsame_(
+ transa, "T")) {
+ info = 1;
+ } else if (! notb && ! lsame_(transb, "C") && !
+ lsame_(transb, "T")) {
+ info = 2;
+ } else if (*m < 0) {
+ info = 3;
+ } else if (*n < 0) {
+ info = 4;
+ } else if (*k < 0) {
+ info = 5;
+ } else if (*lda < max(1,nrowa)) {
+ info = 8;
+ } else if (*ldb < max(1,nrowb)) {
+ info = 10;
+ } else if (*ldc < max(1,*m)) {
+ info = 13;
+ }
+ if (info != 0) {
+ xerbla_("DGEMM ", &info);
+ return 0;
+ }
+/* Quick return if possible. */
+ if (*m == 0 || *n == 0 || (*alpha == 0. || *k == 0) && *beta == 1.) {
+ return 0;
+ }
+/* And if alpha.eq.zero. */
+ if (*alpha == 0.) {
+ if (*beta == 0.) {
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ c___ref(i__, j) = 0.;
+/* L10: */
+ }
+/* L20: */
+ }
+ } else {
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ c___ref(i__, j) = *beta * c___ref(i__, j);
+/* L30: */
+ }
+/* L40: */
+ }
+ }
+ return 0;
+ }
+/* Start the operations. */
+ if (notb) {
+ if (nota) {
+/* Form C := alpha*A*B + beta*C. */
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ if (*beta == 0.) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ c___ref(i__, j) = 0.;
+/* L50: */
+ }
+ } else if (*beta != 1.) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ c___ref(i__, j) = *beta * c___ref(i__, j);
+/* L60: */
+ }
+ }
+ i__2 = *k;
+ for (l = 1; l <= i__2; ++l) {
+ if (b_ref(l, j) != 0.) {
+ temp = *alpha * b_ref(l, j);
+ i__3 = *m;
+ for (i__ = 1; i__ <= i__3; ++i__) {
+ c___ref(i__, j) = c___ref(i__, j) + temp * a_ref(
+ i__, l);
+/* L70: */
+ }
+ }
+/* L80: */
+ }
+/* L90: */
+ }
+ } else {
+/* Form C := alpha*A'*B + beta*C */
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ temp = 0.;
+ i__3 = *k;
+ for (l = 1; l <= i__3; ++l) {
+ temp += a_ref(l, i__) * b_ref(l, j);
+/* L100: */
+ }
+ if (*beta == 0.) {
+ c___ref(i__, j) = *alpha * temp;
+ } else {
+ c___ref(i__, j) = *alpha * temp + *beta * c___ref(i__,
+ j);
+ }
+/* L110: */
+ }
+/* L120: */
+ }
+ }
+ } else {
+ if (nota) {
+/* Form C := alpha*A*B' + beta*C */
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ if (*beta == 0.) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ c___ref(i__, j) = 0.;
+/* L130: */
+ }
+ } else if (*beta != 1.) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ c___ref(i__, j) = *beta * c___ref(i__, j);
+/* L140: */
+ }
+ }
+ i__2 = *k;
+ for (l = 1; l <= i__2; ++l) {
+ if (b_ref(j, l) != 0.) {
+ temp = *alpha * b_ref(j, l);
+ i__3 = *m;
+ for (i__ = 1; i__ <= i__3; ++i__) {
+ c___ref(i__, j) = c___ref(i__, j) + temp * a_ref(
+ i__, l);
+/* L150: */
+ }
+ }
+/* L160: */
+ }
+/* L170: */
+ }
+ } else {
+/* Form C := alpha*A'*B' + beta*C */
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ temp = 0.;
+ i__3 = *k;
+ for (l = 1; l <= i__3; ++l) {
+ temp += a_ref(l, i__) * b_ref(j, l);
+/* L180: */
+ }
+ if (*beta == 0.) {
+ c___ref(i__, j) = *alpha * temp;
+ } else {
+ c___ref(i__, j) = *alpha * temp + *beta * c___ref(i__,
+ j);
+ }
+/* L190: */
+ }
+/* L200: */
+ }
+ }
+ }
+ return 0;
+/* End of DGEMM . */
+} /* dgemm_ */
+#undef c___ref
+#undef b_ref
+#undef a_ref
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dger.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dger.c
new file mode 100644
index 0000000..c53835f
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dger.c
@@ -0,0 +1,143 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+/* Subroutine */ int dger_(integer *m, integer *n, doublereal *alpha,
+ doublereal *x, integer *incx, doublereal *y, integer *incy,
+ doublereal *a, integer *lda)
+{
+ /* System generated locals */
+ integer a_dim1, a_offset, i__1, i__2;
+ /* Local variables */
+ static integer info;
+ static doublereal temp;
+ static integer i__, j, ix, jy, kx;
+ extern /* Subroutine */ int xerbla_(char *, integer *);
+#define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1]
+/* Purpose
+ =======
+ DGER performs the rank 1 operation
+ A := alpha*x*y' + A,
+ where alpha is a scalar, x is an m element vector, y is an n element
+ vector and A is an m by n matrix.
+ Parameters
+ ==========
+ M - INTEGER.
+ On entry, M specifies the number of rows of the matrix A.
+ M must be at least zero.
+ Unchanged on exit.
+ N - INTEGER.
+ On entry, N specifies the number of columns of the matrix A.
+ N must be at least zero.
+ Unchanged on exit.
+ ALPHA - DOUBLE PRECISION.
+ On entry, ALPHA specifies the scalar alpha.
+ Unchanged on exit.
+ X - DOUBLE PRECISION array of dimension at least
+ ( 1 + ( m - 1 )*abs( INCX ) ).
+ Before entry, the incremented array X must contain the m
+ element vector x.
+ Unchanged on exit.
+ INCX - INTEGER.
+ On entry, INCX specifies the increment for the elements of
+ X. INCX must not be zero.
+ Unchanged on exit.
+ Y - DOUBLE PRECISION array of dimension at least
+ ( 1 + ( n - 1 )*abs( INCY ) ).
+ Before entry, the incremented array Y must contain the n
+ element vector y.
+ Unchanged on exit.
+ INCY - INTEGER.
+ On entry, INCY specifies the increment for the elements of
+ Y. INCY must not be zero.
+ Unchanged on exit.
+ A - DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+ Before entry, the leading m by n part of the array A must
+ contain the matrix of coefficients. On exit, A is
+ overwritten by the updated matrix.
+ LDA - INTEGER.
+ On entry, LDA specifies the first dimension of A as declared
+ in the calling (sub) program. LDA must be at least
+ max( 1, m ).
+ Unchanged on exit.
+ Level 2 Blas routine.
+ -- Written on 22-October-1986.
+ Jack Dongarra, Argonne National Lab.
+ Jeremy Du Croz, Nag Central Office.
+ Sven Hammarling, Nag Central Office.
+ Richard Hanson, Sandia National Labs.
+ Test the input parameters.
+ Parameter adjustments */
+ --x;
+ --y;
+ a_dim1 = *lda;
+ a_offset = 1 + a_dim1 * 1;
+ a -= a_offset;
+ /* Function Body */
+ info = 0;
+ if (*m < 0) {
+ info = 1;
+ } else if (*n < 0) {
+ info = 2;
+ } else if (*incx == 0) {
+ info = 5;
+ } else if (*incy == 0) {
+ info = 7;
+ } else if (*lda < max(1,*m)) {
+ info = 9;
+ }
+ if (info != 0) {
+ xerbla_("DGER ", &info);
+ return 0;
+ }
+/* Quick return if possible. */
+ if (*m == 0 || *n == 0 || *alpha == 0.) {
+ return 0;
+ }
+/* Start the operations. In this version the elements of A are
+ accessed sequentially with one pass through A. */
+ if (*incy > 0) {
+ jy = 1;
+ } else {
+ jy = 1 - (*n - 1) * *incy;
+ }
+ if (*incx == 1) {
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ if (y[jy] != 0.) {
+ temp = *alpha * y[jy];
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ a_ref(i__, j) = a_ref(i__, j) + x[i__] * temp;
+/* L10: */
+ }
+ }
+ jy += *incy;
+/* L20: */
+ }
+ } else {
+ if (*incx > 0) {
+ kx = 1;
+ } else {
+ kx = 1 - (*m - 1) * *incx;
+ }
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ if (y[jy] != 0.) {
+ temp = *alpha * y[jy];
+ ix = kx;
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ a_ref(i__, j) = a_ref(i__, j) + x[ix] * temp;
+ ix += *incx;
+/* L30: */
+ }
+ }
+ jy += *incy;
+/* L40: */
+ }
+ }
+ return 0;
+/* End of DGER . */
+} /* dger_ */
+#undef a_ref
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgesv.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgesv.c
new file mode 100644
index 0000000..5c0dc52
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgesv.c
@@ -0,0 +1,117 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+/* Subroutine */ int dgesv_(integer *n, integer *nrhs, doublereal *a, integer
+ *lda, integer *ipiv, doublereal *b, integer *ldb, integer *info)
+{
+/* -- LAPACK driver routine (version 3.0) --
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
+ Courant Institute, Argonne National Lab, and Rice University
+ March 31, 1993
+
+
+ Purpose
+ =======
+
+ DGESV computes the solution to a real system of linear equations
+ A * X = B,
+ where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
+
+ The LU decomposition with partial pivoting and row interchanges is
+ used to factor A as
+ A = P * L * U,
+ where P is a permutation matrix, L is unit lower triangular, and U is
+ upper triangular. The factored form of A is then used to solve the
+ system of equations A * X = B.
+
+ Arguments
+ =========
+
+ N (input) INTEGER
+ The number of linear equations, i.e., the order of the
+ matrix A. N >= 0.
+
+ NRHS (input) INTEGER
+ The number of right hand sides, i.e., the number of columns
+ of the matrix B. NRHS >= 0.
+
+ A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+ On entry, the N-by-N coefficient matrix A.
+ On exit, the factors L and U from the factorization
+ A = P*L*U; the unit diagonal elements of L are not stored.
+
+ LDA (input) INTEGER
+ The leading dimension of the array A. LDA >= max(1,N).
+
+ IPIV (output) INTEGER array, dimension (N)
+ The pivot indices that define the permutation matrix P;
+ row i of the matrix was interchanged with row IPIV(i).
+
+ B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+ On entry, the N-by-NRHS matrix of right hand side matrix B.
+ On exit, if INFO = 0, the N-by-NRHS solution matrix X.
+
+ LDB (input) INTEGER
+ The leading dimension of the array B. LDB >= max(1,N).
+
+ INFO (output) INTEGER
+ = 0: successful exit
+ < 0: if INFO = -i, the i-th argument had an illegal value
+ > 0: if INFO = i, U(i,i) is exactly zero. The factorization
+ has been completed, but the factor U is exactly
+ singular, so the solution could not be computed.
+
+ =====================================================================
+
+
+ Test the input parameters.
+
+ Parameter adjustments */
+ /* System generated locals */
+ integer a_dim1, a_offset, b_dim1, b_offset, i__1;
+ /* Local variables */
+ extern /* Subroutine */ int dgetrf_(integer *, integer *, doublereal *,
+ integer *, integer *, integer *), xerbla_(char *, integer *), dgetrs_(char *, integer *, integer *, doublereal *,
+ integer *, integer *, doublereal *, integer *, integer *);
+
+ a_dim1 = *lda;
+ a_offset = 1 + a_dim1 * 1;
+ a -= a_offset;
+ --ipiv;
+ b_dim1 = *ldb;
+ b_offset = 1 + b_dim1 * 1;
+ b -= b_offset;
+
+ /* Function Body */
+ *info = 0;
+ if (*n < 0) {
+ *info = -1;
+ } else if (*nrhs < 0) {
+ *info = -2;
+ } else if (*lda < max(1,*n)) {
+ *info = -4;
+ } else if (*ldb < max(1,*n)) {
+ *info = -7;
+ }
+ if (*info != 0) {
+ i__1 = -(*info);
+ xerbla_("DGESV ", &i__1);
+ return 0;
+ }
+
+/* Compute the LU factorization of A. */
+
+ dgetrf_(n, n, &a[a_offset], lda, &ipiv[1], info);
+ if (*info == 0) {
+
+/* Solve the system A*X = B, overwriting B with X. */
+
+ dgetrs_("No transpose", n, nrhs, &a[a_offset], lda, &ipiv[1], &b[
+ b_offset], ldb, info);
+ }
+ return 0;
+
+/* End of DGESV */
+
+} /* dgesv_ */
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgetf2.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgetf2.c
new file mode 100644
index 0000000..83bf187
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgetf2.c
@@ -0,0 +1,157 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+/* Subroutine */ int dgetf2_(integer *m, integer *n, doublereal *a, integer *
+ lda, integer *ipiv, integer *info)
+{
+/* -- LAPACK routine (version 3.0) --
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
+ Courant Institute, Argonne National Lab, and Rice University
+ June 30, 1992
+
+
+ Purpose
+ =======
+
+ DGETF2 computes an LU factorization of a general m-by-n matrix A
+ using partial pivoting with row interchanges.
+
+ The factorization has the form
+ A = P * L * U
+ where P is a permutation matrix, L is lower triangular with unit
+ diagonal elements (lower trapezoidal if m > n), and U is upper
+ triangular (upper trapezoidal if m < n).
+
+ This is the right-looking Level 2 BLAS version of the algorithm.
+
+ Arguments
+ =========
+
+ M (input) INTEGER
+ The number of rows of the matrix A. M >= 0.
+
+ N (input) INTEGER
+ The number of columns of the matrix A. N >= 0.
+
+ A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+ On entry, the m by n matrix to be factored.
+ On exit, the factors L and U from the factorization
+ A = P*L*U; the unit diagonal elements of L are not stored.
+
+ LDA (input) INTEGER
+ The leading dimension of the array A. LDA >= max(1,M).
+
+ IPIV (output) INTEGER array, dimension (min(M,N))
+ The pivot indices; for 1 <= i <= min(M,N), row i of the
+ matrix was interchanged with row IPIV(i).
+
+ INFO (output) INTEGER
+ = 0: successful exit
+ < 0: if INFO = -k, the k-th argument had an illegal value
+ > 0: if INFO = k, U(k,k) is exactly zero. The factorization
+ has been completed, but the factor U is exactly
+ singular, and division by zero will occur if it is used
+ to solve a system of equations.
+
+ =====================================================================
+
+
+ Test the input parameters.
+
+ Parameter adjustments */
+ /* Table of constant values */
+ static integer c__1 = 1;
+ static doublereal c_b6 = -1.;
+
+ /* System generated locals */
+ integer a_dim1, a_offset, i__1, i__2, i__3;
+ doublereal d__1;
+ /* Local variables */
+ extern /* Subroutine */ int dger_(integer *, integer *, doublereal *,
+ doublereal *, integer *, doublereal *, integer *, doublereal *,
+ integer *);
+ static integer j;
+ extern /* Subroutine */ int dscal_(integer *, doublereal *, doublereal *,
+ integer *), dswap_(integer *, doublereal *, integer *, doublereal
+ *, integer *);
+ static integer jp;
+ extern integer idamax_(integer *, doublereal *, integer *);
+ extern /* Subroutine */ int xerbla_(char *, integer *);
+#define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1]
+
+
+ a_dim1 = *lda;
+ a_offset = 1 + a_dim1 * 1;
+ a -= a_offset;
+ --ipiv;
+
+ /* Function Body */
+ *info = 0;
+ if (*m < 0) {
+ *info = -1;
+ } else if (*n < 0) {
+ *info = -2;
+ } else if (*lda < max(1,*m)) {
+ *info = -4;
+ }
+ if (*info != 0) {
+ i__1 = -(*info);
+ xerbla_("DGETF2", &i__1);
+ return 0;
+ }
+
+/* Quick return if possible */
+
+ if (*m == 0 || *n == 0) {
+ return 0;
+ }
+
+ i__1 = min(*m,*n);
+ for (j = 1; j <= i__1; ++j) {
+
+/* Find pivot and test for singularity. */
+
+ i__2 = *m - j + 1;
+ jp = j - 1 + idamax_(&i__2, &a_ref(j, j), &c__1);
+ ipiv[j] = jp;
+ if (a_ref(jp, j) != 0.) {
+
+/* Apply the interchange to columns 1:N. */
+
+ if (jp != j) {
+ dswap_(n, &a_ref(j, 1), lda, &a_ref(jp, 1), lda);
+ }
+
+/* Compute elements J+1:M of J-th column. */
+
+ if (j < *m) {
+ i__2 = *m - j;
+ d__1 = 1. / a_ref(j, j);
+ dscal_(&i__2, &d__1, &a_ref(j + 1, j), &c__1);
+ }
+
+ } else if (*info == 0) {
+
+ *info = j;
+ }
+
+ if (j < min(*m,*n)) {
+
+/* Update trailing submatrix. */
+
+ i__2 = *m - j;
+ i__3 = *n - j;
+ dger_(&i__2, &i__3, &c_b6, &a_ref(j + 1, j), &c__1, &a_ref(j, j +
+ 1), lda, &a_ref(j + 1, j + 1), lda);
+ }
+/* L10: */
+ }
+ return 0;
+
+/* End of DGETF2 */
+
+} /* dgetf2_ */
+
+#undef a_ref
+
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgetrf.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgetrf.c
new file mode 100644
index 0000000..13175f0
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgetrf.c
@@ -0,0 +1,197 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+/* Subroutine */ int dgetrf_(integer *m, integer *n, doublereal *a, integer *
+ lda, integer *ipiv, integer *info)
+{
+/* -- LAPACK routine (version 3.0) --
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
+ Courant Institute, Argonne National Lab, and Rice University
+ March 31, 1993
+
+
+ Purpose
+ =======
+
+ DGETRF computes an LU factorization of a general M-by-N matrix A
+ using partial pivoting with row interchanges.
+
+ The factorization has the form
+ A = P * L * U
+ where P is a permutation matrix, L is lower triangular with unit
+ diagonal elements (lower trapezoidal if m > n), and U is upper
+ triangular (upper trapezoidal if m < n).
+
+ This is the right-looking Level 3 BLAS version of the algorithm.
+
+ Arguments
+ =========
+
+ M (input) INTEGER
+ The number of rows of the matrix A. M >= 0.
+
+ N (input) INTEGER
+ The number of columns of the matrix A. N >= 0.
+
+ A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+ On entry, the M-by-N matrix to be factored.
+ On exit, the factors L and U from the factorization
+ A = P*L*U; the unit diagonal elements of L are not stored.
+
+ LDA (input) INTEGER
+ The leading dimension of the array A. LDA >= max(1,M).
+
+ IPIV (output) INTEGER array, dimension (min(M,N))
+ The pivot indices; for 1 <= i <= min(M,N), row i of the
+ matrix was interchanged with row IPIV(i).
+
+ INFO (output) INTEGER
+ = 0: successful exit
+ < 0: if INFO = -i, the i-th argument had an illegal value
+ > 0: if INFO = i, U(i,i) is exactly zero. The factorization
+ has been completed, but the factor U is exactly
+ singular, and division by zero will occur if it is used
+ to solve a system of equations.
+
+ =====================================================================
+
+
+ Test the input parameters.
+
+ Parameter adjustments */
+ /* Table of constant values */
+ static integer c__1 = 1;
+ static integer c_n1 = -1;
+ static doublereal c_b16 = 1.;
+ static doublereal c_b19 = -1.;
+
+ /* System generated locals */
+ integer a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5;
+ /* Local variables */
+ static integer i__, j;
+ extern /* Subroutine */ int dgemm_(char *, char *, integer *, integer *,
+ integer *, doublereal *, doublereal *, integer *, doublereal *,
+ integer *, doublereal *, doublereal *, integer *);
+ static integer iinfo;
+ extern /* Subroutine */ int dtrsm_(char *, char *, char *, char *,
+ integer *, integer *, doublereal *, doublereal *, integer *,
+ doublereal *, integer *), dgetf2_(
+ integer *, integer *, doublereal *, integer *, integer *, integer
+ *);
+ static integer jb, nb;
+ extern /* Subroutine */ int xerbla_(char *, integer *);
+ extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
+ integer *, integer *, ftnlen, ftnlen);
+ extern /* Subroutine */ int dlaswp_(integer *, doublereal *, integer *,
+ integer *, integer *, integer *, integer *);
+#define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1]
+
+
+ a_dim1 = *lda;
+ a_offset = 1 + a_dim1 * 1;
+ a -= a_offset;
+ --ipiv;
+
+ /* Function Body */
+ *info = 0;
+ if (*m < 0) {
+ *info = -1;
+ } else if (*n < 0) {
+ *info = -2;
+ } else if (*lda < max(1,*m)) {
+ *info = -4;
+ }
+ if (*info != 0) {
+ i__1 = -(*info);
+ xerbla_("DGETRF", &i__1);
+ return 0;
+ }
+
+/* Quick return if possible */
+
+ if (*m == 0 || *n == 0) {
+ return 0;
+ }
+
+/* Determine the block size for this environment. */
+
+ nb = ilaenv_(&c__1, "DGETRF", " ", m, n, &c_n1, &c_n1, (ftnlen)6, (ftnlen)
+ 1);
+ if (nb <= 1 || nb >= min(*m,*n)) {
+
+/* Use unblocked code. */
+
+ dgetf2_(m, n, &a[a_offset], lda, &ipiv[1], info);
+ } else {
+
+/* Use blocked code. */
+
+ i__1 = min(*m,*n);
+ i__2 = nb;
+ for (j = 1; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) {
+/* Computing MIN */
+ i__3 = min(*m,*n) - j + 1;
+ jb = min(i__3,nb);
+
+/* Factor diagonal and subdiagonal blocks and test for exact
+ singularity. */
+
+ i__3 = *m - j + 1;
+ dgetf2_(&i__3, &jb, &a_ref(j, j), lda, &ipiv[j], &iinfo);
+
+/* Adjust INFO and the pivot indices. */
+
+ if (*info == 0 && iinfo > 0) {
+ *info = iinfo + j - 1;
+ }
+/* Computing MIN */
+ i__4 = *m, i__5 = j + jb - 1;
+ i__3 = min(i__4,i__5);
+ for (i__ = j; i__ <= i__3; ++i__) {
+ ipiv[i__] = j - 1 + ipiv[i__];
+/* L10: */
+ }
+
+/* Apply interchanges to columns 1:J-1. */
+
+ i__3 = j - 1;
+ i__4 = j + jb - 1;
+ dlaswp_(&i__3, &a[a_offset], lda, &j, &i__4, &ipiv[1], &c__1);
+
+ if (j + jb <= *n) {
+
+/* Apply interchanges to columns J+JB:N. */
+
+ i__3 = *n - j - jb + 1;
+ i__4 = j + jb - 1;
+ dlaswp_(&i__3, &a_ref(1, j + jb), lda, &j, &i__4, &ipiv[1], &
+ c__1);
+
+/* Compute block row of U. */
+
+ i__3 = *n - j - jb + 1;
+ dtrsm_("Left", "Lower", "No transpose", "Unit", &jb, &i__3, &
+ c_b16, &a_ref(j, j), lda, &a_ref(j, j + jb), lda);
+ if (j + jb <= *m) {
+
+/* Update trailing submatrix. */
+
+ i__3 = *m - j - jb + 1;
+ i__4 = *n - j - jb + 1;
+ dgemm_("No transpose", "No transpose", &i__3, &i__4, &jb,
+ &c_b19, &a_ref(j + jb, j), lda, &a_ref(j, j + jb),
+ lda, &c_b16, &a_ref(j + jb, j + jb), lda);
+ }
+ }
+/* L20: */
+ }
+ }
+ return 0;
+
+/* End of DGETRF */
+
+} /* dgetrf_ */
+
+#undef a_ref
+
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgetrs.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgetrs.c
new file mode 100644
index 0000000..c4dd0b3
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dgetrs.c
@@ -0,0 +1,159 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+/* Subroutine */ int dgetrs_(char *trans, integer *n, integer *nrhs,
+ doublereal *a, integer *lda, integer *ipiv, doublereal *b, integer *
+ ldb, integer *info)
+{
+/* -- LAPACK routine (version 3.0) --
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
+ Courant Institute, Argonne National Lab, and Rice University
+ March 31, 1993
+
+
+ Purpose
+ =======
+
+ DGETRS solves a system of linear equations
+ A * X = B or A' * X = B
+ with a general N-by-N matrix A using the LU factorization computed
+ by DGETRF.
+
+ Arguments
+ =========
+
+ TRANS (input) CHARACTER*1
+ Specifies the form of the system of equations:
+ = 'N': A * X = B (No transpose)
+ = 'T': A'* X = B (Transpose)
+ = 'C': A'* X = B (Conjugate transpose = Transpose)
+
+ N (input) INTEGER
+ The order of the matrix A. N >= 0.
+
+ NRHS (input) INTEGER
+ The number of right hand sides, i.e., the number of columns
+ of the matrix B. NRHS >= 0.
+
+ A (input) DOUBLE PRECISION array, dimension (LDA,N)
+ The factors L and U from the factorization A = P*L*U
+ as computed by DGETRF.
+
+ LDA (input) INTEGER
+ The leading dimension of the array A. LDA >= max(1,N).
+
+ IPIV (input) INTEGER array, dimension (N)
+ The pivot indices from DGETRF; for 1<=i<=N, row i of the
+ matrix was interchanged with row IPIV(i).
+
+ B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
+ On entry, the right hand side matrix B.
+ On exit, the solution matrix X.
+
+ LDB (input) INTEGER
+ The leading dimension of the array B. LDB >= max(1,N).
+
+ INFO (output) INTEGER
+ = 0: successful exit
+ < 0: if INFO = -i, the i-th argument had an illegal value
+
+ =====================================================================
+
+
+ Test the input parameters.
+
+ Parameter adjustments */
+ /* Table of constant values */
+ static integer c__1 = 1;
+ static doublereal c_b12 = 1.;
+ static integer c_n1 = -1;
+
+ /* System generated locals */
+ integer a_dim1, a_offset, b_dim1, b_offset, i__1;
+ /* Local variables */
+ extern logical lsame_(char *, char *);
+ extern /* Subroutine */ int dtrsm_(char *, char *, char *, char *,
+ integer *, integer *, doublereal *, doublereal *, integer *,
+ doublereal *, integer *), xerbla_(
+ char *, integer *), dlaswp_(integer *, doublereal *,
+ integer *, integer *, integer *, integer *, integer *);
+ static logical notran;
+
+
+ a_dim1 = *lda;
+ a_offset = 1 + a_dim1 * 1;
+ a -= a_offset;
+ --ipiv;
+ b_dim1 = *ldb;
+ b_offset = 1 + b_dim1 * 1;
+ b -= b_offset;
+
+ /* Function Body */
+ *info = 0;
+ notran = lsame_(trans, "N");
+ if (! notran && ! lsame_(trans, "T") && ! lsame_(
+ trans, "C")) {
+ *info = -1;
+ } else if (*n < 0) {
+ *info = -2;
+ } else if (*nrhs < 0) {
+ *info = -3;
+ } else if (*lda < max(1,*n)) {
+ *info = -5;
+ } else if (*ldb < max(1,*n)) {
+ *info = -8;
+ }
+ if (*info != 0) {
+ i__1 = -(*info);
+ xerbla_("DGETRS", &i__1);
+ return 0;
+ }
+
+/* Quick return if possible */
+
+ if (*n == 0 || *nrhs == 0) {
+ return 0;
+ }
+
+ if (notran) {
+
+/* Solve A * X = B.
+
+ Apply row interchanges to the right hand sides. */
+
+ dlaswp_(nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c__1);
+
+/* Solve L*X = B, overwriting B with X. */
+
+ dtrsm_("Left", "Lower", "No transpose", "Unit", n, nrhs, &c_b12, &a[
+ a_offset], lda, &b[b_offset], ldb);
+
+/* Solve U*X = B, overwriting B with X. */
+
+ dtrsm_("Left", "Upper", "No transpose", "Non-unit", n, nrhs, &c_b12, &
+ a[a_offset], lda, &b[b_offset], ldb);
+ } else {
+
+/* Solve A' * X = B.
+
+ Solve U'*X = B, overwriting B with X. */
+
+ dtrsm_("Left", "Upper", "Transpose", "Non-unit", n, nrhs, &c_b12, &a[
+ a_offset], lda, &b[b_offset], ldb);
+
+/* Solve L'*X = B, overwriting B with X. */
+
+ dtrsm_("Left", "Lower", "Transpose", "Unit", n, nrhs, &c_b12, &a[
+ a_offset], lda, &b[b_offset], ldb);
+
+/* Apply row interchanges to the solution vectors. */
+
+ dlaswp_(nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c_n1);
+ }
+
+ return 0;
+
+/* End of DGETRS */
+
+} /* dgetrs_ */
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dlaswp.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dlaswp.c
new file mode 100644
index 0000000..4dd6fd7
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dlaswp.c
@@ -0,0 +1,143 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+/* Subroutine */ int dlaswp_(integer *n, doublereal *a, integer *lda, integer
+ *k1, integer *k2, integer *ipiv, integer *incx)
+{
+/* -- LAPACK auxiliary routine (version 3.0) --
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
+ Courant Institute, Argonne National Lab, and Rice University
+ June 30, 1999
+
+
+ Purpose
+ =======
+
+ DLASWP performs a series of row interchanges on the matrix A.
+ One row interchange is initiated for each of rows K1 through K2 of A.
+
+ Arguments
+ =========
+
+ N (input) INTEGER
+ The number of columns of the matrix A.
+
+ A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
+ On entry, the matrix of column dimension N to which the row
+ interchanges will be applied.
+ On exit, the permuted matrix.
+
+ LDA (input) INTEGER
+ The leading dimension of the array A.
+
+ K1 (input) INTEGER
+ The first element of IPIV for which a row interchange will
+ be done.
+
+ K2 (input) INTEGER
+ The last element of IPIV for which a row interchange will
+ be done.
+
+ IPIV (input) INTEGER array, dimension (M*abs(INCX))
+ The vector of pivot indices. Only the elements in positions
+ K1 through K2 of IPIV are accessed.
+ IPIV(K) = L implies rows K and L are to be interchanged.
+
+ INCX (input) INTEGER
+ The increment between successive values of IPIV. If IPIV
+ is negative, the pivots are applied in reverse order.
+
+ Further Details
+ ===============
+
+ Modified by
+ R. C. Whaley, Computer Science Dept., Univ. of Tenn., Knoxville, USA
+
+ =====================================================================
+
+
+ Interchange row I with row IPIV(I) for each of rows K1 through K2.
+
+ Parameter adjustments */
+ /* System generated locals */
+ integer a_dim1, a_offset, i__1, i__2, i__3, i__4;
+ /* Local variables */
+ static doublereal temp;
+ static integer i__, j, k, i1, i2, n32, ip, ix, ix0, inc;
+#define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1]
+
+ a_dim1 = *lda;
+ a_offset = 1 + a_dim1 * 1;
+ a -= a_offset;
+ --ipiv;
+
+ /* Function Body */
+ if (*incx > 0) {
+ ix0 = *k1;
+ i1 = *k1;
+ i2 = *k2;
+ inc = 1;
+ } else if (*incx < 0) {
+ ix0 = (1 - *k2) * *incx + 1;
+ i1 = *k2;
+ i2 = *k1;
+ inc = -1;
+ } else {
+ return 0;
+ }
+
+ n32 = *n / 32 << 5;
+ if (n32 != 0) {
+ i__1 = n32;
+ for (j = 1; j <= i__1; j += 32) {
+ ix = ix0;
+ i__2 = i2;
+ i__3 = inc;
+ for (i__ = i1; i__3 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__3)
+ {
+ ip = ipiv[ix];
+ if (ip != i__) {
+ i__4 = j + 31;
+ for (k = j; k <= i__4; ++k) {
+ temp = a_ref(i__, k);
+ a_ref(i__, k) = a_ref(ip, k);
+ a_ref(ip, k) = temp;
+/* L10: */
+ }
+ }
+ ix += *incx;
+/* L20: */
+ }
+/* L30: */
+ }
+ }
+ if (n32 != *n) {
+ ++n32;
+ ix = ix0;
+ i__1 = i2;
+ i__3 = inc;
+ for (i__ = i1; i__3 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__3) {
+ ip = ipiv[ix];
+ if (ip != i__) {
+ i__2 = *n;
+ for (k = n32; k <= i__2; ++k) {
+ temp = a_ref(i__, k);
+ a_ref(i__, k) = a_ref(ip, k);
+ a_ref(ip, k) = temp;
+/* L40: */
+ }
+ }
+ ix += *incx;
+/* L50: */
+ }
+ }
+
+ return 0;
+
+/* End of DLASWP */
+
+} /* dlaswp_ */
+
+#undef a_ref
+
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dscal.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dscal.c
new file mode 100644
index 0000000..e0e6ffb
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dscal.c
@@ -0,0 +1,62 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+/* Subroutine */ int dscal_(integer *n, doublereal *da, doublereal *dx,
+ integer *incx)
+{
+ /* System generated locals */
+ integer i__1, i__2;
+ /* Local variables */
+ static integer i__, m, nincx, mp1;
+/* scales a vector by a constant.
+ uses unrolled loops for increment equal to one.
+ jack dongarra, linpack, 3/11/78.
+ modified 3/93 to return if incx .le. 0.
+ modified 12/3/93, array(1) declarations changed to array(*)
+ Parameter adjustments */
+ --dx;
+ /* Function Body */
+ if (*n <= 0 || *incx <= 0) {
+ return 0;
+ }
+ if (*incx == 1) {
+ goto L20;
+ }
+/* code for increment not equal to 1 */
+ nincx = *n * *incx;
+ i__1 = nincx;
+ i__2 = *incx;
+ for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+ dx[i__] = *da * dx[i__];
+/* L10: */
+ }
+ return 0;
+/* code for increment equal to 1
+ clean-up loop */
+L20:
+ m = *n % 5;
+ if (m == 0) {
+ goto L40;
+ }
+ i__2 = m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ dx[i__] = *da * dx[i__];
+/* L30: */
+ }
+ if (*n < 5) {
+ return 0;
+ }
+L40:
+ mp1 = m + 1;
+ i__2 = *n;
+ for (i__ = mp1; i__ <= i__2; i__ += 5) {
+ dx[i__] = *da * dx[i__];
+ dx[i__ + 1] = *da * dx[i__ + 1];
+ dx[i__ + 2] = *da * dx[i__ + 2];
+ dx[i__ + 3] = *da * dx[i__ + 3];
+ dx[i__ + 4] = *da * dx[i__ + 4];
+/* L50: */
+ }
+ return 0;
+} /* dscal_ */
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dswap.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dswap.c
new file mode 100644
index 0000000..5aacf29
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dswap.c
@@ -0,0 +1,81 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+/* Subroutine */ int dswap_(integer *n, doublereal *dx, integer *incx,
+ doublereal *dy, integer *incy)
+{
+ /* System generated locals */
+ integer i__1;
+ /* Local variables */
+ static integer i__, m;
+ static doublereal dtemp;
+ static integer ix, iy, mp1;
+/* interchanges two vectors.
+ uses unrolled loops for increments equal one.
+ jack dongarra, linpack, 3/11/78.
+ modified 12/3/93, array(1) declarations changed to array(*)
+ Parameter adjustments */
+ --dy;
+ --dx;
+ /* Function Body */
+ if (*n <= 0) {
+ return 0;
+ }
+ if (*incx == 1 && *incy == 1) {
+ goto L20;
+ }
+/* code for unequal increments or equal increments not equal
+ to 1 */
+ ix = 1;
+ iy = 1;
+ if (*incx < 0) {
+ ix = (-(*n) + 1) * *incx + 1;
+ }
+ if (*incy < 0) {
+ iy = (-(*n) + 1) * *incy + 1;
+ }
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ dtemp = dx[ix];
+ dx[ix] = dy[iy];
+ dy[iy] = dtemp;
+ ix += *incx;
+ iy += *incy;
+/* L10: */
+ }
+ return 0;
+/* code for both increments equal to 1
+ clean-up loop */
+L20:
+ m = *n % 3;
+ if (m == 0) {
+ goto L40;
+ }
+ i__1 = m;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ dtemp = dx[i__];
+ dx[i__] = dy[i__];
+ dy[i__] = dtemp;
+/* L30: */
+ }
+ if (*n < 3) {
+ return 0;
+ }
+L40:
+ mp1 = m + 1;
+ i__1 = *n;
+ for (i__ = mp1; i__ <= i__1; i__ += 3) {
+ dtemp = dx[i__];
+ dx[i__] = dy[i__];
+ dy[i__] = dtemp;
+ dtemp = dx[i__ + 1];
+ dx[i__ + 1] = dy[i__ + 1];
+ dy[i__ + 1] = dtemp;
+ dtemp = dx[i__ + 2];
+ dx[i__ + 2] = dy[i__ + 2];
+ dy[i__ + 2] = dtemp;
+/* L50: */
+ }
+ return 0;
+} /* dswap_ */
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dtrsm.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dtrsm.c
new file mode 100644
index 0000000..d178c1e
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/dtrsm.c
@@ -0,0 +1,404 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+/* Subroutine */ int dtrsm_(char *side, char *uplo, char *transa, char *diag,
+ integer *m, integer *n, doublereal *alpha, doublereal *a, integer *
+ lda, doublereal *b, integer *ldb)
+{
+ /* System generated locals */
+ integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3;
+ /* Local variables */
+ static integer info;
+ static doublereal temp;
+ static integer i__, j, k;
+ static logical lside;
+ extern logical lsame_(char *, char *);
+ static integer nrowa;
+ static logical upper;
+ extern /* Subroutine */ int xerbla_(char *, integer *);
+ static logical nounit;
+#define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1]
+#define b_ref(a_1,a_2) b[(a_2)*b_dim1 + a_1]
+/* Purpose
+ =======
+ DTRSM solves one of the matrix equations
+ op( A )*X = alpha*B, or X*op( A ) = alpha*B,
+ where alpha is a scalar, X and B are m by n matrices, A is a unit, or
+ non-unit, upper or lower triangular matrix and op( A ) is one of
+ op( A ) = A or op( A ) = A'.
+ The matrix X is overwritten on B.
+ Parameters
+ ==========
+ SIDE - CHARACTER*1.
+ On entry, SIDE specifies whether op( A ) appears on the left
+ or right of X as follows:
+ SIDE = 'L' or 'l' op( A )*X = alpha*B.
+ SIDE = 'R' or 'r' X*op( A ) = alpha*B.
+ Unchanged on exit.
+ UPLO - CHARACTER*1.
+ On entry, UPLO specifies whether the matrix A is an upper or
+ lower triangular matrix as follows:
+ UPLO = 'U' or 'u' A is an upper triangular matrix.
+ UPLO = 'L' or 'l' A is a lower triangular matrix.
+ Unchanged on exit.
+ TRANSA - CHARACTER*1.
+ On entry, TRANSA specifies the form of op( A ) to be used in
+ the matrix multiplication as follows:
+ TRANSA = 'N' or 'n' op( A ) = A.
+ TRANSA = 'T' or 't' op( A ) = A'.
+ TRANSA = 'C' or 'c' op( A ) = A'.
+ Unchanged on exit.
+ DIAG - CHARACTER*1.
+ On entry, DIAG specifies whether or not A is unit triangular
+ as follows:
+ DIAG = 'U' or 'u' A is assumed to be unit triangular.
+ DIAG = 'N' or 'n' A is not assumed to be unit
+ triangular.
+ Unchanged on exit.
+ M - INTEGER.
+ On entry, M specifies the number of rows of B. M must be at
+ least zero.
+ Unchanged on exit.
+ N - INTEGER.
+ On entry, N specifies the number of columns of B. N must be
+ at least zero.
+ Unchanged on exit.
+ ALPHA - DOUBLE PRECISION.
+ On entry, ALPHA specifies the scalar alpha. When alpha is
+ zero then A is not referenced and B need not be set before
+ entry.
+ Unchanged on exit.
+ A - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m
+ when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'.
+ Before entry with UPLO = 'U' or 'u', the leading k by k
+ upper triangular part of the array A must contain the upper
+ triangular matrix and the strictly lower triangular part of
+ A is not referenced.
+ Before entry with UPLO = 'L' or 'l', the leading k by k
+ lower triangular part of the array A must contain the lower
+ triangular matrix and the strictly upper triangular part of
+ A is not referenced.
+ Note that when DIAG = 'U' or 'u', the diagonal elements of
+ A are not referenced either, but are assumed to be unity.
+ Unchanged on exit.
+ LDA - INTEGER.
+ On entry, LDA specifies the first dimension of A as declared
+ in the calling (sub) program. When SIDE = 'L' or 'l' then
+ LDA must be at least max( 1, m ), when SIDE = 'R' or 'r'
+ then LDA must be at least max( 1, n ).
+ Unchanged on exit.
+ B - DOUBLE PRECISION array of DIMENSION ( LDB, n ).
+ Before entry, the leading m by n part of the array B must
+ contain the right-hand side matrix B, and on exit is
+ overwritten by the solution matrix X.
+ LDB - INTEGER.
+ On entry, LDB specifies the first dimension of B as declared
+ in the calling (sub) program. LDB must be at least
+ max( 1, m ).
+ Unchanged on exit.
+ Level 3 Blas routine.
+ -- Written on 8-February-1989.
+ Jack Dongarra, Argonne National Laboratory.
+ Iain Duff, AERE Harwell.
+ Jeremy Du Croz, Numerical Algorithms Group Ltd.
+ Sven Hammarling, Numerical Algorithms Group Ltd.
+ Test the input parameters.
+ Parameter adjustments */
+ a_dim1 = *lda;
+ a_offset = 1 + a_dim1 * 1;
+ a -= a_offset;
+ b_dim1 = *ldb;
+ b_offset = 1 + b_dim1 * 1;
+ b -= b_offset;
+ /* Function Body */
+ lside = lsame_(side, "L");
+ if (lside) {
+ nrowa = *m;
+ } else {
+ nrowa = *n;
+ }
+ nounit = lsame_(diag, "N");
+ upper = lsame_(uplo, "U");
+ info = 0;
+ if (! lside && ! lsame_(side, "R")) {
+ info = 1;
+ } else if (! upper && ! lsame_(uplo, "L")) {
+ info = 2;
+ } else if (! lsame_(transa, "N") && ! lsame_(transa,
+ "T") && ! lsame_(transa, "C")) {
+ info = 3;
+ } else if (! lsame_(diag, "U") && ! lsame_(diag,
+ "N")) {
+ info = 4;
+ } else if (*m < 0) {
+ info = 5;
+ } else if (*n < 0) {
+ info = 6;
+ } else if (*lda < max(1,nrowa)) {
+ info = 9;
+ } else if (*ldb < max(1,*m)) {
+ info = 11;
+ }
+ if (info != 0) {
+ xerbla_("DTRSM ", &info);
+ return 0;
+ }
+/* Quick return if possible. */
+ if (*n == 0) {
+ return 0;
+ }
+/* And when alpha.eq.zero. */
+ if (*alpha == 0.) {
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ b_ref(i__, j) = 0.;
+/* L10: */
+ }
+/* L20: */
+ }
+ return 0;
+ }
+/* Start the operations. */
+ if (lside) {
+ if (lsame_(transa, "N")) {
+/* Form B := alpha*inv( A )*B. */
+ if (upper) {
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ if (*alpha != 1.) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ b_ref(i__, j) = *alpha * b_ref(i__, j);
+/* L30: */
+ }
+ }
+ for (k = *m; k >= 1; --k) {
+ if (b_ref(k, j) != 0.) {
+ if (nounit) {
+ b_ref(k, j) = b_ref(k, j) / a_ref(k, k);
+ }
+ i__2 = k - 1;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ b_ref(i__, j) = b_ref(i__, j) - b_ref(k, j) *
+ a_ref(i__, k);
+/* L40: */
+ }
+ }
+/* L50: */
+ }
+/* L60: */
+ }
+ } else {
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ if (*alpha != 1.) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ b_ref(i__, j) = *alpha * b_ref(i__, j);
+/* L70: */
+ }
+ }
+ i__2 = *m;
+ for (k = 1; k <= i__2; ++k) {
+ if (b_ref(k, j) != 0.) {
+ if (nounit) {
+ b_ref(k, j) = b_ref(k, j) / a_ref(k, k);
+ }
+ i__3 = *m;
+ for (i__ = k + 1; i__ <= i__3; ++i__) {
+ b_ref(i__, j) = b_ref(i__, j) - b_ref(k, j) *
+ a_ref(i__, k);
+/* L80: */
+ }
+ }
+/* L90: */
+ }
+/* L100: */
+ }
+ }
+ } else {
+/* Form B := alpha*inv( A' )*B. */
+ if (upper) {
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ temp = *alpha * b_ref(i__, j);
+ i__3 = i__ - 1;
+ for (k = 1; k <= i__3; ++k) {
+ temp -= a_ref(k, i__) * b_ref(k, j);
+/* L110: */
+ }
+ if (nounit) {
+ temp /= a_ref(i__, i__);
+ }
+ b_ref(i__, j) = temp;
+/* L120: */
+ }
+/* L130: */
+ }
+ } else {
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ for (i__ = *m; i__ >= 1; --i__) {
+ temp = *alpha * b_ref(i__, j);
+ i__2 = *m;
+ for (k = i__ + 1; k <= i__2; ++k) {
+ temp -= a_ref(k, i__) * b_ref(k, j);
+/* L140: */
+ }
+ if (nounit) {
+ temp /= a_ref(i__, i__);
+ }
+ b_ref(i__, j) = temp;
+/* L150: */
+ }
+/* L160: */
+ }
+ }
+ }
+ } else {
+ if (lsame_(transa, "N")) {
+/* Form B := alpha*B*inv( A ). */
+ if (upper) {
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ if (*alpha != 1.) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ b_ref(i__, j) = *alpha * b_ref(i__, j);
+/* L170: */
+ }
+ }
+ i__2 = j - 1;
+ for (k = 1; k <= i__2; ++k) {
+ if (a_ref(k, j) != 0.) {
+ i__3 = *m;
+ for (i__ = 1; i__ <= i__3; ++i__) {
+ b_ref(i__, j) = b_ref(i__, j) - a_ref(k, j) *
+ b_ref(i__, k);
+/* L180: */
+ }
+ }
+/* L190: */
+ }
+ if (nounit) {
+ temp = 1. / a_ref(j, j);
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ b_ref(i__, j) = temp * b_ref(i__, j);
+/* L200: */
+ }
+ }
+/* L210: */
+ }
+ } else {
+ for (j = *n; j >= 1; --j) {
+ if (*alpha != 1.) {
+ i__1 = *m;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ b_ref(i__, j) = *alpha * b_ref(i__, j);
+/* L220: */
+ }
+ }
+ i__1 = *n;
+ for (k = j + 1; k <= i__1; ++k) {
+ if (a_ref(k, j) != 0.) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ b_ref(i__, j) = b_ref(i__, j) - a_ref(k, j) *
+ b_ref(i__, k);
+/* L230: */
+ }
+ }
+/* L240: */
+ }
+ if (nounit) {
+ temp = 1. / a_ref(j, j);
+ i__1 = *m;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ b_ref(i__, j) = temp * b_ref(i__, j);
+/* L250: */
+ }
+ }
+/* L260: */
+ }
+ }
+ } else {
+/* Form B := alpha*B*inv( A' ). */
+ if (upper) {
+ for (k = *n; k >= 1; --k) {
+ if (nounit) {
+ temp = 1. / a_ref(k, k);
+ i__1 = *m;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ b_ref(i__, k) = temp * b_ref(i__, k);
+/* L270: */
+ }
+ }
+ i__1 = k - 1;
+ for (j = 1; j <= i__1; ++j) {
+ if (a_ref(j, k) != 0.) {
+ temp = a_ref(j, k);
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ b_ref(i__, j) = b_ref(i__, j) - temp * b_ref(
+ i__, k);
+/* L280: */
+ }
+ }
+/* L290: */
+ }
+ if (*alpha != 1.) {
+ i__1 = *m;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ b_ref(i__, k) = *alpha * b_ref(i__, k);
+/* L300: */
+ }
+ }
+/* L310: */
+ }
+ } else {
+ i__1 = *n;
+ for (k = 1; k <= i__1; ++k) {
+ if (nounit) {
+ temp = 1. / a_ref(k, k);
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ b_ref(i__, k) = temp * b_ref(i__, k);
+/* L320: */
+ }
+ }
+ i__2 = *n;
+ for (j = k + 1; j <= i__2; ++j) {
+ if (a_ref(j, k) != 0.) {
+ temp = a_ref(j, k);
+ i__3 = *m;
+ for (i__ = 1; i__ <= i__3; ++i__) {
+ b_ref(i__, j) = b_ref(i__, j) - temp * b_ref(
+ i__, k);
+/* L330: */
+ }
+ }
+/* L340: */
+ }
+ if (*alpha != 1.) {
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ b_ref(i__, k) = *alpha * b_ref(i__, k);
+/* L350: */
+ }
+ }
+/* L360: */
+ }
+ }
+ }
+ }
+ return 0;
+/* End of DTRSM . */
+} /* dtrsm_ */
+#undef b_ref
+#undef a_ref
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/endfile.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/endfile.c
new file mode 100644
index 0000000..ddd35d9
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/endfile.c
@@ -0,0 +1,121 @@
+#include "f2c.h"
+#include "fio.h"
+
+#ifdef KR_headers
+extern char *strcpy();
+extern FILE *tmpfile();
+#else
+#undef abs
+#undef min
+#undef max
+#include "stdlib.h"
+#include "string.h"
+#endif
+
+extern char *f__r_mode[], *f__w_mode[];
+
+#ifdef KR_headers
+integer f_end(a) alist *a;
+#else
+integer f_end(alist *a)
+#endif
+{
+ unit *b;
+ FILE *tf;
+
+ if(a->aunit>=MXUNIT || a->aunit<0) err(a->aerr,101,"endfile");
+ b = &f__units[a->aunit];
+ if(b->ufd==NULL) {
+ char nbuf[10];
+ sprintf(nbuf,"fort.%ld",a->aunit);
+ if (tf = fopen(nbuf, f__w_mode[0]))
+ fclose(tf);
+ return(0);
+ }
+ b->uend=1;
+ return(b->useek ? t_runc(a) : 0);
+}
+
+ static int
+#ifdef KR_headers
+copy(from, len, to) FILE *from, *to; register long len;
+#else
+copy(FILE *from, register long len, FILE *to)
+#endif
+{
+ int len1;
+ char buf[BUFSIZ];
+
+ while(fread(buf, len1 = len > BUFSIZ ? BUFSIZ : (int)len, 1, from)) {
+ if (!fwrite(buf, len1, 1, to))
+ return 1;
+ if ((len -= len1) <= 0)
+ break;
+ }
+ return 0;
+ }
+
+ int
+#ifdef KR_headers
+t_runc(a) alist *a;
+#else
+t_runc(alist *a)
+#endif
+{
+ long loc, len;
+ unit *b;
+ FILE *bf, *tf;
+ int rc = 0;
+
+ b = &f__units[a->aunit];
+ if(b->url)
+ return(0); /*don't truncate direct files*/
+ loc=ftell(bf = b->ufd);
+ fseek(bf,0L,SEEK_END);
+ len=ftell(bf);
+ if (loc >= len || b->useek == 0 || b->ufnm == NULL)
+ return(0);
+ fclose(b->ufd);
+ if (!loc) {
+ if (!(bf = fopen(b->ufnm, f__w_mode[b->ufmt])))
+ rc = 1;
+ if (b->uwrt)
+ b->uwrt = 1;
+ goto done;
+ }
+ if (!(bf = fopen(b->ufnm, f__r_mode[0]))
+ || !(tf = tmpfile())) {
+#ifdef NON_UNIX_STDIO
+ bad:
+#endif
+ rc = 1;
+ goto done;
+ }
+ if (copy(bf, loc, tf)) {
+ bad1:
+ rc = 1;
+ goto done1;
+ }
+ if (!(bf = freopen(b->ufnm, f__w_mode[0], bf)))
+ goto bad1;
+ rewind(tf);
+ if (copy(tf, loc, bf))
+ goto bad1;
+ b->urw = 2;
+#ifdef NON_UNIX_STDIO
+ if (b->ufmt) {
+ fclose(bf);
+ if (!(bf = fopen(b->ufnm, f__w_mode[3])))
+ goto bad;
+ fseek(bf,0L,SEEK_END);
+ b->urw = 3;
+ }
+#endif
+done1:
+ fclose(tf);
+done:
+ f__cf = b->ufd = bf;
+ if (rc)
+ err(a->aerr,111,"endfile");
+ return 0;
+ }
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/err.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/err.c
new file mode 100644
index 0000000..de6f2cc
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/err.c
@@ -0,0 +1,271 @@
+#ifndef NON_UNIX_STDIO
+#define _INCLUDE_POSIX_SOURCE /* for HP-UX */
+#define _INCLUDE_XOPEN_SOURCE /* for HP-UX */
+#include "sys/types.h"
+#include "sys/stat.h"
+#endif
+#include "f2c.h"
+#ifdef KR_headers
+extern char *malloc();
+#else
+#undef abs
+#undef min
+#undef max
+#include "stdlib.h"
+#endif
+#include "fio.h"
+#include "fmt.h" /* for struct syl */
+
+/*global definitions*/
+unit f__units[MXUNIT]; /*unit table*/
+flag f__init; /*0 on entry, 1 after initializations*/
+cilist *f__elist; /*active external io list*/
+icilist *f__svic; /*active internal io list*/
+flag f__reading; /*1 if reading, 0 if writing*/
+flag f__cplus,f__cblank;
+char *f__fmtbuf;
+flag f__external; /*1 if external io, 0 if internal */
+#ifdef KR_headers
+int (*f__doed)(),(*f__doned)();
+int (*f__doend)(),(*f__donewrec)(),(*f__dorevert)();
+int (*f__getn)(); /* for formatted input */
+void (*f__putn)(); /* for formatted output */
+#else
+int (*f__getn)(void); /* for formatted input */
+void (*f__putn)(int); /* for formatted output */
+int (*f__doed)(struct syl*, char*, ftnlen),(*f__doned)(struct syl*);
+int (*f__dorevert)(void),(*f__donewrec)(void),(*f__doend)(void);
+#endif
+flag f__sequential; /*1 if sequential io, 0 if direct*/
+flag f__formatted; /*1 if formatted io, 0 if unformatted*/
+FILE *f__cf; /*current file*/
+unit *f__curunit; /*current unit*/
+int f__recpos; /*place in current record*/
+int f__cursor, f__hiwater, f__scale;
+char *f__icptr;
+
+/*error messages*/
+char *F_err[] =
+{
+ "error in format", /* 100 */
+ "illegal unit number", /* 101 */
+ "formatted io not allowed", /* 102 */
+ "unformatted io not allowed", /* 103 */
+ "direct io not allowed", /* 104 */
+ "sequential io not allowed", /* 105 */
+ "can't backspace file", /* 106 */
+ "null file name", /* 107 */
+ "can't stat file", /* 108 */
+ "unit not connected", /* 109 */
+ "off end of record", /* 110 */
+ "truncation failed in endfile", /* 111 */
+ "incomprehensible list input", /* 112 */
+ "out of free space", /* 113 */
+ "unit not connected", /* 114 */
+ "read unexpected character", /* 115 */
+ "bad logical input field", /* 116 */
+ "bad variable type", /* 117 */
+ "bad namelist name", /* 118 */
+ "variable not in namelist", /* 119 */
+ "no end record", /* 120 */
+ "variable count incorrect", /* 121 */
+ "subscript for scalar variable", /* 122 */
+ "invalid array section", /* 123 */
+ "substring out of bounds", /* 124 */
+ "subscript out of bounds", /* 125 */
+ "can't read file", /* 126 */
+ "can't write file", /* 127 */
+ "'new' file exists", /* 128 */
+ "can't append to file", /* 129 */
+ "non-positive record number" /* 130 */
+};
+#define MAXERR (sizeof(F_err)/sizeof(char *)+100)
+
+#ifdef KR_headers
+f__canseek(f) FILE *f; /*SYSDEP*/
+#else
+f__canseek(FILE *f) /*SYSDEP*/
+#endif
+{
+#ifdef NON_UNIX_STDIO
+ return !isatty(fileno(f));
+#else
+ struct stat x;
+
+ if (fstat(fileno(f),&x) < 0)
+ return(0);
+#ifdef S_IFMT
+ switch(x.st_mode & S_IFMT) {
+ case S_IFDIR:
+ case S_IFREG:
+ if(x.st_nlink > 0) /* !pipe */
+ return(1);
+ else
+ return(0);
+ case S_IFCHR:
+ if(isatty(fileno(f)))
+ return(0);
+ return(1);
+#ifdef S_IFBLK
+ case S_IFBLK:
+ return(1);
+#endif
+ }
+#else
+#ifdef S_ISDIR
+ /* POSIX version */
+ if (S_ISREG(x.st_mode) || S_ISDIR(x.st_mode)) {
+ if(x.st_nlink > 0) /* !pipe */
+ return(1);
+ else
+ return(0);
+ }
+ if (S_ISCHR(x.st_mode)) {
+ if(isatty(fileno(f)))
+ return(0);
+ return(1);
+ }
+ if (S_ISBLK(x.st_mode))
+ return(1);
+#else
+ Help! How does fstat work on this system?
+#endif
+#endif
+ return(0); /* who knows what it is? */
+#endif
+}
+
+ void
+#ifdef KR_headers
+f__fatal(n,s) char *s;
+#else
+f__fatal(int n, char *s)
+#endif
+{
+ if(n<100 && n>=0) perror(s); /*SYSDEP*/
+ else if(n >= (int)MAXERR || n < -1)
+ { fprintf(stderr,"%s: illegal error number %d\n",s,n);
+ }
+ else if(n == -1) fprintf(stderr,"%s: end of file\n",s);
+ else
+ fprintf(stderr,"%s: %s\n",s,F_err[n-100]);
+ if (f__curunit) {
+ fprintf(stderr,"apparent state: unit %d ",
+ (int)(f__curunit-f__units));
+ fprintf(stderr, f__curunit->ufnm ? "named %s\n" : "(unnamed)\n",
+ f__curunit->ufnm);
+ }
+ else
+ fprintf(stderr,"apparent state: internal I/O\n");
+ if (f__fmtbuf)
+ fprintf(stderr,"last format: %s\n",f__fmtbuf);
+ fprintf(stderr,"lately %s %s %s %s",f__reading?"reading":"writing",
+ f__sequential?"sequential":"direct",f__formatted?"formatted":"unformatted",
+ f__external?"external":"internal");
+ sig_die(" IO", 1);
+}
+/*initialization routine*/
+ VOID
+f_init(Void)
+{ unit *p;
+
+ f__init=1;
+ p= &f__units[0];
+ p->ufd=stderr;
+ p->useek=f__canseek(stderr);
+ p->ufmt=1;
+ p->uwrt=1;
+ p = &f__units[5];
+ p->ufd=stdin;
+ p->useek=f__canseek(stdin);
+ p->ufmt=1;
+ p->uwrt=0;
+ p= &f__units[6];
+ p->ufd=stdout;
+ p->useek=f__canseek(stdout);
+ p->ufmt=1;
+ p->uwrt=1;
+}
+#ifdef KR_headers
+f__nowreading(x) unit *x;
+#else
+f__nowreading(unit *x)
+#endif
+{
+ long loc;
+ int ufmt, urw;
+ extern char *f__r_mode[], *f__w_mode[];
+
+ if (x->urw & 1)
+ goto done;
+ if (!x->ufnm)
+ goto cantread;
+ ufmt = x->url ? 0 : x->ufmt;
+ loc = ftell(x->ufd);
+ urw = 3;
+ if (!freopen(x->ufnm, f__w_mode[ufmt|2], x->ufd)) {
+ urw = 1;
+ if(!freopen(x->ufnm, f__r_mode[ufmt], x->ufd)) {
+ cantread:
+ errno = 126;
+ return 1;
+ }
+ }
+ fseek(x->ufd,loc,SEEK_SET);
+ x->urw = urw;
+ done:
+ x->uwrt = 0;
+ return 0;
+}
+#ifdef KR_headers
+f__nowwriting(x) unit *x;
+#else
+f__nowwriting(unit *x)
+#endif
+{
+ long loc;
+ int ufmt;
+ extern char *f__w_mode[];
+
+ if (x->urw & 2)
+ goto done;
+ if (!x->ufnm)
+ goto cantwrite;
+ ufmt = x->url ? 0 : x->ufmt;
+ if (x->uwrt == 3) { /* just did write, rewind */
+ if (!(f__cf = x->ufd =
+ freopen(x->ufnm,f__w_mode[ufmt],x->ufd)))
+ goto cantwrite;
+ x->urw = 2;
+ }
+ else {
+ loc=ftell(x->ufd);
+ if (!(f__cf = x->ufd =
+ freopen(x->ufnm, f__w_mode[ufmt |= 2], x->ufd)))
+ {
+ x->ufd = NULL;
+ cantwrite:
+ errno = 127;
+ return(1);
+ }
+ x->urw = 3;
+ fseek(x->ufd,loc,SEEK_SET);
+ }
+ done:
+ x->uwrt = 1;
+ return 0;
+}
+
+ int
+#ifdef KR_headers
+err__fl(f, m, s) int f, m; char *s;
+#else
+err__fl(int f, int m, char *s)
+#endif
+{
+ if (!f)
+ f__fatal(m, s);
+ if (f__doend)
+ (*f__doend)();
+ return errno = m;
+ }
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/f2c.h b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/f2c.h
new file mode 100644
index 0000000..6514cd9
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/f2c.h
@@ -0,0 +1,223 @@
+/* f2c.h -- Standard Fortran to C header file */
+
+/** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
+
+ - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */
+
+#ifndef F2C_INCLUDE
+#define F2C_INCLUDE
+
+typedef long int integer;
+typedef unsigned long uinteger;
+typedef char *address;
+typedef short int shortint;
+typedef float real;
+typedef double doublereal;
+typedef struct { real r, i; } complex;
+typedef struct { doublereal r, i; } doublecomplex;
+typedef long int logical;
+typedef short int shortlogical;
+typedef char logical1;
+typedef char integer1;
+#if 0 /* Adjust for integer*8. */
+typedef long long longint; /* system-dependent */
+typedef unsigned long long ulongint; /* system-dependent */
+#define qbit_clear(a,b) ((a) & ~((ulongint)1 << (b)))
+#define qbit_set(a,b) ((a) | ((ulongint)1 << (b)))
+#endif
+
+#define TRUE_ (1)
+#define FALSE_ (0)
+
+/* Extern is for use with -E */
+#ifndef Extern
+#define Extern extern
+#endif
+
+/* I/O stuff */
+
+#ifdef f2c_i2
+/* for -i2 */
+typedef short flag;
+typedef short ftnlen;
+typedef short ftnint;
+#else
+typedef long int flag;
+typedef long int ftnlen;
+typedef long int ftnint;
+#endif
+
+/*external read, write*/
+typedef struct
+{ flag cierr;
+ ftnint ciunit;
+ flag ciend;
+ char *cifmt;
+ ftnint cirec;
+} cilist;
+
+/*internal read, write*/
+typedef struct
+{ flag icierr;
+ char *iciunit;
+ flag iciend;
+ char *icifmt;
+ ftnint icirlen;
+ ftnint icirnum;
+} icilist;
+
+/*open*/
+typedef struct
+{ flag oerr;
+ ftnint ounit;
+ char *ofnm;
+ ftnlen ofnmlen;
+ char *osta;
+ char *oacc;
+ char *ofm;
+ ftnint orl;
+ char *oblnk;
+} olist;
+
+/*close*/
+typedef struct
+{ flag cerr;
+ ftnint cunit;
+ char *csta;
+} cllist;
+
+/*rewind, backspace, endfile*/
+typedef struct
+{ flag aerr;
+ ftnint aunit;
+} alist;
+
+/* inquire */
+typedef struct
+{ flag inerr;
+ ftnint inunit;
+ char *infile;
+ ftnlen infilen;
+ ftnint *inex; /*parameters in standard's order*/
+ ftnint *inopen;
+ ftnint *innum;
+ ftnint *innamed;
+ char *inname;
+ ftnlen innamlen;
+ char *inacc;
+ ftnlen inacclen;
+ char *inseq;
+ ftnlen inseqlen;
+ char *indir;
+ ftnlen indirlen;
+ char *infmt;
+ ftnlen infmtlen;
+ char *inform;
+ ftnint informlen;
+ char *inunf;
+ ftnlen inunflen;
+ ftnint *inrecl;
+ ftnint *innrec;
+ char *inblank;
+ ftnlen inblanklen;
+} inlist;
+
+#define VOID void
+
+union Multitype { /* for multiple entry points */
+ integer1 g;
+ shortint h;
+ integer i;
+ /* longint j; */
+ real r;
+ doublereal d;
+ complex c;
+ doublecomplex z;
+ };
+
+typedef union Multitype Multitype;
+
+/*typedef long int Long;*/ /* No longer used; formerly in Namelist */
+
+struct Vardesc { /* for Namelist */
+ char *name;
+ char *addr;
+ ftnlen *dims;
+ int type;
+ };
+typedef struct Vardesc Vardesc;
+
+struct Namelist {
+ char *name;
+ Vardesc **vars;
+ int nvars;
+ };
+typedef struct Namelist Namelist;
+
+#define abs(x) ((x) >= 0 ? (x) : -(x))
+#define dabs(x) (doublereal)abs(x)
+#define min(a,b) ((a) <= (b) ? (a) : (b))
+#define max(a,b) ((a) >= (b) ? (a) : (b))
+#define dmin(a,b) (doublereal)min(a,b)
+#define dmax(a,b) (doublereal)max(a,b)
+#define bit_test(a,b) ((a) >> (b) & 1)
+#define bit_clear(a,b) ((a) & ~((uinteger)1 << (b)))
+#define bit_set(a,b) ((a) | ((uinteger)1 << (b)))
+
+/* procedure parameter types for -A and -C++ */
+
+#define F2C_proc_par_types 1
+#ifdef __cplusplus
+typedef int /* Unknown procedure type */ (*U_fp)(...);
+typedef shortint (*J_fp)(...);
+typedef integer (*I_fp)(...);
+typedef real (*R_fp)(...);
+typedef doublereal (*D_fp)(...), (*E_fp)(...);
+typedef /* Complex */ VOID (*C_fp)(...);
+typedef /* Double Complex */ VOID (*Z_fp)(...);
+typedef logical (*L_fp)(...);
+typedef shortlogical (*K_fp)(...);
+typedef /* Character */ VOID (*H_fp)(...);
+typedef /* Subroutine */ int (*S_fp)(...);
+#else
+typedef int /* Unknown procedure type */ (*U_fp)();
+typedef shortint (*J_fp)();
+typedef integer (*I_fp)();
+typedef real (*R_fp)();
+typedef doublereal (*D_fp)(), (*E_fp)();
+typedef /* Complex */ VOID (*C_fp)();
+typedef /* Double Complex */ VOID (*Z_fp)();
+typedef logical (*L_fp)();
+typedef shortlogical (*K_fp)();
+typedef /* Character */ VOID (*H_fp)();
+typedef /* Subroutine */ int (*S_fp)();
+#endif
+/* E_fp is for real functions when -R is not specified */
+typedef VOID C_f; /* complex function */
+typedef VOID H_f; /* character function */
+typedef VOID Z_f; /* double complex function */
+typedef doublereal E_f; /* real function with -R not specified */
+
+/* undef any lower-case symbols that your C compiler predefines, e.g.: */
+
+#ifndef Skip_f2c_Undefs
+#undef cray
+#undef gcos
+#undef mc68010
+#undef mc68020
+#undef mips
+#undef pdp11
+#undef sgi
+#undef sparc
+#undef sun
+#undef sun2
+#undef sun3
+#undef sun4
+#undef u370
+#undef u3b
+#undef u3b2
+#undef u3b5
+#undef unix
+#undef vax
+#endif
+#endif
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fio.h b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fio.h
new file mode 100644
index 0000000..bb20dd2
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fio.h
@@ -0,0 +1,107 @@
+#include "stdio.h"
+#include "errno.h"
+#ifndef NULL
+/* ANSI C */
+#include "stddef.h"
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+#endif
+
+#ifdef MSDOS
+#ifndef NON_UNIX_STDIO
+#define NON_UNIX_STDIO
+#endif
+#endif
+
+#ifdef UIOLEN_int
+typedef int uiolen;
+#else
+typedef long uiolen;
+#endif
+
+/*units*/
+typedef struct
+{ FILE *ufd; /*0=unconnected*/
+ char *ufnm;
+#ifndef MSDOS
+ long uinode;
+ int udev;
+#endif
+ int url; /*0=sequential*/
+ flag useek; /*true=can backspace, use dir, ...*/
+ flag ufmt;
+ flag urw; /* (1 for can read) | (2 for can write) */
+ flag ublnk;
+ flag uend;
+ flag uwrt; /*last io was write*/
+ flag uscrtch;
+} unit;
+
+extern flag f__init;
+extern cilist *f__elist; /*active external io list*/
+extern flag f__reading,f__external,f__sequential,f__formatted;
+#undef Void
+#ifdef KR_headers
+#define Void /*void*/
+extern int (*f__getn)(); /* for formatted input */
+extern void (*f__putn)(); /* for formatted output */
+extern void x_putc();
+extern long f__inode();
+extern VOID sig_die();
+extern int (*f__donewrec)(), t_putc(), x_wSL();
+extern int c_sfe(), err__fl(), xrd_SL(), f__putbuf();
+#else
+#define Void void
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int (*f__getn)(void); /* for formatted input */
+extern void (*f__putn)(int); /* for formatted output */
+extern void x_putc(int);
+extern long f__inode(char*,int*);
+extern void sig_die(char*,int);
+extern void f__fatal(int,char*);
+extern int t_runc(alist*);
+extern int f__nowreading(unit*), f__nowwriting(unit*);
+extern int fk_open(int,int,ftnint);
+extern int en_fio(void);
+extern void f_init(void);
+extern int (*f__donewrec)(void), t_putc(int), x_wSL(void);
+extern void b_char(char*,char*,ftnlen), g_char(char*,ftnlen,char*);
+extern int c_sfe(cilist*), z_rnew(void);
+extern int isatty(int);
+extern int err__fl(int,int,char*);
+extern int xrd_SL(void);
+extern int f__putbuf(int);
+#ifdef __cplusplus
+ }
+#endif
+#endif
+extern int (*f__doend)(Void);
+extern FILE *f__cf; /*current file*/
+extern unit *f__curunit; /*current unit*/
+extern unit f__units[];
+#define err(f,m,s) {if(f) errno= m; else f__fatal(m,s); return(m);}
+#define errfl(f,m,s) return err__fl((int)f,m,s)
+
+/*Table sizes*/
+#define MXUNIT 100
+
+extern int f__recpos; /*position in current record*/
+extern int f__cursor; /* offset to move to */
+extern int f__hiwater; /* so TL doesn't confuse us */
+
+#define WRITE 1
+#define READ 2
+#define SEQ 3
+#define DIR 4
+#define FMT 5
+#define UNF 6
+#define EXT 7
+#define INT 8
+
+#define buf_end(x) (x->_flag & _IONBF ? x->_ptr : x->_base + BUFSIZ)
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.c
new file mode 100644
index 0000000..364210c
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.c
@@ -0,0 +1,516 @@
+#include "f2c.h"
+#include "fio.h"
+#include "fmt.h"
+#define skip(s) while(*s==' ') s++
+#ifdef interdata
+#define SYLMX 300
+#endif
+#ifdef pdp11
+#define SYLMX 300
+#endif
+#ifdef vax
+#define SYLMX 300
+#endif
+#ifndef SYLMX
+#define SYLMX 300
+#endif
+#define GLITCH '\2'
+ /* special quote character for stu */
+extern int f__cursor,f__scale;
+extern flag f__cblank,f__cplus; /*blanks in I and compulsory plus*/
+static struct syl f__syl[SYLMX];
+int f__parenlvl,f__pc,f__revloc;
+
+ static
+#ifdef KR_headers
+char *ap_end(s) char *s;
+#else
+char *ap_end(char *s)
+#endif
+{ char quote;
+ quote= *s++;
+ for(;*s;s++)
+ { if(*s!=quote) continue;
+ if(*++s!=quote) return(s);
+ }
+ if(f__elist->cierr) {
+ errno = 100;
+ return(NULL);
+ }
+ f__fatal(100, "bad string");
+ /*NOTREACHED*/ return 0;
+}
+ static
+#ifdef KR_headers
+op_gen(a,b,c,d)
+#else
+op_gen(int a, int b, int c, int d)
+#endif
+{ struct syl *p= &f__syl[f__pc];
+ if(f__pc>=SYLMX)
+ { fprintf(stderr,"format too complicated:\n");
+ sig_die(f__fmtbuf, 1);
+ }
+ p->op=a;
+ p->p1=b;
+ p->p2.i[0]=c;
+ p->p2.i[1]=d;
+ return(f__pc++);
+}
+#ifdef KR_headers
+static char *f_list();
+static char *gt_num(s,n,n1) char *s; int *n, n1;
+#else
+static char *f_list(char*);
+static char *gt_num(char *s, int *n, int n1)
+#endif
+{ int m=0,f__cnt=0;
+ char c;
+ for(c= *s;;c = *s)
+ { if(c==' ')
+ { s++;
+ continue;
+ }
+ if(c>'9' || c<'0') break;
+ m=10*m+c-'0';
+ f__cnt++;
+ s++;
+ }
+ if(f__cnt==0) {
+ if (!n1)
+ s = 0;
+ *n=n1;
+ }
+ else *n=m;
+ return(s);
+}
+
+ static
+#ifdef KR_headers
+char *f_s(s,curloc) char *s;
+#else
+char *f_s(char *s, int curloc)
+#endif
+{
+ skip(s);
+ if(*s++!='(')
+ {
+ return(NULL);
+ }
+ if(f__parenlvl++ ==1) f__revloc=curloc;
+ if(op_gen(RET1,curloc,0,0)<0 ||
+ (s=f_list(s))==NULL)
+ {
+ return(NULL);
+ }
+ skip(s);
+ return(s);
+}
+
+ static
+#ifdef KR_headers
+ne_d(s,p) char *s,**p;
+#else
+ne_d(char *s, char **p)
+#endif
+{ int n,x,sign=0;
+ struct syl *sp;
+ switch(*s)
+ {
+ default:
+ return(0);
+ case ':': (void) op_gen(COLON,0,0,0); break;
+ case '$':
+ (void) op_gen(NONL, 0, 0, 0); break;
+ case 'B':
+ case 'b':
+ if(*++s=='z' || *s == 'Z') (void) op_gen(BZ,0,0,0);
+ else (void) op_gen(BN,0,0,0);
+ break;
+ case 'S':
+ case 's':
+ if(*(s+1)=='s' || *(s+1) == 'S')
+ { x=SS;
+ s++;
+ }
+ else if(*(s+1)=='p' || *(s+1) == 'P')
+ { x=SP;
+ s++;
+ }
+ else x=S;
+ (void) op_gen(x,0,0,0);
+ break;
+ case '/': (void) op_gen(SLASH,0,0,0); break;
+ case '-': sign=1;
+ case '+': s++; /*OUTRAGEOUS CODING TRICK*/
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (!(s=gt_num(s,&n,0))) {
+ bad: *p = 0;
+ return 1;
+ }
+ switch(*s)
+ {
+ default:
+ return(0);
+ case 'P':
+ case 'p': if(sign) n= -n; (void) op_gen(P,n,0,0); break;
+ case 'X':
+ case 'x': (void) op_gen(X,n,0,0); break;
+ case 'H':
+ case 'h':
+ sp = &f__syl[op_gen(H,n,0,0)];
+ sp->p2.s = s + 1;
+ s+=n;
+ break;
+ }
+ break;
+ case GLITCH:
+ case '"':
+ case '\'':
+ sp = &f__syl[op_gen(APOS,0,0,0)];
+ sp->p2.s = s;
+ if((*p = ap_end(s)) == NULL)
+ return(0);
+ return(1);
+ case 'T':
+ case 't':
+ if(*(s+1)=='l' || *(s+1) == 'L')
+ { x=TL;
+ s++;
+ }
+ else if(*(s+1)=='r'|| *(s+1) == 'R')
+ { x=TR;
+ s++;
+ }
+ else x=T;
+ if (!(s=gt_num(s+1,&n,0)))
+ goto bad;
+ s--;
+ (void) op_gen(x,n,0,0);
+ break;
+ case 'X':
+ case 'x': (void) op_gen(X,1,0,0); break;
+ case 'P':
+ case 'p': (void) op_gen(P,1,0,0); break;
+ }
+ s++;
+ *p=s;
+ return(1);
+}
+
+ static
+#ifdef KR_headers
+e_d(s,p) char *s,**p;
+#else
+e_d(char *s, char **p)
+#endif
+{ int i,im,n,w,d,e,found=0,x=0;
+ char *sv=s;
+ s=gt_num(s,&n,1);
+ (void) op_gen(STACK,n,0,0);
+ switch(*s++)
+ {
+ default: break;
+ case 'E':
+ case 'e': x=1;
+ case 'G':
+ case 'g':
+ found=1;
+ if (!(s=gt_num(s,&w,0))) {
+ bad:
+ *p = 0;
+ return 1;
+ }
+ if(w==0) break;
+ if(*s=='.') {
+ if (!(s=gt_num(s+1,&d,0)))
+ goto bad;
+ }
+ else d=0;
+ if(*s!='E' && *s != 'e')
+ (void) op_gen(x==1?E:G,w,d,0); /* default is Ew.dE2 */
+ else {
+ if (!(s=gt_num(s+1,&e,0)))
+ goto bad;
+ (void) op_gen(x==1?EE:GE,w,d,e);
+ }
+ break;
+ case 'O':
+ case 'o':
+ i = O;
+ im = OM;
+ goto finish_I;
+ case 'Z':
+ case 'z':
+ i = Z;
+ im = ZM;
+ goto finish_I;
+ case 'L':
+ case 'l':
+ found=1;
+ if (!(s=gt_num(s,&w,0)))
+ goto bad;
+ if(w==0) break;
+ (void) op_gen(L,w,0,0);
+ break;
+ case 'A':
+ case 'a':
+ found=1;
+ skip(s);
+ if(*s>='0' && *s<='9')
+ { s=gt_num(s,&w,1);
+ if(w==0) break;
+ (void) op_gen(AW,w,0,0);
+ break;
+ }
+ (void) op_gen(A,0,0,0);
+ break;
+ case 'F':
+ case 'f':
+ if (!(s=gt_num(s,&w,0)))
+ goto bad;
+ found=1;
+ if(w==0) break;
+ if(*s=='.') {
+ if (!(s=gt_num(s+1,&d,0)))
+ goto bad;
+ }
+ else d=0;
+ (void) op_gen(F,w,d,0);
+ break;
+ case 'D':
+ case 'd':
+ found=1;
+ if (!(s=gt_num(s,&w,0)))
+ goto bad;
+ if(w==0) break;
+ if(*s=='.') {
+ if (!(s=gt_num(s+1,&d,0)))
+ goto bad;
+ }
+ else d=0;
+ (void) op_gen(D,w,d,0);
+ break;
+ case 'I':
+ case 'i':
+ i = I;
+ im = IM;
+ finish_I:
+ if (!(s=gt_num(s,&w,0)))
+ goto bad;
+ found=1;
+ if(w==0) break;
+ if(*s!='.')
+ { (void) op_gen(i,w,0,0);
+ break;
+ }
+ if (!(s=gt_num(s+1,&d,0)))
+ goto bad;
+ (void) op_gen(im,w,d,0);
+ break;
+ }
+ if(found==0)
+ { f__pc--; /*unSTACK*/
+ *p=sv;
+ return(0);
+ }
+ *p=s;
+ return(1);
+}
+ static
+#ifdef KR_headers
+char *i_tem(s) char *s;
+#else
+char *i_tem(char *s)
+#endif
+{ char *t;
+ int n,curloc;
+ if(*s==')') return(s);
+ if(ne_d(s,&t)) return(t);
+ if(e_d(s,&t)) return(t);
+ s=gt_num(s,&n,1);
+ if((curloc=op_gen(STACK,n,0,0))<0) return(NULL);
+ return(f_s(s,curloc));
+}
+
+ static
+#ifdef KR_headers
+char *f_list(s) char *s;
+#else
+char *f_list(char *s)
+#endif
+{
+ for(;*s!=0;)
+ { skip(s);
+ if((s=i_tem(s))==NULL) return(NULL);
+ skip(s);
+ if(*s==',') s++;
+ else if(*s==')')
+ { if(--f__parenlvl==0)
+ {
+ (void) op_gen(REVERT,f__revloc,0,0);
+ return(++s);
+ }
+ (void) op_gen(GOTO,0,0,0);
+ return(++s);
+ }
+ }
+ return(NULL);
+}
+
+#ifdef KR_headers
+pars_f(s) char *s;
+#else
+pars_f(char *s)
+#endif
+{
+ f__parenlvl=f__revloc=f__pc=0;
+ if(f_s(s,0) == NULL)
+ {
+ return(-1);
+ }
+ return(0);
+}
+#define STKSZ 10
+int f__cnt[STKSZ],f__ret[STKSZ],f__cp,f__rp;
+flag f__workdone, f__nonl;
+
+ static
+#ifdef KR_headers
+type_f(n)
+#else
+type_f(int n)
+#endif
+{
+ switch(n)
+ {
+ default:
+ return(n);
+ case RET1:
+ return(RET1);
+ case REVERT: return(REVERT);
+ case GOTO: return(GOTO);
+ case STACK: return(STACK);
+ case X:
+ case SLASH:
+ case APOS: case H:
+ case T: case TL: case TR:
+ return(NED);
+ case F:
+ case I:
+ case IM:
+ case A: case AW:
+ case O: case OM:
+ case L:
+ case E: case EE: case D:
+ case G: case GE:
+ case Z: case ZM:
+ return(ED);
+ }
+}
+#ifdef KR_headers
+integer do_fio(number,ptr,len) ftnint *number; ftnlen len; char *ptr;
+#else
+integer do_fio(ftnint *number, char *ptr, ftnlen len)
+#endif
+{ struct syl *p;
+ int n,i;
+ for(i=0;i<*number;i++,ptr+=len)
+ {
+loop: switch(type_f((p= &f__syl[f__pc])->op))
+ {
+ default:
+ fprintf(stderr,"unknown code in do_fio: %d\n%s\n",
+ p->op,f__fmtbuf);
+ err(f__elist->cierr,100,"do_fio");
+ case NED:
+ if((*f__doned)(p))
+ { f__pc++;
+ goto loop;
+ }
+ f__pc++;
+ continue;
+ case ED:
+ if(f__cnt[f__cp]<=0)
+ { f__cp--;
+ f__pc++;
+ goto loop;
+ }
+ if(ptr==NULL)
+ return((*f__doend)());
+ f__cnt[f__cp]--;
+ f__workdone=1;
+ if((n=(*f__doed)(p,ptr,len))>0)
+ errfl(f__elist->cierr,errno,"fmt");
+ if(n<0)
+ err(f__elist->ciend,(EOF),"fmt");
+ continue;
+ case STACK:
+ f__cnt[++f__cp]=p->p1;
+ f__pc++;
+ goto loop;
+ case RET1:
+ f__ret[++f__rp]=p->p1;
+ f__pc++;
+ goto loop;
+ case GOTO:
+ if(--f__cnt[f__cp]<=0)
+ { f__cp--;
+ f__rp--;
+ f__pc++;
+ goto loop;
+ }
+ f__pc=1+f__ret[f__rp--];
+ goto loop;
+ case REVERT:
+ f__rp=f__cp=0;
+ f__pc = p->p1;
+ if(ptr==NULL)
+ return((*f__doend)());
+ if(!f__workdone) return(0);
+ if((n=(*f__dorevert)()) != 0) return(n);
+ goto loop;
+ case COLON:
+ if(ptr==NULL)
+ return((*f__doend)());
+ f__pc++;
+ goto loop;
+ case NONL:
+ f__nonl = 1;
+ f__pc++;
+ goto loop;
+ case S:
+ case SS:
+ f__cplus=0;
+ f__pc++;
+ goto loop;
+ case SP:
+ f__cplus = 1;
+ f__pc++;
+ goto loop;
+ case P: f__scale=p->p1;
+ f__pc++;
+ goto loop;
+ case BN:
+ f__cblank=0;
+ f__pc++;
+ goto loop;
+ case BZ:
+ f__cblank=1;
+ f__pc++;
+ goto loop;
+ }
+ }
+ return(0);
+}
+en_fio(Void)
+{ ftnint one=1;
+ return(do_fio(&one,(char *)NULL,(ftnint)0));
+}
+ VOID
+fmt_bg(Void)
+{
+ f__workdone=f__cp=f__rp=f__pc=f__cursor=0;
+ f__cnt[0]=f__ret[0]=0;
+}
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.h b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.h
new file mode 100644
index 0000000..19065a2
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.h
@@ -0,0 +1,100 @@
+struct syl
+{ int op;
+ int p1;
+ union { int i[2]; char *s;} p2;
+ };
+#define RET1 1
+#define REVERT 2
+#define GOTO 3
+#define X 4
+#define SLASH 5
+#define STACK 6
+#define I 7
+#define ED 8
+#define NED 9
+#define IM 10
+#define APOS 11
+#define H 12
+#define TL 13
+#define TR 14
+#define T 15
+#define COLON 16
+#define S 17
+#define SP 18
+#define SS 19
+#define P 20
+#define BN 21
+#define BZ 22
+#define F 23
+#define E 24
+#define EE 25
+#define D 26
+#define G 27
+#define GE 28
+#define L 29
+#define A 30
+#define AW 31
+#define O 32
+#define NONL 33
+#define OM 34
+#define Z 35
+#define ZM 36
+extern int f__pc,f__parenlvl,f__revloc;
+typedef union
+{ real pf;
+ doublereal pd;
+} ufloat;
+typedef union
+{ short is;
+#ifndef KR_headers
+ signed
+#endif
+ char ic;
+ integer il;
+#ifdef Allow_TYQUAD
+ longint ili;
+#endif
+} Uint;
+#ifdef KR_headers
+extern int (*f__doed)(),(*f__doned)();
+extern int (*f__dorevert)();
+extern int rd_ed(),rd_ned();
+extern int w_ed(),w_ned();
+#else
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int (*f__doed)(struct syl*, char*, ftnlen),(*f__doned)(struct syl*);
+extern int (*f__dorevert)(void);
+extern void fmt_bg(void);
+extern int pars_f(char*);
+extern int rd_ed(struct syl*, char*, ftnlen),rd_ned(struct syl*);
+extern int w_ed(struct syl*, char*, ftnlen),w_ned(struct syl*);
+extern int wrt_E(ufloat*, int, int, int, ftnlen);
+extern int wrt_F(ufloat*, int, int, ftnlen);
+extern int wrt_L(Uint*, int, ftnlen);
+#ifdef __cplusplus
+ }
+#endif
+#endif
+extern flag f__cblank,f__cplus,f__workdone, f__nonl;
+extern char *f__fmtbuf;
+extern int f__scale;
+#define GET(x) if((x=(*f__getn)())<0) return(x)
+#define VAL(x) (x!='\n'?x:' ')
+#define PUT(x) (*f__putn)(x)
+extern int f__cursor;
+
+#undef TYQUAD
+#ifndef Allow_TYQUAD
+#undef longint
+#define longint long
+#else
+#define TYQUAD 14
+#endif
+
+#ifdef KR_headers
+extern char *f__icvt();
+#else
+extern char *f__icvt(longint, int*, int*, int);
+#endif
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fmtlib.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fmtlib.c
new file mode 100644
index 0000000..91483fc
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fmtlib.c
@@ -0,0 +1,45 @@
+/* @(#)fmtlib.c 1.2 */
+#define MAXINTLENGTH 23
+
+#include "f2c.h"
+#ifndef Allow_TYQUAD
+#undef longint
+#define longint long
+#undef ulongint
+#define ulongint unsigned long
+#endif
+
+#ifdef KR_headers
+char *f__icvt(value,ndigit,sign, base) longint value; int *ndigit,*sign;
+ register int base;
+#else
+char *f__icvt(longint value, int *ndigit, int *sign, int base)
+#endif
+{
+ static char buf[MAXINTLENGTH+1];
+ register int i;
+ ulongint uvalue;
+
+ if(value > 0) {
+ uvalue = value;
+ *sign = 0;
+ }
+ else if (value < 0) {
+ uvalue = -value;
+ *sign = 1;
+ }
+ else {
+ *sign = 0;
+ *ndigit = 1;
+ buf[MAXINTLENGTH-1] = '0';
+ return &buf[MAXINTLENGTH-1];
+ }
+ i = MAXINTLENGTH;
+ do {
+ buf[--i] = (uvalue%base) + '0';
+ uvalue /= base;
+ }
+ while(uvalue > 0);
+ *ndigit = MAXINTLENGTH - i;
+ return &buf[i];
+ }
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fp.h b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fp.h
new file mode 100644
index 0000000..40743d7
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/fp.h
@@ -0,0 +1,28 @@
+#define FMAX 40
+#define EXPMAXDIGS 8
+#define EXPMAX 99999999
+/* FMAX = max number of nonzero digits passed to atof() */
+/* EXPMAX = 10^EXPMAXDIGS - 1 = largest allowed exponent absolute value */
+
+#ifdef V10 /* Research Tenth-Edition Unix */
+#include "local.h"
+#endif
+
+/* MAXFRACDIGS and MAXINTDIGS are for wrt_F -- bounds (not necessarily
+ tight) on the maximum number of digits to the right and left of
+ * the decimal point.
+ */
+
+#ifdef VAX
+#define MAXFRACDIGS 56
+#define MAXINTDIGS 38
+#else
+#ifdef CRAY
+#define MAXFRACDIGS 9880
+#define MAXINTDIGS 9864
+#else
+/* values that suffice for IEEE double */
+#define MAXFRACDIGS 344
+#define MAXINTDIGS 308
+#endif
+#endif
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/idamax.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/idamax.c
new file mode 100644
index 0000000..2cc5481
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/idamax.c
@@ -0,0 +1,61 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+integer idamax_(integer *n, doublereal *dx, integer *incx)
+{
+ /* System generated locals */
+ integer ret_val, i__1;
+ doublereal d__1;
+ /* Local variables */
+ static doublereal dmax__;
+ static integer i__, ix;
+/* finds the index of element having max. absolute value.
+ jack dongarra, linpack, 3/11/78.
+ modified 3/93 to return if incx .le. 0.
+ modified 12/3/93, array(1) declarations changed to array(*)
+ Parameter adjustments */
+ --dx;
+ /* Function Body */
+ ret_val = 0;
+ if (*n < 1 || *incx <= 0) {
+ return ret_val;
+ }
+ ret_val = 1;
+ if (*n == 1) {
+ return ret_val;
+ }
+ if (*incx == 1) {
+ goto L20;
+ }
+/* code for increment not equal to 1 */
+ ix = 1;
+ dmax__ = abs(dx[1]);
+ ix += *incx;
+ i__1 = *n;
+ for (i__ = 2; i__ <= i__1; ++i__) {
+ if ((d__1 = dx[ix], abs(d__1)) <= dmax__) {
+ goto L5;
+ }
+ ret_val = i__;
+ dmax__ = (d__1 = dx[ix], abs(d__1));
+L5:
+ ix += *incx;
+/* L10: */
+ }
+ return ret_val;
+/* code for increment equal to 1 */
+L20:
+ dmax__ = abs(dx[1]);
+ i__1 = *n;
+ for (i__ = 2; i__ <= i__1; ++i__) {
+ if ((d__1 = dx[i__], abs(d__1)) <= dmax__) {
+ goto L30;
+ }
+ ret_val = i__;
+ dmax__ = (d__1 = dx[i__], abs(d__1));
+L30:
+ ;
+ }
+ return ret_val;
+} /* idamax_ */
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/ieeeck.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/ieeeck.c
new file mode 100644
index 0000000..39256a4
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/ieeeck.c
@@ -0,0 +1,150 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+integer ieeeck_(integer *ispec, real *zero, real *one)
+{
+/* -- LAPACK auxiliary routine (version 3.0) --
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
+ Courant Institute, Argonne National Lab, and Rice University
+ June 30, 1998
+
+
+ Purpose
+ =======
+
+ IEEECK is called from the ILAENV to verify that Infinity and
+ possibly NaN arithmetic is safe (i.e. will not trap).
+
+ Arguments
+ =========
+
+ ISPEC (input) INTEGER
+ Specifies whether to test just for inifinity arithmetic
+ or whether to test for infinity and NaN arithmetic.
+ = 0: Verify infinity arithmetic only.
+ = 1: Verify infinity and NaN arithmetic.
+
+ ZERO (input) REAL
+ Must contain the value 0.0
+ This is passed to prevent the compiler from optimizing
+ away this code.
+
+ ONE (input) REAL
+ Must contain the value 1.0
+ This is passed to prevent the compiler from optimizing
+ away this code.
+
+ RETURN VALUE: INTEGER
+ = 0: Arithmetic failed to produce the correct answers
+ = 1: Arithmetic produced the correct answers */
+ /* System generated locals */
+ integer ret_val;
+ /* Local variables */
+ static real neginf, posinf, negzro, newzro, nan1, nan2, nan3, nan4, nan5,
+ nan6;
+
+
+ ret_val = 1;
+
+ posinf = *one / *zero;
+ if (posinf <= *one) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+ neginf = -(*one) / *zero;
+ if (neginf >= *zero) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+ negzro = *one / (neginf + *one);
+ if (negzro != *zero) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+ neginf = *one / negzro;
+ if (neginf >= *zero) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+ newzro = negzro + *zero;
+ if (newzro != *zero) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+ posinf = *one / newzro;
+ if (posinf <= *one) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+ neginf *= posinf;
+ if (neginf >= *zero) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+ posinf *= posinf;
+ if (posinf <= *one) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+
+
+
+/* Return if we were only asked to check infinity arithmetic */
+
+ if (*ispec == 0) {
+ return ret_val;
+ }
+
+ nan1 = posinf + neginf;
+
+ nan2 = posinf / neginf;
+
+ nan3 = posinf / posinf;
+
+ nan4 = posinf * *zero;
+
+ nan5 = neginf * negzro;
+
+ nan6 = nan5 * 0.f;
+
+ if (nan1 == nan1) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+ if (nan2 == nan2) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+ if (nan3 == nan3) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+ if (nan4 == nan4) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+ if (nan5 == nan5) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+ if (nan6 == nan6) {
+ ret_val = 0;
+ return ret_val;
+ }
+
+ return ret_val;
+} /* ieeeck_ */
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/ilaenv.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/ilaenv.c
new file mode 100644
index 0000000..58299ff
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/ilaenv.c
@@ -0,0 +1,610 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+integer ilaenv_(integer *ispec, char *name__, char *opts, integer *n1,
+ integer *n2, integer *n3, integer *n4, ftnlen name_len, ftnlen
+ opts_len)
+{
+/* -- LAPACK auxiliary routine (version 3.0) --
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
+ Courant Institute, Argonne National Lab, and Rice University
+ June 30, 1999
+
+
+ Purpose
+ =======
+
+ ILAENV is called from the LAPACK routines to choose problem-dependent
+ parameters for the local environment. See ISPEC for a description of
+ the parameters.
+
+ This version provides a set of parameters which should give good,
+ but not optimal, performance on many of the currently available
+ computers. Users are encouraged to modify this subroutine to set
+ the tuning parameters for their particular machine using the option
+ and problem size information in the arguments.
+
+ This routine will not function correctly if it is converted to all
+ lower case. Converting it to all upper case is allowed.
+
+ Arguments
+ =========
+
+ ISPEC (input) INTEGER
+ Specifies the parameter to be returned as the value of
+ ILAENV.
+ = 1: the optimal blocksize; if this value is 1, an unblocked
+ algorithm will give the best performance.
+ = 2: the minimum block size for which the block routine
+ should be used; if the usable block size is less than
+ this value, an unblocked routine should be used.
+ = 3: the crossover point (in a block routine, for N less
+ than this value, an unblocked routine should be used)
+ = 4: the number of shifts, used in the nonsymmetric
+ eigenvalue routines
+ = 5: the minimum column dimension for blocking to be used;
+ rectangular blocks must have dimension at least k by m,
+ where k is given by ILAENV(2,...) and m by ILAENV(5,...)
+ = 6: the crossover point for the SVD (when reducing an m by n
+ matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds
+ this value, a QR factorization is used first to reduce
+ the matrix to a triangular form.)
+ = 7: the number of processors
+ = 8: the crossover point for the multishift QR and QZ methods
+ for nonsymmetric eigenvalue problems.
+ = 9: maximum size of the subproblems at the bottom of the
+ computation tree in the divide-and-conquer algorithm
+ (used by xGELSD and xGESDD)
+ =10: ieee NaN arithmetic can be trusted not to trap
+ =11: infinity arithmetic can be trusted not to trap
+
+ NAME (input) CHARACTER*(*)
+ The name of the calling subroutine, in either upper case or
+ lower case.
+
+ OPTS (input) CHARACTER*(*)
+ The character options to the subroutine NAME, concatenated
+ into a single character string. For example, UPLO = 'U',
+ TRANS = 'T', and DIAG = 'N' for a triangular routine would
+ be specified as OPTS = 'UTN'.
+
+ N1 (input) INTEGER
+ N2 (input) INTEGER
+ N3 (input) INTEGER
+ N4 (input) INTEGER
+ Problem dimensions for the subroutine NAME; these may not all
+ be required.
+
+ (ILAENV) (output) INTEGER
+ >= 0: the value of the parameter specified by ISPEC
+ < 0: if ILAENV = -k, the k-th argument had an illegal value.
+
+ Further Details
+ ===============
+
+ The following conventions have been used when calling ILAENV from the
+ LAPACK routines:
+ 1) OPTS is a concatenation of all of the character options to
+ subroutine NAME, in the same order that they appear in the
+ argument list for NAME, even if they are not used in determining
+ the value of the parameter specified by ISPEC.
+ 2) The problem dimensions N1, N2, N3, N4 are specified in the order
+ that they appear in the argument list for NAME. N1 is used
+ first, N2 second, and so on, and unused problem dimensions are
+ passed a value of -1.
+ 3) The parameter value returned by ILAENV is checked for validity in
+ the calling subroutine. For example, ILAENV is used to retrieve
+ the optimal blocksize for STRTRI as follows:
+
+ NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 )
+ IF( NB.LE.1 ) NB = MAX( 1, N )
+
+ ===================================================================== */
+ /* Table of constant values */
+ static integer c__0 = 0;
+ static real c_b162 = 0.f;
+ static real c_b163 = 1.f;
+ static integer c__1 = 1;
+
+ /* System generated locals */
+ integer ret_val;
+ /* Builtin functions
+ Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen);
+ integer s_cmp(char *, char *, ftnlen, ftnlen);
+ /* Local variables */
+ static integer i__;
+ static logical cname, sname;
+ static integer nbmin;
+ static char c1[1], c2[2], c3[3], c4[2];
+ static integer ic, nb;
+ extern integer ieeeck_(integer *, real *, real *);
+ static integer iz, nx;
+ static char subnam[6];
+
+
+
+
+ switch (*ispec) {
+ case 1: goto L100;
+ case 2: goto L100;
+ case 3: goto L100;
+ case 4: goto L400;
+ case 5: goto L500;
+ case 6: goto L600;
+ case 7: goto L700;
+ case 8: goto L800;
+ case 9: goto L900;
+ case 10: goto L1000;
+ case 11: goto L1100;
+ }
+
+/* Invalid value for ISPEC */
+
+ ret_val = -1;
+ return ret_val;
+
+L100:
+
+/* Convert NAME to upper case if the first character is lower case. */
+
+ ret_val = 1;
+ s_copy(subnam, name__, (ftnlen)6, name_len);
+ ic = *(unsigned char *)subnam;
+ iz = 'Z';
+ if (iz == 90 || iz == 122) {
+
+/* ASCII character set */
+
+ if (ic >= 97 && ic <= 122) {
+ *(unsigned char *)subnam = (char) (ic - 32);
+ for (i__ = 2; i__ <= 6; ++i__) {
+ ic = *(unsigned char *)&subnam[i__ - 1];
+ if (ic >= 97 && ic <= 122) {
+ *(unsigned char *)&subnam[i__ - 1] = (char) (ic - 32);
+ }
+/* L10: */
+ }
+ }
+
+ } else if (iz == 233 || iz == 169) {
+
+/* EBCDIC character set */
+
+ if (ic >= 129 && ic <= 137 || ic >= 145 && ic <= 153 || ic >= 162 &&
+ ic <= 169) {
+ *(unsigned char *)subnam = (char) (ic + 64);
+ for (i__ = 2; i__ <= 6; ++i__) {
+ ic = *(unsigned char *)&subnam[i__ - 1];
+ if (ic >= 129 && ic <= 137 || ic >= 145 && ic <= 153 || ic >=
+ 162 && ic <= 169) {
+ *(unsigned char *)&subnam[i__ - 1] = (char) (ic + 64);
+ }
+/* L20: */
+ }
+ }
+
+ } else if (iz == 218 || iz == 250) {
+
+/* Prime machines: ASCII+128 */
+
+ if (ic >= 225 && ic <= 250) {
+ *(unsigned char *)subnam = (char) (ic - 32);
+ for (i__ = 2; i__ <= 6; ++i__) {
+ ic = *(unsigned char *)&subnam[i__ - 1];
+ if (ic >= 225 && ic <= 250) {
+ *(unsigned char *)&subnam[i__ - 1] = (char) (ic - 32);
+ }
+/* L30: */
+ }
+ }
+ }
+
+ *(unsigned char *)c1 = *(unsigned char *)subnam;
+ sname = *(unsigned char *)c1 == 'S' || *(unsigned char *)c1 == 'D';
+ cname = *(unsigned char *)c1 == 'C' || *(unsigned char *)c1 == 'Z';
+ if (! (cname || sname)) {
+ return ret_val;
+ }
+ s_copy(c2, subnam + 1, (ftnlen)2, (ftnlen)2);
+ s_copy(c3, subnam + 3, (ftnlen)3, (ftnlen)3);
+ s_copy(c4, c3 + 1, (ftnlen)2, (ftnlen)2);
+
+ switch (*ispec) {
+ case 1: goto L110;
+ case 2: goto L200;
+ case 3: goto L300;
+ }
+
+L110:
+
+/* ISPEC = 1: block size
+
+ In these examples, separate code is provided for setting NB for
+ real and complex. We assume that NB will take the same value in
+ single or double precision. */
+
+ nb = 1;
+
+ if (s_cmp(c2, "GE", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "TRF", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nb = 64;
+ } else {
+ nb = 64;
+ }
+ } else if (s_cmp(c3, "QRF", (ftnlen)3, (ftnlen)3) == 0 || s_cmp(c3,
+ "RQF", (ftnlen)3, (ftnlen)3) == 0 || s_cmp(c3, "LQF", (ftnlen)
+ 3, (ftnlen)3) == 0 || s_cmp(c3, "QLF", (ftnlen)3, (ftnlen)3)
+ == 0) {
+ if (sname) {
+ nb = 32;
+ } else {
+ nb = 32;
+ }
+ } else if (s_cmp(c3, "HRD", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nb = 32;
+ } else {
+ nb = 32;
+ }
+ } else if (s_cmp(c3, "BRD", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nb = 32;
+ } else {
+ nb = 32;
+ }
+ } else if (s_cmp(c3, "TRI", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nb = 64;
+ } else {
+ nb = 64;
+ }
+ }
+ } else if (s_cmp(c2, "PO", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "TRF", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nb = 64;
+ } else {
+ nb = 64;
+ }
+ }
+ } else if (s_cmp(c2, "SY", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "TRF", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nb = 64;
+ } else {
+ nb = 64;
+ }
+ } else if (sname && s_cmp(c3, "TRD", (ftnlen)3, (ftnlen)3) == 0) {
+ nb = 32;
+ } else if (sname && s_cmp(c3, "GST", (ftnlen)3, (ftnlen)3) == 0) {
+ nb = 64;
+ }
+ } else if (cname && s_cmp(c2, "HE", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "TRF", (ftnlen)3, (ftnlen)3) == 0) {
+ nb = 64;
+ } else if (s_cmp(c3, "TRD", (ftnlen)3, (ftnlen)3) == 0) {
+ nb = 32;
+ } else if (s_cmp(c3, "GST", (ftnlen)3, (ftnlen)3) == 0) {
+ nb = 64;
+ }
+ } else if (sname && s_cmp(c2, "OR", (ftnlen)2, (ftnlen)2) == 0) {
+ if (*(unsigned char *)c3 == 'G') {
+ if (s_cmp(c4, "QR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "RQ",
+ (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "LQ", (ftnlen)2, (
+ ftnlen)2) == 0 || s_cmp(c4, "QL", (ftnlen)2, (ftnlen)2) ==
+ 0 || s_cmp(c4, "HR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(
+ c4, "TR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "BR", (
+ ftnlen)2, (ftnlen)2) == 0) {
+ nb = 32;
+ }
+ } else if (*(unsigned char *)c3 == 'M') {
+ if (s_cmp(c4, "QR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "RQ",
+ (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "LQ", (ftnlen)2, (
+ ftnlen)2) == 0 || s_cmp(c4, "QL", (ftnlen)2, (ftnlen)2) ==
+ 0 || s_cmp(c4, "HR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(
+ c4, "TR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "BR", (
+ ftnlen)2, (ftnlen)2) == 0) {
+ nb = 32;
+ }
+ }
+ } else if (cname && s_cmp(c2, "UN", (ftnlen)2, (ftnlen)2) == 0) {
+ if (*(unsigned char *)c3 == 'G') {
+ if (s_cmp(c4, "QR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "RQ",
+ (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "LQ", (ftnlen)2, (
+ ftnlen)2) == 0 || s_cmp(c4, "QL", (ftnlen)2, (ftnlen)2) ==
+ 0 || s_cmp(c4, "HR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(
+ c4, "TR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "BR", (
+ ftnlen)2, (ftnlen)2) == 0) {
+ nb = 32;
+ }
+ } else if (*(unsigned char *)c3 == 'M') {
+ if (s_cmp(c4, "QR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "RQ",
+ (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "LQ", (ftnlen)2, (
+ ftnlen)2) == 0 || s_cmp(c4, "QL", (ftnlen)2, (ftnlen)2) ==
+ 0 || s_cmp(c4, "HR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(
+ c4, "TR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "BR", (
+ ftnlen)2, (ftnlen)2) == 0) {
+ nb = 32;
+ }
+ }
+ } else if (s_cmp(c2, "GB", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "TRF", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ if (*n4 <= 64) {
+ nb = 1;
+ } else {
+ nb = 32;
+ }
+ } else {
+ if (*n4 <= 64) {
+ nb = 1;
+ } else {
+ nb = 32;
+ }
+ }
+ }
+ } else if (s_cmp(c2, "PB", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "TRF", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ if (*n2 <= 64) {
+ nb = 1;
+ } else {
+ nb = 32;
+ }
+ } else {
+ if (*n2 <= 64) {
+ nb = 1;
+ } else {
+ nb = 32;
+ }
+ }
+ }
+ } else if (s_cmp(c2, "TR", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "TRI", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nb = 64;
+ } else {
+ nb = 64;
+ }
+ }
+ } else if (s_cmp(c2, "LA", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "UUM", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nb = 64;
+ } else {
+ nb = 64;
+ }
+ }
+ } else if (sname && s_cmp(c2, "ST", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "EBZ", (ftnlen)3, (ftnlen)3) == 0) {
+ nb = 1;
+ }
+ }
+ ret_val = nb;
+ return ret_val;
+
+L200:
+
+/* ISPEC = 2: minimum block size */
+
+ nbmin = 2;
+ if (s_cmp(c2, "GE", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "QRF", (ftnlen)3, (ftnlen)3) == 0 || s_cmp(c3, "RQF", (
+ ftnlen)3, (ftnlen)3) == 0 || s_cmp(c3, "LQF", (ftnlen)3, (
+ ftnlen)3) == 0 || s_cmp(c3, "QLF", (ftnlen)3, (ftnlen)3) == 0)
+ {
+ if (sname) {
+ nbmin = 2;
+ } else {
+ nbmin = 2;
+ }
+ } else if (s_cmp(c3, "HRD", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nbmin = 2;
+ } else {
+ nbmin = 2;
+ }
+ } else if (s_cmp(c3, "BRD", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nbmin = 2;
+ } else {
+ nbmin = 2;
+ }
+ } else if (s_cmp(c3, "TRI", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nbmin = 2;
+ } else {
+ nbmin = 2;
+ }
+ }
+ } else if (s_cmp(c2, "SY", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "TRF", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nbmin = 8;
+ } else {
+ nbmin = 8;
+ }
+ } else if (sname && s_cmp(c3, "TRD", (ftnlen)3, (ftnlen)3) == 0) {
+ nbmin = 2;
+ }
+ } else if (cname && s_cmp(c2, "HE", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "TRD", (ftnlen)3, (ftnlen)3) == 0) {
+ nbmin = 2;
+ }
+ } else if (sname && s_cmp(c2, "OR", (ftnlen)2, (ftnlen)2) == 0) {
+ if (*(unsigned char *)c3 == 'G') {
+ if (s_cmp(c4, "QR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "RQ",
+ (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "LQ", (ftnlen)2, (
+ ftnlen)2) == 0 || s_cmp(c4, "QL", (ftnlen)2, (ftnlen)2) ==
+ 0 || s_cmp(c4, "HR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(
+ c4, "TR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "BR", (
+ ftnlen)2, (ftnlen)2) == 0) {
+ nbmin = 2;
+ }
+ } else if (*(unsigned char *)c3 == 'M') {
+ if (s_cmp(c4, "QR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "RQ",
+ (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "LQ", (ftnlen)2, (
+ ftnlen)2) == 0 || s_cmp(c4, "QL", (ftnlen)2, (ftnlen)2) ==
+ 0 || s_cmp(c4, "HR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(
+ c4, "TR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "BR", (
+ ftnlen)2, (ftnlen)2) == 0) {
+ nbmin = 2;
+ }
+ }
+ } else if (cname && s_cmp(c2, "UN", (ftnlen)2, (ftnlen)2) == 0) {
+ if (*(unsigned char *)c3 == 'G') {
+ if (s_cmp(c4, "QR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "RQ",
+ (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "LQ", (ftnlen)2, (
+ ftnlen)2) == 0 || s_cmp(c4, "QL", (ftnlen)2, (ftnlen)2) ==
+ 0 || s_cmp(c4, "HR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(
+ c4, "TR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "BR", (
+ ftnlen)2, (ftnlen)2) == 0) {
+ nbmin = 2;
+ }
+ } else if (*(unsigned char *)c3 == 'M') {
+ if (s_cmp(c4, "QR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "RQ",
+ (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "LQ", (ftnlen)2, (
+ ftnlen)2) == 0 || s_cmp(c4, "QL", (ftnlen)2, (ftnlen)2) ==
+ 0 || s_cmp(c4, "HR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(
+ c4, "TR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "BR", (
+ ftnlen)2, (ftnlen)2) == 0) {
+ nbmin = 2;
+ }
+ }
+ }
+ ret_val = nbmin;
+ return ret_val;
+
+L300:
+
+/* ISPEC = 3: crossover point */
+
+ nx = 0;
+ if (s_cmp(c2, "GE", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "QRF", (ftnlen)3, (ftnlen)3) == 0 || s_cmp(c3, "RQF", (
+ ftnlen)3, (ftnlen)3) == 0 || s_cmp(c3, "LQF", (ftnlen)3, (
+ ftnlen)3) == 0 || s_cmp(c3, "QLF", (ftnlen)3, (ftnlen)3) == 0)
+ {
+ if (sname) {
+ nx = 128;
+ } else {
+ nx = 128;
+ }
+ } else if (s_cmp(c3, "HRD", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nx = 128;
+ } else {
+ nx = 128;
+ }
+ } else if (s_cmp(c3, "BRD", (ftnlen)3, (ftnlen)3) == 0) {
+ if (sname) {
+ nx = 128;
+ } else {
+ nx = 128;
+ }
+ }
+ } else if (s_cmp(c2, "SY", (ftnlen)2, (ftnlen)2) == 0) {
+ if (sname && s_cmp(c3, "TRD", (ftnlen)3, (ftnlen)3) == 0) {
+ nx = 32;
+ }
+ } else if (cname && s_cmp(c2, "HE", (ftnlen)2, (ftnlen)2) == 0) {
+ if (s_cmp(c3, "TRD", (ftnlen)3, (ftnlen)3) == 0) {
+ nx = 32;
+ }
+ } else if (sname && s_cmp(c2, "OR", (ftnlen)2, (ftnlen)2) == 0) {
+ if (*(unsigned char *)c3 == 'G') {
+ if (s_cmp(c4, "QR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "RQ",
+ (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "LQ", (ftnlen)2, (
+ ftnlen)2) == 0 || s_cmp(c4, "QL", (ftnlen)2, (ftnlen)2) ==
+ 0 || s_cmp(c4, "HR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(
+ c4, "TR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "BR", (
+ ftnlen)2, (ftnlen)2) == 0) {
+ nx = 128;
+ }
+ }
+ } else if (cname && s_cmp(c2, "UN", (ftnlen)2, (ftnlen)2) == 0) {
+ if (*(unsigned char *)c3 == 'G') {
+ if (s_cmp(c4, "QR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "RQ",
+ (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "LQ", (ftnlen)2, (
+ ftnlen)2) == 0 || s_cmp(c4, "QL", (ftnlen)2, (ftnlen)2) ==
+ 0 || s_cmp(c4, "HR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(
+ c4, "TR", (ftnlen)2, (ftnlen)2) == 0 || s_cmp(c4, "BR", (
+ ftnlen)2, (ftnlen)2) == 0) {
+ nx = 128;
+ }
+ }
+ }
+ ret_val = nx;
+ return ret_val;
+
+L400:
+
+/* ISPEC = 4: number of shifts (used by xHSEQR) */
+
+ ret_val = 6;
+ return ret_val;
+
+L500:
+
+/* ISPEC = 5: minimum column dimension (not used) */
+
+ ret_val = 2;
+ return ret_val;
+
+L600:
+
+/* ISPEC = 6: crossover point for SVD (used by xGELSS and xGESVD) */
+
+ ret_val = (integer) ((real) min(*n1,*n2) * 1.6f);
+ return ret_val;
+
+L700:
+
+/* ISPEC = 7: number of processors (not used) */
+
+ ret_val = 1;
+ return ret_val;
+
+L800:
+
+/* ISPEC = 8: crossover point for multishift (used by xHSEQR) */
+
+ ret_val = 50;
+ return ret_val;
+
+L900:
+
+/* ISPEC = 9: maximum size of the subproblems at the bottom of the
+ computation tree in the divide-and-conquer algorithm
+ (used by xGELSD and xGESDD) */
+
+ ret_val = 25;
+ return ret_val;
+
+L1000:
+
+/* ISPEC = 10: ieee NaN arithmetic can be trusted not to trap
+
+ ILAENV = 0 */
+ ret_val = 1;
+ if (ret_val == 1) {
+ ret_val = ieeeck_(&c__0, &c_b162, &c_b163);
+ }
+ return ret_val;
+
+L1100:
+
+/* ISPEC = 11: infinity arithmetic can be trusted not to trap
+
+ ILAENV = 0 */
+ ret_val = 1;
+ if (ret_val == 1) {
+ ret_val = ieeeck_(&c__1, &c_b162, &c_b163);
+ }
+ return ret_val;
+
+/* End of ILAENV */
+
+} /* ilaenv_ */
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/lsame.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/lsame.c
new file mode 100644
index 0000000..d9baaa3
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/lsame.c
@@ -0,0 +1,101 @@
+#include "f2c.h"
+
+logical lsame_(char *ca, char *cb)
+{
+/* -- LAPACK auxiliary routine (version 3.0) --
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
+ Courant Institute, Argonne National Lab, and Rice University
+ September 30, 1994
+
+
+ Purpose
+ =======
+
+ LSAME returns .TRUE. if CA is the same letter as CB regardless of
+ case.
+
+ Arguments
+ =========
+
+ CA (input) CHARACTER*1
+ CB (input) CHARACTER*1
+ CA and CB specify the single characters to be compared.
+
+ =====================================================================
+
+
+
+ Test if the characters are equal */
+ /* System generated locals */
+ logical ret_val;
+ /* Local variables */
+ static integer inta, intb, zcode;
+
+
+ ret_val = *(unsigned char *)ca == *(unsigned char *)cb;
+ if (ret_val) {
+ return ret_val;
+ }
+
+/* Now test for equivalence if both characters are alphabetic. */
+
+ zcode = 'Z';
+
+/* Use 'Z' rather than 'A' so that ASCII can be detected on Prime
+ machines, on which ICHAR returns a value with bit 8 set.
+ ICHAR('A') on Prime machines returns 193 which is the same as
+ ICHAR('A') on an EBCDIC machine. */
+
+ inta = *(unsigned char *)ca;
+ intb = *(unsigned char *)cb;
+
+ if (zcode == 90 || zcode == 122) {
+
+/* ASCII is assumed - ZCODE is the ASCII code of either lower o
+r
+ upper case 'Z'. */
+
+ if (inta >= 97 && inta <= 122) {
+ inta += -32;
+ }
+ if (intb >= 97 && intb <= 122) {
+ intb += -32;
+ }
+
+ } else if (zcode == 233 || zcode == 169) {
+
+/* EBCDIC is assumed - ZCODE is the EBCDIC code of either lower
+ or
+ upper case 'Z'. */
+
+ if (inta >= 129 && inta <= 137 || inta >= 145 && inta <= 153 || inta
+ >= 162 && inta <= 169) {
+ inta += 64;
+ }
+ if (intb >= 129 && intb <= 137 || intb >= 145 && intb <= 153 || intb
+ >= 162 && intb <= 169) {
+ intb += 64;
+ }
+
+ } else if (zcode == 218 || zcode == 250) {
+
+/* ASCII is assumed, on Prime machines - ZCODE is the ASCII cod
+e
+ plus 128 of either lower or upper case 'Z'. */
+
+ if (inta >= 225 && inta <= 250) {
+ inta += -32;
+ }
+ if (intb >= 225 && intb <= 250) {
+ intb += -32;
+ }
+ }
+ ret_val = inta == intb;
+
+/* RETURN
+
+ End of LSAME */
+
+ return ret_val;
+} /* lsame_ */
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/open.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/open.c
new file mode 100644
index 0000000..493aaea
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/open.c
@@ -0,0 +1,291 @@
+#include "f2c.h"
+#include "fio.h"
+#include "string.h"
+#ifndef NON_POSIX_STDIO
+#ifdef MSDOS
+#include "io.h"
+#else
+#include "unistd.h" /* for access */
+#endif
+#endif
+
+#ifdef KR_headers
+extern char *malloc();
+#ifdef NON_ANSI_STDIO
+extern char *mktemp();
+#endif
+extern integer f_clos();
+#else
+#undef abs
+#undef min
+#undef max
+#include "stdlib.h"
+extern int f__canseek(FILE*);
+extern integer f_clos(cllist*);
+#endif
+
+#ifdef NON_ANSI_RW_MODES
+char *f__r_mode[2] = {"r", "r"};
+char *f__w_mode[4] = {"w", "w", "r+w", "r+w"};
+#else
+char *f__r_mode[2] = {"rb", "r"};
+char *f__w_mode[4] = {"wb", "w", "r+b", "r+"};
+#endif
+
+ static char f__buf0[400], *f__buf = f__buf0;
+ int f__buflen = (int)sizeof(f__buf0);
+
+ static void
+#ifdef KR_headers
+f__bufadj(n, c) int n, c;
+#else
+f__bufadj(int n, int c)
+#endif
+{
+ unsigned int len;
+ char *nbuf, *s, *t, *te;
+
+ if (f__buf == f__buf0)
+ f__buflen = 1024;
+ while(f__buflen <= n)
+ f__buflen <<= 1;
+ len = (unsigned int)f__buflen;
+ if (len != f__buflen || !(nbuf = (char*)malloc(len)))
+ f__fatal(113, "malloc failure");
+ s = nbuf;
+ t = f__buf;
+ te = t + c;
+ while(t < te)
+ *s++ = *t++;
+ if (f__buf != f__buf0)
+ free(f__buf);
+ f__buf = nbuf;
+ }
+
+ int
+#ifdef KR_headers
+f__putbuf(c) int c;
+#else
+f__putbuf(int c)
+#endif
+{
+ char *s, *se;
+ int n;
+
+ if (f__hiwater > f__recpos)
+ f__recpos = f__hiwater;
+ n = f__recpos + 1;
+ if (n >= f__buflen)
+ f__bufadj(n, f__recpos);
+ s = f__buf;
+ se = s + f__recpos;
+ if (c)
+ *se++ = c;
+ *se = 0;
+ for(;;) {
+ fputs(s, f__cf);
+ s += strlen(s);
+ if (s >= se)
+ break; /* normally happens the first time */
+ putc(*s++, f__cf);
+ }
+ return 0;
+ }
+
+ void
+#ifdef KR_headers
+x_putc(c)
+#else
+x_putc(int c)
+#endif
+{
+ if (f__recpos >= f__buflen)
+ f__bufadj(f__recpos, f__buflen);
+ f__buf[f__recpos++] = c;
+ }
+
+#define opnerr(f,m,s) {if(f) errno= m; else opn_err(m,s,a); return(m);}
+
+ static void
+#ifdef KR_headers
+opn_err(m, s, a) int m; char *s; olist *a;
+#else
+opn_err(int m, char *s, olist *a)
+#endif
+{
+ if (a->ofnm) {
+ /* supply file name to error message */
+ if (a->ofnmlen >= f__buflen)
+ f__bufadj((int)a->ofnmlen, 0);
+ g_char(a->ofnm, a->ofnmlen, f__curunit->ufnm = f__buf);
+ }
+ f__fatal(m, s);
+ }
+
+#ifdef KR_headers
+integer f_open(a) olist *a;
+#else
+integer f_open(olist *a)
+#endif
+{ unit *b;
+ integer rv;
+ char buf[256], *s;
+ cllist x;
+ int ufmt;
+ FILE *tf;
+#ifndef NON_UNIX_STDIO
+ int n;
+#endif
+ f__external = 1;
+ if(a->ounit>=MXUNIT || a->ounit<0)
+ err(a->oerr,101,"open")
+ if (!f__init)
+ f_init();
+ f__curunit = b = &f__units[a->ounit];
+ if(b->ufd) {
+ if(a->ofnm==0)
+ {
+ same: if (a->oblnk)
+ b->ublnk = *a->oblnk == 'z' || *a->oblnk == 'Z';
+ return(0);
+ }
+#ifdef NON_UNIX_STDIO
+ if (b->ufnm
+ && strlen(b->ufnm) == a->ofnmlen
+ && !strncmp(b->ufnm, a->ofnm, (unsigned)a->ofnmlen))
+ goto same;
+#else
+ g_char(a->ofnm,a->ofnmlen,buf);
+ if (f__inode(buf,&n) == b->uinode && n == b->udev)
+ goto same;
+#endif
+ x.cunit=a->ounit;
+ x.csta=0;
+ x.cerr=a->oerr;
+ if ((rv = f_clos(&x)) != 0)
+ return rv;
+ }
+ b->url = (int)a->orl;
+ b->ublnk = a->oblnk && (*a->oblnk == 'z' || *a->oblnk == 'Z');
+ if(a->ofm==0)
+ { if(b->url>0) b->ufmt=0;
+ else b->ufmt=1;
+ }
+ else if(*a->ofm=='f' || *a->ofm == 'F') b->ufmt=1;
+ else b->ufmt=0;
+ ufmt = b->ufmt;
+#ifdef url_Adjust
+ if (b->url && !ufmt)
+ url_Adjust(b->url);
+#endif
+ if (a->ofnm) {
+ g_char(a->ofnm,a->ofnmlen,buf);
+ if (!buf[0])
+ opnerr(a->oerr,107,"open")
+ }
+ else
+ sprintf(buf, "fort.%ld", (long)a->ounit);
+ b->uscrtch = 0;
+ b->uend=0;
+ b->uwrt = 0;
+ b->ufd = 0;
+ b->urw = 3;
+ switch(a->osta ? *a->osta : 'u')
+ {
+ case 'o':
+ case 'O':
+#ifdef NON_POSIX_STDIO
+ if (!(tf = fopen(buf,"r")))
+ opnerr(a->oerr,errno,"open")
+ fclose(tf);
+#else
+ if (access(buf,0))
+ opnerr(a->oerr,errno,"open")
+#endif
+ break;
+ case 's':
+ case 'S':
+ b->uscrtch=1;
+#ifdef NON_ANSI_STDIO
+ (void) strcpy(buf,"tmp.FXXXXXX");
+ (void) mktemp(buf);
+ goto replace;
+#else
+ if (!(b->ufd = tmpfile()))
+ opnerr(a->oerr,errno,"open")
+ b->ufnm = 0;
+#ifndef NON_UNIX_STDIO
+ b->uinode = b->udev = -1;
+#endif
+ b->useek = 1;
+ return 0;
+#endif
+
+ case 'n':
+ case 'N':
+#ifdef NON_POSIX_STDIO
+ if ((tf = fopen(buf,"r")) || (tf = fopen(buf,"a"))) {
+ fclose(tf);
+ opnerr(a->oerr,128,"open")
+ }
+#else
+ if (!access(buf,0))
+ opnerr(a->oerr,128,"open")
+#endif
+ /* no break */
+ case 'r': /* Fortran 90 replace option */
+ case 'R':
+#ifdef NON_ANSI_STDIO
+ replace:
+#endif
+ if (tf = fopen(buf,f__w_mode[0]))
+ fclose(tf);
+ }
+
+ b->ufnm=(char *) malloc((unsigned int)(strlen(buf)+1));
+ if(b->ufnm==NULL) opnerr(a->oerr,113,"no space");
+ (void) strcpy(b->ufnm,buf);
+ if ((s = a->oacc) && b->url)
+ ufmt = 0;
+ if(!(tf = fopen(buf, f__w_mode[ufmt|2]))) {
+ if (tf = fopen(buf, f__r_mode[ufmt]))
+ b->urw = 1;
+ else if (tf = fopen(buf, f__w_mode[ufmt])) {
+ b->uwrt = 1;
+ b->urw = 2;
+ }
+ else
+ err(a->oerr, errno, "open");
+ }
+ b->useek = f__canseek(b->ufd = tf);
+#ifndef NON_UNIX_STDIO
+ if((b->uinode = f__inode(buf,&b->udev)) == -1)
+ opnerr(a->oerr,108,"open")
+#endif
+ if(b->useek)
+ if (a->orl)
+ rewind(b->ufd);
+ else if ((s = a->oacc) && (*s == 'a' || *s == 'A')
+ && fseek(b->ufd, 0L, SEEK_END))
+ opnerr(a->oerr,129,"open");
+ return(0);
+}
+#ifdef KR_headers
+fk_open(seq,fmt,n) ftnint n;
+#else
+fk_open(int seq, int fmt, ftnint n)
+#endif
+{ char nbuf[10];
+ olist a;
+ (void) sprintf(nbuf,"fort.%ld",(long)n);
+ a.oerr=1;
+ a.ounit=n;
+ a.ofnm=nbuf;
+ a.ofnmlen=strlen(nbuf);
+ a.osta=NULL;
+ a.oacc= seq==SEQ?"s":"d";
+ a.ofm = fmt==FMT?"f":"u";
+ a.orl = seq==DIR?1:0;
+ a.oblnk=NULL;
+ return(f_open(&a));
+}
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/s_cmp.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/s_cmp.c
new file mode 100644
index 0000000..1e052f2
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/s_cmp.c
@@ -0,0 +1,44 @@
+#include "f2c.h"
+
+/* compare two strings */
+
+#ifdef KR_headers
+integer s_cmp(a0, b0, la, lb) char *a0, *b0; ftnlen la, lb;
+#else
+integer s_cmp(char *a0, char *b0, ftnlen la, ftnlen lb)
+#endif
+{
+register unsigned char *a, *aend, *b, *bend;
+a = (unsigned char *)a0;
+b = (unsigned char *)b0;
+aend = a + la;
+bend = b + lb;
+
+if(la <= lb)
+ {
+ while(a < aend)
+ if(*a != *b)
+ return( *a - *b );
+ else
+ { ++a; ++b; }
+
+ while(b < bend)
+ if(*b != ' ')
+ return( ' ' - *b );
+ else ++b;
+ }
+
+else
+ {
+ while(b < bend)
+ if(*a == *b)
+ { ++a; ++b; }
+ else
+ return( *a - *b );
+ while(a < aend)
+ if(*a != ' ')
+ return(*a - ' ');
+ else ++a;
+ }
+return(0);
+}
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/s_copy.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/s_copy.c
new file mode 100644
index 0000000..d167351
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/s_copy.c
@@ -0,0 +1,51 @@
+/* Unless compiled with -DNO_OVERWRITE, this variant of s_copy allows the
+ * target of an assignment to appear on its right-hand side (contrary
+ * to the Fortran 77 Standard, but in accordance with Fortran 90),
+ * as in a(2:5) = a(4:7) .
+ */
+
+#include "f2c.h"
+
+/* assign strings: a = b */
+
+#ifdef KR_headers
+VOID s_copy(a, b, la, lb) register char *a, *b; ftnlen la, lb;
+#else
+void s_copy(register char *a, register char *b, ftnlen la, ftnlen lb)
+#endif
+{
+ register char *aend, *bend;
+
+ aend = a + la;
+
+ if(la <= lb)
+#ifndef NO_OVERWRITE
+ if (a <= b || a >= b + la)
+#endif
+ while(a < aend)
+ *a++ = *b++;
+#ifndef NO_OVERWRITE
+ else
+ for(b += la; a < aend; )
+ *--aend = *--b;
+#endif
+
+ else {
+ bend = b + lb;
+#ifndef NO_OVERWRITE
+ if (a <= b || a >= bend)
+#endif
+ while(b < bend)
+ *a++ = *b++;
+#ifndef NO_OVERWRITE
+ else {
+ a += lb;
+ while(b < bend)
+ *--a = *--bend;
+ a += lb;
+ }
+#endif
+ while(a < aend)
+ *a++ = ' ';
+ }
+ }
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/s_stop.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/s_stop.c
new file mode 100644
index 0000000..fb57bde
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/s_stop.c
@@ -0,0 +1,42 @@
+#include "stdio.h"
+#include "f2c.h"
+
+#ifdef KR_headers
+extern void f_exit();
+VOID s_stop(s, n) char *s; ftnlen n;
+#else
+#undef abs
+#undef min
+#undef max
+#include "stdlib.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+void f_exit(void);
+
+int s_stop(char *s, ftnlen n)
+#endif
+{
+int i;
+
+if(n > 0)
+ {
+ fprintf(stderr, "STOP ");
+ for(i = 0; i<n ; ++i)
+ putc(*s++, stderr);
+ fprintf(stderr, " statement executed\n");
+ }
+#ifdef NO_ONEXIT
+f_exit();
+#endif
+exit(0);
+
+/* We cannot avoid (useless) compiler diagnostics here: */
+/* some compilers complain if there is no return statement, */
+/* and others complain that this one cannot be reached. */
+
+return 0; /* NOT REACHED */
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/sfe.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/sfe.c
new file mode 100644
index 0000000..cade56a
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/sfe.c
@@ -0,0 +1,31 @@
+/* sequential formatted external common routines*/
+#include "f2c.h"
+#include "fio.h"
+
+extern char *f__fmtbuf;
+
+integer e_rsfe(Void)
+{ int n;
+ n=en_fio();
+ f__fmtbuf=NULL;
+ return(n);
+}
+#ifdef KR_headers
+c_sfe(a) cilist *a; /* check */
+#else
+c_sfe(cilist *a) /* check */
+#endif
+{ unit *p;
+ f__curunit = p = &f__units[a->ciunit];
+ if(a->ciunit >= MXUNIT || a->ciunit<0)
+ err(a->cierr,101,"startio");
+ if(p->ufd==NULL && fk_open(SEQ,FMT,a->ciunit)) err(a->cierr,114,"sfe")
+ if(!p->ufmt) err(a->cierr,102,"sfe")
+ return(0);
+}
+integer e_wsfe(Void)
+{
+ int n = en_fio();
+ f__fmtbuf = NULL;
+ return n;
+}
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/sig_die.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/sig_die.c
new file mode 100644
index 0000000..dba1521
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/sig_die.c
@@ -0,0 +1,45 @@
+#include "stdio.h"
+#include "signal.h"
+
+#ifndef SIGIOT
+#ifdef SIGABRT
+#define SIGIOT SIGABRT
+#endif
+#endif
+
+#ifdef KR_headers
+void sig_die(s, kill) register char *s; int kill;
+#else
+#include "stdlib.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+ extern void f_exit(void);
+
+void sig_die(register char *s, int kill)
+#endif
+{
+ /* print error message, then clear buffers */
+ fprintf(stderr, "%s\n", s);
+
+ if(kill)
+ {
+ fflush(stderr);
+ f_exit();
+ fflush(stderr);
+ /* now get a core */
+#ifdef SIGIOT
+ signal(SIGIOT, SIG_DFL);
+#endif
+ abort();
+ }
+ else {
+#ifdef NO_ONEXIT
+ f_exit();
+#endif
+ exit(1);
+ }
+ }
+#ifdef __cplusplus
+}
+#endif
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/util.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/util.c
new file mode 100644
index 0000000..6468db0
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/util.c
@@ -0,0 +1,53 @@
+#ifndef NON_UNIX_STDIO
+#define _INCLUDE_POSIX_SOURCE /* for HP-UX */
+#define _INCLUDE_XOPEN_SOURCE /* for HP-UX */
+#include "sys/types.h"
+#include "sys/stat.h"
+#endif
+#include "f2c.h"
+#include "fio.h"
+
+ VOID
+#ifdef KR_headers
+g_char(a,alen,b) char *a,*b; ftnlen alen;
+#else
+g_char(char *a, ftnlen alen, char *b)
+#endif
+{
+ char *x = a + alen, *y = b + alen;
+
+ for(;; y--) {
+ if (x <= a) {
+ *b = 0;
+ return;
+ }
+ if (*--x != ' ')
+ break;
+ }
+ *y-- = 0;
+ do *y-- = *x;
+ while(x-- > a);
+ }
+
+ VOID
+#ifdef KR_headers
+b_char(a,b,blen) char *a,*b; ftnlen blen;
+#else
+b_char(char *a, char *b, ftnlen blen)
+#endif
+{ int i;
+ for(i=0;i<blen && *a!=0;i++) *b++= *a++;
+ for(;i<blen;i++) *b++=' ';
+}
+#ifndef NON_UNIX_STDIO
+#ifdef KR_headers
+long f__inode(a, dev) char *a; int *dev;
+#else
+long f__inode(char *a, int *dev)
+#endif
+{ struct stat x;
+ if(stat(a,&x)<0) return(-1);
+ *dev = x.st_dev;
+ return(x.st_ino);
+}
+#endif
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/wref.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/wref.c
new file mode 100644
index 0000000..2f3fce8
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/wref.c
@@ -0,0 +1,276 @@
+#include "f2c.h"
+#include "fio.h"
+
+#ifndef KR_headers
+#undef abs
+#undef min
+#undef max
+#include "stdlib.h"
+#include "string.h"
+#endif
+
+#include "fmt.h"
+#include "fp.h"
+#ifndef VAX
+#include "ctype.h"
+#endif
+
+#ifdef KR_headers
+wrt_E(p,w,d,e,len) ufloat *p; ftnlen len;
+#else
+wrt_E(ufloat *p, int w, int d, int e, ftnlen len)
+#endif
+{
+ char buf[FMAX+EXPMAXDIGS+4], *s, *se;
+ int d1, delta, e1, i, sign, signspace;
+ double dd;
+#ifdef WANT_LEAD_0
+ int insert0 = 0;
+#endif
+#ifndef VAX
+ int e0 = e;
+#endif
+
+ if(e <= 0)
+ e = 2;
+ if(f__scale) {
+ if(f__scale >= d + 2 || f__scale <= -d)
+ goto nogood;
+ }
+ if(f__scale <= 0)
+ --d;
+ if (len == sizeof(real))
+ dd = p->pf;
+ else
+ dd = p->pd;
+ if (dd < 0.) {
+ signspace = sign = 1;
+ dd = -dd;
+ }
+ else {
+ sign = 0;
+ signspace = (int)f__cplus;
+#ifndef VAX
+ if (!dd)
+ dd = 0.; /* avoid -0 */
+#endif
+ }
+ delta = w - (2 /* for the . and the d adjustment above */
+ + 2 /* for the E+ */ + signspace + d + e);
+#ifdef WANT_LEAD_0
+ if (f__scale <= 0 && delta > 0) {
+ delta--;
+ insert0 = 1;
+ }
+ else
+#endif
+ if (delta < 0) {
+nogood:
+ while(--w >= 0)
+ PUT('*');
+ return(0);
+ }
+ if (f__scale < 0)
+ d += f__scale;
+ if (d > FMAX) {
+ d1 = d - FMAX;
+ d = FMAX;
+ }
+ else
+ d1 = 0;
+ sprintf(buf,"%#.*E", d, dd);
+#ifndef VAX
+ /* check for NaN, Infinity */
+ if (!isdigit(buf[0])) {
+ switch(buf[0]) {
+ case 'n':
+ case 'N':
+ signspace = 0; /* no sign for NaNs */
+ }
+ delta = w - strlen(buf) - signspace;
+ if (delta < 0)
+ goto nogood;
+ while(--delta >= 0)
+ PUT(' ');
+ if (signspace)
+ PUT(sign ? '-' : '+');
+ for(s = buf; *s; s++)
+ PUT(*s);
+ return 0;
+ }
+#endif
+ se = buf + d + 3;
+#ifdef GOOD_SPRINTF_EXPONENT /* When possible, exponent has 2 digits. */
+ if (f__scale != 1 && dd)
+ sprintf(se, "%+.2d", atoi(se) + 1 - f__scale);
+#else
+ if (dd)
+ sprintf(se, "%+.2d", atoi(se) + 1 - f__scale);
+ else
+ strcpy(se, "+00");
+#endif
+ s = ++se;
+ if (e < 2) {
+ if (*s != '0')
+ goto nogood;
+ }
+#ifndef VAX
+ /* accommodate 3 significant digits in exponent */
+ if (s[2]) {
+#ifdef Pedantic
+ if (!e0 && !s[3])
+ for(s -= 2, e1 = 2; s[0] = s[1]; s++);
+
+ /* Pedantic gives the behavior that Fortran 77 specifies, */
+ /* i.e., requires that E be specified for exponent fields */
+ /* of more than 3 digits. With Pedantic undefined, we get */
+ /* the behavior that Cray displays -- you get a bigger */
+ /* exponent field if it fits. */
+#else
+ if (!e0) {
+ for(s -= 2, e1 = 2; s[0] = s[1]; s++)
+#ifdef CRAY
+ delta--;
+ if ((delta += 4) < 0)
+ goto nogood
+#endif
+ ;
+ }
+#endif
+ else if (e0 >= 0)
+ goto shift;
+ else
+ e1 = e;
+ }
+ else
+ shift:
+#endif
+ for(s += 2, e1 = 2; *s; ++e1, ++s)
+ if (e1 >= e)
+ goto nogood;
+ while(--delta >= 0)
+ PUT(' ');
+ if (signspace)
+ PUT(sign ? '-' : '+');
+ s = buf;
+ i = f__scale;
+ if (f__scale <= 0) {
+#ifdef WANT_LEAD_0
+ if (insert0)
+ PUT('0');
+#endif
+ PUT('.');
+ for(; i < 0; ++i)
+ PUT('0');
+ PUT(*s);
+ s += 2;
+ }
+ else if (f__scale > 1) {
+ PUT(*s);
+ s += 2;
+ while(--i > 0)
+ PUT(*s++);
+ PUT('.');
+ }
+ if (d1) {
+ se -= 2;
+ while(s < se) PUT(*s++);
+ se += 2;
+ do PUT('0'); while(--d1 > 0);
+ }
+ while(s < se)
+ PUT(*s++);
+ if (e < 2)
+ PUT(s[1]);
+ else {
+ while(++e1 <= e)
+ PUT('0');
+ while(*s)
+ PUT(*s++);
+ }
+ return 0;
+ }
+
+#ifdef KR_headers
+wrt_F(p,w,d,len) ufloat *p; ftnlen len;
+#else
+wrt_F(ufloat *p, int w, int d, ftnlen len)
+#endif
+{
+ int d1, sign, n;
+ double x;
+ char *b, buf[MAXINTDIGS+MAXFRACDIGS+4], *s;
+
+ x= (len==sizeof(real)?p->pf:p->pd);
+ if (d < MAXFRACDIGS)
+ d1 = 0;
+ else {
+ d1 = d - MAXFRACDIGS;
+ d = MAXFRACDIGS;
+ }
+ if (x < 0.)
+ { x = -x; sign = 1; }
+ else {
+ sign = 0;
+#ifndef VAX
+ if (!x)
+ x = 0.;
+#endif
+ }
+
+ if (n = f__scale)
+ if (n > 0)
+ do x *= 10.; while(--n > 0);
+ else
+ do x *= 0.1; while(++n < 0);
+
+#ifdef USE_STRLEN
+ sprintf(b = buf, "%#.*f", d, x);
+ n = strlen(b) + d1;
+#else
+ n = sprintf(b = buf, "%#.*f", d, x) + d1;
+#endif
+
+#ifndef WANT_LEAD_0
+ if (buf[0] == '0' && d)
+ { ++b; --n; }
+#endif
+ if (sign) {
+ /* check for all zeros */
+ for(s = b;;) {
+ while(*s == '0') s++;
+ switch(*s) {
+ case '.':
+ s++; continue;
+ case 0:
+ sign = 0;
+ }
+ break;
+ }
+ }
+ if (sign || f__cplus)
+ ++n;
+ if (n > w) {
+#ifdef WANT_LEAD_0
+ if (buf[0] == '0' && --n == w)
+ ++b;
+ else
+#endif
+ {
+ while(--w >= 0)
+ PUT('*');
+ return 0;
+ }
+ }
+ for(w -= n; --w >= 0; )
+ PUT(' ');
+ if (sign)
+ PUT('-');
+ else if (f__cplus)
+ PUT('+');
+ while(n = *b++)
+ PUT(n);
+ while(--d1 >= 0)
+ PUT('0');
+ return 0;
+ }
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/wrtfmt.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/wrtfmt.c
new file mode 100644
index 0000000..477c40f
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/wrtfmt.c
@@ -0,0 +1,365 @@
+#include "f2c.h"
+#include "fio.h"
+#include "fmt.h"
+
+extern icilist *f__svic;
+extern char *f__icptr;
+
+ static int
+mv_cur(Void) /* shouldn't use fseek because it insists on calling fflush */
+ /* instead we know too much about stdio */
+{
+ int cursor = f__cursor;
+ f__cursor = 0;
+ if(f__external == 0) {
+ if(cursor < 0) {
+ if(f__hiwater < f__recpos)
+ f__hiwater = f__recpos;
+ f__recpos += cursor;
+ f__icptr += cursor;
+ if(f__recpos < 0)
+ err(f__elist->cierr, 110, "left off");
+ }
+ else if(cursor > 0) {
+ if(f__recpos + cursor >= f__svic->icirlen)
+ err(f__elist->cierr, 110, "recend");
+ if(f__hiwater <= f__recpos)
+ for(; cursor > 0; cursor--)
+ (*f__putn)(' ');
+ else if(f__hiwater <= f__recpos + cursor) {
+ cursor -= f__hiwater - f__recpos;
+ f__icptr += f__hiwater - f__recpos;
+ f__recpos = f__hiwater;
+ for(; cursor > 0; cursor--)
+ (*f__putn)(' ');
+ }
+ else {
+ f__icptr += cursor;
+ f__recpos += cursor;
+ }
+ }
+ return(0);
+ }
+ if (cursor > 0) {
+ if(f__hiwater <= f__recpos)
+ for(;cursor>0;cursor--) (*f__putn)(' ');
+ else if(f__hiwater <= f__recpos + cursor) {
+ cursor -= f__hiwater - f__recpos;
+ f__recpos = f__hiwater;
+ for(; cursor > 0; cursor--)
+ (*f__putn)(' ');
+ }
+ else {
+ f__recpos += cursor;
+ }
+ }
+ else if (cursor < 0)
+ {
+ if(cursor + f__recpos < 0)
+ err(f__elist->cierr,110,"left off");
+ if(f__hiwater < f__recpos)
+ f__hiwater = f__recpos;
+ f__recpos += cursor;
+ }
+ return(0);
+}
+
+ static int
+#ifdef KR_headers
+wrt_Z(n,w,minlen,len) Uint *n; int w, minlen; ftnlen len;
+#else
+wrt_Z(Uint *n, int w, int minlen, ftnlen len)
+#endif
+{
+ register char *s, *se;
+ register int i, w1;
+ static int one = 1;
+ static char hex[] = "0123456789ABCDEF";
+ s = (char *)n;
+ --len;
+ if (*(char *)&one) {
+ /* little endian */
+ se = s;
+ s += len;
+ i = -1;
+ }
+ else {
+ se = s + len;
+ i = 1;
+ }
+ for(;; s += i)
+ if (s == se || *s)
+ break;
+ w1 = (i*(se-s) << 1) + 1;
+ if (*s & 0xf0)
+ w1++;
+ if (w1 > w)
+ for(i = 0; i < w; i++)
+ (*f__putn)('*');
+ else {
+ if ((minlen -= w1) > 0)
+ w1 += minlen;
+ while(--w >= w1)
+ (*f__putn)(' ');
+ while(--minlen >= 0)
+ (*f__putn)('0');
+ if (!(*s & 0xf0)) {
+ (*f__putn)(hex[*s & 0xf]);
+ if (s == se)
+ return 0;
+ s += i;
+ }
+ for(;; s += i) {
+ (*f__putn)(hex[*s >> 4 & 0xf]);
+ (*f__putn)(hex[*s & 0xf]);
+ if (s == se)
+ break;
+ }
+ }
+ return 0;
+ }
+
+ static int
+#ifdef KR_headers
+wrt_I(n,w,len, base) Uint *n; ftnlen len; register int base;
+#else
+wrt_I(Uint *n, int w, ftnlen len, register int base)
+#endif
+{ int ndigit,sign,spare,i;
+ longint x;
+ char *ans;
+ if(len==sizeof(integer)) x=n->il;
+ else if(len == sizeof(char)) x = n->ic;
+#ifdef Allow_TYQUAD
+ else if (len == sizeof(longint)) x = n->ili;
+#endif
+ else x=n->is;
+ ans=f__icvt(x,&ndigit,&sign, base);
+ spare=w-ndigit;
+ if(sign || f__cplus) spare--;
+ if(spare<0)
+ for(i=0;i<w;i++) (*f__putn)('*');
+ else
+ { for(i=0;i<spare;i++) (*f__putn)(' ');
+ if(sign) (*f__putn)('-');
+ else if(f__cplus) (*f__putn)('+');
+ for(i=0;i<ndigit;i++) (*f__putn)(*ans++);
+ }
+ return(0);
+}
+ static int
+#ifdef KR_headers
+wrt_IM(n,w,m,len,base) Uint *n; ftnlen len; int base;
+#else
+wrt_IM(Uint *n, int w, int m, ftnlen len, int base)
+#endif
+{ int ndigit,sign,spare,i,xsign;
+ longint x;
+ char *ans;
+ if(sizeof(integer)==len) x=n->il;
+ else if(len == sizeof(char)) x = n->ic;
+#ifdef Allow_TYQUAD
+ else if (len == sizeof(longint)) x = n->ili;
+#endif
+ else x=n->is;
+ ans=f__icvt(x,&ndigit,&sign, base);
+ if(sign || f__cplus) xsign=1;
+ else xsign=0;
+ if(ndigit+xsign>w || m+xsign>w)
+ { for(i=0;i<w;i++) (*f__putn)('*');
+ return(0);
+ }
+ if(x==0 && m==0)
+ { for(i=0;i<w;i++) (*f__putn)(' ');
+ return(0);
+ }
+ if(ndigit>=m)
+ spare=w-ndigit-xsign;
+ else
+ spare=w-m-xsign;
+ for(i=0;i<spare;i++) (*f__putn)(' ');
+ if(sign) (*f__putn)('-');
+ else if(f__cplus) (*f__putn)('+');
+ for(i=0;i<m-ndigit;i++) (*f__putn)('0');
+ for(i=0;i<ndigit;i++) (*f__putn)(*ans++);
+ return(0);
+}
+ static int
+#ifdef KR_headers
+wrt_AP(s) char *s;
+#else
+wrt_AP(char *s)
+#endif
+{ char quote;
+ int i;
+
+ if(f__cursor && (i = mv_cur()))
+ return i;
+ quote = *s++;
+ for(;*s;s++)
+ { if(*s!=quote) (*f__putn)(*s);
+ else if(*++s==quote) (*f__putn)(*s);
+ else return(1);
+ }
+ return(1);
+}
+ static int
+#ifdef KR_headers
+wrt_H(a,s) char *s;
+#else
+wrt_H(int a, char *s)
+#endif
+{
+ int i;
+
+ if(f__cursor && (i = mv_cur()))
+ return i;
+ while(a--) (*f__putn)(*s++);
+ return(1);
+}
+#ifdef KR_headers
+wrt_L(n,len, sz) Uint *n; ftnlen sz;
+#else
+wrt_L(Uint *n, int len, ftnlen sz)
+#endif
+{ int i;
+ long x;
+ if(sizeof(long)==sz) x=n->il;
+ else if(sz == sizeof(char)) x = n->ic;
+ else x=n->is;
+ for(i=0;i<len-1;i++)
+ (*f__putn)(' ');
+ if(x) (*f__putn)('T');
+ else (*f__putn)('F');
+ return(0);
+}
+ static int
+#ifdef KR_headers
+wrt_A(p,len) char *p; ftnlen len;
+#else
+wrt_A(char *p, ftnlen len)
+#endif
+{
+ while(len-- > 0) (*f__putn)(*p++);
+ return(0);
+}
+ static int
+#ifdef KR_headers
+wrt_AW(p,w,len) char * p; ftnlen len;
+#else
+wrt_AW(char * p, int w, ftnlen len)
+#endif
+{
+ while(w>len)
+ { w--;
+ (*f__putn)(' ');
+ }
+ while(w-- > 0)
+ (*f__putn)(*p++);
+ return(0);
+}
+
+ static int
+#ifdef KR_headers
+wrt_G(p,w,d,e,len) ufloat *p; ftnlen len;
+#else
+wrt_G(ufloat *p, int w, int d, int e, ftnlen len)
+#endif
+{ double up = 1,x;
+ int i=0,oldscale,n,j;
+ x = len==sizeof(real)?p->pf:p->pd;
+ if(x < 0 ) x = -x;
+ if(x<.1) {
+ if (x != 0.)
+ return(wrt_E(p,w,d,e,len));
+ i = 1;
+ goto have_i;
+ }
+ for(;i<=d;i++,up*=10)
+ { if(x>=up) continue;
+ have_i:
+ oldscale = f__scale;
+ f__scale = 0;
+ if(e==0) n=4;
+ else n=e+2;
+ i=wrt_F(p,w-n,d-i,len);
+ for(j=0;j<n;j++) (*f__putn)(' ');
+ f__scale=oldscale;
+ return(i);
+ }
+ return(wrt_E(p,w,d,e,len));
+}
+#ifdef KR_headers
+w_ed(p,ptr,len) struct syl *p; char *ptr; ftnlen len;
+#else
+w_ed(struct syl *p, char *ptr, ftnlen len)
+#endif
+{
+ int i;
+
+ if(f__cursor && (i = mv_cur()))
+ return i;
+ switch(p->op)
+ {
+ default:
+ fprintf(stderr,"w_ed, unexpected code: %d\n", p->op);
+ sig_die(f__fmtbuf, 1);
+ case I: return(wrt_I((Uint *)ptr,p->p1,len, 10));
+ case IM:
+ return(wrt_IM((Uint *)ptr,p->p1,p->p2.i[0],len,10));
+
+ /* O and OM don't work right for character, double, complex, */
+ /* or doublecomplex, and they differ from Fortran 90 in */
+ /* showing a minus sign for negative values. */
+
+ case O: return(wrt_I((Uint *)ptr, p->p1, len, 8));
+ case OM:
+ return(wrt_IM((Uint *)ptr,p->p1,p->p2.i[0],len,8));
+ case L: return(wrt_L((Uint *)ptr,p->p1, len));
+ case A: return(wrt_A(ptr,len));
+ case AW:
+ return(wrt_AW(ptr,p->p1,len));
+ case D:
+ case E:
+ case EE:
+ return(wrt_E((ufloat *)ptr,p->p1,p->p2.i[0],p->p2.i[1],len));
+ case G:
+ case GE:
+ return(wrt_G((ufloat *)ptr,p->p1,p->p2.i[0],p->p2.i[1],len));
+ case F: return(wrt_F((ufloat *)ptr,p->p1,p->p2.i[0],len));
+
+ /* Z and ZM assume 8-bit bytes. */
+
+ case Z: return(wrt_Z((Uint *)ptr,p->p1,0,len));
+ case ZM:
+ return(wrt_Z((Uint *)ptr,p->p1,p->p2.i[0],len));
+ }
+}
+#ifdef KR_headers
+w_ned(p) struct syl *p;
+#else
+w_ned(struct syl *p)
+#endif
+{
+ switch(p->op)
+ {
+ default: fprintf(stderr,"w_ned, unexpected code: %d\n", p->op);
+ sig_die(f__fmtbuf, 1);
+ case SLASH:
+ return((*f__donewrec)());
+ case T: f__cursor = p->p1-f__recpos - 1;
+ return(1);
+ case TL: f__cursor -= p->p1;
+ if(f__cursor < -f__recpos) /* TL1000, 1X */
+ f__cursor = -f__recpos;
+ return(1);
+ case TR:
+ case X:
+ f__cursor += p->p1;
+ return(1);
+ case APOS:
+ return(wrt_AP(p->p2.s));
+ case H:
+ return(wrt_H(p->p1,p->p2.s));
+ }
+}
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/wsfe.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/wsfe.c
new file mode 100644
index 0000000..a74e2d5
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/wsfe.c
@@ -0,0 +1,73 @@
+/*write sequential formatted external*/
+#include "f2c.h"
+#include "fio.h"
+#include "fmt.h"
+extern int f__hiwater;
+
+ int
+x_wSL(Void)
+{
+ int n = f__putbuf('\n');
+ f__hiwater = f__recpos = f__cursor = 0;
+ return(n == 0);
+}
+
+ static int
+xw_end(Void)
+{
+ int n;
+
+ if(f__nonl) {
+ f__putbuf(n = 0);
+ fflush(f__cf);
+ }
+ else
+ n = f__putbuf('\n');
+ f__hiwater = f__recpos = f__cursor = 0;
+ return n;
+}
+
+ static int
+xw_rev(Void)
+{
+ int n = 0;
+ if(f__workdone) {
+ n = f__putbuf('\n');
+ f__workdone = 0;
+ }
+ f__hiwater = f__recpos = f__cursor = 0;
+ return n;
+}
+
+#ifdef KR_headers
+integer s_wsfe(a) cilist *a; /*start*/
+#else
+integer s_wsfe(cilist *a) /*start*/
+#endif
+{ int n;
+ if(!f__init) f_init();
+ f__reading=0;
+ f__sequential=1;
+ f__formatted=1;
+ f__external=1;
+ if(n=c_sfe(a)) return(n);
+ f__elist=a;
+ f__hiwater = f__cursor=f__recpos=0;
+ f__nonl = 0;
+ f__scale=0;
+ f__fmtbuf=a->cifmt;
+ f__cf=f__curunit->ufd;
+ if(pars_f(f__fmtbuf)<0) err(a->cierr,100,"startio");
+ f__putn= x_putc;
+ f__doed= w_ed;
+ f__doned= w_ned;
+ f__doend=xw_end;
+ f__dorevert=xw_rev;
+ f__donewrec=x_wSL;
+ fmt_bg();
+ f__cplus=0;
+ f__cblank=f__curunit->ublnk;
+ if(f__curunit->uwrt != 1 && f__nowwriting(f__curunit))
+ err(a->cierr,errno,"write start");
+ return(0);
+}
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/xerbla.c b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/xerbla.c
new file mode 100644
index 0000000..d8ef512
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/clapack/xerbla.c
@@ -0,0 +1,58 @@
+#include "blaswrap.h"
+#include "f2c.h"
+
+/* Subroutine */ int xerbla_(char *srname, integer *info)
+{
+/* -- LAPACK auxiliary routine (preliminary version) --
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
+ Courant Institute, Argonne National Lab, and Rice University
+ February 29, 1992
+
+
+ Purpose
+ =======
+
+ XERBLA is an error handler for the LAPACK routines.
+ It is called by an LAPACK routine if an input parameter has an
+ invalid value. A message is printed and execution stops.
+
+ Installers may consider modifying the STOP statement in order to
+ call system-specific exception-handling facilities.
+
+ Arguments
+ =========
+
+ SRNAME (input) CHARACTER*6
+ The name of the routine which called XERBLA.
+
+ INFO (input) INTEGER
+ The position of the invalid parameter in the parameter list
+ of the calling routine. */
+ /* Table of constant values */
+ static integer c__1 = 1;
+
+ /* Format strings */
+ static char fmt_9999[] = "(\002 ** On entry to \002,a6,\002 parameter nu"
+ "mber \002,i2,\002 had \002,\002an illegal value\002)";
+ /* Builtin functions */
+ integer s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void);
+ /* Subroutine */ int s_stop(char *, ftnlen);
+ /* Fortran I/O blocks */
+ static cilist io___1 = { 0, 6, 0, fmt_9999, 0 };
+
+
+
+
+ s_wsfe(&io___1);
+ do_fio(&c__1, srname, (ftnlen)6);
+ do_fio(&c__1, (char *)&(*info), (ftnlen)sizeof(integer));
+ e_wsfe();
+
+ s_stop("", (ftnlen)0);
+
+
+/* End of XERBLA */
+
+ return 0;
+} /* xerbla_ */
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/imageeffect_sharpen.cpp b/digikam/imageplugins/coreplugin/sharpnesseditor/imageeffect_sharpen.cpp
new file mode 100644
index 0000000..25ef715
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/imageeffect_sharpen.cpp
@@ -0,0 +1,696 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-09
+ * Description : a tool to sharp an image
+ *
+ * Copyright (C) 2004-2007 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.
+ *
+ * ============================================================ */
+
+#define MAX_MATRIX_SIZE 25
+
+// C++ includes.
+
+#include <cmath>
+
+// Qt includes.
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+#include <qcombobox.h>
+#include <qwidgetstack.h>
+
+// KDE includes.
+
+#include <kaboutdata.h>
+#include <knuminput.h>
+#include <kcursor.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kseparator.h>
+#include <kconfig.h>
+#include <kurl.h>
+#include <kfiledialog.h>
+#include <kglobalsettings.h>
+#include <kmessagebox.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "imageiface.h"
+#include "dimgsharpen.h"
+#include "unsharp.h"
+#include "refocus.h"
+#include "imageeffect_sharpen.h"
+#include "imageeffect_sharpen.moc"
+
+namespace DigikamImagesPluginCore
+{
+
+ImageEffect_Sharpen::ImageEffect_Sharpen(QWidget* parent)
+ : Digikam::CtrlPanelDlg(parent, i18n("Sharpening Photograph"), "sharpen",
+ true, true, true)
+{
+ setHelp("blursharpentool.anchor", "digikam");
+
+ // -------------------------------------------------------------
+
+ QWidget *gboxSettings = new QWidget(m_imagePreviewWidget);
+ QGridLayout* gridSettings = new QGridLayout( gboxSettings, 2, 1, 0, spacingHint());
+
+ QLabel *label1 = new QLabel(i18n("Method:"), gboxSettings);
+
+ m_sharpMethod = new QComboBox( false, gboxSettings );
+ m_sharpMethod->insertItem( i18n("Simple sharp") );
+ m_sharpMethod->insertItem( i18n("Unsharp mask") );
+ m_sharpMethod->insertItem( i18n("Refocus") );
+ QWhatsThis::add( m_sharpMethod, i18n("<p>Select the sharpening method to apply to the image."));
+
+ m_stack = new QWidgetStack(gboxSettings);
+
+ gridSettings->addMultiCellWidget(label1, 0, 0, 0, 0);
+ gridSettings->addMultiCellWidget(m_sharpMethod, 0, 0, 1, 1);
+ gridSettings->addMultiCellWidget(new KSeparator(gboxSettings), 1, 1, 0, 1);
+ gridSettings->addMultiCellWidget(m_stack, 2, 2, 0, 1);
+
+ // -------------------------------------------------------------
+
+ QWidget *simpleSharpSettings = new QWidget(m_stack);
+ QGridLayout* grid1 = new QGridLayout( simpleSharpSettings, 2, 1, 0, spacingHint());
+
+ QLabel *label = new QLabel(i18n("Sharpness:"), simpleSharpSettings);
+ m_radiusInput = new KIntNumInput(simpleSharpSettings);
+ m_radiusInput->setRange(0, 100, 1, true);
+ m_radiusInput->setValue(0);
+ QWhatsThis::add( m_radiusInput, i18n("<p>A sharpness of 0 has no effect, "
+ "1 and above determine the sharpen matrix radius "
+ "that determines how much to sharpen the image."));
+
+ grid1->addMultiCellWidget(label, 0, 0, 0, 1);
+ grid1->addMultiCellWidget(m_radiusInput, 1, 1, 0, 1);
+ grid1->setRowStretch(2, 10);
+ m_stack->addWidget(simpleSharpSettings, SimpleSharp);
+
+ // -------------------------------------------------------------
+
+ QWidget *unsharpMaskSettings = new QWidget(m_stack);
+ QGridLayout* grid2 = new QGridLayout( unsharpMaskSettings, 6, 1, 0, spacingHint());
+
+ QLabel *label2 = new QLabel(i18n("Radius:"), unsharpMaskSettings);
+ m_radiusInput2 = new KIntNumInput(unsharpMaskSettings);
+ m_radiusInput2->setRange(1, 120, 1, true);
+ QWhatsThis::add( m_radiusInput2, i18n("<p>Radius value is the gaussian blur matrix radius value "
+ "used to determines how much to blur the image.") );
+
+ QLabel *label3 = new QLabel(i18n("Amount:"), unsharpMaskSettings);
+ m_amountInput = new KDoubleNumInput(unsharpMaskSettings);
+ m_amountInput->setPrecision(1);
+ m_amountInput->setRange(0.0, 5.0, 0.1, true);
+ QWhatsThis::add( m_amountInput, i18n("<p>The value of the difference between the "
+ "original and the blur image that is added back into the original.") );
+
+ QLabel *label4 = new QLabel(i18n("Threshold:"), unsharpMaskSettings);
+ m_thresholdInput = new KDoubleNumInput(unsharpMaskSettings);
+ m_thresholdInput->setPrecision(2);
+ m_thresholdInput->setRange(0.0, 1.0, 0.01, true);
+ QWhatsThis::add( m_thresholdInput, i18n("<p>The threshold, as a fraction of the maximum "
+ "luminosity value, needed to apply the difference amount.") );
+
+ grid2->addMultiCellWidget(label2, 0, 0, 0, 1);
+ grid2->addMultiCellWidget(m_radiusInput2, 1, 1, 0, 1);
+ grid2->addMultiCellWidget(label3, 2, 2, 0, 1);
+ grid2->addMultiCellWidget(m_amountInput, 3, 3, 0, 1);
+ grid2->addMultiCellWidget(label4, 4, 4, 0, 1);
+ grid2->addMultiCellWidget(m_thresholdInput, 5, 5, 0, 1);
+ grid2->setRowStretch(6, 10);
+ m_stack->addWidget(unsharpMaskSettings, UnsharpMask);
+
+ // -------------------------------------------------------------
+
+ QWidget *refocusSettings = new QWidget(m_stack);
+ QGridLayout* grid3 = new QGridLayout(refocusSettings, 10, 1, 0, spacingHint());
+
+ QLabel *label5 = new QLabel(i18n("Circular sharpness:"), refocusSettings);
+ m_radius = new KDoubleNumInput(refocusSettings);
+ m_radius->setPrecision(2);
+ m_radius->setRange(0.0, 5.0, 0.01, true);
+ QWhatsThis::add( m_radius, i18n("<p>This is the radius of the circular convolution. It is the most important "
+ "parameter for using this plugin. For most images the default value of 1.0 "
+ "should give good results. Select a higher value when your image is very blurred."));
+
+ QLabel *label6 = new QLabel(i18n("Correlation:"), refocusSettings);
+ m_correlation = new KDoubleNumInput(refocusSettings);
+ m_correlation->setPrecision(2);
+ m_correlation->setRange(0.0, 1.0, 0.01, true);
+ QWhatsThis::add( m_correlation, i18n("<p>Increasing the correlation may help to reduce artifacts. The correlation can "
+ "range from 0-1. Useful values are 0.5 and values close to 1, e.g. 0.95 and 0.99. "
+ "Using a high value for the correlation will reduce the sharpening effect of the "
+ "plugin."));
+
+ QLabel *label7 = new QLabel(i18n("Noise filter:"), refocusSettings);
+ m_noise = new KDoubleNumInput(refocusSettings);
+ m_noise->setPrecision(3);
+ m_noise->setRange(0.0, 1.0, 0.001, true);
+ QWhatsThis::add( m_noise, i18n("<p>Increasing the noise filter parameter may help to reduce artifacts. The noise filter "
+ "can range from 0-1 but values higher than 0.1 are rarely helpful. When the noise filter "
+ "value is too low, e.g. 0.0 the image quality will be very poor. A useful value is 0.01. "
+ "Using a high value for the noise filter will reduce the sharpening "
+ "effect of the plugin."));
+
+ QLabel *label8 = new QLabel(i18n("Gaussian sharpness:"), refocusSettings);
+ m_gauss = new KDoubleNumInput(refocusSettings);
+ m_gauss->setPrecision(2);
+ m_gauss->setRange(0.0, 1.0, 0.01, true);
+ QWhatsThis::add( m_gauss, i18n("<p>This is the sharpness for the gaussian convolution. Use this parameter when your "
+ "blurring is of a Gaussian type. In most cases you should set this parameter to 0, because "
+ "it causes nasty artifacts. When you use non-zero values, you will probably have to "
+ "increase the correlation and/or noise filter parameters too."));
+
+ QLabel *label9 = new QLabel(i18n("Matrix size:"), refocusSettings);
+ m_matrixSize = new KIntNumInput(refocusSettings);
+ m_matrixSize->setRange(0, MAX_MATRIX_SIZE, 1, true);
+ QWhatsThis::add( m_matrixSize, i18n("<p>This parameter determines the size of the transformation matrix. "
+ "Increasing the matrix width may give better results, especially when you have "
+ "chosen large values for circular or gaussian sharpness."));
+
+ grid3->addMultiCellWidget(label5, 0, 0, 0, 1);
+ grid3->addMultiCellWidget(m_radius, 1, 1, 0, 1);
+ grid3->addMultiCellWidget(label6, 2, 2, 0, 1);
+ grid3->addMultiCellWidget(m_correlation, 3, 3, 0, 1);
+ grid3->addMultiCellWidget(label7, 4, 4, 0, 1);
+ grid3->addMultiCellWidget(m_noise, 5, 5, 0, 1);
+ grid3->addMultiCellWidget(label8, 6, 6, 0, 1);
+ grid3->addMultiCellWidget(m_gauss, 7, 7, 0, 1);
+ grid3->addMultiCellWidget(label9, 8, 8, 0, 1);
+ grid3->addMultiCellWidget(m_matrixSize, 9, 9, 0, 1);
+ grid3->setRowStretch(10, 10);
+ m_stack->addWidget(refocusSettings, Refocus);
+
+ m_imagePreviewWidget->setUserAreaWidget(gboxSettings);
+
+ // -------------------------------------------------------------
+
+ connect(m_sharpMethod, SIGNAL(activated(int)),
+ this, SLOT(slotSharpMethodActived(int)));
+
+ // -------------------------------------------------------------
+
+ // Image creation with dummy borders (mosaic mode) used by Refocus method. It needs to do
+ // it before to apply deconvolution filter on original image border pixels including
+ // on matrix size area. This way limit artifacts on image border.
+
+ Digikam::ImageIface iface(0, 0);
+
+ uchar* data = iface.getOriginalImage();
+ int w = iface.originalWidth();
+ int h = iface.originalHeight();
+ bool sb = iface.originalSixteenBit();
+ bool a = iface.originalHasAlpha();
+
+ m_img = Digikam::DImg( w + 4*MAX_MATRIX_SIZE, h + 4*MAX_MATRIX_SIZE, sb, a);
+
+ Digikam::DImg tmp;
+ Digikam::DImg org(w, h, sb, a, data);
+
+ // Copy original.
+ m_img.bitBltImage(&org, 2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+
+ // Create dummy top border
+ tmp = org.copy(0, 0, w, 2*MAX_MATRIX_SIZE);
+ tmp.flip(Digikam::DImg::VERTICAL);
+ m_img.bitBltImage(&tmp, 2*MAX_MATRIX_SIZE, 0);
+
+ // Create dummy bottom border
+ tmp = org.copy(0, h-2*MAX_MATRIX_SIZE, w, 2*MAX_MATRIX_SIZE);
+ tmp.flip(Digikam::DImg::VERTICAL);
+ m_img.bitBltImage(&tmp, 2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE+h);
+
+ // Create dummy left border
+ tmp = org.copy(0, 0, 2*MAX_MATRIX_SIZE, h);
+ tmp.flip(Digikam::DImg::HORIZONTAL);
+ m_img.bitBltImage(&tmp, 0, 2*MAX_MATRIX_SIZE);
+
+ // Create dummy right border
+ tmp = org.copy(w-2*MAX_MATRIX_SIZE, 0, 2*MAX_MATRIX_SIZE, h);
+ tmp.flip(Digikam::DImg::HORIZONTAL);
+ m_img.bitBltImage(&tmp, w+2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+
+ // Create dummy top/left corner
+ tmp = org.copy(0, 0, 2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+ tmp.flip(Digikam::DImg::HORIZONTAL);
+ tmp.flip(Digikam::DImg::VERTICAL);
+ m_img.bitBltImage(&tmp, 0, 0);
+
+ // Create dummy top/right corner
+ tmp = org.copy(w-2*MAX_MATRIX_SIZE, 0, 2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+ tmp.flip(Digikam::DImg::HORIZONTAL);
+ tmp.flip(Digikam::DImg::VERTICAL);
+ m_img.bitBltImage(&tmp, w+2*MAX_MATRIX_SIZE, 0);
+
+ // Create dummy bottom/left corner
+ tmp = org.copy(0, h-2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+ tmp.flip(Digikam::DImg::HORIZONTAL);
+ tmp.flip(Digikam::DImg::VERTICAL);
+ m_img.bitBltImage(&tmp, 0, h+2*MAX_MATRIX_SIZE);
+
+ // Create dummy bottom/right corner
+ tmp = org.copy(w-2*MAX_MATRIX_SIZE, h-2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+ tmp.flip(Digikam::DImg::HORIZONTAL);
+ tmp.flip(Digikam::DImg::VERTICAL);
+ m_img.bitBltImage(&tmp, w+2*MAX_MATRIX_SIZE, h+2*MAX_MATRIX_SIZE);
+
+ delete [] data;
+}
+
+ImageEffect_Sharpen::~ImageEffect_Sharpen()
+{
+}
+
+void ImageEffect_Sharpen::renderingFinished(void)
+{
+ switch (m_stack->id(m_stack->visibleWidget()))
+ {
+ case SimpleSharp:
+ {
+ m_radiusInput->setEnabled(true);
+ enableButton(User2, false);
+ enableButton(User3, false);
+ break;
+ }
+
+ case UnsharpMask:
+ {
+ m_radiusInput2->setEnabled(true);
+ m_amountInput->setEnabled(true);
+ m_thresholdInput->setEnabled(true);
+ enableButton(User2, false);
+ enableButton(User3, false);
+ break;
+ }
+
+ case Refocus:
+ {
+ m_matrixSize->setEnabled(true);
+ m_radius->setEnabled(true);
+ m_gauss->setEnabled(true);
+ m_correlation->setEnabled(true);
+ m_noise->setEnabled(true);
+ break;
+ }
+ }
+}
+
+void ImageEffect_Sharpen::slotSharpMethodActived(int w)
+{
+ m_stack->raiseWidget(w);
+ if (w == Refocus)
+ {
+ enableButton(User2, true);
+ enableButton(User3, true);
+ }
+ else
+ {
+ enableButton(User2, false);
+ enableButton(User3, false);
+ }
+}
+
+void ImageEffect_Sharpen::readUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("sharpen Tool Dialog");
+ m_radiusInput->blockSignals(true);
+ m_radiusInput2->blockSignals(true);
+ m_amountInput->blockSignals(true);
+ m_thresholdInput->blockSignals(true);
+ m_matrixSize->blockSignals(true);
+ m_radius->blockSignals(true);
+ m_gauss->blockSignals(true);
+ m_correlation->blockSignals(true);
+ m_noise->blockSignals(true);
+ m_sharpMethod->blockSignals(true);
+ m_radiusInput->setValue(config->readNumEntry("SimpleSharpRadiusAjustment", 0));
+ m_radiusInput2->setValue(config->readNumEntry("UnsharpMaskRadiusAjustment", 1));
+ m_amountInput->setValue(config->readDoubleNumEntry("UnsharpMaskAmountAjustment", 1.0));
+ m_thresholdInput->setValue(config->readDoubleNumEntry("UnsharpMaskThresholdAjustment", 0.05));
+ m_matrixSize->setValue(config->readNumEntry("RefocusMatrixSize", 5));
+ m_radius->setValue(config->readDoubleNumEntry("RefocusRadiusAjustment", 1.0));
+ m_gauss->setValue(config->readDoubleNumEntry("RefocusGaussAjustment", 0.0));
+ m_correlation->setValue(config->readDoubleNumEntry("RefocusCorrelationAjustment", 0.5));
+ m_noise->setValue(config->readDoubleNumEntry("RefocusNoiseAjustment", 0.03));
+ m_sharpMethod->setCurrentItem(config->readNumEntry("SharpenMethod", SimpleSharp));
+ m_radiusInput->blockSignals(false);
+ m_radiusInput2->blockSignals(false);
+ m_amountInput->blockSignals(false);
+ m_thresholdInput->blockSignals(false);
+ m_matrixSize->blockSignals(false);
+ m_radius->blockSignals(false);
+ m_gauss->blockSignals(false);
+ m_correlation->blockSignals(false);
+ m_noise->blockSignals(false);
+ m_sharpMethod->blockSignals(false);
+ slotSharpMethodActived(m_sharpMethod->currentItem());
+}
+
+void ImageEffect_Sharpen::writeUserSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("sharpen Tool Dialog");
+ config->writeEntry("SimpleSharpRadiusAjustment", m_radiusInput->value());
+ config->writeEntry("UnsharpMaskRadiusAjustment", m_radiusInput2->value());
+ config->writeEntry("UnsharpMaskAmountAjustment", m_amountInput->value());
+ config->writeEntry("UnsharpMaskThresholdAjustment", m_thresholdInput->value());
+ config->writeEntry("RefocusMatrixSize", m_matrixSize->value());
+ config->writeEntry("RefocusRadiusAjustment", m_radius->value());
+ config->writeEntry("RefocusGaussAjustment", m_gauss->value());
+ config->writeEntry("RefocusCorrelationAjustment", m_correlation->value());
+ config->writeEntry("RefocusNoiseAjustment", m_noise->value());
+ config->writeEntry("SharpenMethod", m_sharpMethod->currentItem());
+ config->sync();
+}
+
+void ImageEffect_Sharpen::resetValues(void)
+{
+ switch (m_stack->id(m_stack->visibleWidget()))
+ {
+ case SimpleSharp:
+ {
+ m_radiusInput->blockSignals(true);
+ m_radiusInput->setValue(0);
+ m_radiusInput->blockSignals(false);
+ break;
+ }
+
+ case UnsharpMask:
+ {
+ m_radiusInput2->blockSignals(true);
+ m_amountInput->blockSignals(true);
+ m_thresholdInput->blockSignals(true);
+ m_radiusInput2->setValue(1);
+ m_amountInput->setValue(1.0);
+ m_thresholdInput->setValue(0.05);
+ m_radiusInput2->blockSignals(false);
+ m_amountInput->blockSignals(false);
+ m_thresholdInput->blockSignals(false);
+ break;
+ }
+
+ case Refocus:
+ {
+ m_matrixSize->blockSignals(true);
+ m_radius->blockSignals(true);
+ m_gauss->blockSignals(true);
+ m_correlation->blockSignals(true);
+ m_noise->blockSignals(true);
+ m_matrixSize->setValue(5);
+ m_radius->setValue(1.0);
+ m_gauss->setValue(0.0);
+ m_correlation->setValue(0.5);
+ m_noise->setValue(0.03);
+ m_matrixSize->blockSignals(false);
+ m_radius->blockSignals(false);
+ m_gauss->blockSignals(false);
+ m_correlation->blockSignals(false);
+ m_noise->blockSignals(false);
+ break;
+ }
+ }
+}
+
+void ImageEffect_Sharpen::prepareEffect()
+{
+ switch (m_stack->id(m_stack->visibleWidget()))
+ {
+ case SimpleSharp:
+ {
+ m_radiusInput->setEnabled(false);
+
+ Digikam::DImg img = m_imagePreviewWidget->getOriginalRegionImage();
+
+ double radius = m_radiusInput->value()/10.0;
+ double sigma;
+
+ if (radius < 1.0) sigma = radius;
+ else sigma = sqrt(radius);
+
+ m_threadedFilter = dynamic_cast<Digikam::DImgThreadedFilter *>
+ (new Digikam::DImgSharpen(&img, this, radius, sigma ));
+ break;
+ }
+
+ case UnsharpMask:
+ {
+ m_radiusInput2->setEnabled(false);
+ m_amountInput->setEnabled(false);
+ m_thresholdInput->setEnabled(false);
+
+ Digikam::DImg img = m_imagePreviewWidget->getOriginalRegionImage();
+
+ int r = m_radiusInput2->value();
+ double a = m_amountInput->value();
+ double th = m_thresholdInput->value();
+
+ m_threadedFilter = dynamic_cast<Digikam::DImgThreadedFilter *>
+ (new DigikamImagesPluginCore::UnsharpMask(&img, this, r, a, th));
+ break;
+ }
+
+ case Refocus:
+ {
+ m_matrixSize->setEnabled(false);
+ m_radius->setEnabled(false);
+ m_gauss->setEnabled(false);
+ m_correlation->setEnabled(false);
+ m_noise->setEnabled(false);
+
+ int ms = m_matrixSize->value();
+ double r = m_radius->value();
+ double g = m_gauss->value();
+ double c = m_correlation->value();
+ double n = m_noise->value();
+
+ QRect area = m_imagePreviewWidget->getOriginalImageRegionToRender();
+ QRect tmpRect;
+ tmpRect.setLeft(area.left()-2*ms);
+ tmpRect.setRight(area.right()+2*ms);
+ tmpRect.setTop(area.top()-2*ms);
+ tmpRect.setBottom(area.bottom()+2*ms);
+ tmpRect.moveBy(2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+ Digikam::DImg imTemp = m_img.copy(tmpRect);
+
+ m_threadedFilter = dynamic_cast<Digikam::DImgThreadedFilter *>
+ (new DigikamImagesPluginCore::Refocus(&imTemp, this, ms, r, g, c, n));
+ break;
+ }
+ }
+}
+
+void ImageEffect_Sharpen::prepareFinal()
+{
+ switch (m_stack->id(m_stack->visibleWidget()))
+ {
+ case SimpleSharp:
+ {
+ m_radiusInput->setEnabled(false);
+
+ double radius = m_radiusInput->value()/10.0;
+ double sigma;
+
+ if (radius < 1.0) sigma = radius;
+ else sigma = sqrt(radius);
+
+ Digikam::ImageIface iface(0, 0);
+ uchar *data = iface.getOriginalImage();
+ int w = iface.originalWidth();
+ int h = iface.originalHeight();
+ bool sixteenBit = iface.originalSixteenBit();
+ bool hasAlpha = iface.originalHasAlpha();
+ Digikam::DImg orgImage = Digikam::DImg(w, h, sixteenBit, hasAlpha ,data);
+ delete [] data;
+ m_threadedFilter = dynamic_cast<Digikam::DImgThreadedFilter *>
+ (new Digikam::DImgSharpen(&orgImage, this, radius, sigma ));
+ break;
+ }
+
+ case UnsharpMask:
+ {
+ m_radiusInput2->setEnabled(false);
+ m_amountInput->setEnabled(false);
+ m_thresholdInput->setEnabled(false);
+
+ int r = m_radiusInput2->value();
+ double a = m_amountInput->value();
+ double th = m_thresholdInput->value();
+
+ Digikam::ImageIface iface(0, 0);
+ uchar *data = iface.getOriginalImage();
+ int w = iface.originalWidth();
+ int h = iface.originalHeight();
+ bool sixteenBit = iface.originalSixteenBit();
+ bool hasAlpha = iface.originalHasAlpha();
+ Digikam::DImg orgImage = Digikam::DImg(w, h, sixteenBit, hasAlpha ,data);
+ delete [] data;
+ m_threadedFilter = dynamic_cast<Digikam::DImgThreadedFilter *>
+ (new DigikamImagesPluginCore::UnsharpMask(&orgImage, this, r, a, th));
+ break;
+ }
+
+ case Refocus:
+ {
+
+ m_matrixSize->setEnabled(false);
+ m_radius->setEnabled(false);
+ m_gauss->setEnabled(false);
+ m_correlation->setEnabled(false);
+ m_noise->setEnabled(false);
+
+ int ms = m_matrixSize->value();
+ double r = m_radius->value();
+ double g = m_gauss->value();
+ double c = m_correlation->value();
+ double n = m_noise->value();
+
+ m_threadedFilter = dynamic_cast<Digikam::DImgThreadedFilter *>
+ (new DigikamImagesPluginCore::Refocus(&m_img, this, ms, r, g, c, n));
+ break;
+ }
+ }
+}
+
+void ImageEffect_Sharpen::putPreviewData(void)
+{
+ switch (m_stack->id(m_stack->visibleWidget()))
+ {
+ case SimpleSharp:
+ case UnsharpMask:
+ {
+ Digikam::DImg imDest = m_threadedFilter->getTargetImage();
+ m_imagePreviewWidget->setPreviewImage(imDest);
+ break;
+ }
+
+ case Refocus:
+ {
+ int ms = m_matrixSize->value();
+ QRect area = m_imagePreviewWidget->getOriginalImageRegionToRender();
+
+ Digikam::DImg imDest = m_threadedFilter->getTargetImage()
+ .copy(2*ms, 2*ms, area.width(), area.height());
+ m_imagePreviewWidget->setPreviewImage(imDest);
+ break;
+ }
+ }
+}
+
+void ImageEffect_Sharpen::putFinalData(void)
+{
+ Digikam::ImageIface iface(0, 0);
+ Digikam::DImg imDest = m_threadedFilter->getTargetImage();
+
+ switch (m_stack->id(m_stack->visibleWidget()))
+ {
+ case SimpleSharp:
+ {
+ iface.putOriginalImage(i18n("Sharpen"), imDest.bits());
+ break;
+ }
+
+ case UnsharpMask:
+ {
+ iface.putOriginalImage(i18n("Unsharp Mask"), imDest.bits());
+ break;
+ }
+
+ case Refocus:
+ {
+ QRect area = m_imagePreviewWidget->getOriginalImageRegionToRender();
+ Digikam::ImageIface iface(0, 0);
+
+ iface.putOriginalImage(i18n("Refocus"), m_threadedFilter->getTargetImage()
+ .copy(2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE,
+ iface.originalWidth(),
+ iface.originalHeight())
+ .bits());
+ break;
+ }
+ }
+}
+
+void ImageEffect_Sharpen::slotUser3()
+{
+ KURL loadRestorationFile = KFileDialog::getOpenURL(KGlobalSettings::documentPath(),
+ QString( "*" ), this,
+ QString( i18n("Photograph Refocus Settings File to Load")) );
+ if ( loadRestorationFile.isEmpty() )
+ return;
+
+ QFile file(loadRestorationFile.path());
+
+ if ( file.open(IO_ReadOnly) )
+ {
+ QTextStream stream( &file );
+ if ( stream.readLine() != "# Photograph Refocus Configuration File" )
+ {
+ KMessageBox::error(this,
+ i18n("\"%1\" is not a Photograph Refocus settings text file.")
+ .arg(loadRestorationFile.fileName()));
+ file.close();
+ return;
+ }
+
+ blockSignals(true);
+ m_matrixSize->setValue( stream.readLine().toInt() );
+ m_radius->setValue( stream.readLine().toDouble() );
+ m_gauss->setValue( stream.readLine().toDouble() );
+ m_correlation->setValue( stream.readLine().toDouble() );
+ m_noise->setValue( stream.readLine().toDouble() );
+ blockSignals(false);
+ }
+ else
+ KMessageBox::error(this, i18n("Cannot load settings from the Photograph Refocus text file."));
+
+ file.close();
+}
+
+void ImageEffect_Sharpen::slotUser2()
+{
+ KURL saveRestorationFile = KFileDialog::getSaveURL(KGlobalSettings::documentPath(),
+ QString( "*" ), this,
+ QString( i18n("Photograph Refocus Settings File to Save")) );
+ if ( saveRestorationFile.isEmpty() )
+ return;
+
+ QFile file(saveRestorationFile.path());
+
+ if ( file.open(IO_WriteOnly) )
+ {
+ QTextStream stream( &file );
+ stream << "# Photograph Refocus Configuration File\n";
+ stream << m_matrixSize->value() << "\n";
+ stream << m_radius->value() << "\n";
+ stream << m_gauss->value() << "\n";
+ stream << m_correlation->value() << "\n";
+ stream << m_noise->value() << "\n";
+ }
+ else
+ KMessageBox::error(this, i18n("Cannot save settings to the Photograph Refocus text file."));
+
+ file.close();
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/imageeffect_sharpen.h b/digikam/imageplugins/coreplugin/sharpnesseditor/imageeffect_sharpen.h
new file mode 100644
index 0000000..0bec84d
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/imageeffect_sharpen.h
@@ -0,0 +1,101 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-09
+ * Description : a tool to sharp an image
+ *
+ * Copyright (C) 2004-2007 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 IMAGEEFFECT_SHARPEN_H
+#define IMAGEEFFECT_SHARPEN_H
+
+// Digikam include.
+
+#include "ctrlpaneldlg.h"
+
+class QComboBox;
+class QWidgetStack;
+
+class KIntNumInput;
+class KDoubleNumInput;
+
+namespace Digikam
+{
+ class DImg;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class ImageEffect_Sharpen : public Digikam::CtrlPanelDlg
+{
+ Q_OBJECT
+
+public:
+
+ ImageEffect_Sharpen(QWidget *parent);
+ ~ImageEffect_Sharpen();
+
+private slots:
+
+ void slotUser2();
+ void slotUser3();
+ void readUserSettings();
+ void slotSharpMethodActived(int);
+
+private:
+
+ void writeUserSettings();
+ void resetValues();
+ void prepareEffect();
+ void prepareFinal();
+ void abortPreview();
+ void putPreviewData();
+ void putFinalData();
+ void renderingFinished();
+
+private:
+
+ enum SharpingMethods
+ {
+ SimpleSharp=0,
+ UnsharpMask,
+ Refocus
+ };
+
+ QWidgetStack *m_stack;
+
+ QComboBox *m_sharpMethod;
+
+ KIntNumInput *m_matrixSize;
+ KIntNumInput *m_radiusInput;
+ KIntNumInput *m_radiusInput2;
+
+ KDoubleNumInput *m_radius;
+ KDoubleNumInput *m_gauss;
+ KDoubleNumInput *m_correlation;
+ KDoubleNumInput *m_noise;
+ KDoubleNumInput *m_amountInput;
+ KDoubleNumInput *m_thresholdInput;
+
+ Digikam::DImg m_img;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* IMAGEEFFECT_SHARPEN_H */
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/matrix.cpp b/digikam/imageplugins/coreplugin/sharpnesseditor/matrix.cpp
new file mode 100644
index 0000000..016b012
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/matrix.cpp
@@ -0,0 +1,663 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-04-29
+ * Description : refocus deconvolution matrix implementation.
+ *
+ * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * Original implementation from Refocus Gimp plug-in
+ * Copyright (C) 1999-2003 Ernst Lippe
+ *
+ * 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.
+ *
+ * ============================================================ */
+
+// Uncomment this line to debug matrix computation.
+//#define RF_DEBUG 1
+
+// Square
+#define SQR(x) ((x) * (x))
+
+extern "C"
+{
+#include "f2c.h"
+#include "clapack.h"
+}
+
+// C++ includes.
+
+#include <cmath>
+
+// Qt includes.
+
+#include <qglobal.h>
+#include <qstring.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "matrix.h"
+
+namespace DigikamImagesPluginCore
+{
+
+Mat *RefocusMatrix::allocate_matrix (int nrows, int ncols)
+{
+ Mat *result = new Mat;
+ memset (result, 0, sizeof(result));
+
+ result->cols = ncols;
+ result->rows = nrows;
+ result->data = new double [nrows * ncols];
+ memset (result->data, 0, nrows * ncols * sizeof(double));
+
+ return (result);
+}
+
+void RefocusMatrix::finish_matrix (Mat * mat)
+{
+ delete [] mat->data;
+}
+
+void RefocusMatrix::finish_and_free_matrix (Mat * mat)
+{
+ delete [] mat->data;
+ delete mat;
+}
+
+double *RefocusMatrix::mat_eltptr (Mat * mat, const int r, const int c)
+{
+ Q_ASSERT ((r >= 0) && (r < mat->rows));
+ Q_ASSERT ((c >= 0) && (c < mat->rows));
+ return (&(mat->data[mat->rows * c + r]));
+}
+
+double RefocusMatrix::mat_elt (const Mat * mat, const int r, const int c)
+{
+ Q_ASSERT ((r >= 0) && (r < mat->rows));
+ Q_ASSERT ((c >= 0) && (c < mat->rows));
+ return (mat->data[mat->rows * c + r]);
+}
+
+void RefocusMatrix::init_c_mat (CMat * mat, const int radius)
+{
+ mat->radius = radius;
+ mat->row_stride = 2 * radius + 1;
+ mat->data = new double [SQR (mat->row_stride)];
+ memset (mat->data, 0, SQR (mat->row_stride) * sizeof(double));
+ mat->center = mat->data + mat->row_stride * mat->radius + mat->radius;
+}
+
+CMat *RefocusMatrix::allocate_c_mat (const int radius)
+{
+ CMat *result = new CMat;
+ memset(result, 0, sizeof(result));
+ init_c_mat (result, radius);
+ return (result);
+}
+
+void RefocusMatrix::finish_c_mat (CMat * mat)
+{
+ delete [] mat->data;
+ mat->data = NULL;
+}
+
+inline double *RefocusMatrix::c_mat_eltptr (CMat * mat, const int col, const int row)
+{
+ Q_ASSERT ((QABS (row) <= mat->radius) && (QABS (col) <= mat->radius));
+ return (mat->center + mat->row_stride * row + col);
+}
+
+inline double RefocusMatrix::c_mat_elt (const CMat * const mat, const int col, const int row)
+{
+ Q_ASSERT ((QABS (row) <= mat->radius) && (QABS (col) <= mat->radius));
+ return (mat->center[mat->row_stride * row + col]);
+}
+
+void RefocusMatrix::convolve_mat (CMat * result, const CMat * const mata, const CMat * const matb)
+{
+ register int xr, yr, xa, ya;
+
+ for (yr = -result->radius; yr <= result->radius; yr++)
+ {
+ for (xr = -result->radius; xr <= result->radius; xr++)
+ {
+ const int ya_low = QMAX (-mata->radius, yr - matb->radius);
+ const int ya_high = QMIN (mata->radius, yr + matb->radius);
+ const int xa_low = QMAX (-mata->radius, xr - matb->radius);
+ const int xa_high = QMIN (mata->radius, xr + matb->radius);
+ register double val = 0.0;
+
+ for (ya = ya_low; ya <= ya_high; ya++)
+ {
+ for (xa = xa_low; xa <= xa_high; xa++)
+ {
+ val += c_mat_elt (mata, xa, ya) *
+ c_mat_elt (matb, xr - xa, yr - ya);
+ }
+ }
+
+ *c_mat_eltptr (result, xr, yr) = val;
+ }
+ }
+}
+
+void RefocusMatrix::convolve_star_mat (CMat * result, const CMat * const mata, const CMat * const matb)
+{
+ register int xr, yr, xa, ya;
+
+ for (yr = -result->radius; yr <= result->radius; yr++)
+ {
+ for (xr = -result->radius; xr <= result->radius; xr++)
+ {
+ const int ya_low = QMAX (-mata->radius, -matb->radius - yr);
+ const int ya_high = QMIN (mata->radius, matb->radius - yr);
+ const int xa_low = QMAX (-mata->radius, -matb->radius - xr);
+ const int xa_high = QMIN (mata->radius, matb->radius - xr);
+ register double val = 0.0;
+
+ for (ya = ya_low; ya <= ya_high; ya++)
+ {
+ for (xa = xa_low; xa <= xa_high; xa++)
+ {
+ val += c_mat_elt (mata, xa, ya) *
+ c_mat_elt (matb, xr + xa, yr + ya);
+ }
+ }
+
+ *c_mat_eltptr (result, xr, yr) = val;
+ }
+ }
+}
+
+void RefocusMatrix::convolve_mat_fun (CMat * result, const CMat * const mata, double (f) (int, int))
+{
+ register int xr, yr, xa, ya;
+
+ for (yr = -result->radius; yr <= result->radius; yr++)
+ {
+ for (xr = -result->radius; xr <= result->radius; xr++)
+ {
+ register double val = 0.0;
+
+ for (ya = -mata->radius; ya <= mata->radius; ya++)
+ {
+ for (xa = -mata->radius; xa <= mata->radius; xa++)
+ {
+ val += c_mat_elt (mata, xa, ya) * f (xr - xa, yr - ya);
+ }
+ }
+
+ *c_mat_eltptr (result, xr, yr) = val;
+ }
+ }
+}
+
+int RefocusMatrix::as_idx (const int k, const int l, const int m)
+{
+ return ((k + m) * (2 * m + 1) + (l + m));
+}
+
+int RefocusMatrix::as_cidx (const int k, const int l)
+{
+ const int a = QMAX (QABS (k), QABS (l));
+ const int b = QMIN (QABS (k), QABS (l));
+ return ((a * (a + 1)) / 2 + b);
+}
+
+void RefocusMatrix::print_c_mat (const CMat * const mat)
+{
+ register int x, y;
+
+ for (y = -mat->radius; y <= mat->radius; y++)
+ {
+ QString output, num;
+
+ for (x = -mat->radius; x <= mat->radius; x++)
+ {
+ output.append( num.setNum( c_mat_elt (mat, x, y) ) );
+ }
+
+ DDebug() << output << endl;
+ }
+}
+
+void RefocusMatrix::print_matrix (Mat * matrix)
+{
+ int col_idx, row_idx;
+
+ for (row_idx = 0; row_idx < matrix->rows; row_idx++)
+ {
+ QString output, num;
+
+ for (col_idx = 0; col_idx < matrix->cols; col_idx++)
+ {
+ output.append( num.setNum( mat_elt (matrix, row_idx, col_idx) ) );
+ }
+
+ DDebug() << output << endl;
+ }
+}
+
+Mat *RefocusMatrix::make_s_matrix (CMat * mat, int m, double noise_factor)
+{
+ const int mat_size = SQR (2 * m + 1);
+ Mat *result = allocate_matrix (mat_size, mat_size);
+ register int yr, yc, xr, xc;
+
+ for (yr = -m; yr <= m; yr++)
+ {
+ for (xr = -m; xr <= m; xr++)
+ {
+ for (yc = -m; yc <= m; yc++)
+ {
+ for (xc = -m; xc <= m; xc++)
+ {
+ *mat_eltptr (result, as_idx (xr, yr, m),
+ as_idx (xc, yc, m)) =
+ c_mat_elt (mat, xr - xc, yr - yc);
+ if ((xr == xc) && (yr == yc))
+ {
+ *mat_eltptr (result, as_idx (xr, yr, m),
+ as_idx (xc, yc, m)) += noise_factor;
+ }
+ }
+ }
+ }
+ }
+
+ return (result);
+}
+
+Mat *RefocusMatrix::make_s_cmatrix (CMat * mat, int m, double noise_factor)
+{
+ const int mat_size = as_cidx (m + 1, 0);
+ Mat *result = allocate_matrix (mat_size, mat_size);
+ register int yr, yc, xr, xc;
+
+ for (yr = 0; yr <= m; yr++)
+ {
+ for (xr = 0; xr <= yr; xr++)
+ {
+ for (yc = -m; yc <= m; yc++)
+ {
+ for (xc = -m; xc <= m; xc++)
+ {
+ *mat_eltptr (result, as_cidx (xr, yr), as_cidx (xc, yc)) +=
+ c_mat_elt (mat, xr - xc, yr - yc);
+ if ((xr == xc) && (yr == yc))
+ {
+ *mat_eltptr (result, as_cidx (xr, yr),
+ as_cidx (xc, yc)) += noise_factor;
+ }
+ }
+ }
+ }
+ }
+
+ return (result);
+}
+
+double RefocusMatrix::correlation (const int x, const int y, const double gamma, const double musq)
+{
+ return (musq + pow (gamma, sqrt (SQR (x) + SQR (y))));
+}
+
+Mat *RefocusMatrix::copy_vec (const CMat * const mat, const int m)
+{
+ Mat *result = allocate_matrix (SQR (2 * m + 1), 1);
+ register int x, y, index = 0;
+
+ for (y = -m; y <= m; y++)
+ {
+ for (x = -m; x <= m; x++)
+ {
+ *mat_eltptr (result, index, 0) = c_mat_elt (mat, x, y);
+ index++;
+ }
+ }
+
+ Q_ASSERT (index == SQR (2 * m + 1));
+ return (result);
+}
+
+Mat *RefocusMatrix::copy_cvec (const CMat * const mat, const int m)
+{
+ Mat *result = allocate_matrix (as_cidx (m + 1, 0), 1);
+ register int x, y, index = 0;
+
+ for (y = 0; y <= m; y++)
+ {
+ for (x = 0; x <= y; x++)
+ {
+ *mat_eltptr (result, index, 0) = c_mat_elt (mat, x, y);
+ index++;
+ }
+ }
+
+ Q_ASSERT (index == as_cidx (m + 1, 0));
+ return (result);
+}
+
+CMat *RefocusMatrix::copy_cvec2mat (const Mat * const cvec, const int m)
+{
+ CMat *result = allocate_c_mat (m);
+ register int x, y;
+
+ for (y = -m; y <= m; y++)
+ {
+ for (x = -m; x <= m; x++)
+ {
+ *c_mat_eltptr (result, x, y) = mat_elt (cvec, as_cidx (x, y), 0);
+ }
+ }
+
+ return (result);
+}
+
+CMat *RefocusMatrix::copy_vec2mat (const Mat * const cvec, const int m)
+{
+ CMat *result = allocate_c_mat (m);
+ register int x, y;
+
+ for (y = -m; y <= m; y++)
+ {
+ for (x = -m; x <= m; x++)
+ {
+ *c_mat_eltptr (result, x, y) = mat_elt (cvec, as_idx (x, y, m), 0);
+ }
+ }
+
+ return (result);
+}
+
+CMat *RefocusMatrix::compute_g (const CMat * const convolution, const int m, const double gamma,
+ const double noise_factor, const double musq, const bool symmetric)
+{
+ CMat h_conv_ruv, a, corr;
+ CMat *result;
+ Mat *b;
+ Mat *s;
+ int status;
+
+ init_c_mat (&h_conv_ruv, 3 * m);
+ fill_matrix2 (&corr, 4 * m, correlation, gamma, musq);
+ convolve_mat (&h_conv_ruv, convolution, &corr);
+ init_c_mat (&a, 2 * m);
+ convolve_star_mat (&a, convolution, &h_conv_ruv);
+
+ if (symmetric)
+ {
+ s = make_s_cmatrix (&a, m, noise_factor);
+ b = copy_cvec (&h_conv_ruv, m);
+ }
+ else
+ {
+ s = make_s_matrix (&a, m, noise_factor);
+ b = copy_vec (&h_conv_ruv, m);
+ }
+
+#ifdef RF_DEBUG
+ DDebug() << "Convolution:" << endl;
+ print_c_mat (convolution);
+ DDebug() << "h_conv_ruv:" << endl;
+ print_c_mat (&h_conv_ruv);
+ DDebug() << "Value of s:" << endl;
+ print_matrix (s);
+#endif
+
+ Q_ASSERT (s->cols == s->rows);
+ Q_ASSERT (s->rows == b->rows);
+ status = dgesv (s->rows, 1, s->data, s->rows, b->data, b->rows);
+
+ if (symmetric)
+ {
+ result = copy_cvec2mat (b, m);
+ }
+ else
+ {
+ result = copy_vec2mat (b, m);
+ }
+
+#ifdef RF_DEBUG
+ DDebug() << "Deconvolution:" << endl;
+ print_c_mat (result);
+#endif
+
+ finish_c_mat (&a);
+ finish_c_mat (&h_conv_ruv);
+ finish_c_mat (&corr);
+ finish_and_free_matrix (s);
+ finish_and_free_matrix (b);
+ return (result);
+}
+
+CMat *RefocusMatrix::compute_g_matrix (const CMat * const convolution, const int m,
+ const double gamma, const double noise_factor,
+ const double musq, const bool symmetric)
+{
+#ifdef RF_DEBUG
+ DDebug() << "matrix size: " << m << endl;
+ DDebug() << "correlation: " << gamma << endl;
+ DDebug() << "noise: " << noise_factor << endl;
+#endif
+
+ CMat *g = compute_g (convolution, m, gamma, noise_factor, musq, symmetric);
+ int r, c;
+ double sum = 0.0;
+
+ /* Determine sum of array */
+ for (r = -g->radius; r <= g->radius; r++)
+ {
+ for (c = -g->radius; c <= g->radius; c++)
+ {
+ sum += c_mat_elt (g, r, c);
+ }
+ }
+
+ for (r = -g->radius; r <= g->radius; r++)
+ {
+ for (c = -g->radius; c <= g->radius; c++)
+ {
+ *c_mat_eltptr (g, r, c) /= sum;
+ }
+ }
+
+ return (g);
+}
+
+void RefocusMatrix::fill_matrix (CMat * matrix, const int m,
+ double f (const int, const int, const double),
+ const double fun_arg)
+{
+ register int x, y;
+ init_c_mat (matrix, m);
+
+ for (y = -m; y <= m; y++)
+ {
+ for (x = -m; x <= m; x++)
+ {
+ *c_mat_eltptr (matrix, x, y) = f (x, y, fun_arg);
+ }
+ }
+}
+
+void RefocusMatrix::fill_matrix2 (CMat * matrix, const int m,
+ double f (const int, const int, const double, const double),
+ const double fun_arg1, const double fun_arg2)
+{
+ register int x, y;
+ init_c_mat (matrix, m);
+
+ for (y = -m; y <= m; y++)
+ {
+ for (x = -m; x <= m; x++)
+ {
+ *c_mat_eltptr (matrix, x, y) = f (x, y, fun_arg1, fun_arg2);
+ }
+ }
+}
+
+void RefocusMatrix::make_gaussian_convolution (const double gradius, CMat * convolution, const int m)
+{
+ register int x, y;
+
+#ifdef RF_DEBUG
+ DDebug() << "gauss: " << gradius << endl;
+#endif
+
+ init_c_mat (convolution, m);
+
+ if (SQR (gradius) <= 1 / 3.40282347e38F)
+ {
+ for (y = -m; y <= m; y++)
+ {
+ for (x = -m; x <= m; x++)
+ {
+ *c_mat_eltptr (convolution, x, y) = 0;
+ }
+ }
+
+ *c_mat_eltptr (convolution, 0, 0) = 1;
+ }
+ else
+ {
+ const double alpha = log (2.0) / SQR (gradius);
+
+ for (y = -m; y <= m; y++)
+ {
+ for (x = -m; x <= m; x++)
+ {
+ *c_mat_eltptr (convolution, x, y) =
+ exp (-alpha * (SQR (x) + SQR (y)));
+ }
+ }
+ }
+}
+
+/** Return the integral of sqrt(radius^2 - z^2) for z = 0 to x. */
+
+double RefocusMatrix::circle_integral (const double x, const double radius)
+{
+ if (radius == 0)
+ {
+ // Perhaps some epsilon must be added here.
+ return (0);
+ }
+ else
+ {
+ const double sin = x / radius;
+ const double sq_diff = SQR (radius) - SQR (x);
+ // From a mathematical point of view the following is redundant.
+ // Numerically they are not equivalent!
+
+ if ((sq_diff < 0.0) || (sin < -1.0) || (sin > 1.0))
+ {
+ if (sin < 0)
+ {
+ return (-0.25 * SQR (radius) * M_PI);
+ }
+ else
+ {
+ return (0.25 * SQR (radius) * M_PI);
+ }
+ }
+ else
+ {
+ return (0.5 * x * sqrt (sq_diff) + 0.5 * SQR (radius) * asin (sin));
+ }
+ }
+}
+
+double RefocusMatrix::circle_intensity (const int x, const int y, const double radius)
+{
+ if (radius == 0)
+ {
+ return (((x == 0) && (y == 0)) ? 1 : 0);
+ }
+ else
+ {
+ register double xlo = QABS (x) - 0.5, xhi = QABS (x) + 0.5,
+ ylo = QABS (y) - 0.5, yhi = QABS (y) + 0.5;
+ register double symmetry_factor = 1, xc1, xc2;
+
+ if (xlo < 0)
+ {
+ xlo = 0;
+ symmetry_factor *= 2;
+ }
+
+ if (ylo < 0)
+ {
+ ylo = 0;
+ symmetry_factor *= 2;
+ }
+
+ if (SQR (xlo) + SQR (yhi) > SQR (radius))
+ {
+ xc1 = xlo;
+ }
+ else if (SQR (xhi) + SQR (yhi) > SQR (radius))
+ {
+ xc1 = sqrt (SQR (radius) - SQR (yhi));
+ }
+ else
+ {
+ xc1 = xhi;
+ }
+
+ if (SQR (xlo) + SQR (ylo) > SQR (radius))
+ {
+ xc2 = xlo;
+ }
+ else if (SQR (xhi) + SQR (ylo) > SQR (radius))
+ {
+ xc2 = sqrt (SQR (radius) - SQR (ylo));
+ }
+ else
+ {
+ xc2 = xhi;
+ }
+
+ return (((yhi - ylo) * (xc1 - xlo) +
+ circle_integral (xc2, radius) - circle_integral (xc1, radius) -
+ (xc2 - xc1) * ylo) * symmetry_factor / (M_PI * SQR (radius)));
+ }
+}
+
+void RefocusMatrix::make_circle_convolution (const double radius, CMat * convolution, const int m)
+{
+#ifdef RF_DEBUG
+ DDebug() << "radius: " << radius << endl;
+#endif
+
+ fill_matrix (convolution, m, circle_intensity, radius);
+}
+
+int RefocusMatrix::dgesv (const int N, const int NRHS, double *A, const int lda, double *B, const int ldb)
+{
+ int result = 0;
+ integer i_N = N, i_NHRS = NRHS, i_lda = lda, i_ldb = ldb, info;
+ integer *ipiv = new integer[N];
+
+ // Clapack call.
+ dgesv_ (&i_N, &i_NHRS, A, &i_lda, ipiv, B, &i_ldb, &info);
+
+ delete [] ipiv;
+ result = info;
+ return (result);
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/matrix.h b/digikam/imageplugins/coreplugin/sharpnesseditor/matrix.h
new file mode 100644
index 0000000..6b2f65c
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/matrix.h
@@ -0,0 +1,129 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-04-29
+ * Description : refocus deconvolution matrix implementation.
+ *
+ * Copyright (C) 2005-2007 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 MATRIX_H_INCLUDED
+#define MATRIX_H_INCLUDED
+
+// C ++ includes.
+
+#include <cstdio>
+
+namespace DigikamImagesPluginCore
+{
+
+/**
+* CMat:
+* @radius: Radius of the matrix.
+*
+* Centered matrix. This is a square matrix where
+* the indices range from [-radius, radius].
+* The matrix contains (2 * radius + 1) ** 2 elements.
+*
+**/
+typedef struct
+{
+ int radius; // Radius of the matrix
+ int row_stride; // Size of one row = 2 * radius + 1
+ double *data; // Contents of matrix
+ double *center; // Points to element with index (0, 0)
+}
+CMat;
+
+/**
+* Mat:
+* @rows: Number of rows in the matrix.
+*
+* Normal matrix type. Indices range from
+* [0, rows -1 ] and [0, cols - 1].
+*
+**/
+typedef struct
+{
+ int rows; // Number of rows in the matrix
+ int cols; // Number of columns in the matrix
+ double *data; // Content of the matrix
+}
+Mat;
+
+class RefocusMatrix
+{
+
+public:
+
+ static void fill_matrix (CMat * matrix, const int m, double f (int, int, double), const double fun_arg);
+
+ static void fill_matrix2 (CMat * matrix, const int m,
+ double f (const int, const int, const double, const double),
+ const double fun_arg1, const double fun_arg2);
+
+ static void make_circle_convolution (const double radius, CMat *convolution, const int m);
+
+ static void make_gaussian_convolution (const double alpha, CMat *convolution, const int m);
+
+ static void convolve_star_mat (CMat *result, const CMat *const mata, const CMat* const matb);
+
+ static CMat *compute_g_matrix (const CMat * const convolution, const int m,
+ const double gamma, const double noise_factor,
+ const double musq, const bool symmetric);
+
+ static void finish_matrix (Mat * mat);
+ static void finish_and_free_matrix (Mat * mat);
+ static void init_c_mat (CMat * mat, const int radius);
+ static void finish_c_mat (CMat * mat);
+
+private:
+
+ // Debug methods.
+ static void print_c_mat (const CMat * const mat);
+ static void print_matrix (Mat * matrix);
+
+ static Mat *allocate_matrix (int nrows, int ncols);
+ static double *mat_eltptr (Mat * mat, const int r, const int c);
+ static double mat_elt (const Mat * mat, const int r, const int c);
+ static CMat *allocate_c_mat (const int radius);
+ static inline double *c_mat_eltptr (CMat * mat, const int col, const int row);
+ static inline double c_mat_elt (const CMat * const mat, const int col, const int row);
+ static void convolve_mat (CMat * result, const CMat * const mata, const CMat * const matb);
+ static void convolve_mat_fun (CMat * result, const CMat * const mata, double (f) (int, int));
+ static int as_idx (const int k, const int l, const int m);
+ static int as_cidx (const int k, const int l);
+ static Mat *make_s_matrix (CMat * mat, int m, double noise_factor);
+ static Mat *make_s_cmatrix (CMat * mat, int m, double noise_factor);
+ static double correlation (const int x, const int y, const double gamma, const double musq);
+ static Mat *copy_vec (const CMat * const mat, const int m);
+ static Mat *copy_cvec (const CMat * const mat, const int m);
+ static CMat *copy_cvec2mat (const Mat * const cvec, const int m);
+ static CMat *copy_vec2mat (const Mat * const cvec, const int m);
+ static CMat *compute_g (const CMat * const convolution, const int m, const double gamma,
+ const double noise_factor, const double musq, const bool symmetric);
+ static double circle_integral (const double x, const double radius);
+ static double circle_intensity (const int x, const int y, const double radius);
+
+ // CLapack interface.
+ static int dgesv (const int N, const int NRHS, double *A, const int lda, double *B, const int ldb);
+
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* MATRIX_H_INCLUDED */
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/refocus.cpp b/digikam/imageplugins/coreplugin/sharpnesseditor/refocus.cpp
new file mode 100644
index 0000000..480bc6c
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/refocus.cpp
@@ -0,0 +1,199 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-05-25
+ * Description : Refocus threaded image filter.
+ *
+ * Copyright (C) 2005-2007 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.
+ *
+ * ============================================================ */
+
+// C++ includes.
+
+#include <cmath>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "dimg.h"
+#include "dcolor.h"
+#include "dimgimagefilters.h"
+#include "matrix.h"
+#include "refocus.h"
+
+namespace DigikamImagesPluginCore
+{
+
+Refocus::Refocus(Digikam::DImg *orgImage, QObject *parent, int matrixSize, double radius,
+ double gauss, double correlation, double noise)
+ : Digikam::DImgThreadedFilter(orgImage, parent, "Refocus")
+{
+ m_matrixSize = matrixSize;
+ m_radius = radius;
+ m_gauss = gauss;
+ m_correlation = correlation;
+ m_noise = noise;
+ initFilter();
+}
+
+void Refocus::filterImage(void)
+{
+ refocusImage(m_orgImage.bits(), m_orgImage.width(), m_orgImage.height(),
+ m_orgImage.sixteenBit(), m_matrixSize, m_radius, m_gauss,
+ m_correlation, m_noise);
+}
+
+void Refocus::refocusImage(uchar* data, int width, int height, bool sixteenBit,
+ int matrixSize, double radius, double gauss,
+ double correlation, double noise)
+{
+ CMat *matrix=0;
+
+ // Compute matrix
+ DDebug() << "Refocus::Compute matrix..." << endl;
+
+ CMat circle, gaussian, convolution;
+
+ RefocusMatrix::make_gaussian_convolution (gauss, &gaussian, matrixSize);
+ RefocusMatrix::make_circle_convolution (radius, &circle, matrixSize);
+ RefocusMatrix::init_c_mat (&convolution, matrixSize);
+ RefocusMatrix::convolve_star_mat (&convolution, &gaussian, &circle);
+
+ matrix = RefocusMatrix::compute_g_matrix (&convolution, matrixSize, correlation, noise, 0.0, true);
+
+ RefocusMatrix::finish_c_mat (&convolution);
+ RefocusMatrix::finish_c_mat (&gaussian);
+ RefocusMatrix::finish_c_mat (&circle);
+
+ // Apply deconvolution kernel to image.
+ DDebug() << "Refocus::Apply Matrix to image..." << endl;
+ convolveImage(data, m_destImage.bits(), width, height, sixteenBit,
+ matrix->data, 2 * matrixSize + 1);
+
+ // Clean up memory
+ delete matrix;
+}
+
+void Refocus::convolveImage(uchar *orgData, uchar *destData, int width, int height,
+ bool sixteenBit, const double *const matrix, int mat_size)
+{
+ int progress;
+ unsigned short *orgData16 = (unsigned short *)orgData;
+ unsigned short *destData16 = (unsigned short *)destData;
+
+ double valRed, valGreen, valBlue;
+ int x1, y1, x2, y2, index1, index2;
+
+ const int imageSize = width*height;
+ const int mat_offset = mat_size / 2;
+
+ for (y1 = 0; !m_cancel && (y1 < height); y1++)
+ {
+ for (x1 = 0; !m_cancel && (x1 < width); x1++)
+ {
+ valRed = valGreen = valBlue = 0.0;
+
+ if (!sixteenBit) // 8 bits image.
+ {
+ uchar red, green, blue;
+ uchar *ptr;
+
+ for (y2 = 0; !m_cancel && (y2 < mat_size); y2++)
+ {
+ for (x2 = 0; !m_cancel && (x2 < mat_size); x2++)
+ {
+ index1 = width * (y1 + y2 - mat_offset) +
+ x1 + x2 - mat_offset;
+
+ if ( index1 >= 0 && index1 < imageSize )
+ {
+ ptr = &orgData[index1*4];
+ blue = ptr[0];
+ green = ptr[1];
+ red = ptr[2];
+ const double matrixValue = matrix[y2 * mat_size + x2];
+ valRed += matrixValue * red;
+ valGreen += matrixValue * green;
+ valBlue += matrixValue * blue;
+ }
+ }
+ }
+
+ index2 = y1 * width + x1;
+
+ if (index2 >= 0 && index2 < imageSize)
+ {
+ // To get Alpha channel value from original (unchanged)
+ memcpy (&destData[index2*4], &orgData[index2*4], 4);
+ ptr = &destData[index2*4];
+
+ // Overwrite RGB values to destination.
+ ptr[0] = (uchar) CLAMP (valBlue, 0, 255);
+ ptr[1] = (uchar) CLAMP (valGreen, 0, 255);
+ ptr[2] = (uchar) CLAMP (valRed, 0, 255);
+ }
+ }
+ else // 16 bits image.
+ {
+ unsigned short red, green, blue;
+ unsigned short *ptr;
+
+ for (y2 = 0; !m_cancel && (y2 < mat_size); y2++)
+ {
+ for (x2 = 0; !m_cancel && (x2 < mat_size); x2++)
+ {
+ index1 = width * (y1 + y2 - mat_offset) +
+ x1 + x2 - mat_offset;
+
+ if ( index1 >= 0 && index1 < imageSize )
+ {
+ ptr = &orgData16[index1*4];
+ blue = ptr[0];
+ green = ptr[1];
+ red = ptr[2];
+ const double matrixValue = matrix[y2 * mat_size + x2];
+ valRed += matrixValue * red;
+ valGreen += matrixValue * green;
+ valBlue += matrixValue * blue;
+ }
+ }
+ }
+
+ index2 = y1 * width + x1;
+
+ if (index2 >= 0 && index2 < imageSize)
+ {
+ // To get Alpha channel value from original (unchanged)
+ memcpy (&destData16[index2*4], &orgData16[index2*4], 8);
+ ptr = &destData16[index2*4];
+
+ // Overwrite RGB values to destination.
+ ptr[0] = (unsigned short) CLAMP (valBlue, 0, 65535);
+ ptr[1] = (unsigned short) CLAMP (valGreen, 0, 65535);
+ ptr[2] = (unsigned short) CLAMP (valRed, 0, 65535);
+ }
+ }
+ }
+
+ // Update the progress bar in dialog.
+ progress = (int)(((double)y1 * 100.0) / height);
+ if (progress%5 == 0)
+ postProgress( progress );
+ }
+}
+
+} // NameSpace DigikamImagesPluginCore
+
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/refocus.h b/digikam/imageplugins/coreplugin/sharpnesseditor/refocus.h
new file mode 100644
index 0000000..7cf7b56
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/refocus.h
@@ -0,0 +1,67 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-05-25
+ * Description : Refocus threaded image filter.
+ *
+ * Copyright (C) 2005-2007 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 REFOCUS_H
+#define REFOCUS_H
+
+// Local includes.
+
+#include "dimgthreadedfilter.h"
+
+namespace DigikamImagesPluginCore
+{
+
+class Refocus : public Digikam::DImgThreadedFilter
+{
+
+public:
+
+ Refocus(Digikam::DImg *orgImage, QObject *parent=0, int matrixSize=5, double radius=0.9,
+ double gauss=0.0, double correlation=0.5, double noise=0.01);
+
+ ~Refocus(){};
+
+private: // Refocus filter methods.
+
+ virtual void filterImage(void);
+
+ void refocusImage(uchar* data, int width, int height, bool sixteenBit,
+ int matrixSize, double radius, double gauss,
+ double correlation, double noise);
+
+ void convolveImage(uchar *orgData, uchar *destData, int width, int height,
+ bool sixteenBit, const double *const matrix, int mat_size);
+
+private: // Refocus filter data.
+
+ int m_matrixSize;
+
+ double m_radius;
+ double m_gauss;
+ double m_correlation;
+ double m_noise;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* REFOCUS_H */
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/sharpentool.cpp b/digikam/imageplugins/coreplugin/sharpnesseditor/sharpentool.cpp
new file mode 100644
index 0000000..a1e41f7
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/sharpentool.cpp
@@ -0,0 +1,741 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-09
+ * Description : a tool to sharp 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.
+ *
+ * ============================================================ */
+
+#define MAX_MATRIX_SIZE 25
+
+// C++ includes.
+
+#include <cmath>
+
+// Qt includes.
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+#include <qwidgetstack.h>
+
+// KDE includes.
+
+#include <kaboutdata.h>
+#include <kcursor.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kseparator.h>
+#include <kconfig.h>
+#include <kurl.h>
+#include <kiconloader.h>
+#include <kfiledialog.h>
+#include <kglobalsettings.h>
+#include <kmessagebox.h>
+
+// LibKDcraw includes.
+
+#include <libkdcraw/rnuminput.h>
+#include <libkdcraw/rcombobox.h>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "imageiface.h"
+#include "imagepanelwidget.h"
+#include "editortoolsettings.h"
+#include "dimgsharpen.h"
+#include "unsharp.h"
+#include "refocus.h"
+#include "sharpentool.h"
+#include "sharpentool.moc"
+
+using namespace KDcrawIface;
+using namespace Digikam;
+
+namespace DigikamImagesPluginCore
+{
+
+SharpenTool::SharpenTool(QObject* parent)
+ : EditorToolThreaded(parent)
+{
+ setName("sharpen");
+ setToolName(i18n("Sharpen"));
+ setToolIcon(SmallIcon("sharpenimage"));
+ setToolHelp("blursharpentool.anchor");
+
+ // -------------------------------------------------------------
+
+ m_gboxSettings = new EditorToolSettings(EditorToolSettings::Default|
+ EditorToolSettings::Ok|
+ EditorToolSettings::Cancel|
+ EditorToolSettings::Load|
+ EditorToolSettings::SaveAs|
+ EditorToolSettings::Try,
+ EditorToolSettings::PanIcon);
+ QGridLayout* grid = new QGridLayout( m_gboxSettings->plainPage(), 3, 1);
+
+ QLabel *label1 = new QLabel(i18n("Method:"), m_gboxSettings->plainPage());
+
+ m_sharpMethod = new RComboBox(m_gboxSettings->plainPage());
+ m_sharpMethod->insertItem( i18n("Simple sharp") );
+ m_sharpMethod->insertItem( i18n("Unsharp mask") );
+ m_sharpMethod->insertItem( i18n("Refocus") );
+ m_sharpMethod->setDefaultItem(SimpleSharp);
+ QWhatsThis::add( m_sharpMethod, i18n("<p>Select the sharpening method to apply to the image."));
+
+ m_stack = new QWidgetStack(m_gboxSettings->plainPage());
+
+ grid->addMultiCellWidget(label1, 0, 0, 0, 0);
+ grid->addMultiCellWidget(m_sharpMethod, 0, 0, 1, 1);
+ grid->addMultiCellWidget(new KSeparator(m_gboxSettings->plainPage()), 1, 1, 0, 1);
+ grid->addMultiCellWidget(m_stack, 2, 2, 0, 1);
+ grid->setRowStretch(3, 10);
+ grid->setMargin(m_gboxSettings->spacingHint());
+ grid->setSpacing(m_gboxSettings->spacingHint());
+
+ // -------------------------------------------------------------
+
+ QWidget *simpleSharpSettings = new QWidget(m_stack);
+ QGridLayout* grid1 = new QGridLayout( simpleSharpSettings, 2, 1);
+
+ QLabel *label = new QLabel(i18n("Sharpness:"), simpleSharpSettings);
+ m_radiusInput = new RIntNumInput(simpleSharpSettings);
+ m_radiusInput->setRange(0, 100, 1);
+ m_radiusInput->setDefaultValue(0);
+ QWhatsThis::add( m_radiusInput, i18n("<p>A sharpness of 0 has no effect, "
+ "1 and above determine the sharpen matrix radius "
+ "that determines how much to sharpen the image."));
+
+ grid1->addMultiCellWidget(label, 0, 0, 0, 1);
+ grid1->addMultiCellWidget(m_radiusInput, 1, 1, 0, 1);
+ grid1->setRowStretch(2, 10);
+ grid1->setMargin(0);
+ grid1->setSpacing(0);
+
+ m_stack->addWidget(simpleSharpSettings, SimpleSharp);
+
+ // -------------------------------------------------------------
+
+ QWidget *unsharpMaskSettings = new QWidget(m_stack);
+ QGridLayout* grid2 = new QGridLayout( unsharpMaskSettings, 6, 1);
+
+ QLabel *label2 = new QLabel(i18n("Radius:"), unsharpMaskSettings);
+ m_radiusInput2 = new RIntNumInput(unsharpMaskSettings);
+ m_radiusInput2->setRange(1, 120, 1);
+ m_radiusInput2->setDefaultValue(1);
+ QWhatsThis::add( m_radiusInput2, i18n("<p>Radius value is the gaussian blur matrix radius value "
+ "used to determines how much to blur the image.") );
+
+ QLabel *label3 = new QLabel(i18n("Amount:"), unsharpMaskSettings);
+ m_amountInput = new RDoubleNumInput(unsharpMaskSettings);
+ m_amountInput->setPrecision(1);
+ m_amountInput->setRange(0.0, 5.0, 0.1);
+ m_amountInput->setDefaultValue(1.0);
+ QWhatsThis::add( m_amountInput, i18n("<p>The value of the difference between the "
+ "original and the blur image that is added back into the original.") );
+
+ QLabel *label4 = new QLabel(i18n("Threshold:"), unsharpMaskSettings);
+ m_thresholdInput = new RDoubleNumInput(unsharpMaskSettings);
+ m_thresholdInput->setPrecision(2);
+ m_thresholdInput->setRange(0.0, 1.0, 0.01);
+ m_thresholdInput->setDefaultValue(0.05);
+ QWhatsThis::add( m_thresholdInput, i18n("<p>The threshold, as a fraction of the maximum "
+ "luminosity value, needed to apply the difference amount.") );
+
+ grid2->addMultiCellWidget(label2, 0, 0, 0, 1);
+ grid2->addMultiCellWidget(m_radiusInput2, 1, 1, 0, 1);
+ grid2->addMultiCellWidget(label3, 2, 2, 0, 1);
+ grid2->addMultiCellWidget(m_amountInput, 3, 3, 0, 1);
+ grid2->addMultiCellWidget(label4, 4, 4, 0, 1);
+ grid2->addMultiCellWidget(m_thresholdInput, 5, 5, 0, 1);
+ grid2->setRowStretch(6, 10);
+ grid2->setMargin(0);
+ grid2->setSpacing(0);
+
+ m_stack->addWidget(unsharpMaskSettings, UnsharpMask);
+
+ // -------------------------------------------------------------
+
+ QWidget *refocusSettings = new QWidget(m_stack);
+ QGridLayout* grid3 = new QGridLayout(refocusSettings, 10, 1);
+
+ QLabel *label5 = new QLabel(i18n("Circular sharpness:"), refocusSettings);
+ m_radius = new RDoubleNumInput(refocusSettings);
+ m_radius->setPrecision(2);
+ m_radius->setRange(0.0, 5.0, 0.01);
+ m_radius->setDefaultValue(1.0);
+ QWhatsThis::add( m_radius, i18n("<p>This is the radius of the circular convolution. It is the most important "
+ "parameter for using this plugin. For most images the default value of 1.0 "
+ "should give good results. Select a higher value when your image is very blurred."));
+
+ QLabel *label6 = new QLabel(i18n("Correlation:"), refocusSettings);
+ m_correlation = new RDoubleNumInput(refocusSettings);
+ m_correlation->setPrecision(2);
+ m_correlation->setRange(0.0, 1.0, 0.01);
+ m_correlation->setDefaultValue(0.5);
+ QWhatsThis::add( m_correlation, i18n("<p>Increasing the correlation may help to reduce artifacts. The correlation can "
+ "range from 0-1. Useful values are 0.5 and values close to 1, e.g. 0.95 and 0.99. "
+ "Using a high value for the correlation will reduce the sharpening effect of the "
+ "plugin."));
+
+ QLabel *label7 = new QLabel(i18n("Noise filter:"), refocusSettings);
+ m_noise = new RDoubleNumInput(refocusSettings);
+ m_noise->setPrecision(3);
+ m_noise->setRange(0.0, 1.0, 0.001);
+ m_noise->setDefaultValue(0.03);
+ QWhatsThis::add( m_noise, i18n("<p>Increasing the noise filter parameter may help to reduce artifacts. The noise filter "
+ "can range from 0-1 but values higher than 0.1 are rarely helpful. When the noise filter "
+ "value is too low, e.g. 0.0 the image quality will be very poor. A useful value is 0.01. "
+ "Using a high value for the noise filter will reduce the sharpening "
+ "effect of the plugin."));
+
+ QLabel *label8 = new QLabel(i18n("Gaussian sharpness:"), refocusSettings);
+ m_gauss = new RDoubleNumInput(refocusSettings);
+ m_gauss->setPrecision(2);
+ m_gauss->setRange(0.0, 1.0, 0.01);
+ m_gauss->setDefaultValue(0.0);
+ QWhatsThis::add( m_gauss, i18n("<p>This is the sharpness for the gaussian convolution. Use this parameter when your "
+ "blurring is of a Gaussian type. In most cases you should set this parameter to 0, because "
+ "it causes nasty artifacts. When you use non-zero values, you will probably have to "
+ "increase the correlation and/or noise filter parameters too."));
+
+ QLabel *label9 = new QLabel(i18n("Matrix size:"), refocusSettings);
+ m_matrixSize = new RIntNumInput(refocusSettings);
+ m_matrixSize->setRange(0, MAX_MATRIX_SIZE, 1);
+ m_matrixSize->setDefaultValue(5);
+ QWhatsThis::add( m_matrixSize, i18n("<p>This parameter determines the size of the transformation matrix. "
+ "Increasing the matrix width may give better results, especially when you have "
+ "chosen large values for circular or gaussian sharpness."));
+
+ grid3->addMultiCellWidget(label5, 0, 0, 0, 1);
+ grid3->addMultiCellWidget(m_radius, 1, 1, 0, 1);
+ grid3->addMultiCellWidget(label6, 2, 2, 0, 1);
+ grid3->addMultiCellWidget(m_correlation, 3, 3, 0, 1);
+ grid3->addMultiCellWidget(label7, 4, 4, 0, 1);
+ grid3->addMultiCellWidget(m_noise, 5, 5, 0, 1);
+ grid3->addMultiCellWidget(label8, 6, 6, 0, 1);
+ grid3->addMultiCellWidget(m_gauss, 7, 7, 0, 1);
+ grid3->addMultiCellWidget(label9, 8, 8, 0, 1);
+ grid3->addMultiCellWidget(m_matrixSize, 9, 9, 0, 1);
+ grid3->setRowStretch(10, 10);
+ grid3->setMargin(0);
+ grid3->setSpacing(0);
+
+ m_stack->addWidget(refocusSettings, Refocus);
+
+ setToolSettings(m_gboxSettings);
+
+ m_previewWidget = new ImagePanelWidget(470, 350, "sharpen Tool", m_gboxSettings->panIconView());
+
+ setToolView(m_previewWidget);
+ init();
+
+ // -------------------------------------------------------------
+
+ connect(m_sharpMethod, SIGNAL(activated(int)),
+ this, SLOT(slotSharpMethodActived(int)));
+
+ // -------------------------------------------------------------
+
+ // Image creation with dummy borders (mosaic mode) used by Refocus method. It needs to do
+ // it before to apply deconvolution filter on original image border pixels including
+ // on matrix size area. This way limit artifacts on image border.
+
+ ImageIface iface(0, 0);
+
+ uchar* data = iface.getOriginalImage();
+ int w = iface.originalWidth();
+ int h = iface.originalHeight();
+ bool sb = iface.originalSixteenBit();
+ bool a = iface.originalHasAlpha();
+
+ m_img = DImg( w + 4*MAX_MATRIX_SIZE, h + 4*MAX_MATRIX_SIZE, sb, a);
+
+ DImg tmp;
+ DImg org(w, h, sb, a, data);
+
+ // Copy original.
+ m_img.bitBltImage(&org, 2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+
+ // Create dummy top border
+ tmp = org.copy(0, 0, w, 2*MAX_MATRIX_SIZE);
+ tmp.flip(DImg::VERTICAL);
+ m_img.bitBltImage(&tmp, 2*MAX_MATRIX_SIZE, 0);
+
+ // Create dummy bottom border
+ tmp = org.copy(0, h-2*MAX_MATRIX_SIZE, w, 2*MAX_MATRIX_SIZE);
+ tmp.flip(DImg::VERTICAL);
+ m_img.bitBltImage(&tmp, 2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE+h);
+
+ // Create dummy left border
+ tmp = org.copy(0, 0, 2*MAX_MATRIX_SIZE, h);
+ tmp.flip(DImg::HORIZONTAL);
+ m_img.bitBltImage(&tmp, 0, 2*MAX_MATRIX_SIZE);
+
+ // Create dummy right border
+ tmp = org.copy(w-2*MAX_MATRIX_SIZE, 0, 2*MAX_MATRIX_SIZE, h);
+ tmp.flip(DImg::HORIZONTAL);
+ m_img.bitBltImage(&tmp, w+2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+
+ // Create dummy top/left corner
+ tmp = org.copy(0, 0, 2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+ tmp.flip(DImg::HORIZONTAL);
+ tmp.flip(DImg::VERTICAL);
+ m_img.bitBltImage(&tmp, 0, 0);
+
+ // Create dummy top/right corner
+ tmp = org.copy(w-2*MAX_MATRIX_SIZE, 0, 2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+ tmp.flip(DImg::HORIZONTAL);
+ tmp.flip(DImg::VERTICAL);
+ m_img.bitBltImage(&tmp, w+2*MAX_MATRIX_SIZE, 0);
+
+ // Create dummy bottom/left corner
+ tmp = org.copy(0, h-2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+ tmp.flip(DImg::HORIZONTAL);
+ tmp.flip(DImg::VERTICAL);
+ m_img.bitBltImage(&tmp, 0, h+2*MAX_MATRIX_SIZE);
+
+ // Create dummy bottom/right corner
+ tmp = org.copy(w-2*MAX_MATRIX_SIZE, h-2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+ tmp.flip(DImg::HORIZONTAL);
+ tmp.flip(DImg::VERTICAL);
+ m_img.bitBltImage(&tmp, w+2*MAX_MATRIX_SIZE, h+2*MAX_MATRIX_SIZE);
+
+ delete [] data;
+}
+
+SharpenTool::~SharpenTool()
+{
+}
+
+void SharpenTool::renderingFinished()
+{
+ switch (m_stack->id(m_stack->visibleWidget()))
+ {
+ case SimpleSharp:
+ {
+ m_radiusInput->setEnabled(true);
+ m_gboxSettings->enableButton(EditorToolSettings::Load, false);
+ m_gboxSettings->enableButton(EditorToolSettings::SaveAs, false);
+ break;
+ }
+
+ case UnsharpMask:
+ {
+ m_radiusInput2->setEnabled(true);
+ m_amountInput->setEnabled(true);
+ m_thresholdInput->setEnabled(true);
+ m_gboxSettings->enableButton(EditorToolSettings::Load, false);
+ m_gboxSettings->enableButton(EditorToolSettings::SaveAs, false);
+ break;
+ }
+
+ case Refocus:
+ {
+ m_matrixSize->setEnabled(true);
+ m_radius->setEnabled(true);
+ m_gauss->setEnabled(true);
+ m_correlation->setEnabled(true);
+ m_noise->setEnabled(true);
+ break;
+ }
+ }
+}
+
+void SharpenTool::slotSharpMethodActived(int w)
+{
+ m_stack->raiseWidget(w);
+ if (w == Refocus)
+ {
+ m_gboxSettings->enableButton(EditorToolSettings::Load, true);
+ m_gboxSettings->enableButton(EditorToolSettings::SaveAs, true);
+ }
+ else
+ {
+ m_gboxSettings->enableButton(EditorToolSettings::Load, false);
+ m_gboxSettings->enableButton(EditorToolSettings::SaveAs, false);
+ }
+}
+
+void SharpenTool::readSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("sharpen Tool");
+ m_radiusInput->blockSignals(true);
+ m_radiusInput2->blockSignals(true);
+ m_amountInput->blockSignals(true);
+ m_thresholdInput->blockSignals(true);
+ m_matrixSize->blockSignals(true);
+ m_radius->blockSignals(true);
+ m_gauss->blockSignals(true);
+ m_correlation->blockSignals(true);
+ m_noise->blockSignals(true);
+ m_sharpMethod->blockSignals(true);
+
+ m_radiusInput->setValue(config->readNumEntry("SimpleSharpRadiusAjustment", m_radiusInput->defaultValue()));
+ m_radiusInput2->setValue(config->readNumEntry("UnsharpMaskRadiusAjustment", m_radiusInput2->defaultValue()));
+ m_amountInput->setValue(config->readDoubleNumEntry("UnsharpMaskAmountAjustment", m_amountInput->defaultValue()));
+ m_thresholdInput->setValue(config->readDoubleNumEntry("UnsharpMaskThresholdAjustment", m_thresholdInput->defaultValue()));
+ m_matrixSize->setValue(config->readNumEntry("RefocusMatrixSize", m_matrixSize->defaultValue()));
+ m_radius->setValue(config->readDoubleNumEntry("RefocusRadiusAjustment", m_radius->defaultValue()));
+ m_gauss->setValue(config->readDoubleNumEntry("RefocusGaussAjustment", m_gauss->defaultValue()));
+ m_correlation->setValue(config->readDoubleNumEntry("RefocusCorrelationAjustment", m_correlation->defaultValue()));
+ m_noise->setValue(config->readDoubleNumEntry("RefocusNoiseAjustment", m_noise->defaultValue()));
+ m_sharpMethod->setCurrentItem(config->readNumEntry("SharpenMethod", SimpleSharp));
+
+ m_radiusInput->blockSignals(false);
+ m_radiusInput2->blockSignals(false);
+ m_amountInput->blockSignals(false);
+ m_thresholdInput->blockSignals(false);
+ m_matrixSize->blockSignals(false);
+ m_radius->blockSignals(false);
+ m_gauss->blockSignals(false);
+ m_correlation->blockSignals(false);
+ m_noise->blockSignals(false);
+ m_sharpMethod->blockSignals(false);
+
+ slotSharpMethodActived(m_sharpMethod->currentItem());
+}
+
+void SharpenTool::writeSettings()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("sharpen Tool");
+ config->writeEntry("SimpleSharpRadiusAjustment", m_radiusInput->value());
+ config->writeEntry("UnsharpMaskRadiusAjustment", m_radiusInput2->value());
+ config->writeEntry("UnsharpMaskAmountAjustment", m_amountInput->value());
+ config->writeEntry("UnsharpMaskThresholdAjustment", m_thresholdInput->value());
+ config->writeEntry("RefocusMatrixSize", m_matrixSize->value());
+ config->writeEntry("RefocusRadiusAjustment", m_radius->value());
+ config->writeEntry("RefocusGaussAjustment", m_gauss->value());
+ config->writeEntry("RefocusCorrelationAjustment", m_correlation->value());
+ config->writeEntry("RefocusNoiseAjustment", m_noise->value());
+ config->writeEntry("SharpenMethod", m_sharpMethod->currentItem());
+ m_previewWidget->writeSettings();
+ config->sync();
+}
+
+void SharpenTool::slotResetSettings()
+{
+ switch (m_stack->id(m_stack->visibleWidget()))
+ {
+ case SimpleSharp:
+ {
+ m_radiusInput->blockSignals(true);
+ m_radiusInput->slotReset();
+ m_radiusInput->blockSignals(false);
+ break;
+ }
+
+ case UnsharpMask:
+ {
+ m_radiusInput2->blockSignals(true);
+ m_amountInput->blockSignals(true);
+ m_thresholdInput->blockSignals(true);
+
+ m_radiusInput2->slotReset();
+ m_amountInput->slotReset();
+ m_thresholdInput->slotReset();
+
+ m_radiusInput2->blockSignals(false);
+ m_amountInput->blockSignals(false);
+ m_thresholdInput->blockSignals(false);
+ break;
+ }
+
+ case Refocus:
+ {
+ m_matrixSize->blockSignals(true);
+ m_radius->blockSignals(true);
+ m_gauss->blockSignals(true);
+ m_correlation->blockSignals(true);
+ m_noise->blockSignals(true);
+
+ m_matrixSize->slotReset();
+ m_radius->slotReset();
+ m_gauss->slotReset();
+ m_correlation->slotReset();
+ m_noise->slotReset();
+
+ m_matrixSize->blockSignals(false);
+ m_radius->blockSignals(false);
+ m_gauss->blockSignals(false);
+ m_correlation->blockSignals(false);
+ m_noise->blockSignals(false);
+ break;
+ }
+ }
+}
+
+void SharpenTool::prepareEffect()
+{
+ switch (m_stack->id(m_stack->visibleWidget()))
+ {
+ case SimpleSharp:
+ {
+ m_radiusInput->setEnabled(false);
+
+ DImg img = m_previewWidget->getOriginalRegionImage();
+
+ double radius = m_radiusInput->value()/10.0;
+ double sigma;
+
+ if (radius < 1.0) sigma = radius;
+ else sigma = sqrt(radius);
+
+ setFilter(dynamic_cast<DImgThreadedFilter*>(new DImgSharpen(&img, this, radius, sigma )));
+ break;
+ }
+
+ case UnsharpMask:
+ {
+ m_radiusInput2->setEnabled(false);
+ m_amountInput->setEnabled(false);
+ m_thresholdInput->setEnabled(false);
+
+ DImg img = m_previewWidget->getOriginalRegionImage();
+
+ int r = m_radiusInput2->value();
+ double a = m_amountInput->value();
+ double th = m_thresholdInput->value();
+
+ setFilter(dynamic_cast<DImgThreadedFilter*>(new DigikamImagesPluginCore::UnsharpMask(&img, this, r, a, th)));
+ break;
+ }
+
+ case Refocus:
+ {
+ m_matrixSize->setEnabled(false);
+ m_radius->setEnabled(false);
+ m_gauss->setEnabled(false);
+ m_correlation->setEnabled(false);
+ m_noise->setEnabled(false);
+
+ int ms = m_matrixSize->value();
+ double r = m_radius->value();
+ double g = m_gauss->value();
+ double c = m_correlation->value();
+ double n = m_noise->value();
+
+ QRect area = m_previewWidget->getOriginalImageRegionToRender();
+ QRect tmpRect;
+ tmpRect.setLeft(area.left()-2*ms);
+ tmpRect.setRight(area.right()+2*ms);
+ tmpRect.setTop(area.top()-2*ms);
+ tmpRect.setBottom(area.bottom()+2*ms);
+ tmpRect.moveBy(2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE);
+ DImg imTemp = m_img.copy(tmpRect);
+
+ setFilter(dynamic_cast<DImgThreadedFilter*>(new DigikamImagesPluginCore::Refocus(&imTemp, this, ms, r, g, c, n)));
+ break;
+ }
+ }
+}
+
+void SharpenTool::prepareFinal()
+{
+ switch (m_stack->id(m_stack->visibleWidget()))
+ {
+ case SimpleSharp:
+ {
+ m_radiusInput->setEnabled(false);
+
+ double radius = m_radiusInput->value()/10.0;
+ double sigma;
+
+ if (radius < 1.0) sigma = radius;
+ else sigma = sqrt(radius);
+
+ ImageIface iface(0, 0);
+ uchar *data = iface.getOriginalImage();
+ int w = iface.originalWidth();
+ int h = iface.originalHeight();
+ bool sixteenBit = iface.originalSixteenBit();
+ bool hasAlpha = iface.originalHasAlpha();
+ DImg orgImage = DImg(w, h, sixteenBit, hasAlpha ,data);
+ delete [] data;
+ setFilter(dynamic_cast<DImgThreadedFilter*>(new DImgSharpen(&orgImage, this, radius, sigma )));
+ break;
+ }
+
+ case UnsharpMask:
+ {
+ m_radiusInput2->setEnabled(false);
+ m_amountInput->setEnabled(false);
+ m_thresholdInput->setEnabled(false);
+
+ int r = m_radiusInput2->value();
+ double a = m_amountInput->value();
+ double th = m_thresholdInput->value();
+
+ ImageIface iface(0, 0);
+ uchar *data = iface.getOriginalImage();
+ int w = iface.originalWidth();
+ int h = iface.originalHeight();
+ bool sixteenBit = iface.originalSixteenBit();
+ bool hasAlpha = iface.originalHasAlpha();
+ DImg orgImage = DImg(w, h, sixteenBit, hasAlpha ,data);
+ delete [] data;
+ setFilter(dynamic_cast<DImgThreadedFilter*>(new DigikamImagesPluginCore::UnsharpMask(&orgImage, this, r, a, th)));
+ break;
+ }
+
+ case Refocus:
+ {
+
+ m_matrixSize->setEnabled(false);
+ m_radius->setEnabled(false);
+ m_gauss->setEnabled(false);
+ m_correlation->setEnabled(false);
+ m_noise->setEnabled(false);
+
+ int ms = m_matrixSize->value();
+ double r = m_radius->value();
+ double g = m_gauss->value();
+ double c = m_correlation->value();
+ double n = m_noise->value();
+
+ setFilter(dynamic_cast<DImgThreadedFilter*>(new DigikamImagesPluginCore::Refocus(&m_img, this, ms, r, g, c, n)));
+ break;
+ }
+ }
+}
+
+void SharpenTool::putPreviewData()
+{
+ switch (m_stack->id(m_stack->visibleWidget()))
+ {
+ case SimpleSharp:
+ case UnsharpMask:
+ {
+ DImg imDest = filter()->getTargetImage();
+ m_previewWidget->setPreviewImage(imDest);
+ break;
+ }
+
+ case Refocus:
+ {
+ int ms = m_matrixSize->value();
+ QRect area = m_previewWidget->getOriginalImageRegionToRender();
+
+ DImg imDest = filter()->getTargetImage()
+ .copy(2*ms, 2*ms, area.width(), area.height());
+ m_previewWidget->setPreviewImage(imDest);
+ break;
+ }
+ }
+}
+
+void SharpenTool::putFinalData()
+{
+ ImageIface iface(0, 0);
+ DImg imDest = filter()->getTargetImage();
+
+ switch (m_stack->id(m_stack->visibleWidget()))
+ {
+ case SimpleSharp:
+ {
+ iface.putOriginalImage(i18n("Sharpen"), imDest.bits());
+ break;
+ }
+
+ case UnsharpMask:
+ {
+ iface.putOriginalImage(i18n("Unsharp Mask"), imDest.bits());
+ break;
+ }
+
+ case Refocus:
+ {
+ QRect area = m_previewWidget->getOriginalImageRegionToRender();
+ ImageIface iface(0, 0);
+
+ iface.putOriginalImage(i18n("Refocus"), filter()->getTargetImage()
+ .copy(2*MAX_MATRIX_SIZE, 2*MAX_MATRIX_SIZE,
+ iface.originalWidth(),
+ iface.originalHeight())
+ .bits());
+ break;
+ }
+ }
+}
+
+void SharpenTool::slotLoadSettings()
+{
+ KURL loadRestorationFile = KFileDialog::getOpenURL(KGlobalSettings::documentPath(),
+ QString( "*" ), kapp->activeWindow(),
+ QString( i18n("Photograph Refocus Settings File to Load")) );
+ if ( loadRestorationFile.isEmpty() )
+ return;
+
+ QFile file(loadRestorationFile.path());
+
+ if ( file.open(IO_ReadOnly) )
+ {
+ QTextStream stream( &file );
+ if ( stream.readLine() != "# Photograph Refocus Configuration File" )
+ {
+ KMessageBox::error(kapp->activeWindow(),
+ i18n("\"%1\" is not a Photograph Refocus settings text file.")
+ .arg(loadRestorationFile.fileName()));
+ file.close();
+ return;
+ }
+
+ blockSignals(true);
+ m_matrixSize->setValue( stream.readLine().toInt() );
+ m_radius->setValue( stream.readLine().toDouble() );
+ m_gauss->setValue( stream.readLine().toDouble() );
+ m_correlation->setValue( stream.readLine().toDouble() );
+ m_noise->setValue( stream.readLine().toDouble() );
+ blockSignals(false);
+ }
+ else
+ KMessageBox::error(kapp->activeWindow(), i18n("Cannot load settings from the Photograph Refocus text file."));
+
+ file.close();
+}
+
+void SharpenTool::slotSaveAsSettings()
+{
+ KURL saveRestorationFile = KFileDialog::getSaveURL(KGlobalSettings::documentPath(),
+ QString( "*" ), kapp->activeWindow(),
+ QString( i18n("Photograph Refocus Settings File to Save")) );
+ if ( saveRestorationFile.isEmpty() )
+ return;
+
+ QFile file(saveRestorationFile.path());
+
+ if ( file.open(IO_WriteOnly) )
+ {
+ QTextStream stream( &file );
+ stream << "# Photograph Refocus Configuration File\n";
+ stream << m_matrixSize->value() << "\n";
+ stream << m_radius->value() << "\n";
+ stream << m_gauss->value() << "\n";
+ stream << m_correlation->value() << "\n";
+ stream << m_noise->value() << "\n";
+ }
+ else
+ KMessageBox::error(kapp->activeWindow(), i18n("Cannot save settings to the Photograph Refocus text file."));
+
+ file.close();
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/sharpentool.h b/digikam/imageplugins/coreplugin/sharpnesseditor/sharpentool.h
new file mode 100644
index 0000000..b14f1a8
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/sharpentool.h
@@ -0,0 +1,110 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2004-07-09
+ * Description : a tool to sharp 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 SHARPENTOOL_H
+#define SHARPENTOOL_H
+
+// Digikam includes.
+
+#include "editortool.h"
+
+class QWidgetStack;
+
+namespace KDcrawIface
+{
+class RIntNumInput;
+class RDoubleNumInput;
+class RComboBox;
+}
+
+namespace Digikam
+{
+class DImg;
+class EditorToolSettings;
+class ImagePanelWidget;
+}
+
+namespace DigikamImagesPluginCore
+{
+
+class SharpenTool : public Digikam::EditorToolThreaded
+{
+ Q_OBJECT
+
+public:
+
+ SharpenTool(QObject *parent);
+ ~SharpenTool();
+
+private slots:
+
+ void slotSaveAsSettings();
+ void slotLoadSettings();
+ void slotResetSettings();
+ void slotSharpMethodActived(int);
+
+private:
+
+ void readSettings();
+ void writeSettings();
+ void prepareEffect();
+ void prepareFinal();
+ void abortPreview();
+ void putPreviewData();
+ void putFinalData();
+ void renderingFinished();
+
+private:
+
+ enum SharpingMethods
+ {
+ SimpleSharp=0,
+ UnsharpMask,
+ Refocus
+ };
+
+ QWidgetStack *m_stack;
+
+ KDcrawIface::RComboBox *m_sharpMethod;
+
+ KDcrawIface::RIntNumInput *m_matrixSize;
+ KDcrawIface::RIntNumInput *m_radiusInput;
+ KDcrawIface::RIntNumInput *m_radiusInput2;
+
+ KDcrawIface::RDoubleNumInput *m_radius;
+ KDcrawIface::RDoubleNumInput *m_gauss;
+ KDcrawIface::RDoubleNumInput *m_correlation;
+ KDcrawIface::RDoubleNumInput *m_noise;
+ KDcrawIface::RDoubleNumInput *m_amountInput;
+ KDcrawIface::RDoubleNumInput *m_thresholdInput;
+
+ Digikam::DImg m_img;
+
+ Digikam::ImagePanelWidget *m_previewWidget;
+
+ Digikam::EditorToolSettings *m_gboxSettings;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* SHARPENTOOL_H */
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/unsharp.cpp b/digikam/imageplugins/coreplugin/sharpnesseditor/unsharp.cpp
new file mode 100644
index 0000000..a565ccf
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/unsharp.cpp
@@ -0,0 +1,127 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-05-25
+ * Description : Unsharp Mask threaded image filter.
+ *
+ * Copyright (C) 2005-2007 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.
+ *
+ * ============================================================ */
+
+// C++ includes.
+
+#include <cmath>
+#include <cstdlib>
+
+// Local includes.
+
+#include "ddebug.h"
+#include "dimg.h"
+#include "dcolor.h"
+#include "dimgimagefilters.h"
+#include "dimggaussianblur.h"
+#include "unsharp.h"
+
+namespace DigikamImagesPluginCore
+{
+
+UnsharpMask::UnsharpMask(Digikam::DImg *orgImage, QObject *parent, int radius,
+ double amount, double threshold)
+ : DImgThreadedFilter(orgImage, parent, "UnsharpMask")
+{
+ m_radius = radius;
+ m_amount = amount;
+ m_threshold = threshold;
+ initFilter();
+}
+
+void UnsharpMask::filterImage(void)
+{
+ int progress;
+ int quantum;
+ double quantumThreshold;
+ double value;
+ Digikam::DColor p;
+ Digikam::DColor q;
+
+ if (m_orgImage.isNull())
+ {
+ DWarning() << k_funcinfo << "No image data available!" << endl;
+ return;
+ }
+
+ Digikam::DImgGaussianBlur(this, m_orgImage, m_destImage, 0, 10, (int)(m_radius));
+
+ quantum = m_destImage.sixteenBit() ? 65535 : 255;
+ quantumThreshold = quantum*m_threshold;
+
+ for (uint y = 0 ; !m_cancel && (y < m_destImage.height()) ; y++)
+ {
+ for (uint x = 0 ; !m_cancel && (x < m_destImage.width()) ; x++)
+ {
+ p = m_orgImage.getPixelColor(x, y);
+ q = m_destImage.getPixelColor(x, y);
+
+ // Red channel.
+ value = (double)(p.red())-(double)(q.red());
+
+ if (fabs(2.0*value) < quantumThreshold)
+ value = (double)(p.red());
+ else
+ value = (double)(p.red()) + value*m_amount;
+
+ q.setRed(CLAMP(ROUND(value), 0, quantum));
+
+ // Green Channel.
+ value = (double)(p.green())-(double)(q.green());
+
+ if (fabs(2.0*value) < quantumThreshold)
+ value = (double)(p.green());
+ else
+ value = (double)(p.green()) + value*m_amount;
+
+ q.setGreen(CLAMP(ROUND(value), 0, quantum));
+
+ // Blue Channel.
+ value = (double)(p.blue())-(double)(q.blue());
+
+ if (fabs(2.0*value) < quantumThreshold)
+ value = (double)(p.blue());
+ else
+ value = (double)(p.blue()) + value*m_amount;
+
+ q.setBlue(CLAMP(ROUND(value), 0, quantum));
+
+ // Alpha Channel.
+ value = (double)(p.alpha())-(double)(q.alpha());
+
+ if (fabs(2.0*value) < quantumThreshold)
+ value = (double)(p.alpha());
+ else
+ value = (double)(p.alpha()) + value*m_amount;
+
+ q.setAlpha(CLAMP(ROUND(value), 0, quantum));
+
+ m_destImage.setPixelColor(x, y, q);
+ }
+
+ progress = (int)(10.0 + ((double)y * 90.0) / m_destImage.height());
+ if ( progress%5 == 0 )
+ postProgress( progress );
+ }
+}
+
+} // NameSpace DigikamImagesPluginCore
diff --git a/digikam/imageplugins/coreplugin/sharpnesseditor/unsharp.h b/digikam/imageplugins/coreplugin/sharpnesseditor/unsharp.h
new file mode 100644
index 0000000..74ff431
--- /dev/null
+++ b/digikam/imageplugins/coreplugin/sharpnesseditor/unsharp.h
@@ -0,0 +1,58 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-05-25
+ * Description : Unsharp Mask threaded image filter.
+ *
+ * Copyright (C) 2005-2007 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 UNSHARP_MASK_H
+#define UNSHARP_MASK_H
+
+// Local includes.
+
+#include "dimgthreadedfilter.h"
+
+namespace DigikamImagesPluginCore
+{
+
+class UnsharpMask : public Digikam::DImgThreadedFilter
+{
+
+public:
+
+ UnsharpMask(Digikam::DImg *orgImage, QObject *parent=0, int radius=1,
+ double amount=1.0, double threshold=0.05);
+
+ ~UnsharpMask(){};
+
+private:
+
+ virtual void filterImage(void);
+
+private:
+
+ int m_radius;
+
+ double m_amount;
+ double m_threshold;
+};
+
+} // NameSpace DigikamImagesPluginCore
+
+#endif /* UNSHARP_MASK_H */