diff options
Diffstat (limited to 'src/imageplugins/coreplugin')
98 files changed, 29724 insertions, 0 deletions
diff --git a/src/imageplugins/coreplugin/Makefile.am b/src/imageplugins/coreplugin/Makefile.am new file mode 100644 index 00000000..b36d6f36 --- /dev/null +++ b/src/imageplugins/coreplugin/Makefile.am @@ -0,0 +1,52 @@ +SUBDIRS = sharpnesseditor hsl ratiocrop +COMPILE_FIRST = sharpnesseditor hsl ratiocrop +METASOURCES = AUTO + +INCLUDES = -I$(top_srcdir)/src/utilities/imageeditor/editor \ + -I$(top_srcdir)/src/utilities/imageeditor/canvas \ + -I$(top_srcdir)/src/libs/histogram \ + -I$(top_srcdir)/src/libs/levels \ + -I$(top_srcdir)/src/libs/curves \ + -I$(top_srcdir)/src/libs/whitebalance \ + -I$(top_srcdir)/src/libs/widgets/common \ + -I$(top_srcdir)/src/libs/widgets/iccprofiles \ + -I$(top_srcdir)/src/libs/widgets/imageplugins \ + -I$(top_srcdir)/src/libs/dialogs \ + -I$(top_srcdir)/src/libs/dimg \ + -I$(top_srcdir)/src/libs/dmetadata \ + -I$(top_srcdir)/src/libs/dimg/filters \ + -I$(top_srcdir)/src/digikam \ + -I$(top_srcdir)/src/imageplugins/coreplugin/sharpnesseditor \ + -I$(top_srcdir)/src/imageplugins/coreplugin/hsl \ + -I$(top_srcdir)/src/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_TDEPARTS) \ + $(top_builddir)/src/imageplugins/coreplugin/sharpnesseditor/libsharpnesseditor.la \ + $(top_builddir)/src/imageplugins/coreplugin/hsl/libhsl.la \ + $(top_builddir)/src/imageplugins/coreplugin/ratiocrop/libratiocrop.la \ + $(top_builddir)/src/digikam/libdigikam.la \ + $(top_builddir)/src/utilities/imageeditor/editor/libdimgeditor.la \ + $(top_builddir)/src/libs/curves/libcurves.la \ + $(top_builddir)/src/libs/widgets/common/libcommonwidgets.la \ + $(top_builddir)/src/libs/widgets/imageplugins/libimagepluginswidgets.la + +digikamimageplugin_core_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -ltdecore -ltdeui $(LIB_TQT) -ltdefx -lkdcraw -ltdeio -lkexiv2 -ltdeutils + +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/src/imageplugins/coreplugin/autocorrectiontool.cpp b/src/imageplugins/coreplugin/autocorrectiontool.cpp new file mode 100644 index 00000000..32f00b44 --- /dev/null +++ b/src/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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqcheckbox.h> +#include <tqcolor.h> +#include <tqcombobox.h> +#include <tqframe.h> +#include <tqgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqhgroupbox.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqlistbox.h> +#include <tqpushbutton.h> +#include <tqradiobutton.h> +#include <tqtimer.h> +#include <tqtooltip.h> +#include <tqvbox.h> +#include <tqvgroupbox.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <tdeapplication.h> +#include <tdeconfig.h> +#include <kcursor.h> +#include <kiconloader.h> +#include <tdelocale.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(TQObject* 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, TQSize::ScaleMin); + m_destinationPreviewData = 0; + + EditorToolSettings *gboxSettings = new EditorToolSettings(EditorToolSettings::Default| + EditorToolSettings::Ok| + EditorToolSettings::Cancel); + + TQGridLayout* gridSettings = new TQGridLayout(gboxSettings->plainPage(), 2, 4); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), gboxSettings->plainPage()); + label1->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_channelCB = new TQComboBox( false, gboxSettings->plainPage() ); + m_channelCB->insertItem( i18n("Luminosity") ); + m_channelCB->insertItem( i18n("Red") ); + m_channelCB->insertItem( i18n("Green") ); + m_channelCB->insertItem( i18n("Blue") ); + TQWhatsThis::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 TQHButtonGroup(gboxSettings->plainPage()); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin( 0 ); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(linHistoButton, i18n("<p>Linear")); + m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap( TQPixmap( directory + "histogram-lin.png" ) ); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(logHistoButton, i18n("<p>Logarithmic")); + m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap(TQPixmap(directory + "histogram-log.png")); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(gboxSettings->plainPage()); + m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, histoBox); + m_hGradient->setColors(TQColor("black"), TQColor("white")); + + // ------------------------------------------------------------- + + m_correctionTools = new TQListBox(gboxSettings->plainPage()); + m_correctionTools->setColumnMode(1); + m_correctionTools->setVariableWidth(false); + m_correctionTools->setVariableHeight(false); + ListBoxWhatsThis* whatsThis = new ListBoxWhatsThis(m_correctionTools); + + TQPixmap 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, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget(const DColor&, const TQPoint&)), + this, TQ_SLOT(slotColorSelectedFromTarget(const DColor&))); + + connect(m_correctionTools, TQ_SIGNAL(highlighted(int)), + this, TQ_SLOT(slotEffect())); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_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( TQColor( "black" ), TQColor( "white" ) ); + break; + + case RedChannel: + m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "green" ) ); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "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() +{ + TDEConfig* 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() +{ + TDEConfig* 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(); +} + +TQPixmap 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); + TQString 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/src/imageplugins/coreplugin/autocorrectiontool.h b/src/imageplugins/coreplugin/autocorrectiontool.h new file mode 100644 index 00000000..73a388f2 --- /dev/null +++ b/src/imageplugins/coreplugin/autocorrectiontool.h @@ -0,0 +1,128 @@ +/* ============================================================ + * + * 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 + +// TQt includes. + +#include <tqstring.h> + +// Digikam includes. + +#include "editortool.h" + +class TQHButtonGroup; +class TQComboBox; +class TQListBox; +class TQButtonGroup; + +namespace Digikam +{ +class HistogramWidget; +class ColorGradientWidget; +class ImageWidget; +class DColor; +class DImg; +} + +namespace DigikamImagesPluginCore +{ + +class AutoCorrectionTool : public Digikam::EditorTool +{ + TQ_OBJECT + + +public: + + AutoCorrectionTool(TQObject *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); + TQPixmap getThumbnailForEffect(AutoCorrectionType type); + +private: + + enum HistogramScale + { + Linear=0, + Logarithmic + }; + + enum ColorChannel + { + LuminosityChannel=0, + RedChannel, + GreenChannel, + BlueChannel + }; + + uchar *m_destinationPreviewData; + + TQComboBox *m_channelCB; + + TQHButtonGroup *m_scaleBG; + + TQListBox *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/src/imageplugins/coreplugin/bcgtool.cpp b/src/imageplugins/coreplugin/bcgtool.cpp new file mode 100644 index 00000000..17ecf838 --- /dev/null +++ b/src/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 <[email protected]> + * 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqcheckbox.h> +#include <tqcolor.h> +#include <tqcombobox.h> +#include <tqframe.h> +#include <tqgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqhgroupbox.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqpushbutton.h> +#include <tqtooltip.h> +#include <tqvbox.h> +#include <tqvgroupbox.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <tdeapplication.h> +#include <tdeconfig.h> +#include <kcursor.h> +#include <kiconloader.h> +#include <tdelocale.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(TQObject* 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); + + TQGridLayout* gridSettings = new TQGridLayout(m_gboxSettings->plainPage(), 9, 4); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), m_gboxSettings->plainPage()); + label1->setAlignment(TQt::AlignRight | TQt::AlignVCenter); + m_channelCB = new TQComboBox(false, m_gboxSettings->plainPage()); + m_channelCB->insertItem(i18n("Luminosity")); + m_channelCB->insertItem(i18n("Red")); + m_channelCB->insertItem(i18n("Green")); + m_channelCB->insertItem(i18n("Blue")); + TQWhatsThis::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 TQHButtonGroup(m_gboxSettings->plainPage()); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin(0); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(linHistoButton, i18n("<p>Linear")); + m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap(TQPixmap(directory + "histogram-lin.png")); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(logHistoButton, i18n("<p>Logarithmic")); + m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap(TQPixmap(directory + "histogram-log.png")); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(m_gboxSettings->plainPage()); + m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, histoBox); + m_hGradient->setColors(TQColor("black"), TQColor("white")); + + // ------------------------------------------------------------- + + TQLabel *label2 = new TQLabel(i18n("Brightness:"), m_gboxSettings->plainPage()); + m_bInput = new RIntNumInput(m_gboxSettings->plainPage()); + m_bInput->setRange(-100, 100, 1); + m_bInput->setDefaultValue(0); + TQWhatsThis::add( m_bInput, i18n("<p>Set here the brightness adjustment of the image.")); + + TQLabel *label3 = new TQLabel(i18n("Contrast:"), m_gboxSettings->plainPage()); + m_cInput = new RIntNumInput(m_gboxSettings->plainPage()); + m_cInput->setRange(-100, 100, 1); + m_cInput->setDefaultValue(0); + TQWhatsThis::add( m_cInput, i18n("<p>Set here the contrast adjustment of the image.")); + + TQLabel *label4 = new TQLabel(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); + TQWhatsThis::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, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotColorSelectedFromTarget( const Digikam::DColor & ))); + + connect(m_bInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_cInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_gInput, TQ_SIGNAL(valueChanged(double)), + this, TQ_SLOT(slotTimer())); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_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(TQColor("black"), TQColor("white")); + break; + + case RedChannel: + m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("red")); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("green")); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("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() +{ + TDEConfig* 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() +{ + TDEConfig* 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/src/imageplugins/coreplugin/bcgtool.h b/src/imageplugins/coreplugin/bcgtool.h new file mode 100644 index 00000000..4a1e9d21 --- /dev/null +++ b/src/imageplugins/coreplugin/bcgtool.h @@ -0,0 +1,115 @@ +/* ============================================================ + * + * 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 <[email protected]> + * 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 TQCheckBox; +class TQComboBox; +class TQHButtonGroup; + +namespace KDcrawIface +{ +class RIntNumInput; +class RDoubleNumInput; +} + +namespace Digikam +{ +class HistogramWidget; +class ColorGradientWidget; +class ImageWidget; +class DColor; +} + +namespace DigikamImagesPluginCore +{ + +class BCGTool : public Digikam::EditorTool +{ + TQ_OBJECT + + +public: + + BCGTool(TQObject *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; + + TQComboBox *m_channelCB; + + TQHButtonGroup *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/src/imageplugins/coreplugin/blurtool.cpp b/src/imageplugins/coreplugin/blurtool.cpp new file mode 100644 index 00000000..85e1dc19 --- /dev/null +++ b/src/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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqlayout.h> +#include <tqlabel.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <tdeaboutdata.h> +#include <kiconloader.h> +#include <tdeconfig.h> +#include <kcursor.h> +#include <tdelocale.h> +#include <tdeapplication.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(TQObject* 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); + TQGridLayout* grid = new TQGridLayout( m_gboxSettings->plainPage(), 2, 1); + TQLabel *label = new TQLabel(i18n("Smoothness:"), m_gboxSettings->plainPage()); + + m_radiusInput = new RIntNumInput(m_gboxSettings->plainPage()); + m_radiusInput->setRange(0, 100, 1); + m_radiusInput->setDefaultValue(0); + TQWhatsThis::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() +{ + TDEConfig* config = kapp->config(); + config->setGroup("gaussianblur Tool"); + m_radiusInput->setValue(config->readNumEntry("RadiusAjustment", m_radiusInput->defaultValue())); +} + +void BlurTool::writeSettings() +{ + TDEConfig* 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/src/imageplugins/coreplugin/blurtool.h b/src/imageplugins/coreplugin/blurtool.h new file mode 100644 index 00000000..545f4aa2 --- /dev/null +++ b/src/imageplugins/coreplugin/blurtool.h @@ -0,0 +1,81 @@ +/* ============================================================ + * + * 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 +{ + TQ_OBJECT + + +public: + + BlurTool(TQObject *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/src/imageplugins/coreplugin/bwsepiatool.cpp b/src/imageplugins/coreplugin/bwsepiatool.cpp new file mode 100644 index 00000000..06c30462 --- /dev/null +++ b/src/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 <[email protected]> + * 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqcolor.h> +#include <tqcombobox.h> +#include <tqfile.h> +#include <tqframe.h> +#include <tqgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqhgroupbox.h> +#include <tqintdict.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqlistbox.h> +#include <tqpushbutton.h> +#include <tqtextstream.h> +#include <tqtimer.h> +#include <tqtooltip.h> +#include <tqvbox.h> +#include <tqvgroupbox.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <tdeapplication.h> +#include <tdeconfig.h> +#include <kcursor.h> +#include <tdefiledialog.h> +#include <tdeglobalsettings.h> +#include <kiconloader.h> +#include <tdelocale.h> +#include <tdemessagebox.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 TQObject +{ +public: + + PreviewPixmapFactory(BWSepiaTool* bwSepia); + + void invalidate() { m_previewPixmapMap.clear(); } + + const TQPixmap* pixmap(int id); + +private: + + TQPixmap makePixmap(int id); + + TQIntDict<TQPixmap> m_previewPixmapMap; + BWSepiaTool *m_bwSepia; +}; + +PreviewPixmapFactory::PreviewPixmapFactory(BWSepiaTool* bwSepia) + : TQObject(bwSepia), m_bwSepia(bwSepia) +{ + m_previewPixmapMap.setAutoDelete(true); +} + +const TQPixmap* PreviewPixmapFactory::pixmap(int id) +{ + if (m_previewPixmapMap.find(id) == 0) + { + TQPixmap pix = makePixmap(id); + m_previewPixmapMap.insert(id, new TQPixmap(pix)); + } + + TQPixmap* res = m_previewPixmapMap[id]; + + return res; +} + +TQPixmap PreviewPixmapFactory::makePixmap(int id) +{ + return m_bwSepia->getThumbnailForEffect(id); +} + +// ----------------------------------------------------------------------------------- + +class ListBoxBWPreviewItem : public ListBoxPreviewItem +{ + +public: + + ListBoxBWPreviewItem(TQListBox *listbox, const TQString &text, + PreviewPixmapFactory* factory, int id) + : ListBoxPreviewItem(listbox, TQPixmap(), text) + { + m_previewPixmapFactory = factory; + m_id = id; + }; + + virtual const TQPixmap* pixmap() const; + +private: + + int m_id; + PreviewPixmapFactory* m_previewPixmapFactory; +}; + +const TQPixmap* ListBoxBWPreviewItem::pixmap() const +{ + return m_previewPixmapFactory->pixmap(m_id); +} + +// ----------------------------------------------------------------------------------- + +BWSepiaTool::BWSepiaTool(TQObject* 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, TQSize::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); + + TQGridLayout* gridSettings = new TQGridLayout(gboxSettings->plainPage(), 4, 4); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), gboxSettings->plainPage()); + label1->setAlignment(TQt::AlignRight | TQt::AlignVCenter); + m_channelCB = new TQComboBox(false, gboxSettings->plainPage()); + m_channelCB->insertItem(i18n("Luminosity")); + m_channelCB->insertItem(i18n("Red")); + m_channelCB->insertItem(i18n("Green")); + m_channelCB->insertItem(i18n("Blue")); + TQWhatsThis::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 TQHButtonGroup(gboxSettings->plainPage()); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin(0); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(linHistoButton, i18n("<p>Linear")); + m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap(TQPixmap(directory + "histogram-lin.png")); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(logHistoButton, i18n("<p>Logarithmic")); + m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap(TQPixmap(directory + "histogram-log.png")); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(gboxSettings->plainPage()); + m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, histoBox); + m_hGradient->setColors(TQColor("black"), TQColor("white")); + + gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4); + + // ------------------------------------------------------------- + + m_tab = new KTabWidget(gboxSettings->plainPage()); + + m_bwFilm = new TQListBox(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>")); + + // ------------------------------------------------------------- + + TQVBox *vbox = new TQVBox(m_tab); + + m_bwFilters = new TQListBox(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); + TQWhatsThis::add(m_strengthInput, i18n("<p>Here, set the strength adjustment of the lens filter.")); + + // ------------------------------------------------------------- + + m_bwTone = new TQListBox(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>")); + + // ------------------------------------------------------------- + + TQWidget *curveBox = new TQWidget( m_tab ); + TQGridLayout *gridTab2 = new TQGridLayout(curveBox, 5, 2, 0); + + ColorGradientWidget* vGradient = new ColorGradientWidget( + ColorGradientWidget::Vertical, + 10, curveBox); + vGradient->setColors(TQColor("white"), TQColor("black")); + + TQLabel *spacev = new TQLabel(curveBox); + spacev->setFixedWidth(1); + + m_curvesWidget = new CurvesWidget(256, 256, m_originalImage->bits(), m_originalImage->width(), + m_originalImage->height(), m_originalImage->sixteenBit(), + curveBox); + TQWhatsThis::add( m_curvesWidget, i18n("<p>This is the curve adjustment of the image luminosity")); + + TQLabel *spaceh = new TQLabel(curveBox); + spaceh->setFixedHeight(1); + + ColorGradientWidget *hGradient = new ColorGradientWidget( + ColorGradientWidget::Horizontal, + 10, curveBox); + hGradient->setColors(TQColor("black"), TQColor("white")); + + m_cInput = new RIntNumInput(curveBox); + m_cInput->input()->setLabel(i18n("Contrast:"), AlignLeft | AlignVCenter); + m_cInput->setRange(-100, 100, 1); + m_cInput->setDefaultValue(0); + TQWhatsThis::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, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromOriginal(const Digikam::DColor&, const TQPoint&)), + this, TQ_SLOT(slotSpotColorChanged(const Digikam::DColor&))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotColorSelectedFromTarget( const Digikam::DColor & ))); + + connect(m_bwFilters, TQ_SIGNAL(highlighted(int)), + this, TQ_SLOT(slotFilterSelected(int))); + + connect(m_strengthInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_bwFilm, TQ_SIGNAL(highlighted(int)), + this, TQ_SLOT(slotEffect())); + + connect(m_bwTone, TQ_SIGNAL(highlighted(int)), + this, TQ_SLOT(slotEffect())); + + connect(m_curvesWidget, TQ_SIGNAL(signalCurvesChanged()), + this, TQ_SLOT(slotTimer())); + + connect(m_cInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_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(); +} + +TQPixmap 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(TQColor("black"), TQColor("white")); + break; + + case RedChannel: + m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("red")); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("green")); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("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() +{ + TDEConfig* 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++) + { + TQPoint disable(-1, -1); + TQPoint p = config->readPointEntry(TQString("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() +{ + TDEConfig* 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++) + { + TQPoint 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(TQString("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(TDEGlobalSettings::documentPath(), + TQString( "*" ), kapp->activeWindow(), + TQString( i18n("Black & White Settings File to Load")) ); + if( loadFile.isEmpty() ) + return; + + TQFile file(loadFile.path()); + + if (file.open(IO_ReadOnly)) + { + TQTextStream 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++) + { + TQPoint disable(-1, -1); + TQPoint 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(TDEGlobalSettings::documentPath(), + TQString( "*" ), kapp->activeWindow(), + TQString( i18n("Black & White Settings File to Save"))); + if( saveFile.isEmpty() ) + return; + + TQFile file(saveFile.path()); + + if (file.open(IO_WriteOnly)) + { + TQTextStream 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++) + { + TQPoint 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/src/imageplugins/coreplugin/bwsepiatool.h b/src/imageplugins/coreplugin/bwsepiatool.h new file mode 100644 index 00000000..7145f567 --- /dev/null +++ b/src/imageplugins/coreplugin/bwsepiatool.h @@ -0,0 +1,193 @@ +/* ============================================================ + * + * 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 <[email protected]> + * 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 + +// TQt includes. + +#include <tqstring.h> + +// Digikam includes. + +#include "editortool.h" + +class TQHButtonGroup; +class TQComboBox; +class TQButtonGroup; +class TQListBox; + +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 +{ + TQ_OBJECT + + +public: + + BWSepiaTool(TQObject *parent); + ~BWSepiaTool(); + + friend class PreviewPixmapFactory; + +protected: + + TQPixmap 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; + + TQComboBox *m_channelCB; + + TQHButtonGroup *m_scaleBG; + + TQListBox *m_bwFilters; + TQListBox *m_bwFilm; + TQListBox *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/src/imageplugins/coreplugin/digikamimageplugin_core.desktop b/src/imageplugins/coreplugin/digikamimageplugin_core.desktop new file mode 100644 index 00000000..8f8b3d10 --- /dev/null +++ b/src/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 +X-TDE-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-TDE-Library=digikamimageplugin_core +author=Caulier Gilles, caulier dot gilles at gmail dot com diff --git a/src/imageplugins/coreplugin/digikamimageplugin_core_ui.rc b/src/imageplugins/coreplugin/digikamimageplugin_core_ui.rc new file mode 100644 index 00000000..cb1148bd --- /dev/null +++ b/src/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>&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>&Depth</text> + <Action name="implugcore_convertto8bits" /> + <Action name="implugcore_convertto16bits" /> + </Menu> + <Separator /> + <Action name="implugcore_colormanagement" /> + <Separator /> + </Menu> + <Menu name="Enhance"><text>Enh&ance</text> + <Action name="implugcore_sharpen" /> + <Action name="implugcore_blur" /> + <Separator /> + <Action name="implugcore_redeye" /> + </Menu> + + <Menu name="Transform" ><text>Tra&nsform</text> + <Action name="implugcore_ratiocrop" /> + </Menu> + + <Menu name="Filters" ><text>F&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/src/imageplugins/coreplugin/hsl/Makefile.am b/src/imageplugins/coreplugin/hsl/Makefile.am new file mode 100644 index 00000000..4465d44c --- /dev/null +++ b/src/imageplugins/coreplugin/hsl/Makefile.am @@ -0,0 +1,26 @@ +noinst_LTLIBRARIES = libhsl.la +METASOURCES = AUTO + +INCLUDES = -I$(top_srcdir)/src/utilities/imageeditor/editor \ + -I$(top_srcdir)/src/utilities/imageeditor/canvas \ + -I$(top_srcdir)/src/libs/histogram \ + -I$(top_srcdir)/src/libs/levels \ + -I$(top_srcdir)/src/libs/curves \ + -I$(top_srcdir)/src/libs/whitebalance \ + -I$(top_srcdir)/src/libs/widgets/common \ + -I$(top_srcdir)/src/libs/widgets/iccprofiles \ + -I$(top_srcdir)/src/libs/widgets/imageplugins \ + -I$(top_srcdir)/src/libs/dialogs \ + -I$(top_srcdir)/src/libs/dimg \ + -I$(top_srcdir)/src/libs/dmetadata \ + -I$(top_srcdir)/src/libs/dimg/filters \ + -I$(top_srcdir)/src/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/src/imageplugins/coreplugin/hsl/hsltool.cpp b/src/imageplugins/coreplugin/hsl/hsltool.cpp new file mode 100644 index 00000000..5fa3d746 --- /dev/null +++ b/src/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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqcolor.h> +#include <tqcombobox.h> +#include <tqframe.h> +#include <tqgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqhgroupbox.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqpushbutton.h> +#include <tqtimer.h> +#include <tqtooltip.h> +#include <tqvbox.h> +#include <tqvgroupbox.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <tdeapplication.h> +#include <kcolordialog.h> +#include <tdeconfig.h> +#include <kcursor.h> +#include <kiconloader.h> +#include <tdelocale.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(TQObject* 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); + + TQGridLayout* gridSettings = new TQGridLayout(m_gboxSettings->plainPage(), 11, 4); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), m_gboxSettings->plainPage()); + label1->setAlignment(TQt::AlignRight | TQt::AlignVCenter); + m_channelCB = new TQComboBox(false, m_gboxSettings->plainPage()); + m_channelCB->insertItem(i18n("Luminosity")); + m_channelCB->insertItem(i18n("Red")); + m_channelCB->insertItem(i18n("Green")); + m_channelCB->insertItem(i18n("Blue")); + TQWhatsThis::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 TQHButtonGroup(m_gboxSettings->plainPage()); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin( 0 ); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(linHistoButton, i18n("<p>Linear")); + m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap(TQPixmap(directory + "histogram-lin.png")); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(logHistoButton, i18n("<p>Logarithmic")); + m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap(TQPixmap(directory + "histogram-log.png")); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(m_gboxSettings->plainPage()); + m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, histoBox); + m_hGradient->setColors(TQColor("black"), TQColor("white")); + + gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4); + + // ------------------------------------------------------------- + + m_HSSelector = new KHSSelector(m_gboxSettings->plainPage()); + TQWhatsThis::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()); + TQWhatsThis::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); + + TQLabel *label2 = new TQLabel(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); + TQWhatsThis::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); + + TQLabel *label3 = new TQLabel(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); + TQWhatsThis::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); + + TQLabel *label4 = new TQLabel(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); + TQWhatsThis::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, TQ_SIGNAL(valueChanged(int, int)), + this, TQ_SLOT(slotHSChanged(int, int))); + + connect(m_channelCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotColorSelectedFromTarget( const Digikam::DColor & ))); + + connect(m_hInput, TQ_SIGNAL(valueChanged (double)), + this, TQ_SLOT(slotTimer())); + + connect(m_hInput, TQ_SIGNAL(valueChanged (double)), + this, TQ_SLOT(slotHChanged(double))); + + connect(m_sInput, TQ_SIGNAL(valueChanged (double)), + this, TQ_SLOT(slotTimer())); + + connect(m_sInput, TQ_SIGNAL(valueChanged (double)), + this, TQ_SLOT(slotSChanged(double))); + + connect(m_lInput, TQ_SIGNAL(valueChanged (double)), + this, TQ_SLOT(slotTimer())); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_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(TQColor("black"), TQColor("white")); + break; + + case RedChannel: + m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("red")); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("green")); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("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() +{ + TDEConfig* 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() +{ + TDEConfig* 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/src/imageplugins/coreplugin/hsl/hsltool.h b/src/imageplugins/coreplugin/hsl/hsltool.h new file mode 100644 index 00000000..751bacf3 --- /dev/null +++ b/src/imageplugins/coreplugin/hsl/hsltool.h @@ -0,0 +1,126 @@ +/* ============================================================ + * + * 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 TQComboBox; +class TQHButtonGroup; + +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 +{ + TQ_OBJECT + + +public: + + HSLTool(TQObject *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; + + TQComboBox *m_channelCB; + + TQHButtonGroup *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/src/imageplugins/coreplugin/hsl/hspreviewwidget.cpp b/src/imageplugins/coreplugin/hsl/hspreviewwidget.cpp new file mode 100644 index 00000000..3841ca38 --- /dev/null +++ b/src/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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqdrawutil.h> +#include <tqimage.h> +#include <tqpainter.h> +#include <tqpixmap.h> + +// KDE includes. + +#include <tdeapplication.h> +#include <tdelocale.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; + + TQPixmap pixmap; +}; + +HSPreviewWidget::HSPreviewWidget(TQWidget *parent, int xBorder) + : TQWidget(parent, 0, TQt::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( TQResizeEvent * ) +{ + updatePixmap(); +} + +void HSPreviewWidget::paintEvent( TQPaintEvent * ) +{ + 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); + TQColor 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/src/imageplugins/coreplugin/hsl/hspreviewwidget.h b/src/imageplugins/coreplugin/hsl/hspreviewwidget.h new file mode 100644 index 00000000..3744907c --- /dev/null +++ b/src/imageplugins/coreplugin/hsl/hspreviewwidget.h @@ -0,0 +1,64 @@ +/* ============================================================ + * + * 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 + +// TQt includes. + +#include <tqwidget.h> + +namespace DigikamImagesPluginCore +{ + +class HSPreviewWidgetPrivate; + +class HSPreviewWidget : public TQWidget +{ + TQ_OBJECT + + +public: + + HSPreviewWidget(TQWidget *parent=0, int xBorder=0); + ~HSPreviewWidget(); + + void setHS(double hue, double sat); + +protected: + + void resizeEvent( TQResizeEvent * ); + void paintEvent( TQPaintEvent * ); + +private: + + void updatePixmap(); + +private: + + HSPreviewWidgetPrivate *d; +}; + +} // NameSpace DigikamImagesPluginCore + +#endif /* HSPREVIEWWIDGET_H */ diff --git a/src/imageplugins/coreplugin/hsl/imageeffect_hsl.cpp b/src/imageplugins/coreplugin/hsl/imageeffect_hsl.cpp new file mode 100644 index 00000000..e179d36f --- /dev/null +++ b/src/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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqcolor.h> +#include <tqgroupbox.h> +#include <tqhgroupbox.h> +#include <tqvgroupbox.h> +#include <tqvbox.h> +#include <tqhbuttongroup.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqframe.h> +#include <tqlabel.h> +#include <tqpushbutton.h> +#include <tqcombobox.h> +#include <tqwhatsthis.h> +#include <tqtooltip.h> +#include <tqtimer.h> + +// KDE includes. + +#include <knuminput.h> +#include <tdelocale.h> +#include <tdeapplication.h> +#include <tdeconfig.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(TQWidget* 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); + + // ------------------------------------------------------------- + + TQWidget *gboxSettings = new TQWidget(plainPage()); + TQGridLayout* gridSettings = new TQGridLayout(gboxSettings, 11, 4, spacingHint()); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), gboxSettings); + label1->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_channelCB = new TQComboBox( false, gboxSettings ); + m_channelCB->insertItem( i18n("Luminosity") ); + m_channelCB->insertItem( i18n("Red") ); + m_channelCB->insertItem( i18n("Green") ); + m_channelCB->insertItem( i18n("Blue") ); + TQWhatsThis::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 TQHButtonGroup(gboxSettings); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin( 0 ); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( linHistoButton, i18n( "<p>Linear" ) ); + m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap( TQPixmap( directory + "histogram-lin.png" ) ); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) ); + m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap( TQPixmap( directory + "histogram-log.png" ) ); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(gboxSettings); + m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new Digikam::ColorGradientWidget( Digikam::ColorGradientWidget::Horizontal, 10, histoBox ); + m_hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + + gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4); + + // ------------------------------------------------------------- + + m_HSSelector = new KHSSelector(gboxSettings); + TQWhatsThis::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()); + TQWhatsThis::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); + + TQLabel *label2 = new TQLabel(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); + TQWhatsThis::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); + + TQLabel *label3 = new TQLabel(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); + TQWhatsThis::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); + + TQLabel *label4 = new TQLabel(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); + TQWhatsThis::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, TQ_SIGNAL(valueChanged(int, int)), + this, TQ_SLOT(slotHSChanged(int, int))); + + connect(m_channelCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotColorSelectedFromTarget( const Digikam::DColor & ))); + + connect(m_hInput, TQ_SIGNAL(valueChanged (double)), + this, TQ_SLOT(slotTimer())); + + connect(m_hInput, TQ_SIGNAL(valueChanged (double)), + this, TQ_SLOT(slotHChanged(double))); + + connect(m_sInput, TQ_SIGNAL(valueChanged (double)), + this, TQ_SLOT(slotTimer())); + + connect(m_sInput, TQ_SIGNAL(valueChanged (double)), + this, TQ_SLOT(slotSChanged(double))); + + connect(m_lInput, TQ_SIGNAL(valueChanged (double)), + this, TQ_SLOT(slotTimer())); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_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( TQColor( "black" ), TQColor( "white" ) ); + break; + + case RedChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "green" ) ); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "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() +{ + TDEConfig* 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() +{ + TDEConfig* 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/src/imageplugins/coreplugin/hsl/imageeffect_hsl.h b/src/imageplugins/coreplugin/hsl/imageeffect_hsl.h new file mode 100644 index 00000000..24880f4d --- /dev/null +++ b/src/imageplugins/coreplugin/hsl/imageeffect_hsl.h @@ -0,0 +1,116 @@ +/* ============================================================ + * + * 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 TQComboBox; +class TQHButtonGroup; + +class KDoubleNumInput; +class KHSSelector; + +namespace Digikam +{ +class HistogramWidget; +class ColorGradientWidget; +class ImageWidget; +class DColor; +} + +namespace DigikamImagesPluginCore +{ +class HSPreviewWidget; + +class ImageEffect_HSL : public Digikam::ImageDlgBase +{ + TQ_OBJECT + + +public: + + ImageEffect_HSL(TQWidget *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; + + TQComboBox *m_channelCB; + + TQHButtonGroup *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/src/imageplugins/coreplugin/iccprooftool.cpp b/src/imageplugins/coreplugin/iccprooftool.cpp new file mode 100644 index 00000000..b74adf9a --- /dev/null +++ b/src/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 <[email protected]> + * 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqcheckbox.h> +#include <tqcolor.h> +#include <tqcombobox.h> +#include <tqfile.h> +#include <tqframe.h> +#include <tqgroupbox.h> +#include <tqhbox.h> +#include <tqhbuttongroup.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqpoint.h> +#include <tqpushbutton.h> +#include <tqradiobutton.h> +#include <tqtextstream.h> +#include <tqtoolbox.h> +#include <tqtooltip.h> +#include <tqvbox.h> +#include <tqvbuttongroup.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <tdeapplication.h> +#include <tdeconfig.h> +#include <kcursor.h> +#include <tdefile.h> +#include <tdefiledialog.h> +#include <tdeglobalsettings.h> +#include <kiconloader.h> +#include <tdelocale.h> +#include <tdemessagebox.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(TQObject* 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); + + TQGridLayout *gridSettings = new TQGridLayout(m_gboxSettings->plainPage(), 3, 2); + + TQLabel *label1 = new TQLabel(i18n("Channel: "), m_gboxSettings->plainPage()); + label1->setAlignment(TQt::AlignRight | TQt::AlignVCenter); + m_channelCB = new TQComboBox(false, m_gboxSettings->plainPage()); + m_channelCB->insertItem(i18n("Luminosity")); + m_channelCB->insertItem(i18n("Red")); + m_channelCB->insertItem(i18n("Green")); + m_channelCB->insertItem(i18n("Blue")); + TQWhatsThis::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 TQHButtonGroup(m_gboxSettings->plainPage()); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin(0); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(linHistoButton, i18n("<p>Linear")); + m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap(TQPixmap(directory + "histogram-lin.png")); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(logHistoButton, i18n("<p>Logarithmic")); + m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap(TQPixmap(directory + "histogram-log.png")); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + gridSettings->addMultiCellLayout(l1, 0, 0, 0, 2); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(m_gboxSettings->plainPage()); + m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new ColorGradientWidget( ColorGradientWidget::Horizontal, 10, + histoBox ); + m_hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + + gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 2); + + // ------------------------------------------------------------- + + m_toolBoxWidgets = new TQToolBox(m_gboxSettings->plainPage()); + TQWidget *generalOptions = new TQWidget(m_toolBoxWidgets); + TQWidget *inProfiles = new TQWidget(m_toolBoxWidgets); + TQWidget *spaceProfiles = new TQWidget(m_toolBoxWidgets); + TQWidget *proofProfiles = new TQWidget(m_toolBoxWidgets); + TQWidget *lightnessadjust = new TQWidget(m_toolBoxWidgets); + + //---------- "General" Page Setup ---------------------------------- + + m_toolBoxWidgets->insertItem(GENERALPAGE, generalOptions, + SmallIconSet("misc"), i18n("General Settings")); + TQWhatsThis::add(generalOptions, i18n("<p>Here you can set general parameters.</p>")); + + TQGridLayout *zeroPageLayout = new TQGridLayout(generalOptions, 5, 1); + + m_doSoftProofBox = new TQCheckBox(generalOptions); + m_doSoftProofBox->setText(i18n("Soft-proofing")); + TQWhatsThis::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 TQCheckBox(generalOptions); + m_checkGamutBox->setText(i18n("Check gamut")); + TQWhatsThis::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 TQCheckBox(generalOptions); + m_embeddProfileBox->setChecked(true); + m_embeddProfileBox->setText(i18n("Assign profile")); + TQWhatsThis::add(m_embeddProfileBox, i18n("<p>You can use this option to embed " + "the selected workspace color profile into the image.</p>")); + + m_BPCBox = new TQCheckBox(generalOptions); + m_BPCBox->setText(i18n("Use BPC")); + TQWhatsThis::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>")); + + TQLabel *intent = new TQLabel(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); + TQWhatsThis::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(TQString()); + lcmsLogoLabel->setURL("http://www.littlecms.com"); + TDEGlobal::dirs()->addResourceType("logo-lcms", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("logo-lcms", "logo-lcms.png"); + lcmsLogoLabel->setPixmap(TQPixmap(directory + "logo-lcms.png")); + TQToolTip::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-photo"), i18n("Input Profile")); + TQWhatsThis::add(inProfiles, i18n("<p>Set here all parameters relevant of Input Color " + "Profiles.</p>")); + + TQGridLayout *firstPageLayout = new TQGridLayout(inProfiles, 4, 2); + + m_inProfileBG = new TQButtonGroup(4, TQt::Vertical, inProfiles); + m_inProfileBG->setFrameStyle(TQFrame::NoFrame); + m_inProfileBG->setInsideMargin(0); + + m_useEmbeddedProfile = new TQRadioButton(m_inProfileBG); + m_useEmbeddedProfile->setText(i18n("Use embedded profile")); + + m_useSRGBDefaultProfile = new TQRadioButton(m_inProfileBG); + m_useSRGBDefaultProfile->setText(i18n("Use builtin sRGB profile")); + m_useSRGBDefaultProfile->setChecked(true); + + m_useInDefaultProfile = new TQRadioButton(m_inProfileBG); + m_useInDefaultProfile->setText(i18n("Use default profile")); + + m_useInSelectedProfile = new TQRadioButton(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); + + TQPushButton *inProfilesInfo = new TQPushButton(i18n("Info..."), inProfiles); + + TQGroupBox *pictureInfo = new TQGroupBox(2, TQt::Horizontal, i18n("Camera information"), inProfiles); + new TQLabel(i18n("Make:"), pictureInfo); + KSqueezedTextLabel *make = new KSqueezedTextLabel(0, pictureInfo); + new TQLabel(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("input-tablet"), i18n("Workspace Profile")); + TQWhatsThis::add(spaceProfiles, i18n("<p>Set here all parameters relevant to Color Workspace " + "Profiles.</p>")); + + TQGridLayout *secondPageLayout = new TQGridLayout(spaceProfiles, 3, 2); + + m_spaceProfileBG = new TQButtonGroup(2, TQt::Vertical, spaceProfiles); + m_spaceProfileBG->setFrameStyle(TQFrame::NoFrame); + m_spaceProfileBG->setInsideMargin(0); + + m_useSpaceDefaultProfile = new TQRadioButton(m_spaceProfileBG); + m_useSpaceDefaultProfile->setText(i18n("Use default workspace profile")); + + m_useSpaceSelectedProfile = new TQRadioButton(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); + + TQPushButton *spaceProfilesInfo = new TQPushButton(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("printer"), i18n("Proofing Profile")); + TQWhatsThis::add(proofProfiles, i18n("<p>Set here all parameters relevant to Proofing Color " + "Profiles.</p>")); + + TQGridLayout *thirdPageLayout = new TQGridLayout(proofProfiles, 3, 2); + + m_proofProfileBG = new TQButtonGroup(2, TQt::Vertical, proofProfiles); + m_proofProfileBG->setFrameStyle(TQFrame::NoFrame); + m_proofProfileBG->setInsideMargin(0); + + m_useProofDefaultProfile = new TQRadioButton(m_proofProfileBG); + m_useProofDefaultProfile->setText(i18n("Use default proof profile")); + + m_useProofSelectedProfile = new TQRadioButton(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); + + TQPushButton *proofProfilesInfo = new TQPushButton(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")); + TQWhatsThis::add(lightnessadjust, i18n("<p>Set here all lightness adjustments to the target image.</p>")); + + TQGridLayout *fourPageLayout = new TQGridLayout( lightnessadjust, 5, 2); + + ColorGradientWidget* vGradient = new ColorGradientWidget(ColorGradientWidget::Vertical, + 10, lightnessadjust ); + vGradient->setColors(TQColor("white"), TQColor("black")); + + TQLabel *spacev = new TQLabel(lightnessadjust); + spacev->setFixedWidth(1); + + m_curvesWidget = new CurvesWidget(256, 192, m_originalImage->bits(), m_originalImage->width(), + m_originalImage->height(), m_originalImage->sixteenBit(), + lightnessadjust); + TQWhatsThis::add( m_curvesWidget, i18n("<p>This is the curve adjustment of the image luminosity")); + + TQLabel *spaceh = new TQLabel(lightnessadjust); + spaceh->setFixedHeight(1); + + ColorGradientWidget *hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, + 10, + lightnessadjust); + + hGradient->setColors(TQColor("black"), TQColor("white")); + + m_cInput = new RIntNumInput(lightnessadjust); + m_cInput->input()->setLabel(i18n("Contrast:"), AlignLeft | AlignVCenter); + m_cInput->setRange(-100, 100, 1); + m_cInput->setDefaultValue(0); + TQWhatsThis::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, TQ_SIGNAL(leftClickedURL(const TQString&)), + this, TQ_SLOT(processLCMSURL(const TQString&))); + + connect(m_channelCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_curvesWidget, TQ_SIGNAL(signalCurvesChanged()), + this, TQ_SLOT(slotTimer())); + + connect(m_cInput, TQ_SIGNAL(valueChanged (int)), + this, TQ_SLOT(slotTimer())); + + connect(m_renderingIntentsCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotEffect())); + + //-- Check box options connections ------------------------------------------- + + connect(m_doSoftProofBox, TQ_SIGNAL(toggled (bool)), + this, TQ_SLOT(slotEffect())); + + connect(m_checkGamutBox, TQ_SIGNAL(toggled (bool)), + this, TQ_SLOT(slotEffect())); + + connect(m_BPCBox, TQ_SIGNAL(toggled (bool)), + this, TQ_SLOT(slotEffect())); + + //-- Button Group ICC profile options connections ---------------------------- + + connect(m_inProfileBG, TQ_SIGNAL(released (int)), + this, TQ_SLOT(slotEffect())); + + connect(m_spaceProfileBG, TQ_SIGNAL(released (int)), + this, TQ_SLOT(slotEffect())); + + connect(m_proofProfileBG, TQ_SIGNAL(released (int)), + this, TQ_SLOT(slotEffect())); + + //-- url requester ICC profile connections ----------------------------------- + + connect(m_inProfilesPath, TQ_SIGNAL(urlSelected(const TQString&)), + this, TQ_SLOT(slotEffect())); + + connect(m_spaceProfilePath, TQ_SIGNAL(urlSelected(const TQString&)), + this, TQ_SLOT(slotEffect())); + + connect(m_proofProfilePath, TQ_SIGNAL(urlSelected(const TQString&)), + this, TQ_SLOT(slotEffect())); + + //-- Image preview widget connections ---------------------------- + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_SLOT(slotEffect())); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromOriginal( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotSpotColorChanged( const Digikam::DColor & ))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotColorSelectedFromTarget( const Digikam::DColor & ))); + + //-- ICC profile preview connections ----------------------------- + + connect(inProfilesInfo, TQ_SIGNAL(clicked()), + this, TQ_SLOT(slotInICCInfo())); + + connect(spaceProfilesInfo, TQ_SIGNAL(clicked()), + this, TQ_SLOT(slotSpaceICCInfo())); + + connect(proofProfilesInfo, TQ_SIGNAL(clicked()), + this, TQ_SLOT(slotProofICCInfo())); +} + +ICCProofTool::~ICCProofTool() +{ + if (m_destinationPreviewData) + delete [] m_destinationPreviewData; +} + +void ICCProofTool::readSettings() +{ + TQString defaultICCPath = TDEGlobalSettings::documentPath(); + TDEConfig* 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 (TQFile::exists(config->readPathEntry("DefaultPath"))) + { + defaultICCPath = config->readPathEntry("DefaultPath"); + } + else + { + TQString 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++) + { + TQPoint disable(-1, -1); + TQPoint p = config->readPointEntry(TQString("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() +{ + TDEConfig* 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++) + { + TQPoint 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(TQString("CurveAjustmentPoint%1").arg(j), p); + } + + m_previewWidget->writeSettings(); + config->sync(); +} + +void ICCProofTool::processLCMSURL(const TQString& url) +{ + TDEApplication::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(TQColor("black"), TQColor("white")); + break; + + case RedChannel: + m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("red")); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("green")); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("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); + + TQString tmpInPath = TQString(); + TQString tmpProofPath = TQString(); + TQString tmpSpacePath = TQString(); + + bool proofCondition = false; + bool spaceCondition = false; + + //-- Input profile parameters ------------------ + + if (useDefaultInProfile()) + { + tmpInPath = m_inPath; + } + else if (useSelectedInProfile()) + { + tmpInPath = m_inProfilesPath->url(); + TQFileInfo 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(); + TQFileInfo 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(); + TQFileInfo 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(); + TQString 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 + { + TQByteArray fakeProfile = TQByteArray(); + 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); + + TQString tmpInPath; + TQString tmpProofPath; + TQString tmpSpacePath; + bool proofCondition; + + //-- Input profile parameters ------------------ + + if (useDefaultInProfile()) + { + tmpInPath = m_inPath; + } + else if (useSelectedInProfile()) + { + tmpInPath = m_inProfilesPath->url(); + TQFileInfo 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(); + TQFileInfo 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(); + TQFileInfo 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 + { + TQByteArray fakeProfile = TQByteArray(); + 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 << TQFile::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()) + { + TQString 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 TQString& 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 TQByteArray& 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(), TQString(), profile); + infoDlg.exec(); +} + +void ICCProofTool::slotCMDisabledWarning() +{ + if (!m_cmEnabled) + { + TQString 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(TDEGlobalSettings::documentPath(), + TQString("*"), kapp->activeWindow(), + TQString(i18n("Color Management Settings File to Load"))); + if (loadColorManagementFile.isEmpty()) + return; + + TQFile file(loadColorManagementFile.path()); + + if (file.open(IO_ReadOnly)) + { + TQTextStream 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++) + { + TQPoint disable(-1, -1); + TQPoint 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(TDEGlobalSettings::documentPath(), + TQString( "*" ), kapp->activeWindow(), + TQString(i18n("Color Management Settings File to Save"))); + if (saveColorManagementFile.isEmpty()) + return; + + TQFile file(saveColorManagementFile.path()); + + if (file.open(IO_WriteOnly)) + { + TQTextStream 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++) + { + TQPoint 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/src/imageplugins/coreplugin/iccprooftool.h b/src/imageplugins/coreplugin/iccprooftool.h new file mode 100644 index 00000000..86d93ea9 --- /dev/null +++ b/src/imageplugins/coreplugin/iccprooftool.h @@ -0,0 +1,209 @@ +/* ============================================================ + * + * 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 <[email protected]> + * 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 TQCheckBox; +class TQComboBox; +class TQVButtonGroup; +class TQButtonGroup; +class TQHButtonGroup; +class TQRadioButton; +class TQPushButton; +class TQToolBox; + +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 +{ + TQ_OBJECT + + +public: + + ICCProofTool(TQObject* parent); + ~ICCProofTool(); + +protected: + + void finalRendering(); + +private: + + void readSettings(); + void writeSettings(); + + void getICCInfo(const TQString&); + void getICCInfo(const TQByteArray&); + + 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 TQString&); + +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; + + TQComboBox *m_channelCB; + + TQCheckBox *m_doSoftProofBox; + TQCheckBox *m_checkGamutBox; + TQCheckBox *m_embeddProfileBox; + TQCheckBox *m_BPCBox; + + TQRadioButton *m_useEmbeddedProfile; + TQRadioButton *m_useInDefaultProfile; + TQRadioButton *m_useInSelectedProfile; + TQRadioButton *m_useProofDefaultProfile; + TQRadioButton *m_useProofSelectedProfile; + TQRadioButton *m_useSpaceDefaultProfile; + TQRadioButton *m_useSpaceSelectedProfile; + TQRadioButton *m_useSRGBDefaultProfile; + + TQString m_inPath; + TQString m_spacePath; + TQString m_proofPath; + + TQButtonGroup *m_optionsBG; + TQButtonGroup *m_inProfileBG; + TQButtonGroup *m_spaceProfileBG; + TQButtonGroup *m_proofProfileBG; + + TQHButtonGroup *m_scaleBG; + TQVButtonGroup *m_renderingIntentBG; + TQVButtonGroup *m_profilesBG; + + TQByteArray m_embeddedICC; + + TQToolBox *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/src/imageplugins/coreplugin/imageeffect_autocorrection.cpp b/src/imageplugins/coreplugin/imageeffect_autocorrection.cpp new file mode 100644 index 00000000..290b93cb --- /dev/null +++ b/src/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. + * + * ============================================================ */ + + // TQt includes. + +#include <tqcolor.h> +#include <tqgroupbox.h> +#include <tqhgroupbox.h> +#include <tqvgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqradiobutton.h> +#include <tqvgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqframe.h> +#include <tqtimer.h> +#include <tqvbox.h> +#include <tqlabel.h> +#include <tqpushbutton.h> +#include <tqcheckbox.h> +#include <tqcombobox.h> +#include <tqlistbox.h> +#include <tqwhatsthis.h> +#include <tqtooltip.h> + +// KDE includes. + +#include <kcursor.h> +#include <kstandarddirs.h> +#include <tdeconfig.h> +#include <tdelocale.h> +#include <tdeapplication.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(TQWidget* 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, TQSize::ScaleMin); + + TQWidget *gboxSettings = new TQWidget(plainPage()); + TQGridLayout* gridSettings = new TQGridLayout( gboxSettings, 4, 4, spacingHint()); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), gboxSettings); + label1->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_channelCB = new TQComboBox( false, gboxSettings ); + m_channelCB->insertItem( i18n("Luminosity") ); + m_channelCB->insertItem( i18n("Red") ); + m_channelCB->insertItem( i18n("Green") ); + m_channelCB->insertItem( i18n("Blue") ); + TQWhatsThis::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 TQHButtonGroup(gboxSettings); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin( 0 ); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( linHistoButton, i18n( "<p>Linear" ) ); + m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap( TQPixmap( directory + "histogram-lin.png" ) ); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) ); + m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap( TQPixmap( directory + "histogram-log.png" ) ); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(gboxSettings); + m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new Digikam::ColorGradientWidget( Digikam::ColorGradientWidget::Horizontal, 10, histoBox ); + m_hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + + gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4); + + // ------------------------------------------------------------- + + m_correctionTools = new TQListBox(gboxSettings); + m_correctionTools->setColumnMode(1); + m_correctionTools->setVariableWidth(false); + m_correctionTools->setVariableHeight(false); + Digikam::ListBoxWhatsThis* whatsThis = new Digikam::ListBoxWhatsThis(m_correctionTools); + + TQPixmap 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, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotColorSelectedFromTarget( const Digikam::DColor & ))); + + connect(m_correctionTools, TQ_SIGNAL(highlighted(int)), + this, TQ_SLOT(slotEffect())); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_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( TQColor( "black" ), TQColor( "white" ) ); + break; + + case RedChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "green" ) ); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "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() +{ + TDEConfig* 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() +{ + TDEConfig* 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(); +} + +TQPixmap 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); + TQString 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/src/imageplugins/coreplugin/imageeffect_autocorrection.h b/src/imageplugins/coreplugin/imageeffect_autocorrection.h new file mode 100644 index 00000000..c707ac1b --- /dev/null +++ b/src/imageplugins/coreplugin/imageeffect_autocorrection.h @@ -0,0 +1,128 @@ +/* ============================================================ + * + * 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 + +// TQt Includes. + +#include <tqstring.h> + +// Digikam include. + +#include "imagedlgbase.h" + +class TQHButtonGroup; +class TQComboBox; +class TQListBox; +class TQButtonGroup; + +namespace Digikam +{ +class HistogramWidget; +class ColorGradientWidget; +class ImageWidget; +class DColor; +class DImg; +} + +namespace DigikamImagesPluginCore +{ + +class ImageEffect_AutoCorrection : public Digikam::ImageDlgBase +{ + TQ_OBJECT + + +public: + + ImageEffect_AutoCorrection(TQWidget *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); + TQPixmap getThumbnailForEffect(AutoCorrectionType type); + +private: + + enum HistogramScale + { + Linear=0, + Logarithmic + }; + + enum ColorChannel + { + LuminosityChannel=0, + RedChannel, + GreenChannel, + BlueChannel + }; + + uchar *m_destinationPreviewData; + + TQComboBox *m_channelCB; + + TQHButtonGroup *m_scaleBG; + + TQListBox *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/src/imageplugins/coreplugin/imageeffect_bcg.cpp b/src/imageplugins/coreplugin/imageeffect_bcg.cpp new file mode 100644 index 00000000..9d21115d --- /dev/null +++ b/src/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 <[email protected]> + * 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqcolor.h> +#include <tqgroupbox.h> +#include <tqhgroupbox.h> +#include <tqvgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqlabel.h> +#include <tqvbox.h> +#include <tqlayout.h> +#include <tqframe.h> +#include <tqlabel.h> +#include <tqpushbutton.h> +#include <tqcheckbox.h> +#include <tqcombobox.h> +#include <tqwhatsthis.h> +#include <tqtooltip.h> + +// KDE includes. + +#include <knuminput.h> +#include <tdelocale.h> +#include <tdeapplication.h> +#include <tdeconfig.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(TQWidget* 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); + + // ------------------------------------------------------------- + + TQWidget *gboxSettings = new TQWidget(plainPage()); + TQGridLayout* gridSettings = new TQGridLayout( gboxSettings, 9, 4, spacingHint()); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), gboxSettings); + label1->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_channelCB = new TQComboBox( false, gboxSettings ); + m_channelCB->insertItem( i18n("Luminosity") ); + m_channelCB->insertItem( i18n("Red") ); + m_channelCB->insertItem( i18n("Green") ); + m_channelCB->insertItem( i18n("Blue") ); + TQWhatsThis::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 TQHButtonGroup(gboxSettings); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin( 0 ); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( linHistoButton, i18n( "<p>Linear" ) ); + m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap( TQPixmap( directory + "histogram-lin.png" ) ); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) ); + m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap( TQPixmap( directory + "histogram-log.png" ) ); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(gboxSettings); + m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new Digikam::ColorGradientWidget( Digikam::ColorGradientWidget::Horizontal, 10, histoBox ); + m_hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + + gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4); + + // ------------------------------------------------------------- + + TQLabel *label2 = new TQLabel(i18n("Brightness:"), gboxSettings); + m_bInput = new KIntNumInput(gboxSettings); + m_bInput->setRange(-100, 100, 1, true); + m_bInput->setValue(0); + TQWhatsThis::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); + + TQLabel *label3 = new TQLabel(i18n("Contrast:"), gboxSettings); + m_cInput = new KIntNumInput(gboxSettings); + m_cInput->setRange(-100, 100, 1, true); + m_cInput->setValue(0); + TQWhatsThis::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); + + TQLabel *label4 = new TQLabel(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); + TQWhatsThis::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, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotColorSelectedFromTarget( const Digikam::DColor & ))); + + connect(m_bInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_cInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_gInput, TQ_SIGNAL(valueChanged(double)), + this, TQ_SLOT(slotTimer())); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_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( TQColor( "black" ), TQColor( "white" ) ); + break; + + case RedChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "green" ) ); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "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() +{ + TDEConfig* 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() +{ + TDEConfig* 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/src/imageplugins/coreplugin/imageeffect_bcg.h b/src/imageplugins/coreplugin/imageeffect_bcg.h new file mode 100644 index 00000000..a9cd020b --- /dev/null +++ b/src/imageplugins/coreplugin/imageeffect_bcg.h @@ -0,0 +1,110 @@ +/* ============================================================ + * + * 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 <[email protected]> + * 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 TQCheckBox; +class TQComboBox; +class TQHButtonGroup; + +class KIntNumInput; +class KDoubleNumInput; + +namespace Digikam +{ +class HistogramWidget; +class ColorGradientWidget; +class ImageWidget; +class DColor; +} + +namespace DigikamImagesPluginCore +{ + +class ImageEffect_BCG : public Digikam::ImageDlgBase +{ + TQ_OBJECT + + +public: + + ImageEffect_BCG(TQWidget *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; + + TQComboBox *m_channelCB; + + TQHButtonGroup *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/src/imageplugins/coreplugin/imageeffect_blur.cpp b/src/imageplugins/coreplugin/imageeffect_blur.cpp new file mode 100644 index 00000000..bd23854b --- /dev/null +++ b/src/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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqlayout.h> +#include <tqlabel.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <tdeaboutdata.h> +#include <knuminput.h> +#include <tdeconfig.h> +#include <kcursor.h> +#include <tdelocale.h> +#include <tdeapplication.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(TQWidget* parent) + : Digikam::CtrlPanelDlg(parent, i18n("Apply Gaussian Blur on Photograph"), + "gaussianblur", false, true, true) +{ + setHelp("blursharpentool.anchor", "digikam"); + + TQWidget *gboxSettings = new TQWidget(m_imagePreviewWidget); + TQGridLayout* gridSettings = new TQGridLayout( gboxSettings, 1, 1, 0, spacingHint()); + TQLabel *label = new TQLabel(i18n("Smoothness:"), gboxSettings); + + m_radiusInput = new KIntNumInput(gboxSettings); + m_radiusInput->setRange(0, 100, 1, true); + m_radiusInput->setValue(0); + TQWhatsThis::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() +{ + TDEConfig* config = kapp->config(); + config->setGroup("gaussianblur Tool Dialog"); + m_radiusInput->setValue(config->readNumEntry("RadiusAjustment", 0)); +} + +void ImageEffect_Blur::writeUserSettings() +{ + TDEConfig* 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/src/imageplugins/coreplugin/imageeffect_blur.h b/src/imageplugins/coreplugin/imageeffect_blur.h new file mode 100644 index 00000000..eab7694e --- /dev/null +++ b/src/imageplugins/coreplugin/imageeffect_blur.h @@ -0,0 +1,68 @@ +/* ============================================================ + * + * 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 +{ + TQ_OBJECT + + +public: + + ImageEffect_Blur(TQWidget *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/src/imageplugins/coreplugin/imageeffect_bwsepia.cpp b/src/imageplugins/coreplugin/imageeffect_bwsepia.cpp new file mode 100644 index 00000000..7dcdf0da --- /dev/null +++ b/src/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 <[email protected]> + * 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. + * + * ============================================================ */ + + // TQt includes. + +#include <tqcolor.h> +#include <tqgroupbox.h> +#include <tqhgroupbox.h> +#include <tqvgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqlistbox.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqframe.h> +#include <tqlabel.h> +#include <tqpushbutton.h> +#include <tqtimer.h> +#include <tqcombobox.h> +#include <tqwhatsthis.h> +#include <tqtooltip.h> +#include <tqintdict.h> +#include <tqtextstream.h> +#include <tqfile.h> +#include <tqvbox.h> + +// KDE includes. + +#include <tdefiledialog.h> +#include <tdeglobalsettings.h> +#include <tdemessagebox.h> +#include <kcursor.h> +#include <tdelocale.h> +#include <kstandarddirs.h> +#include <tdeapplication.h> +#include <knuminput.h> +#include <ktabwidget.h> +#include <tdeconfig.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 TQObject +{ +public: + + PreviewPixmapFactory(ImageEffect_BWSepia* bwSepia); + + void invalidate() { m_previewPixmapMap.clear(); } + + const TQPixmap* pixmap(int id); + +private: + + TQPixmap makePixmap(int id); + + TQIntDict<TQPixmap> m_previewPixmapMap; + ImageEffect_BWSepia *m_bwSepia; +}; + +PreviewPixmapFactory::PreviewPixmapFactory(ImageEffect_BWSepia* bwSepia) + : TQObject(bwSepia), m_bwSepia(bwSepia) +{ + m_previewPixmapMap.setAutoDelete(true); +} + +const TQPixmap* PreviewPixmapFactory::pixmap(int id) +{ + if (m_previewPixmapMap.find(id) == 0) + { + TQPixmap pix = makePixmap(id); + m_previewPixmapMap.insert(id, new TQPixmap(pix)); + } + + TQPixmap* res = m_previewPixmapMap[id]; + + return res; +} + +TQPixmap PreviewPixmapFactory::makePixmap(int id) +{ + return m_bwSepia->getThumbnailForEffect(id); +} + +// ----------------------------------------------------------------------------------- + +class ListBoxBWPreviewItem : public Digikam::ListBoxPreviewItem +{ + +public: + + ListBoxBWPreviewItem(TQListBox *listbox, const TQString &text, + PreviewPixmapFactory* factory, int id) + : ListBoxPreviewItem(listbox, TQPixmap(), text) + { + m_previewPixmapFactory = factory; + m_id = id; + }; + + virtual const TQPixmap* pixmap() const; + +private: + + int m_id; + PreviewPixmapFactory* m_previewPixmapFactory; +}; + +const TQPixmap* ListBoxBWPreviewItem::pixmap() const +{ + return m_previewPixmapFactory->pixmap(m_id); +} + +// ----------------------------------------------------------------------------------- + +ImageEffect_BWSepia::ImageEffect_BWSepia(TQWidget* 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, TQSize::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); + + // ------------------------------------------------------------- + + TQWidget *gboxSettings = new TQWidget(plainPage()); + TQGridLayout* gridSettings = new TQGridLayout( gboxSettings, 4, 4, spacingHint()); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), gboxSettings); + label1->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_channelCB = new TQComboBox( false, gboxSettings ); + m_channelCB->insertItem( i18n("Luminosity") ); + m_channelCB->insertItem( i18n("Red") ); + m_channelCB->insertItem( i18n("Green") ); + m_channelCB->insertItem( i18n("Blue") ); + TQWhatsThis::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 TQHButtonGroup(gboxSettings); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin( 0 ); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( linHistoButton, i18n( "<p>Linear" ) ); + m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap( TQPixmap( directory + "histogram-lin.png" ) ); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) ); + m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap( TQPixmap( directory + "histogram-log.png" ) ); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(gboxSettings); + m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new Digikam::ColorGradientWidget( Digikam::ColorGradientWidget::Horizontal, 10, histoBox ); + m_hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + + gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4); + + // ------------------------------------------------------------- + + m_tab = new KTabWidget(gboxSettings); + + m_bwFilm = new TQListBox(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>")); + + // ------------------------------------------------------------- + + TQVBox *vbox = new TQVBox(m_tab); + vbox->setSpacing(spacingHint()); + + m_bwFilters = new TQListBox(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); + TQWhatsThis::add(m_strengthInput, i18n("<p>Here, set the strength adjustment of the lens filter.")); + + // ------------------------------------------------------------- + + m_bwTone = new TQListBox(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>")); + + // ------------------------------------------------------------- + + TQWidget *curveBox = new TQWidget( m_tab ); + TQGridLayout *gridTab2 = new TQGridLayout(curveBox, 5, 2, spacingHint(), 0); + + Digikam::ColorGradientWidget* vGradient = new Digikam::ColorGradientWidget( + Digikam::ColorGradientWidget::Vertical, + 10, curveBox ); + vGradient->setColors( TQColor( "white" ), TQColor( "black" ) ); + + TQLabel *spacev = new TQLabel(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); + TQWhatsThis::add( m_curvesWidget, i18n("<p>This is the curve adjustment of the image luminosity")); + + TQLabel *spaceh = new TQLabel(curveBox); + spaceh->setFixedHeight(1); + + Digikam::ColorGradientWidget *hGradient = new Digikam::ColorGradientWidget( + Digikam::ColorGradientWidget::Horizontal, + 10, curveBox ); + hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + + m_cInput = new KIntNumInput(curveBox); + m_cInput->setLabel(i18n("Contrast:"), AlignLeft | AlignVCenter); + m_cInput->setRange(-100, 100, 1, true); + m_cInput->setValue(0); + TQWhatsThis::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, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromOriginal(const Digikam::DColor&, const TQPoint&)), + this, TQ_SLOT(slotSpotColorChanged(const Digikam::DColor&))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotColorSelectedFromTarget( const Digikam::DColor & ))); + + connect(m_bwFilters, TQ_SIGNAL(highlighted(int)), + this, TQ_SLOT(slotFilterSelected(int))); + + connect(m_strengthInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_bwFilm, TQ_SIGNAL(highlighted(int)), + this, TQ_SLOT(slotEffect())); + + connect(m_bwTone, TQ_SIGNAL(highlighted(int)), + this, TQ_SLOT(slotEffect())); + + connect(m_curvesWidget, TQ_SIGNAL(signalCurvesChanged()), + this, TQ_SLOT(slotTimer())); + + connect(m_cInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_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(); +} + +TQPixmap 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( TQColor( "black" ), TQColor( "white" ) ); + break; + + case RedChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "green" ) ); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "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() +{ + TDEConfig* 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++) + { + TQPoint disable(-1, -1); + TQPoint p = config->readPointEntry(TQString("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() +{ + TDEConfig* 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++) + { + TQPoint 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(TQString("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(TDEGlobalSettings::documentPath(), + TQString( "*" ), this, + TQString( i18n("Black & White Settings File to Load")) ); + if( loadFile.isEmpty() ) + return; + + TQFile file(loadFile.path()); + + if ( file.open(IO_ReadOnly) ) + { + TQTextStream 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++) + { + TQPoint disable(-1, -1); + TQPoint 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(TDEGlobalSettings::documentPath(), + TQString( "*" ), this, + TQString( i18n("Black & White Settings File to Save")) ); + if( saveFile.isEmpty() ) + return; + + TQFile file(saveFile.path()); + + if ( file.open(IO_WriteOnly) ) + { + TQTextStream 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++) + { + TQPoint 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/src/imageplugins/coreplugin/imageeffect_bwsepia.h b/src/imageplugins/coreplugin/imageeffect_bwsepia.h new file mode 100644 index 00000000..74b4edf3 --- /dev/null +++ b/src/imageplugins/coreplugin/imageeffect_bwsepia.h @@ -0,0 +1,195 @@ +/* ============================================================ + * + * 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 <[email protected]> + * 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 + +// TQt Includes. + +#include <tqstring.h> + +// Digikam include. + +#include "imagedlgbase.h" + +class TQHButtonGroup; +class TQComboBox; +class TQButtonGroup; + +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 +{ + TQ_OBJECT + + +public: + + ImageEffect_BWSepia(TQWidget *parent); + ~ImageEffect_BWSepia(); + + friend class PreviewPixmapFactory; + +protected: + + TQPixmap 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; + + TQComboBox *m_channelCB; + + TQHButtonGroup *m_scaleBG; + + TQListBox *m_bwFilters; + TQListBox *m_bwFilm; + TQListBox *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/src/imageplugins/coreplugin/imageeffect_iccproof.cpp b/src/imageplugins/coreplugin/imageeffect_iccproof.cpp new file mode 100644 index 00000000..79a09983 --- /dev/null +++ b/src/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 <[email protected]> + * 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqcolor.h> +#include <tqgroupbox.h> +#include <tqhbox.h> +#include <tqhbuttongroup.h> +#include <tqvbuttongroup.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqframe.h> +#include <tqpoint.h> +#include <tqvbox.h> +#include <tqlabel.h> +#include <tqpushbutton.h> +#include <tqcheckbox.h> +#include <tqcombobox.h> +#include <tqwhatsthis.h> +#include <tqtooltip.h> +#include <tqradiobutton.h> +#include <tqfile.h> +#include <tqtoolbox.h> +#include <tqtextstream.h> + +// KDE includes. + +#include <knuminput.h> +#include <tdelocale.h> +#include <tdeapplication.h> +#include <kcursor.h> +#include <kstandarddirs.h> +#include <ktabwidget.h> +#include <tdeconfig.h> +#include <kurlrequester.h> +#include <kurllabel.h> +#include <tdefiledialog.h> +#include <tdefile.h> +#include <tdemessagebox.h> +#include <tdeglobalsettings.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(TQWidget* 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); + + // ------------------------------------------------------------------- + + TQWidget *gboxSettings = new TQWidget(plainPage()); + TQGridLayout *gridSettings = new TQGridLayout( gboxSettings, 3, 2, spacingHint()); + + TQLabel *label1 = new TQLabel(i18n("Channel: "), gboxSettings); + label1->setAlignment(TQt::AlignRight | TQt::AlignVCenter); + m_channelCB = new TQComboBox(false, gboxSettings); + m_channelCB->insertItem(i18n("Luminosity")); + m_channelCB->insertItem(i18n("Red")); + m_channelCB->insertItem(i18n("Green")); + m_channelCB->insertItem(i18n("Blue")); + TQWhatsThis::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 TQHButtonGroup(gboxSettings); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin( 0 ); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( linHistoButton, i18n( "<p>Linear" ) ); + m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap( TQPixmap( directory + "histogram-lin.png" ) ); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) ); + m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap( TQPixmap( directory + "histogram-log.png" ) ); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + gridSettings->addMultiCellLayout(l1, 0, 0, 0, 2); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(gboxSettings); + m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new Digikam::ColorGradientWidget( Digikam::ColorGradientWidget::Horizontal, 10, + histoBox ); + m_hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + + gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 2); + + // ------------------------------------------------------------- + + m_toolBoxWidgets = new TQToolBox(gboxSettings); + TQWidget *generalOptions = new TQWidget(m_toolBoxWidgets); + TQWidget *inProfiles = new TQWidget(m_toolBoxWidgets); + TQWidget *spaceProfiles = new TQWidget(m_toolBoxWidgets); + TQWidget *proofProfiles = new TQWidget(m_toolBoxWidgets); + TQWidget *lightnessadjust = new TQWidget(m_toolBoxWidgets); + + //---------- "General" Page Setup ---------------------------------- + + m_toolBoxWidgets->insertItem(GENERALPAGE, generalOptions, + SmallIconSet("misc"), i18n("General Settings")); + TQWhatsThis::add(generalOptions, i18n("<p>Here you can set general parameters.</p>")); + + TQGridLayout *zeroPageLayout = new TQGridLayout(generalOptions, 5, 1, spacingHint()); + + m_doSoftProofBox = new TQCheckBox(generalOptions); + m_doSoftProofBox->setText(i18n("Soft-proofing")); + TQWhatsThis::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 TQCheckBox(generalOptions); + m_checkGamutBox->setText(i18n("Check gamut")); + TQWhatsThis::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 TQCheckBox(generalOptions); + m_embeddProfileBox->setChecked(true); + m_embeddProfileBox->setText(i18n("Assign profile")); + TQWhatsThis::add(m_embeddProfileBox, i18n("<p>You can use this option to embed " + "the selected workspace color profile into the image.</p>")); + + m_BPCBox = new TQCheckBox(generalOptions); + m_BPCBox->setText(i18n("Use BPC")); + TQWhatsThis::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>")); + + TQLabel *intent = new TQLabel(i18n("Rendering Intent:"), generalOptions); + m_renderingIntentsCB = new TQComboBox(false, generalOptions); + m_renderingIntentsCB->insertItem("Perceptual"); + m_renderingIntentsCB->insertItem("Absolute Colorimetric"); + m_renderingIntentsCB->insertItem("Relative Colorimetric"); + m_renderingIntentsCB->insertItem("Saturation"); + TQWhatsThis::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(TQString()); + lcmsLogoLabel->setURL("http://www.littlecms.com"); + TDEGlobal::dirs()->addResourceType("logo-lcms", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("logo-lcms", "logo-lcms.png"); + lcmsLogoLabel->setPixmap( TQPixmap( directory + "logo-lcms.png" ) ); + TQToolTip::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-photo"), i18n("Input Profile")); + TQWhatsThis::add(inProfiles, i18n("<p>Set here all parameters relevant of Input Color " + "Profiles.</p>")); + + TQGridLayout *firstPageLayout = new TQGridLayout(inProfiles, 4, 2, spacingHint()); + + m_inProfileBG = new TQButtonGroup(4, TQt::Vertical, inProfiles); + m_inProfileBG->setFrameStyle(TQFrame::NoFrame); + m_inProfileBG->setInsideMargin(0); + + m_useEmbeddedProfile = new TQRadioButton(m_inProfileBG); + m_useEmbeddedProfile->setText(i18n("Use embedded profile")); + + m_useSRGBDefaultProfile = new TQRadioButton(m_inProfileBG); + m_useSRGBDefaultProfile->setText(i18n("Use builtin sRGB profile")); + m_useSRGBDefaultProfile->setChecked(true); + + m_useInDefaultProfile = new TQRadioButton(m_inProfileBG); + m_useInDefaultProfile->setText(i18n("Use default profile")); + + m_useInSelectedProfile = new TQRadioButton(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); + + TQPushButton *inProfilesInfo = new TQPushButton(i18n("Info..."), inProfiles); + + TQGroupBox *pictureInfo = new TQGroupBox(2, TQt::Horizontal, i18n("Camera information"), inProfiles); + new TQLabel(i18n("Make:"), pictureInfo); + KSqueezedTextLabel *make = new KSqueezedTextLabel(0, pictureInfo); + new TQLabel(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("input-tablet"), i18n("Workspace Profile")); + TQWhatsThis::add(spaceProfiles, i18n("<p>Set here all parameters relevant to Color Workspace " + "Profiles.</p>")); + + TQGridLayout *secondPageLayout = new TQGridLayout(spaceProfiles, 3, 2, spacingHint()); + + m_spaceProfileBG = new TQButtonGroup(2, TQt::Vertical, spaceProfiles); + m_spaceProfileBG->setFrameStyle(TQFrame::NoFrame); + m_spaceProfileBG->setInsideMargin(0); + + m_useSpaceDefaultProfile = new TQRadioButton(m_spaceProfileBG); + m_useSpaceDefaultProfile->setText(i18n("Use default workspace profile")); + + m_useSpaceSelectedProfile = new TQRadioButton(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); + + TQPushButton *spaceProfilesInfo = new TQPushButton(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("printer"), i18n("Proofing Profile")); + TQWhatsThis::add(proofProfiles, i18n("<p>Set here all parameters relevant to Proofing Color " + "Profiles.</p>")); + + TQGridLayout *thirdPageLayout = new TQGridLayout(proofProfiles, 3, 2, + spacingHint(), spacingHint()); + + m_proofProfileBG = new TQButtonGroup(2, TQt::Vertical, proofProfiles); + m_proofProfileBG->setFrameStyle(TQFrame::NoFrame); + m_proofProfileBG->setInsideMargin(0); + + m_useProofDefaultProfile = new TQRadioButton(m_proofProfileBG); + m_useProofDefaultProfile->setText(i18n("Use default proof profile")); + + m_useProofSelectedProfile = new TQRadioButton(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); + + TQPushButton *proofProfilesInfo = new TQPushButton(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")); + TQWhatsThis::add(lightnessadjust, i18n("<p>Set here all lightness adjustments to the target image.</p>")); + + TQGridLayout *fourPageLayout = new TQGridLayout( lightnessadjust, 5, 2, spacingHint(), 0); + + Digikam::ColorGradientWidget* vGradient = new Digikam::ColorGradientWidget( + Digikam::ColorGradientWidget::Vertical, + 10, lightnessadjust ); + vGradient->setColors( TQColor( "white" ), TQColor( "black" ) ); + + TQLabel *spacev = new TQLabel(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); + TQWhatsThis::add( m_curvesWidget, i18n("<p>This is the curve adjustment of the image luminosity")); + + TQLabel *spaceh = new TQLabel(lightnessadjust); + spaceh->setFixedHeight(1); + + Digikam::ColorGradientWidget *hGradient = new Digikam::ColorGradientWidget( + Digikam::ColorGradientWidget::Horizontal, + 10, lightnessadjust ); + hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + + m_cInput = new KIntNumInput(lightnessadjust); + m_cInput->setLabel(i18n("Contrast:"), AlignLeft | AlignVCenter); + m_cInput->setRange(-100, 100, 1, true); + m_cInput->setValue(0); + TQWhatsThis::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, TQ_SIGNAL(leftClickedURL(const TQString&)), + this, TQ_SLOT(processLCMSURL(const TQString&))); + + connect(m_channelCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_curvesWidget, TQ_SIGNAL(signalCurvesChanged()), + this, TQ_SLOT(slotTimer())); + + connect(m_cInput, TQ_SIGNAL(valueChanged (int)), + this, TQ_SLOT(slotTimer())); + + connect(m_renderingIntentsCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotEffect())); + + //-- Check box options connections ------------------------------------------- + + connect(m_doSoftProofBox, TQ_SIGNAL(toggled (bool)), + this, TQ_SLOT(slotEffect())); + + connect(m_checkGamutBox, TQ_SIGNAL(toggled (bool)), + this, TQ_SLOT(slotEffect())); + + connect(m_BPCBox, TQ_SIGNAL(toggled (bool)), + this, TQ_SLOT(slotEffect())); + + //-- Button Group ICC profile options connections ---------------------------- + + connect(m_inProfileBG, TQ_SIGNAL(released (int)), + this, TQ_SLOT(slotEffect())); + + connect(m_spaceProfileBG, TQ_SIGNAL(released (int)), + this, TQ_SLOT(slotEffect())); + + connect(m_proofProfileBG, TQ_SIGNAL(released (int)), + this, TQ_SLOT(slotEffect())); + + //-- url requester ICC profile connections ----------------------------------- + + connect(m_inProfilesPath, TQ_SIGNAL(urlSelected(const TQString&)), + this, TQ_SLOT(slotEffect())); + + connect(m_spaceProfilePath, TQ_SIGNAL(urlSelected(const TQString&)), + this, TQ_SLOT(slotEffect())); + + connect(m_proofProfilePath, TQ_SIGNAL(urlSelected(const TQString&)), + this, TQ_SLOT(slotEffect())); + + //-- Image preview widget connections ---------------------------- + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_SLOT(slotEffect())); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromOriginal( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotSpotColorChanged( const Digikam::DColor & ))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotColorSelectedFromTarget( const Digikam::DColor & ))); + + //-- ICC profile preview connections ----------------------------- + + connect(inProfilesInfo, TQ_SIGNAL(clicked()), + this, TQ_SLOT(slotInICCInfo())); + + connect(spaceProfilesInfo, TQ_SIGNAL(clicked()), + this, TQ_SLOT(slotSpaceICCInfo())); + + connect(proofProfilesInfo, TQ_SIGNAL(clicked()), + this, TQ_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() +{ + TQString defaultICCPath = TDEGlobalSettings::documentPath(); + TDEConfig* 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 (TQFile::exists(config->readPathEntry("DefaultPath"))) + { + defaultICCPath = config->readPathEntry("DefaultPath"); + } + else + { + TQString 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++) + { + TQPoint disable(-1, -1); + TQPoint p = config->readPointEntry(TQString("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() +{ + TDEConfig* 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++) + { + TQPoint 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(TQString("CurveAjustmentPoint%1").arg(j), p); + } + + config->sync(); +} + +void ImageEffect_ICCProof::processLCMSURL(const TQString& url) +{ + TDEApplication::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( TQColor( "black" ), TQColor( "white" ) ); + break; + + case RedChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "green" ) ); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "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); + + TQString tmpInPath = TQString(); + TQString tmpProofPath = TQString(); + TQString tmpSpacePath = TQString(); + + bool proofCondition = false; + bool spaceCondition = false; + + //-- Input profile parameters ------------------ + + if (useDefaultInProfile()) + { + tmpInPath = m_inPath; + } + else if (useSelectedInProfile()) + { + tmpInPath = m_inProfilesPath->url(); + TQFileInfo 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(); + TQFileInfo 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(); + TQFileInfo 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(); + TQString 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 + { + TQByteArray fakeProfile = TQByteArray(); + 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); + + TQString tmpInPath; + TQString tmpProofPath; + TQString tmpSpacePath; + bool proofCondition; + + //-- Input profile parameters ------------------ + + if (useDefaultInProfile()) + { + tmpInPath = m_inPath; + } + else if (useSelectedInProfile()) + { + tmpInPath = m_inProfilesPath->url(); + TQFileInfo 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(); + TQFileInfo 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(); + TQFileInfo 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 + { + TQByteArray fakeProfile = TQByteArray(); + 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 << TQFile::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()) + { + TQString 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 TQString& 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 TQByteArray& profile) +{ + if (profile.isNull()) + { + KMessageBox::error(this, i18n("Sorry, it seems there is no embedded profile"), i18n("Profile Error")); + return; + } + + Digikam::ICCProfileInfoDlg infoDlg(this, TQString(), profile); + infoDlg.exec(); +} + +void ImageEffect_ICCProof::slotCMDisabledWarning() +{ + if (!m_cmEnabled) + { + TQString 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(TDEGlobalSettings::documentPath(), + TQString( "*" ), this, + TQString( i18n("Color Management Settings File to Load")) ); + if( loadColorManagementFile.isEmpty() ) + return; + + TQFile file(loadColorManagementFile.path()); + + if ( file.open(IO_ReadOnly) ) + { + TQTextStream 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++) + { + TQPoint disable(-1, -1); + TQPoint 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(TDEGlobalSettings::documentPath(), + TQString( "*" ), this, + TQString( i18n("Color Management Settings File to Save")) ); + if( saveColorManagementFile.isEmpty() ) + return; + + TQFile file(saveColorManagementFile.path()); + + if ( file.open(IO_WriteOnly) ) + { + TQTextStream 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++) + { + TQPoint 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/src/imageplugins/coreplugin/imageeffect_iccproof.h b/src/imageplugins/coreplugin/imageeffect_iccproof.h new file mode 100644 index 00000000..58112aef --- /dev/null +++ b/src/imageplugins/coreplugin/imageeffect_iccproof.h @@ -0,0 +1,204 @@ +/* ============================================================ + * + * 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 <[email protected]> + * 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 TQCheckBox; +class TQComboBox; +class TQVButtonGroup; +class TQButtonGroup; +class TQHButtonGroup; +class TQRadioButton; +class TQPushButton; +class TQToolBox; + +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 +{ + TQ_OBJECT + + +public: + + ImageEffect_ICCProof(TQWidget* parent); + ~ImageEffect_ICCProof(); + +protected: + + void finalRendering(); + +private: + + void readUserSettings(); + void writeUserSettings(); + void resetValues(); + + void getICCInfo(const TQString&); + void getICCInfo(const TQByteArray&); + + 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 TQString&); + +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; + + TQComboBox *m_channelCB; + TQComboBox *m_renderingIntentsCB; + + TQCheckBox *m_doSoftProofBox; + TQCheckBox *m_checkGamutBox; + TQCheckBox *m_embeddProfileBox; + TQCheckBox *m_BPCBox; + + TQRadioButton *m_useEmbeddedProfile; + TQRadioButton *m_useInDefaultProfile; + TQRadioButton *m_useInSelectedProfile; + TQRadioButton *m_useProofDefaultProfile; + TQRadioButton *m_useProofSelectedProfile; + TQRadioButton *m_useSpaceDefaultProfile; + TQRadioButton *m_useSpaceSelectedProfile; + TQRadioButton *m_useSRGBDefaultProfile; + + TQString m_inPath; + TQString m_spacePath; + TQString m_proofPath; + + TQButtonGroup *m_optionsBG; + TQButtonGroup *m_inProfileBG; + TQButtonGroup *m_spaceProfileBG; + TQButtonGroup *m_proofProfileBG; + + TQHButtonGroup *m_scaleBG; + TQVButtonGroup *m_renderingIntentBG; + TQVButtonGroup *m_profilesBG; + + TQByteArray m_embeddedICC; + + TQToolBox *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/src/imageplugins/coreplugin/imageeffect_redeye.cpp b/src/imageplugins/coreplugin/imageeffect_redeye.cpp new file mode 100644 index 00000000..df3ae2e7 --- /dev/null +++ b/src/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 <[email protected]> + * 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqcolor.h> +#include <tqhbox.h> +#include <tqhgroupbox.h> +#include <tqvgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqvbox.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqframe.h> +#include <tqlabel.h> +#include <tqpushbutton.h> +#include <tqcombobox.h> +#include <tqwhatsthis.h> +#include <tqtooltip.h> + +// KDE includes. + +#include <kcolordialog.h> +#include <knuminput.h> +#include <tdelocale.h> +#include <tdeapplication.h> +#include <tdeconfig.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(TQWidget* 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); + + // ------------------------------------------------------------- + + TQWidget *gboxSettings = new TQWidget(plainPage()); + TQGridLayout* gridSettings = new TQGridLayout(gboxSettings, 11, 4, spacingHint()); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), gboxSettings); + label1->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_channelCB = new TQComboBox( false, gboxSettings ); + m_channelCB->insertItem( i18n("Luminosity") ); + m_channelCB->insertItem( i18n("Red") ); + m_channelCB->insertItem( i18n("Green") ); + m_channelCB->insertItem( i18n("Blue") ); + TQWhatsThis::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 TQHButtonGroup(gboxSettings); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin(0); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( linHistoButton, i18n( "<p>Linear" ) ); + m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap( TQPixmap( directory + "histogram-lin.png" ) ); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) ); + m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap( TQPixmap( directory + "histogram-log.png" ) ); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(gboxSettings); + m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new Digikam::ColorGradientWidget(Digikam::ColorGradientWidget::Horizontal, 10, histoBox); + m_hGradient->setColors(TQColor("black"), TQColor("white")); + + // ------------------------------------------------------------- + + m_thresholdLabel = new TQLabel(i18n("Sensitivity:"), gboxSettings); + m_redThreshold = new KIntNumInput(gboxSettings); + m_redThreshold->setRange(10, 90, 1, true); + m_redThreshold->setValue(20); + TQWhatsThis::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 TQLabel(i18n("Smooth:"), gboxSettings); + m_smoothLevel = new KIntNumInput(gboxSettings); + m_smoothLevel->setRange(0, 5, 1, true); + m_smoothLevel->setValue(1); + TQWhatsThis::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.")); + + TQLabel *label3 = new TQLabel(i18n("Coloring Tint:"), gboxSettings); + m_HSSelector = new KHSSelector(gboxSettings); + m_VSelector = new KValueSelector(gboxSettings); + m_HSSelector->setMinimumSize(200, 142); + m_VSelector->setMinimumSize(26, 142); + TQWhatsThis::add(m_HSSelector, i18n("<p>Sets a custom color to re-colorize the eyes.")); + + TQLabel *label4 = new TQLabel(i18n("Tint Level:"), gboxSettings); + m_tintLevel = new KIntNumInput(gboxSettings); + m_tintLevel->setRange(1, 200, 1, true); + m_tintLevel->setValue(128); + TQWhatsThis::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, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget(const Digikam::DColor&, const TQPoint&)), + this, TQ_SLOT(slotColorSelectedFromTarget(const Digikam::DColor&))); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_SLOT(slotEffect())); + + connect(m_redThreshold, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_smoothLevel, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_HSSelector, TQ_SIGNAL(valueChanged(int, int)), + this, TQ_SLOT(slotHSChanged(int, int))); + + connect(m_VSelector, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_tintLevel, TQ_SIGNAL(valueChanged(int)), + this, TQ_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( TQColor( "black" ), TQColor( "white" ) ); + break; + + case RedChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "green" ) ); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "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() +{ + TDEConfig* 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() +{ + TDEConfig* 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 = TQMIN(255, (int)(red_norm * (red_chan.red_gain * r + + red_chan.green_gain * g + + red_chan.blue_gain * b))); + + g1 = TQMIN(255, (int)(green_norm * (green_chan.red_gain * r + + green_chan.green_gain * g + + green_chan.blue_gain * b))); + + b1 = TQMIN(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] = TQMIN( (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 = TQMIN(65535, (int)(red_norm * (red_chan.red_gain * r + + red_chan.green_gain * g + + red_chan.blue_gain * b))); + + g1 = TQMIN(65535, (int)(green_norm * (green_chan.red_gain * r + + green_chan.green_gain * g + + green_chan.blue_gain * b))); + + b1 = TQMIN(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] = TQMIN( (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/src/imageplugins/coreplugin/imageeffect_redeye.h b/src/imageplugins/coreplugin/imageeffect_redeye.h new file mode 100644 index 00000000..79b517ee --- /dev/null +++ b/src/imageplugins/coreplugin/imageeffect_redeye.h @@ -0,0 +1,153 @@ +/* ============================================================ + * + * 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 <[email protected]> + * 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 TQLabel; +class TQComboBox; +class TQHButtonGroup; + +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(TQWidget* parent) + : KPassivePopup(parent), m_parent(parent) + { + } + +protected: + + virtual void positionSelf() + { + move(m_parent->x() + 30, m_parent->y() + 30); + } + +private: + + TQWidget* m_parent; +}; + +// ---------------------------------------------------------------- + +class ImageEffect_RedEye : public Digikam::ImageDlgBase +{ + TQ_OBJECT + + +public: + + ImageEffect_RedEye(TQWidget *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; + + TQLabel *m_thresholdLabel; + TQLabel *m_smoothLabel; + + TQComboBox *m_channelCB; + + TQHButtonGroup *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/src/imageplugins/coreplugin/imageeffect_rgb.cpp b/src/imageplugins/coreplugin/imageeffect_rgb.cpp new file mode 100644 index 00000000..fcff9c41 --- /dev/null +++ b/src/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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqspinbox.h> +#include <tqslider.h> +#include <tqcolor.h> +#include <tqgroupbox.h> +#include <tqhgroupbox.h> +#include <tqvgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqframe.h> +#include <tqvbox.h> +#include <tqlabel.h> +#include <tqpushbutton.h> +#include <tqcheckbox.h> +#include <tqcombobox.h> +#include <tqwhatsthis.h> +#include <tqtooltip.h> + +// KDE includes. + +#include <tdeconfig.h> +#include <tdelocale.h> +#include <tdeapplication.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(TQWidget* 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); + + // ------------------------------------------------------------- + + TQWidget *gboxSettings = new TQWidget(plainPage()); + TQGridLayout* gridSettings = new TQGridLayout( gboxSettings, 7, 4, spacingHint()); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), gboxSettings); + label1->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_channelCB = new TQComboBox( false, gboxSettings ); + m_channelCB->insertItem( i18n("Luminosity") ); + m_channelCB->insertItem( i18n("Red") ); + m_channelCB->insertItem( i18n("Green") ); + m_channelCB->insertItem( i18n("Blue") ); + TQWhatsThis::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 TQHButtonGroup(gboxSettings); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin( 0 ); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( linHistoButton, i18n( "<p>Linear" ) ); + m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap( TQPixmap( directory + "histogram-lin.png" ) ); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) ); + m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap( TQPixmap( directory + "histogram-log.png" ) ); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(gboxSettings); + m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new Digikam::ColorGradientWidget( Digikam::ColorGradientWidget::Horizontal, 10, histoBox ); + m_hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + + gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4); + + // ------------------------------------------------------------- + + TQLabel *labelLeft = new TQLabel(i18n("Cyan"), gboxSettings); + labelLeft->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_rSlider = new TQSlider(-100, 100, 1, 0, TQt::Horizontal, gboxSettings, "m_rSlider"); + m_rSlider->setTickmarks(TQSlider::Below); + m_rSlider->setTickInterval(20); + TQWhatsThis::add( m_rSlider, i18n("<p>Set here the cyan/red color adjustment of the image.")); + TQLabel *labelRight = new TQLabel(i18n("Red"), gboxSettings); + labelRight->setAlignment ( TQt::AlignLeft | TQt::AlignVCenter ); + m_rInput = new TQSpinBox(-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 TQLabel(i18n("Magenta"), gboxSettings); + labelLeft->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_gSlider = new TQSlider(-100, 100, 1, 0, TQt::Horizontal, gboxSettings, "m_gSlider"); + m_gSlider->setTickmarks(TQSlider::Below); + m_gSlider->setTickInterval(20); + TQWhatsThis::add( m_gSlider, i18n("<p>Set here the magenta/green color adjustment of the image.")); + labelRight = new TQLabel(i18n("Green"), gboxSettings); + labelRight->setAlignment ( TQt::AlignLeft | TQt::AlignVCenter ); + m_gInput = new TQSpinBox(-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 TQLabel(i18n("Yellow"), gboxSettings); + labelLeft->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_bSlider = new TQSlider(-100, 100, 1, 0, TQt::Horizontal, gboxSettings, "m_bSlider"); + m_bSlider->setTickmarks(TQSlider::Below); + m_bSlider->setTickInterval(20); + TQWhatsThis::add( m_bSlider, i18n("<p>Set here the yellow/blue color adjustment of the image.")); + labelRight = new TQLabel(i18n("Blue"), gboxSettings); + labelRight->setAlignment ( TQt::AlignLeft | TQt::AlignVCenter ); + m_bInput = new TQSpinBox(-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, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotColorSelectedFromTarget( const Digikam::DColor & ))); + + connect(m_rSlider, TQ_SIGNAL(valueChanged(int)), + m_rInput, TQ_SLOT(setValue(int))); + connect(m_rInput, TQ_SIGNAL(valueChanged (int)), + m_rSlider, TQ_SLOT(setValue(int))); + connect(m_rInput, TQ_SIGNAL(valueChanged (int)), + this, TQ_SLOT(slotTimer())); + + connect(m_gSlider, TQ_SIGNAL(valueChanged(int)), + m_gInput, TQ_SLOT(setValue(int))); + connect(m_gInput, TQ_SIGNAL(valueChanged (int)), + m_gSlider, TQ_SLOT(setValue(int))); + connect(m_gInput, TQ_SIGNAL(valueChanged (int)), + this, TQ_SLOT(slotTimer())); + + connect(m_bSlider, TQ_SIGNAL(valueChanged(int)), + m_bInput, TQ_SLOT(setValue(int))); + connect(m_bInput, TQ_SIGNAL(valueChanged (int)), + m_bSlider, TQ_SLOT(setValue(int))); + connect(m_bInput, TQ_SIGNAL(valueChanged (int)), + this, TQ_SLOT(slotTimer())); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_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( TQColor( "black" ), TQColor( "white" ) ); + break; + + case RedChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "green" ) ); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "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() +{ + TDEConfig* 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() +{ + TDEConfig* 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/src/imageplugins/coreplugin/imageeffect_rgb.h b/src/imageplugins/coreplugin/imageeffect_rgb.h new file mode 100644 index 00000000..9f5db52c --- /dev/null +++ b/src/imageplugins/coreplugin/imageeffect_rgb.h @@ -0,0 +1,113 @@ +/* ============================================================ + * + * 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 TQComboBox; +class TQHButtonGroup; + +class TQSpinBox; +class TQSlider; + +namespace Digikam +{ +class HistogramWidget; +class ColorGradientWidget; +class ImageWidget; +class DColor; +} + +namespace DigikamImagesPluginCore +{ + +class ImageEffect_RGB : public Digikam::ImageDlgBase +{ + TQ_OBJECT + + +public: + + ImageEffect_RGB(TQWidget *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; + + TQComboBox *m_channelCB; + + TQHButtonGroup *m_scaleBG; + + TQSpinBox *m_rInput; + TQSpinBox *m_gInput; + TQSpinBox *m_bInput; + + TQSlider *m_rSlider; + TQSlider *m_gSlider; + TQSlider *m_bSlider; + + Digikam::ImageWidget *m_previewWidget; + + Digikam::ColorGradientWidget *m_hGradient; + + Digikam::HistogramWidget *m_histogramWidget; + +}; + +} // NameSpace DigikamImagesPluginCore + +#endif /* IMAGEEFFECT_RGB_H */ diff --git a/src/imageplugins/coreplugin/imageplugin_core.cpp b/src/imageplugins/coreplugin/imageplugin_core.cpp new file mode 100644 index 00000000..22c63b34 --- /dev/null +++ b/src/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 <[email protected]> + * 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 <tdelocale.h> +#include <kgenericfactory.h> +#include <klibloader.h> +#include <tdeaction.h> +#include <kcursor.h> +#include <tdemessagebox.h> +#include <tdeapplication.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(TQObject *parent, const char*, const TQStringList&) + : ImagePlugin(parent, "ImagePlugin_Core") +{ + //------------------------------- + // Fix and Colors menu actions + + m_blurAction = new TDEAction(i18n("Blur..."), "blurimage", 0, + this, TQ_SLOT(slotBlur()), + actionCollection(), "implugcore_blur"); + + m_sharpenAction = new TDEAction(i18n("Sharpen..."), "sharpenimage", 0, + this, TQ_SLOT(slotSharpen()), + actionCollection(), "implugcore_sharpen"); + + m_redeyeAction = new TDEAction(i18n("Red Eye..."), "redeyes", 0, + this, TQ_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 TDEAction(i18n("Brightness/Contrast/Gamma..."), "contrast", 0, + this, TQ_SLOT(slotBCG()), + actionCollection(), "implugcore_bcg"); + + m_HSLAction = new TDEAction(i18n("Hue/Saturation/Lightness..."), "adjusthsl", + CTRL+Key_U, // NOTE: Photoshop 7 use CTRL+U. + this, TQ_SLOT(slotHSL()), + actionCollection(), "implugcore_hsl"); + + m_RGBAction = new TDEAction(i18n("Color Balance..."), "adjustrgb", + CTRL+Key_B, // NOTE: Photoshop 7 use CTRL+B. + this, TQ_SLOT(slotRGB()), + actionCollection(), "implugcore_rgb"); + + m_autoCorrectionAction = new TDEAction(i18n("Auto-Correction..."), "autocorrection", + CTRL+SHIFT+Key_B, // NOTE: Photoshop 7 use CTRL+SHIFT+B with 'Auto-Color' option. + this, TQ_SLOT(slotAutoCorrection()), + actionCollection(), "implugcore_autocorrection"); + + m_invertAction = new TDEAction(i18n("Invert"), "invertimage", + CTRL+Key_I, // NOTE: Photoshop 7 use CTRL+I. + this, TQ_SLOT(slotInvert()), + actionCollection(), "implugcore_invert"); + + m_convertTo8Bits = new TDEAction(i18n("8 bits"), "depth16to8", 0, + this, TQ_SLOT(slotConvertTo8Bits()), + actionCollection(), "implugcore_convertto8bits"); + + m_convertTo16Bits = new TDEAction(i18n("16 bits"), "depth8to16", 0, + this, TQ_SLOT(slotConvertTo16Bits()), + actionCollection(), "implugcore_convertto16bits"); + + m_colorManagementAction = new TDEAction(i18n("Color Management..."), "colormanagement", 0, + this, TQ_SLOT(slotColorManagement()), + actionCollection(), "implugcore_colormanagement"); + //------------------------------- + // Filters menu actions. + + m_BWAction = new TDEAction(i18n("Black && White..."), "bwtonal", 0, + this, TQ_SLOT(slotBW()), + actionCollection(), "implugcore_blackwhite"); + + //------------------------------- + // Transform menu actions. + + m_aspectRatioCropAction = new TDEAction(i18n("Aspect Ratio Crop..."), "ratiocrop", 0, + this, TQ_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?"), TQString(), + KStdGuiItem::cont(), + TQString("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/src/imageplugins/coreplugin/imageplugin_core.h b/src/imageplugins/coreplugin/imageplugin_core.h new file mode 100644 index 00000000..41168d26 --- /dev/null +++ b/src/imageplugins/coreplugin/imageplugin_core.h @@ -0,0 +1,85 @@ +/* ============================================================ + * + * 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 <[email protected]> + * 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 TDEAction; + +class DIGIKAMIMAGEPLUGINS_EXPORT ImagePlugin_Core : public Digikam::ImagePlugin +{ + TQ_OBJECT + + +public: + + ImagePlugin_Core(TQObject *parent, const char* name, const TQStringList &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: + + TDEAction *m_redeyeAction; + TDEAction *m_BCGAction; + TDEAction *m_HSLAction; + TDEAction *m_RGBAction; + TDEAction *m_autoCorrectionAction; + TDEAction *m_invertAction; + TDEAction *m_BWAction; + TDEAction *m_aspectRatioCropAction; + TDEAction *m_sharpenAction; + TDEAction *m_blurAction; + TDEAction *m_colorManagementAction; + TDEAction *m_convertTo8Bits; + TDEAction *m_convertTo16Bits; +}; + +#endif /* IMAGEPLUGIN_CORE_H */ diff --git a/src/imageplugins/coreplugin/ratiocrop/Makefile.am b/src/imageplugins/coreplugin/ratiocrop/Makefile.am new file mode 100644 index 00000000..47ec5b58 --- /dev/null +++ b/src/imageplugins/coreplugin/ratiocrop/Makefile.am @@ -0,0 +1,26 @@ +noinst_LTLIBRARIES = libratiocrop.la +METASOURCES = AUTO + +INCLUDES = -I$(top_srcdir)/src/utilities/imageeditor/editor \ + -I$(top_srcdir)/src/utilities/imageeditor/canvas \ + -I$(top_srcdir)/src/libs/histogram \ + -I$(top_srcdir)/src/libs/levels \ + -I$(top_srcdir)/src/libs/curves \ + -I$(top_srcdir)/src/libs/whitebalance \ + -I$(top_srcdir)/src/libs/widgets/common \ + -I$(top_srcdir)/src/libs/widgets/iccprofiles \ + -I$(top_srcdir)/src/libs/widgets/imageplugins \ + -I$(top_srcdir)/src/libs/dialogs \ + -I$(top_srcdir)/src/libs/dimg \ + -I$(top_srcdir)/src/libs/dmetadata \ + -I$(top_srcdir)/src/libs/dimg/filters \ + -I$(top_srcdir)/src/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/src/imageplugins/coreplugin/ratiocrop/imageeffect_ratiocrop.cpp b/src/imageplugins/coreplugin/ratiocrop/imageeffect_ratiocrop.cpp new file mode 100644 index 00000000..64bc7a8e --- /dev/null +++ b/src/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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqlayout.h> +#include <tqframe.h> +#include <tqrect.h> +#include <tqvgroupbox.h> +#include <tqlabel.h> +#include <tqwhatsthis.h> +#include <tqcombobox.h> +#include <tqspinbox.h> +#include <tqimage.h> +#include <tqpushbutton.h> +#include <tqtimer.h> +#include <tqcheckbox.h> + +// KDE includes. + +#include <kcursor.h> +#include <tdelocale.h> +#include <knuminput.h> +#include <tdeapplication.h> +#include <tdeconfig.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(TQWidget* 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); + + // ------------------------------------------------------------- + + TQFrame *frame = new TQFrame(plainPage()); + frame->setFrameStyle(TQFrame::Panel|TQFrame::Sunken); + TQVBoxLayout* l = new TQVBoxLayout(frame, 5, 0); + m_imageSelectionWidget = new ImageSelectionWidget(480, 320, frame); + l->addWidget(m_imageSelectionWidget); + TQWhatsThis::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(); + + // ------------------------------------------------------------- + + TQWidget *gbox2 = new TQWidget(plainPage()); + TQGridLayout *gridBox2 = new TQGridLayout( gbox2, 2, 0); + + TQFrame *cropSelection = new TQFrame( gbox2 ); + cropSelection->setFrameStyle(TQFrame::Panel|TQFrame::Sunken); + TQGridLayout* grid = new TQGridLayout( cropSelection, 6, 4, spacingHint()); + + TQLabel *label = new TQLabel(i18n("Aspect ratio:"), cropSelection); + m_ratioCB = new TQComboBox( false, cropSelection ); + setRatioCBText(ImageSelectionWidget::Landscape); + TQWhatsThis::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 TQCheckBox(i18n("Exact"), cropSelection); + TQWhatsThis::add( m_preciseCrop, i18n("<p>Enable this option to force exact aspect ratio crop.")); + + m_orientLabel = new TQLabel(i18n("Orientation:"), cropSelection); + m_orientCB = new TQComboBox( false, cropSelection ); + m_orientCB->insertItem( i18n("Landscape") ); + m_orientCB->insertItem( i18n("Portrait") ); + TQWhatsThis::add( m_orientCB, i18n("<p>Select constrained aspect ratio orientation.")); + + m_autoOrientation = new TQCheckBox(i18n("Auto"), cropSelection); + TQWhatsThis::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 TQLabel(i18n("Custom ratio:"), cropSelection); + m_customLabel1->setAlignment(AlignLeft|AlignVCenter); + m_customRatioNInput = new KIntSpinBox(1, 10000, 1, 1, 10, cropSelection); + TQWhatsThis::add( m_customRatioNInput, i18n("<p>Set here the desired custom aspect numerator value.")); + m_customLabel2 = new TQLabel(" : ", cropSelection); + m_customLabel2->setAlignment(AlignCenter|AlignVCenter); + m_customRatioDInput = new KIntSpinBox(1, 10000, 1, 1, 10, cropSelection); + TQWhatsThis::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); + TQWhatsThis::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); + TQWhatsThis::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 TQPushButton(cropSelection); + TDEGlobal::dirs()->addResourceType("centerwidth", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("centerwidth", "centerwidth.png"); + m_centerWidth->setPixmap( TQPixmap( directory + "centerwidth.png" ) ); + TQWhatsThis::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); + TQWhatsThis::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); + TQWhatsThis::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 TQPushButton(cropSelection); + TDEGlobal::dirs()->addResourceType("centerheight", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("centerheight", "centerheight.png"); + m_centerHeight->setPixmap( TQPixmap( directory + "centerheight.png" ) ); + TQWhatsThis::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); + + // ------------------------------------------------------------- + + TQFrame* compositionGuide = new TQFrame( gbox2 ); + TQGridLayout* grid2 = new TQGridLayout( compositionGuide, 7, 2, spacingHint()); + compositionGuide->setFrameStyle(TQFrame::Panel|TQFrame::Sunken); + + TQLabel *labelGuideLines = new TQLabel(i18n("Composition guide:"), compositionGuide); + m_guideLinesCB = new TQComboBox( 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") ); + TQWhatsThis::add( m_guideLinesCB, i18n("<p>With this option, you can display guide lines " + "which help you to compose your photograph.")); + + m_goldenSectionBox = new TQCheckBox(i18n("Golden sections"), compositionGuide); + TQWhatsThis::add( m_goldenSectionBox, i18n("<p>Enable this option to show golden sections.")); + + m_goldenSpiralSectionBox = new TQCheckBox(i18n("Golden spiral sections"), compositionGuide); + TQWhatsThis::add( m_goldenSpiralSectionBox, i18n("<p>Enable this option to show golden spiral sections.")); + + m_goldenSpiralBox = new TQCheckBox(i18n("Golden spiral"), compositionGuide); + TQWhatsThis::add( m_goldenSpiralBox, i18n("<p>Enable this option to show golden spiral guide.")); + + m_goldenTriangleBox = new TQCheckBox(i18n("Golden triangles"), compositionGuide); + TQWhatsThis::add( m_goldenTriangleBox, i18n("<p>Enable this option to show golden triangles.")); + + m_flipHorBox = new TQCheckBox(i18n("Flip horizontally"), compositionGuide); + TQWhatsThis::add( m_flipHorBox, i18n("<p>Enable this option to flip horizontally guidelines.")); + + m_flipVerBox = new TQCheckBox(i18n("Flip vertically"), compositionGuide); + TQWhatsThis::add( m_flipVerBox, i18n("<p>Enable this option to flip vertically guidelines.")); + + m_colorGuideLabel = new TQLabel(i18n("Color and width:"), compositionGuide); + m_guideColorBt = new KColorButton( TQColor( 250, 250, 255 ), compositionGuide ); + m_guideSize = new TQSpinBox( 1, 5, 1, compositionGuide); + TQWhatsThis::add( m_guideColorBt, i18n("<p>Set here the color used to draw composition guides.")); + TQWhatsThis::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, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotRatioChanged(int))); + + connect(m_preciseCrop, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotPreciseCropChanged(bool))); + + connect(m_orientCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotOrientChanged(int))); + + connect(m_autoOrientation, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotAutoOrientChanged(bool))); + + connect(m_xInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotXChanged(int))); + + connect(m_yInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotYChanged(int))); + + connect(m_customRatioNInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotCustomNRatioChanged(int))); + + connect(m_customRatioDInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotCustomDRatioChanged(int))); + + connect(m_guideLinesCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotGuideTypeChanged(int))); + + connect(m_goldenSectionBox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotGoldenGuideTypeChanged())); + + connect(m_goldenSpiralSectionBox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotGoldenGuideTypeChanged())); + + connect(m_goldenSpiralBox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotGoldenGuideTypeChanged())); + + connect(m_goldenTriangleBox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotGoldenGuideTypeChanged())); + + connect(m_flipHorBox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotGoldenGuideTypeChanged())); + + connect(m_flipVerBox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotGoldenGuideTypeChanged())); + + connect(m_guideColorBt, TQ_SIGNAL(changed(const TQColor &)), + m_imageSelectionWidget, TQ_SLOT(slotChangeGuideColor(const TQColor &))); + + connect(m_guideSize, TQ_SIGNAL(valueChanged(int)), + m_imageSelectionWidget, TQ_SLOT(slotChangeGuideSize(int))); + + connect(m_widthInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotWidthChanged(int))); + + connect(m_heightInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotHeightChanged(int))); + + connect(m_imageSelectionWidget, TQ_SIGNAL(signalSelectionChanged(TQRect)), + this, TQ_SLOT(slotSelectionChanged(TQRect))); + + connect(m_imageSelectionWidget, TQ_SIGNAL(signalSelectionMoved(TQRect)), + this, TQ_SLOT(slotSelectionChanged(TQRect))); + + connect(m_imageSelectionWidget, TQ_SIGNAL(signalSelectionOrientationChanged(int)), + this, TQ_SLOT(slotSelectionOrientationChanged(int))); + + connect(m_centerWidth, TQ_SIGNAL(clicked()), + this, TQ_SLOT(slotCenterWidth())); + + connect(m_centerHeight, TQ_SIGNAL(clicked()), + this, TQ_SLOT(slotCenterHeight())); + + // ------------------------------------------------------------- + + // Sets current region selection + slotSelectionChanged(m_imageSelectionWidget->getRegionSelection()); + + readSettings(); +} + +ImageEffect_RatioCrop::~ImageEffect_RatioCrop() +{ +} + +void ImageEffect_RatioCrop::readSettings() +{ + TQColor defaultGuideColor(250, 250, 255); + TDEConfig *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() +{ + TDEConfig *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(TQRect 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() ); + + TQRect 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(); + + TQRect 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/src/imageplugins/coreplugin/ratiocrop/imageeffect_ratiocrop.h b/src/imageplugins/coreplugin/ratiocrop/imageeffect_ratiocrop.h new file mode 100644 index 00000000..ca24eeac --- /dev/null +++ b/src/imageplugins/coreplugin/ratiocrop/imageeffect_ratiocrop.h @@ -0,0 +1,132 @@ +/* ============================================================ + * + * 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 TQLabel; +class TQComboBox; +class TQPushButton; +class TQCheckBox; +class TQSpinBox; + +class KIntNumInput; +class KIntSpinBox; +class KColorButton; + +namespace DigikamImagesPluginCore +{ + +class ImageSelectionWidget; + +class ImageEffect_RatioCrop : public Digikam::ImageDlgBase +{ + TQ_OBJECT + + +public: + + ImageEffect_RatioCrop(TQWidget *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(TQRect rect ); + void slotSelectionOrientationChanged(int); + void slotGuideTypeChanged(int t); + void slotGoldenGuideTypeChanged(); + +private: + + bool m_originalIsLandscape; + + TQLabel *m_customLabel1; + TQLabel *m_customLabel2; + TQLabel *m_orientLabel; + TQLabel *m_colorGuideLabel; + + TQComboBox *m_ratioCB; + TQComboBox *m_orientCB; + TQComboBox *m_guideLinesCB; + + TQPushButton *m_centerWidth; + TQPushButton *m_centerHeight; + + TQCheckBox *m_goldenSectionBox; + TQCheckBox *m_goldenSpiralSectionBox; + TQCheckBox *m_goldenSpiralBox; + TQCheckBox *m_goldenTriangleBox; + TQCheckBox *m_flipHorBox; + TQCheckBox *m_flipVerBox; + TQCheckBox *m_autoOrientation; + TQCheckBox *m_preciseCrop; + + TQSpinBox *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/src/imageplugins/coreplugin/ratiocrop/imageselectionwidget.cpp b/src/imageplugins/coreplugin/ratiocrop/imageselectionwidget.cpp new file mode 100644 index 00000000..17eaf415 --- /dev/null +++ b/src/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> + +// TQt includes. + +#include <tqregion.h> +#include <tqcolor.h> +#include <tqpainter.h> +#include <tqbrush.h> +#include <tqpixmap.h> +#include <tqimage.h> +#include <tqpen.h> +#include <tqpoint.h> +#include <tqtimer.h> +#include <tqsizepolicy.h> + +// KDE includes. + +#include <kstandarddirs.h> +#include <kcursor.h> +#include <tdeglobal.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; + + TQPoint lastPos; + + TQRect rect; + TQRect image; // Real image dimension. + TQRect regionSelection; // Real size image selection. + TQRect localRegionSelection; // Local size selection. + + // Draggable local region selection corners. + TQRect localTopLeftCorner; + TQRect localBottomLeftCorner; + TQRect localTopRightCorner; + TQRect localBottomRightCorner; + + TQPixmap *pixmap; + + TQColor guideColor; + + Digikam::DImg preview; + + Digikam::ImageIface *iface; +}; + +ImageSelectionWidget::ImageSelectionWidget(int w, int h, TQWidget *parent, + int widthRatioValue, int heightRatioValue, + int aspectRatioType, int orient, int guideLinesType) + : TQWidget(parent, 0, TQt::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(TQt::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 TQPixmap(w, h); + + d->image = TQRect(0, 0, d->iface->originalWidth(), d->iface->originalHeight()); + d->rect = TQRect(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(TQResizeEvent *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 TQPixmap(w, h); + + d->rect = TQRect(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(); +} + +TQRect 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 + TQPoint 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 TQColor &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(); +} + +TQPoint ImageSelectionWidget::convertPoint(const TQPoint pm, bool localToReal) +{ + return convertPoint(pm.x(), pm.y(), localToReal); +} + +TQPoint 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 TQPoint(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. + TQRect 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 + TQRect 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; + } + } + + TQPixmap 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; + + TQPainter p(d->pixmap); + + // Drawing selection borders. + + p.setPen(TQPen(TQColor(250, 250, 255), 1, TQt::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(TQPen(TQt::white, d->guideSize, TQt::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(TQPen(d->guideColor, d->guideSize, TQt::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(TQPen(TQt::white, d->guideSize, TQt::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(TQPen(d->guideColor, d->guideSize, TQt::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(TQPen(TQt::white, d->guideSize, TQt::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(TQPen(d->guideColor, d->guideSize, TQt::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; + + TQRect 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 + TQRect R2(w_g-w_2, h_2-h_g, w-w_g+1-(w - 2*w_2), h_g); + + TQRect R3((int)(w_2 - R2.width()*INVPHI), -h_2, + (int)(R2.width()*INVPHI), h - R2.height()); + TQRect R4(R2.x(), R1.y(), R3.x() - R2.x(), + (int)(R3.height()*INVPHI)); + TQRect R5(R4.x(), R4.bottom(), (int)(R4.width()*INVPHI), + R3.height() - R4.height()); + TQRect R6(R5.x() + R5.width(), R5.bottom() - (int)(R5.height()*INVPHI), + R3.x() - R5.right(), (int)(R5.height()*INVPHI)); + TQRect R7(R6.right() - (int)(R6.width()*INVPHI), R4.bottom(), + (int)(R6.width()*INVPHI), R5.height() - R6.height()); + + p.setPen(TQPen(TQt::white, d->guideSize, TQt::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(TQPen(d->guideColor, d->guideSize, TQt::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( TQPaintEvent * ) +{ + bitBlt(this, 0, 0, d->pixmap); +} + +TQPoint ImageSelectionWidget::opposite() +{ + TQPoint 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(TQPoint a, TQPoint 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(TQPoint pm, bool symmetric, TQPoint center) +{ + // Set orientation + if ( d->autoOrientation ) + { + TQPoint 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 ( TQMouseEvent * e ) +{ + if ( e->button() == TQt::LeftButton ) + { + TQPoint pm = TQPoint(e->x(), e->y()); + TQPoint pmVirtual = convertPoint(pm); + d->moving = false; + + if ( (e->state() & TQt::ShiftButton) == TQt::ShiftButton ) + { + bool symmetric = (e->state() & TQt::ControlButton ) == TQt::ControlButton; + TQPoint center = d->regionSelection.center(); + + // Find the closest corner + + TQPoint 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++) + { + TQPoint 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 ( TQMouseEvent * ) +{ + 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 ( TQMouseEvent * e ) +{ + if ( ( e->state() & TQt::LeftButton ) == TQt::LeftButton ) + { + if ( d->moving ) + { + setCursor( KCursor::sizeAllCursor() ); + TQPoint 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 + { + TQPoint 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 + } + + TQPoint center = d->regionSelection.center(); + bool symmetric = (e->state() & TQt::ControlButton ) == TQt::ControlButton; + + // Change resizing mode + + TQPoint opp = symmetric ? center : opposite(); + TQPoint 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/src/imageplugins/coreplugin/ratiocrop/imageselectionwidget.h b/src/imageplugins/coreplugin/ratiocrop/imageselectionwidget.h new file mode 100644 index 00000000..0d2bd4fd --- /dev/null +++ b/src/imageplugins/coreplugin/ratiocrop/imageselectionwidget.h @@ -0,0 +1,176 @@ +/* ============================================================ + * + * 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 + +// TQt includes. + +#include <tqwidget.h> +#include <tqrect.h> +#include <tqcolor.h> + +namespace Digikam +{ +class ImageIface; +} + +namespace DigikamImagesPluginCore +{ + +class ImageSelectionWidgetPriv; + +class ImageSelectionWidget : public TQWidget +{ + +TQ_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, TQWidget *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(); + TQRect 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 TQColor &color); + void slotChangeGuideSize(int size); + +signals: + + void signalSelectionMoved( TQRect rect ); + void signalSelectionChanged( TQRect rect ); + void signalSelectionOrientationChanged( int newOrientation ); + +protected: + + void paintEvent( TQPaintEvent *e ); + void mousePressEvent ( TQMouseEvent * e ); + void mouseReleaseEvent ( TQMouseEvent * e ); + void mouseMoveEvent ( TQMouseEvent * e ); + void resizeEvent(TQResizeEvent * e); + +private: + + // Recalculate the target selection position and emit 'signalSelectionMoved'. + void regionSelectionMoved(); + + void regionSelectionChanged(); + TQPoint convertPoint(const TQPoint pm, bool localToReal=true); + TQPoint 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(); + TQPoint opposite(); + float distance(TQPoint a, TQPoint b); + void placeSelection(TQPoint pm, bool symetric, TQPoint center); + void setCursorResizing(); + +private: + + ImageSelectionWidgetPriv* d; +}; + +} // NameSpace DigikamImagesPluginCore + +#endif /* IMAGESELECTIONWIDGET_H */ diff --git a/src/imageplugins/coreplugin/ratiocrop/ratiocroptool.cpp b/src/imageplugins/coreplugin/ratiocrop/ratiocroptool.cpp new file mode 100644 index 00000000..ed0e670e --- /dev/null +++ b/src/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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqcheckbox.h> +#include <tqframe.h> +#include <tqimage.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqrect.h> +#include <tqspinbox.h> +#include <tqtimer.h> +#include <tqtoolbutton.h> +#include <tqtooltip.h> +#include <tqvgroupbox.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <tdeapplication.h> +#include <kcolorbutton.h> +#include <tdeconfig.h> +#include <kcursor.h> +#include <kiconloader.h> +#include <tdelocale.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(TQObject* parent) + : EditorTool(parent) +{ + setName("aspectratiocrop"); + setToolName(i18n("Aspect Ratio Crop")); + setToolIcon(SmallIcon("ratiocrop")); + setToolHelp("ratiocroptool.anchor"); + + // ------------------------------------------------------------- + + m_imageSelectionWidget = new ImageSelectionWidget(480, 320); + TQWhatsThis::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")); + + TQToolTip::add(m_gboxSettings->button(EditorToolSettings::Try), + i18n("<p>Set selection area to the maximum size according " + "to the current ratio.")); + + // ------------------------------------------------------------- + + TQGridLayout *gboxLayout = new TQGridLayout(m_gboxSettings->plainPage(), 3, 2); + + TQFrame *cropSelection = new TQFrame(m_gboxSettings->plainPage()); + cropSelection->setFrameStyle(TQFrame::Panel | TQFrame::Sunken); + + TQGridLayout* grid = new TQGridLayout(cropSelection, 7, 5); + + TQLabel *label = new TQLabel(i18n("Ratio:"), cropSelection); + m_ratioCB = new RComboBox(cropSelection); + m_ratioCB->setDefaultItem(ImageSelectionWidget::RATIO03X04); + setRatioCBText(ImageSelectionWidget::Landscape); + TQWhatsThis::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 TQCheckBox(i18n("Exact"), cropSelection); + TQWhatsThis::add( m_preciseCrop, i18n("<p>Enable this option to force exact aspect ratio crop.")); + + m_orientLabel = new TQLabel(i18n("Orientation:"), cropSelection); + m_orientCB = new RComboBox(cropSelection); + m_orientCB->insertItem( i18n("Landscape")); + m_orientCB->insertItem( i18n("Portrait")); + m_orientCB->setDefaultItem(ImageSelectionWidget::Landscape); + TQWhatsThis::add( m_orientCB, i18n("<p>Select constrained aspect ratio orientation.")); + + m_autoOrientation = new TQCheckBox(i18n("Auto"), cropSelection); + TQWhatsThis::add( m_autoOrientation, i18n("<p>Enable this option to automatically set the orientation.")); + + // ------------------------------------------------------------- + + m_customLabel1 = new TQLabel(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); + TQWhatsThis::add( m_customRatioNInput, i18n("<p>Set here the desired custom aspect numerator value.")); + + m_customLabel2 = new TQLabel(" : ", cropSelection); + m_customLabel2->setAlignment(AlignCenter|AlignVCenter); + m_customRatioDInput = new RIntNumInput(cropSelection); + m_customRatioDInput->input()->setRange(1, 10000, 1, false); + m_customRatioDInput->setDefaultValue(1); + TQWhatsThis::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); + TQWhatsThis::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); + TQWhatsThis::add( m_widthInput, i18n("<p>Set here the width selection for cropping.")); + + m_centerWidth = new TQToolButton(cropSelection); + TDEGlobal::dirs()->addResourceType("centerwidth", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("centerwidth", "centerwidth.png"); + m_centerWidth->setPixmap(TQPixmap(directory + "centerwidth.png")); + TQWhatsThis::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); + TQWhatsThis::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); + TQWhatsThis::add( m_heightInput, i18n("<p>Set here the height selection for cropping.")); + + m_centerHeight = new TQToolButton(cropSelection); + TDEGlobal::dirs()->addResourceType("centerheight", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("centerheight", "centerheight.png"); + m_centerHeight->setPixmap(TQPixmap(directory + "centerheight.png")); + TQWhatsThis::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()); + + // ------------------------------------------------------------- + + TQFrame* compositionGuide = new TQFrame(m_gboxSettings->plainPage()); + TQGridLayout* grid2 = new TQGridLayout(compositionGuide, 8, 3); + compositionGuide->setFrameStyle(TQFrame::Panel|TQFrame::Sunken); + + TQLabel *labelGuideLines = new TQLabel(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); + TQWhatsThis::add( m_guideLinesCB, i18n("<p>With this option, you can display guide lines " + "which help you to compose your photograph.")); + + m_goldenSectionBox = new TQCheckBox(i18n("Golden sections"), compositionGuide); + TQWhatsThis::add( m_goldenSectionBox, i18n("<p>Enable this option to show golden sections.")); + + m_goldenSpiralSectionBox = new TQCheckBox(i18n("Golden spiral sections"), compositionGuide); + TQWhatsThis::add( m_goldenSpiralSectionBox, i18n("<p>Enable this option to show golden spiral sections.")); + + m_goldenSpiralBox = new TQCheckBox(i18n("Golden spiral"), compositionGuide); + TQWhatsThis::add( m_goldenSpiralBox, i18n("<p>Enable this option to show golden spiral guide.")); + + m_goldenTriangleBox = new TQCheckBox(i18n("Golden triangles"), compositionGuide); + TQWhatsThis::add( m_goldenTriangleBox, i18n("<p>Enable this option to show golden triangles.")); + + m_flipHorBox = new TQCheckBox(i18n("Flip horizontally"), compositionGuide); + TQWhatsThis::add( m_flipHorBox, i18n("<p>Enable this option to flip horizontally guidelines.")); + + m_flipVerBox = new TQCheckBox(i18n("Flip vertically"), compositionGuide); + TQWhatsThis::add( m_flipVerBox, i18n("<p>Enable this option to flip vertically guidelines.")); + + m_colorGuideLabel = new TQLabel(i18n("Color and width:"), compositionGuide); + m_guideColorBt = new KColorButton(TQColor(250, 250, 255), compositionGuide); + m_guideSize = new RIntNumInput(compositionGuide); + m_guideSize->input()->setRange(1, 5, 1, false); + m_guideSize->setDefaultValue(1); + TQWhatsThis::add( m_guideColorBt, i18n("<p>Set here the color used to draw composition guides.")); + TQWhatsThis::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, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotRatioChanged(int))); + + connect(m_preciseCrop, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotPreciseCropChanged(bool))); + + connect(m_orientCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotOrientChanged(int))); + + connect(m_autoOrientation, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotAutoOrientChanged(bool))); + + connect(m_xInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotXChanged(int))); + + connect(m_yInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotYChanged(int))); + + connect(m_customRatioNInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotCustomNRatioChanged(int))); + + connect(m_customRatioDInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotCustomDRatioChanged(int))); + + connect(m_guideLinesCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotGuideTypeChanged(int))); + + connect(m_goldenSectionBox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotGoldenGuideTypeChanged())); + + connect(m_goldenSpiralSectionBox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotGoldenGuideTypeChanged())); + + connect(m_goldenSpiralBox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotGoldenGuideTypeChanged())); + + connect(m_goldenTriangleBox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotGoldenGuideTypeChanged())); + + connect(m_flipHorBox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotGoldenGuideTypeChanged())); + + connect(m_flipVerBox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotGoldenGuideTypeChanged())); + + connect(m_guideColorBt, TQ_SIGNAL(changed(const TQColor&)), + m_imageSelectionWidget, TQ_SLOT(slotChangeGuideColor(const TQColor&))); + + connect(m_guideSize, TQ_SIGNAL(valueChanged(int)), + m_imageSelectionWidget, TQ_SLOT(slotChangeGuideSize(int))); + + connect(m_widthInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotWidthChanged(int))); + + connect(m_heightInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotHeightChanged(int))); + + connect(m_imageSelectionWidget, TQ_SIGNAL(signalSelectionChanged(TQRect)), + this, TQ_SLOT(slotSelectionChanged(TQRect))); + + connect(m_imageSelectionWidget, TQ_SIGNAL(signalSelectionMoved(TQRect)), + this, TQ_SLOT(slotSelectionChanged(TQRect))); + + connect(m_imageSelectionWidget, TQ_SIGNAL(signalSelectionOrientationChanged(int)), + this, TQ_SLOT(slotSelectionOrientationChanged(int))); + + connect(m_centerWidth, TQ_SIGNAL(clicked()), + this, TQ_SLOT(slotCenterWidth())); + + connect(m_centerHeight, TQ_SIGNAL(clicked()), + this, TQ_SLOT(slotCenterHeight())); + + // we need to disconnect the standard connection of the Try button first + disconnect(m_gboxSettings, TQ_SIGNAL(signalTryClicked()), + this, TQ_SLOT(slotEffect())); + + connect(m_gboxSettings, TQ_SIGNAL(signalTryClicked()), + this, TQ_SLOT(slotMaxAspectRatio())); + + // ------------------------------------------------------------- + + // Sets current region selection + slotSelectionChanged(m_imageSelectionWidget->getRegionSelection()); +} + +RatioCropTool::~RatioCropTool() +{ +} + +void RatioCropTool::readSettings() +{ + TQColor defaultGuideColor(250, 250, 255); + TDEConfig *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() +{ + TDEConfig *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(TQRect 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() ); + + TQRect 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(); + + TQRect 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/src/imageplugins/coreplugin/ratiocrop/ratiocroptool.h b/src/imageplugins/coreplugin/ratiocrop/ratiocroptool.h new file mode 100644 index 00000000..833677da --- /dev/null +++ b/src/imageplugins/coreplugin/ratiocrop/ratiocroptool.h @@ -0,0 +1,135 @@ +/* ============================================================ + * + * 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 TQCheckBox; +class TQLabel; +class TQToolButton; + +class KColorButton; + +namespace KDcrawIface +{ +class RComboBox; +class RIntNumInput; +} + +namespace DigikamImagesPluginCore +{ + +class ImageSelectionWidget; + +class RatioCropTool : public Digikam::EditorTool +{ + TQ_OBJECT + + +public: + + RatioCropTool(TQObject *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(TQRect rect ); + void slotSelectionOrientationChanged(int); + void slotGuideTypeChanged(int t); + void slotGoldenGuideTypeChanged(); + +private: + + bool m_originalIsLandscape; + + TQLabel *m_customLabel1; + TQLabel *m_customLabel2; + TQLabel *m_orientLabel; + TQLabel *m_colorGuideLabel; + + + TQToolButton *m_centerWidth; + TQToolButton *m_centerHeight; + + TQCheckBox *m_goldenSectionBox; + TQCheckBox *m_goldenSpiralSectionBox; + TQCheckBox *m_goldenSpiralBox; + TQCheckBox *m_goldenTriangleBox; + TQCheckBox *m_flipHorBox; + TQCheckBox *m_flipVerBox; + TQCheckBox *m_autoOrientation; + TQCheckBox *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/src/imageplugins/coreplugin/redeyetool.cpp b/src/imageplugins/coreplugin/redeyetool.cpp new file mode 100644 index 00000000..5b5af7e7 --- /dev/null +++ b/src/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 <[email protected]> + * 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqcolor.h> +#include <tqhbox.h> +#include <tqhgroupbox.h> +#include <tqvgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqvbox.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqframe.h> +#include <tqlabel.h> +#include <tqpushbutton.h> +#include <tqcombobox.h> +#include <tqwhatsthis.h> +#include <tqtooltip.h> + +// KDE includes. + +#include <tdeapplication.h> +#include <kcolordialog.h> +#include <kcolordialog.h> +#include <tdeconfig.h> +#include <kcursor.h> +#include <kiconloader.h> +#include <tdelocale.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(TQObject* 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); + + TQGridLayout* gridSettings = new TQGridLayout(gboxSettings->plainPage(), 11, 4); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), gboxSettings->plainPage()); + label1->setAlignment(TQt::AlignRight | TQt::AlignVCenter); + m_channelCB = new TQComboBox(false, gboxSettings->plainPage()); + m_channelCB->insertItem(i18n("Luminosity")); + m_channelCB->insertItem(i18n("Red")); + m_channelCB->insertItem(i18n("Green")); + m_channelCB->insertItem(i18n("Blue")); + TQWhatsThis::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 TQHButtonGroup(gboxSettings->plainPage()); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin(0); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(linHistoButton, i18n("<p>Linear")); + m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap(TQPixmap(directory + "histogram-lin.png")); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(logHistoButton, i18n("<p>Logarithmic")); + m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap(TQPixmap(directory + "histogram-log.png")); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(gboxSettings->plainPage()); + m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, histoBox); + m_hGradient->setColors(TQColor("black"), TQColor("white")); + + // ------------------------------------------------------------- + + m_thresholdLabel = new TQLabel(i18n("Sensitivity:"), gboxSettings->plainPage()); + m_redThreshold = new RIntNumInput(gboxSettings->plainPage()); + m_redThreshold->setRange(10, 90, 1); + m_redThreshold->setDefaultValue(20); + TQWhatsThis::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 TQLabel(i18n("Smooth:"), gboxSettings->plainPage()); + m_smoothLevel = new RIntNumInput(gboxSettings->plainPage()); + m_smoothLevel->setRange(0, 5, 1); + m_smoothLevel->setDefaultValue(1); + TQWhatsThis::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.")); + + TQLabel *label3 = new TQLabel(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); + TQWhatsThis::add(m_HSSelector, i18n("<p>Sets a custom color to re-colorize the eyes.")); + + TQLabel *label4 = new TQLabel(i18n("Tint Level:"), gboxSettings->plainPage()); + m_tintLevel = new RIntNumInput(gboxSettings->plainPage()); + m_tintLevel->setRange(1, 200, 1); + m_tintLevel->setDefaultValue(128); + TQWhatsThis::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, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget(const Digikam::DColor&, const TQPoint&)), + this, TQ_SLOT(slotColorSelectedFromTarget(const Digikam::DColor&))); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_SLOT(slotEffect())); + + connect(m_redThreshold, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_smoothLevel, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_HSSelector, TQ_SIGNAL(valueChanged(int, int)), + this, TQ_SLOT(slotHSChanged(int, int))); + + connect(m_VSelector, TQ_SIGNAL(valueChanged(int)), + this, TQ_SLOT(slotTimer())); + + connect(m_tintLevel, TQ_SIGNAL(valueChanged(int)), + this, TQ_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(TQColor("black"), TQColor("white")); + break; + + case RedChannel: + m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("red")); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("green")); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("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() +{ + TDEConfig* 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() +{ + TDEConfig* 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 = TQMIN(255, (int)(red_norm * (red_chan.red_gain * r + + red_chan.green_gain * g + + red_chan.blue_gain * b))); + + g1 = TQMIN(255, (int)(green_norm * (green_chan.red_gain * r + + green_chan.green_gain * g + + green_chan.blue_gain * b))); + + b1 = TQMIN(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] = TQMIN( (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 = TQMIN(65535, (int)(red_norm * (red_chan.red_gain * r + + red_chan.green_gain * g + + red_chan.blue_gain * b))); + + g1 = TQMIN(65535, (int)(green_norm * (green_chan.red_gain * r + + green_chan.green_gain * g + + green_chan.blue_gain * b))); + + b1 = TQMIN(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] = TQMIN( (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/src/imageplugins/coreplugin/redeyetool.h b/src/imageplugins/coreplugin/redeyetool.h new file mode 100644 index 00000000..eb614fd3 --- /dev/null +++ b/src/imageplugins/coreplugin/redeyetool.h @@ -0,0 +1,157 @@ +/* ============================================================ + * + * 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 <[email protected]> + * 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 TQLabel; +class TQComboBox; +class TQHButtonGroup; + +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(TQWidget* parent) + : KPassivePopup(parent), m_parent(parent) + { + } + +protected: + + virtual void positionSelf() + { + move(m_parent->x() + 30, m_parent->y() + 30); + } + +private: + + TQWidget* m_parent; +}; + +// ---------------------------------------------------------------- + +class RedEyeTool : public Digikam::EditorTool +{ + TQ_OBJECT + + +public: + + RedEyeTool(TQObject *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; + + TQLabel *m_thresholdLabel; + TQLabel *m_smoothLabel; + + TQComboBox *m_channelCB; + + TQHButtonGroup *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/src/imageplugins/coreplugin/rgbtool.cpp b/src/imageplugins/coreplugin/rgbtool.cpp new file mode 100644 index 00000000..e27e396e --- /dev/null +++ b/src/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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqcheckbox.h> +#include <tqcolor.h> +#include <tqcombobox.h> +#include <tqframe.h> +#include <tqgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqhgroupbox.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqpushbutton.h> +#include <tqslider.h> +#include <tqtooltip.h> +#include <tqvbox.h> +#include <tqvgroupbox.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <tdeapplication.h> +#include <tdeconfig.h> +#include <kcursor.h> +#include <kiconloader.h> +#include <tdelocale.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(TQObject* 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); + + TQGridLayout* gridSettings = new TQGridLayout(m_gboxSettings->plainPage(), 7, 4); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), m_gboxSettings->plainPage()); + label1->setAlignment(TQt::AlignRight | TQt::AlignVCenter); + m_channelCB = new TQComboBox(false, m_gboxSettings->plainPage()); + m_channelCB->insertItem(i18n("Luminosity")); + m_channelCB->insertItem(i18n("Red")); + m_channelCB->insertItem(i18n("Green")); + m_channelCB->insertItem(i18n("Blue")); + TQWhatsThis::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 TQHButtonGroup(m_gboxSettings->plainPage()); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin(0); + TQWhatsThis::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.")); + + TQPushButton *linHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(linHistoButton, i18n("<p>Linear")); + m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap(TQPixmap(directory + "histogram-lin.png")); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton(m_scaleBG); + TQToolTip::add(logHistoButton, i18n("<p>Logarithmic")); + m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap(TQPixmap(directory + "histogram-log.png")); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + gridSettings->addMultiCellLayout(l1, 0, 0, 0, 4); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(m_gboxSettings->plainPage()); + m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::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.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, histoBox); + m_hGradient->setColors(TQColor("black"), TQColor("white")); + + gridSettings->addMultiCellWidget(histoBox, 1, 2, 0, 4); + + // ------------------------------------------------------------- + + TQLabel *labelLeft = new TQLabel(i18n("Cyan"), m_gboxSettings->plainPage()); + labelLeft->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_rSlider = new TQSlider(-100, 100, 1, 0, TQt::Horizontal, m_gboxSettings->plainPage(), "m_rSlider"); + m_rSlider->setTickmarks(TQSlider::Below); + m_rSlider->setTickInterval(20); + TQWhatsThis::add( m_rSlider, i18n("<p>Set here the cyan/red color adjustment of the image.")); + TQLabel *labelRight = new TQLabel(i18n("Red"), m_gboxSettings->plainPage()); + labelRight->setAlignment ( TQt::AlignLeft | TQt::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 TQLabel(i18n("Magenta"), m_gboxSettings->plainPage()); + labelLeft->setAlignment(TQt::AlignRight | TQt::AlignVCenter); + m_gSlider = new TQSlider(-100, 100, 1, 0, TQt::Horizontal, m_gboxSettings->plainPage(), "m_gSlider"); + m_gSlider->setTickmarks(TQSlider::Below); + m_gSlider->setTickInterval(20); + TQWhatsThis::add( m_gSlider, i18n("<p>Set here the magenta/green color adjustment of the image.")); + labelRight = new TQLabel(i18n("Green"), m_gboxSettings->plainPage()); + labelRight->setAlignment(TQt::AlignLeft | TQt::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 TQLabel(i18n("Yellow"), m_gboxSettings->plainPage()); + labelLeft->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_bSlider = new TQSlider(-100, 100, 1, 0, TQt::Horizontal, m_gboxSettings->plainPage(), "m_bSlider"); + m_bSlider->setTickmarks(TQSlider::Below); + m_bSlider->setTickInterval(20); + TQWhatsThis::add( m_bSlider, i18n("<p>Set here the yellow/blue color adjustment of the image.")); + labelRight = new TQLabel(i18n("Blue"), m_gboxSettings->plainPage()); + labelRight->setAlignment(TQt::AlignLeft | TQt::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, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotColorSelectedFromTarget( const Digikam::DColor & ))); + + connect(m_rSlider, TQ_SIGNAL(valueChanged(int)), + m_rInput, TQ_SLOT(setValue(int))); + connect(m_rInput, TQ_SIGNAL(valueChanged (int)), + m_rSlider, TQ_SLOT(setValue(int))); + connect(m_rInput, TQ_SIGNAL(valueChanged (int)), + this, TQ_SLOT(slotTimer())); + + connect(m_gSlider, TQ_SIGNAL(valueChanged(int)), + m_gInput, TQ_SLOT(setValue(int))); + connect(m_gInput, TQ_SIGNAL(valueChanged (int)), + m_gSlider, TQ_SLOT(setValue(int))); + connect(m_gInput, TQ_SIGNAL(valueChanged (int)), + this, TQ_SLOT(slotTimer())); + + connect(m_bSlider, TQ_SIGNAL(valueChanged(int)), + m_bInput, TQ_SLOT(setValue(int))); + connect(m_bInput, TQ_SIGNAL(valueChanged (int)), + m_bSlider, TQ_SLOT(setValue(int))); + connect(m_bInput, TQ_SIGNAL(valueChanged (int)), + this, TQ_SLOT(slotTimer())); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_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(TQColor("black"), TQColor("white")); + break; + + case RedChannel: + m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("red")); + break; + + case GreenChannel: + m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("green")); + break; + + case BlueChannel: + m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors(TQColor("black"), TQColor("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() +{ + TDEConfig* 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() +{ + TDEConfig* 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/src/imageplugins/coreplugin/rgbtool.h b/src/imageplugins/coreplugin/rgbtool.h new file mode 100644 index 00000000..dadb6a0e --- /dev/null +++ b/src/imageplugins/coreplugin/rgbtool.h @@ -0,0 +1,119 @@ +/* ============================================================ + * + * 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 TQComboBox; +class TQHButtonGroup; + +class TQSlider; + +namespace KDcrawIface +{ +class RIntNumInput; +} + +namespace Digikam +{ +class HistogramWidget; +class ColorGradientWidget; +class ImageWidget; +class DColor; +} + +namespace DigikamImagesPluginCore +{ + +class RGBTool : public Digikam::EditorTool +{ + TQ_OBJECT + + +public: + + RGBTool(TQObject *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; + + TQComboBox *m_channelCB; + + TQHButtonGroup *m_scaleBG; + + KDcrawIface::RIntNumInput *m_rInput; + KDcrawIface::RIntNumInput *m_gInput; + KDcrawIface::RIntNumInput *m_bInput; + + TQSlider *m_rSlider; + TQSlider *m_gSlider; + TQSlider *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/src/imageplugins/coreplugin/sharpnesseditor/Makefile.am b/src/imageplugins/coreplugin/sharpnesseditor/Makefile.am new file mode 100644 index 00000000..c02087ee --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/Makefile.am @@ -0,0 +1,32 @@ +SUBDIRS = clapack +COMPILE_FIRST = clapack + +noinst_LTLIBRARIES = libsharpnesseditor.la +METASOURCES = AUTO + +INCLUDES = -I$(top_srcdir)/src/utilities/imageeditor/editor \ + -I$(top_srcdir)/src/utilities/imageeditor/canvas \ + -I$(top_srcdir)/src/libs/histogram \ + -I$(top_srcdir)/src/libs/levels \ + -I$(top_srcdir)/src/libs/curves \ + -I$(top_srcdir)/src/libs/whitebalance \ + -I$(top_srcdir)/src/libs/widgets/common \ + -I$(top_srcdir)/src/libs/widgets/iccprofiles \ + -I$(top_srcdir)/src/libs/widgets/imageplugins \ + -I$(top_srcdir)/src/libs/dialogs \ + -I$(top_srcdir)/src/libs/dimg \ + -I$(top_srcdir)/src/libs/dmetadata \ + -I$(top_srcdir)/src/libs/dimg/filters \ + -I$(top_srcdir)/src/digikam \ + -I$(top_srcdir)/src/imageplugins/coreplugin/sharpnesseditor/clapack \ + $(LIBKDCRAW_CFLAGS) \ + $(all_includes) + +libsharpnesseditor_la_LIBADD = $(top_builddir)/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/LICENCE b/src/imageplugins/coreplugin/sharpnesseditor/clapack/LICENCE new file mode 100644 index 00000000..a338f860 --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/Makefile.am b/src/imageplugins/coreplugin/sharpnesseditor/clapack/Makefile.am new file mode 100644 index 00000000..bf478556 --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/README b/src/imageplugins/coreplugin/sharpnesseditor/clapack/README new file mode 100644 index 00000000..530f73ee --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/abort_.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/abort_.c new file mode 100644 index 00000000..67278e93 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/abort_.c @@ -0,0 +1,10 @@ +#include "stdio.h" +#include "f2c.h" + +extern void sig_die(char*,int); + +int abort_(void) +{ +sig_die("Fortran abort routine called", 1); +return 0; /* not reached */ +} diff --git a/src/imageplugins/coreplugin/sharpnesseditor/clapack/blaswrap.h b/src/imageplugins/coreplugin/sharpnesseditor/clapack/blaswrap.h new file mode 100644 index 00000000..84c08d30 --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/clapack.h b/src/imageplugins/coreplugin/sharpnesseditor/clapack/clapack.h new file mode 100644 index 00000000..cad9a4c2 --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/close.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/close.c new file mode 100644 index 00000000..d305ccf8 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/close.c @@ -0,0 +1,80 @@ +#include "f2c.h" +#include "fio.h" +#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) +{ 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 f_exit(void) +{ 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 flush_(void) +{ 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/src/imageplugins/coreplugin/sharpnesseditor/clapack/dgemm.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/dgemm.c new file mode 100644 index 00000000..964a278a --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/dger.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/dger.c new file mode 100644 index 00000000..c53835fa --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/dgesv.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/dgesv.c new file mode 100644 index 00000000..5c0dc52b --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/dgetf2.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/dgetf2.c new file mode 100644 index 00000000..83bf1872 --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/dgetrf.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/dgetrf.c new file mode 100644 index 00000000..13175f01 --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/dgetrs.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/dgetrs.c new file mode 100644 index 00000000..c4dd0b38 --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/dlaswp.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/dlaswp.c new file mode 100644 index 00000000..4dd6fd7b --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/dscal.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/dscal.c new file mode 100644 index 00000000..e0e6ffb9 --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/dswap.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/dswap.c new file mode 100644 index 00000000..5aacf29b --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/dtrsm.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/dtrsm.c new file mode 100644 index 00000000..d178c1ed --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/endfile.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/endfile.c new file mode 100644 index 00000000..d309fc26 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/endfile.c @@ -0,0 +1,102 @@ +#include "f2c.h" +#include "fio.h" + +#undef abs +#undef min +#undef max +#include "stdlib.h" +#include "string.h" + +extern char *f__r_mode[], *f__w_mode[]; + +integer f_end(alist *a) +{ + 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 copy(FILE *from, long len, FILE *to) +{ + 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 t_runc(alist *a) +{ + 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/src/imageplugins/coreplugin/sharpnesseditor/clapack/err.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/err.c new file mode 100644 index 00000000..90af7cae --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/err.c @@ -0,0 +1,240 @@ +#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" +#undef abs +#undef min +#undef max +#include "stdlib.h" +#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 */ +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); +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) + +int f__canseek(FILE *f) /*SYSDEP*/ +{ +#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 f__fatal(int n, char *s) +{ + 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; +} + +int f__nowreading(unit *x) +{ + 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; +} + +int f__nowwriting(unit *x) +{ + 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 err__fl(int f, int m, char *s) +{ + if (!f) + f__fatal(m, s); + if (f__doend) + (*f__doend)(); + return errno = m; + } diff --git a/src/imageplugins/coreplugin/sharpnesseditor/clapack/f2c.h b/src/imageplugins/coreplugin/sharpnesseditor/clapack/f2c.h new file mode 100644 index 00000000..6514cd91 --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/fio.h b/src/imageplugins/coreplugin/sharpnesseditor/clapack/fio.h new file mode 100644 index 00000000..b1632d50 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/fio.h @@ -0,0 +1,96 @@ +#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 +#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 +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/src/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.c new file mode 100644 index 00000000..a4fcbc38 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.c @@ -0,0 +1,470 @@ +#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 char *ap_end(char *s) +{ 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 int op_gen(int a, int b, int c, int d) +{ 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++); +} + +static char *f_list(char*); +static char *gt_num(char *s, int *n, int n1) +{ 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 char *f_s(char *s, int curloc) +{ + 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 int ne_d(char *s, char **p) +{ 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 int e_d(char *s, char **p) +{ 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 char *i_tem(char *s) +{ 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 char *f_list(char *s) +{ + 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); +} + +int pars_f(char *s) +{ + 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 int type_f(int n) +{ + 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); + } +} + +integer do_fio(ftnint *number, char *ptr, ftnlen len) +{ 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); +} + +int 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/src/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.h b/src/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.h new file mode 100644 index 00000000..b46bc9c5 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/fmt.h @@ -0,0 +1,86 @@ +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; + signed char ic; + integer il; +#ifdef Allow_TYQUAD + longint ili; +#endif +} Uint; +#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 +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 + +extern char *f__icvt(longint, int*, int*, int); diff --git a/src/imageplugins/coreplugin/sharpnesseditor/clapack/fmtlib.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/fmtlib.c new file mode 100644 index 00000000..8343337b --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/fmtlib.c @@ -0,0 +1,40 @@ +/* @(#)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 + +char *f__icvt(longint value, int *ndigit, int *sign, int base) +{ + static char buf[MAXINTLENGTH+1]; + 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/src/imageplugins/coreplugin/sharpnesseditor/clapack/fp.h b/src/imageplugins/coreplugin/sharpnesseditor/clapack/fp.h new file mode 100644 index 00000000..40743d79 --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/idamax.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/idamax.c new file mode 100644 index 00000000..2cc54813 --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/ieeeck.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/ieeeck.c new file mode 100644 index 00000000..39256a48 --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/ilaenv.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/ilaenv.c new file mode 100644 index 00000000..58299fff --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/lsame.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/lsame.c new file mode 100644 index 00000000..d9baaa3f --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/clapack/open.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/open.c new file mode 100644 index 00000000..e7810757 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/open.c @@ -0,0 +1,256 @@ +#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 + +#undef abs +#undef min +#undef max +#include "stdlib.h" +extern int f__canseek(FILE*); +extern integer f_clos(cllist*); + +#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 f__bufadj(int n, int c) +{ + 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 f__putbuf(int c) +{ + 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 x_putc(int c) +{ + 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 opn_err(int m, char *s, olist *a) +{ + 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); + } + +integer f_open(olist *a) +{ 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); +} + +int fk_open(int seq, int fmt, ftnint n) +{ 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/src/imageplugins/coreplugin/sharpnesseditor/clapack/s_cmp.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/s_cmp.c new file mode 100644 index 00000000..cd6a7dc4 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/s_cmp.c @@ -0,0 +1,40 @@ +#include "f2c.h" + +/* compare two strings */ + +integer s_cmp(char *a0, char *b0, ftnlen la, ftnlen lb) +{ +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/src/imageplugins/coreplugin/sharpnesseditor/clapack/s_copy.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/s_copy.c new file mode 100644 index 00000000..289c67dd --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/s_copy.c @@ -0,0 +1,47 @@ +/* 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 */ + +void s_copy(char *a, char *b, ftnlen la, ftnlen lb) +{ + 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/src/imageplugins/coreplugin/sharpnesseditor/clapack/s_stop.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/s_stop.c new file mode 100644 index 00000000..049f71b6 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/s_stop.c @@ -0,0 +1,37 @@ +#include "stdio.h" +#include "f2c.h" + +#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) +{ +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/src/imageplugins/coreplugin/sharpnesseditor/clapack/sfe.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/sfe.c new file mode 100644 index 00000000..4f8907ea --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/sfe.c @@ -0,0 +1,29 @@ +/* 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); +} + +int c_sfe(cilist *a) /* check */ +{ 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/src/imageplugins/coreplugin/sharpnesseditor/clapack/sig_die.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/sig_die.c new file mode 100644 index 00000000..78335200 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/sig_die.c @@ -0,0 +1,41 @@ +#include "stdio.h" +#include "signal.h" + +#ifndef SIGIOT +#ifdef SIGABRT +#define SIGIOT SIGABRT +#endif +#endif + +#include "stdlib.h" +#ifdef __cplusplus +extern "C" { +#endif + extern void f_exit(void); + +void sig_die(char *s, int kill) +{ + /* 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/src/imageplugins/coreplugin/sharpnesseditor/clapack/util.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/util.c new file mode 100644 index 00000000..684cdfc4 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/util.c @@ -0,0 +1,39 @@ +#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 g_char(char *a, ftnlen alen, char *b) +{ + 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 b_char(char *a, char *b, ftnlen blen) +{ int i; + for(i=0;i<blen && *a!=0;i++) *b++= *a++; + for(;i<blen;i++) *b++=' '; +} +#ifndef NON_UNIX_STDIO +long f__inode(char *a, int *dev) +{ struct stat x; + if(stat(a,&x)<0) return(-1); + *dev = x.st_dev; + return(x.st_ino); +} +#endif diff --git a/src/imageplugins/coreplugin/sharpnesseditor/clapack/wref.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/wref.c new file mode 100644 index 00000000..636489c3 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/wref.c @@ -0,0 +1,266 @@ +#include "f2c.h" +#include "fio.h" + +#undef abs +#undef min +#undef max +#include "stdlib.h" +#include "string.h" + +#include "fmt.h" +#include "fp.h" +#ifndef VAX +#include "ctype.h" +#endif + +int wrt_E(ufloat *p, int w, int d, int e, ftnlen len) +{ + 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; + } + +int wrt_F(ufloat *p, int w, int d, ftnlen len) +{ + 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/src/imageplugins/coreplugin/sharpnesseditor/clapack/wrtfmt.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/wrtfmt.c new file mode 100644 index 00000000..74d1131a --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/wrtfmt.c @@ -0,0 +1,321 @@ +#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 wrt_Z(Uint *n, int w, int minlen, ftnlen len) +{ + char *s, *se; + 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 wrt_I(Uint *n, int w, ftnlen len, int base) +{ 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 wrt_IM(Uint *n, int w, int m, ftnlen len, int base) +{ 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 wrt_AP(char *s) +{ 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 wrt_H(int a, char *s) +{ + int i; + + if(f__cursor && (i = mv_cur())) + return i; + while(a--) (*f__putn)(*s++); + return(1); +} + +int wrt_L(Uint *n, int len, ftnlen sz) +{ 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 wrt_A(char *p, ftnlen len) +{ + while(len-- > 0) (*f__putn)(*p++); + return(0); +} + +static int wrt_AW(char * p, int w, ftnlen len) +{ + while(w>len) + { w--; + (*f__putn)(' '); + } + while(w-- > 0) + (*f__putn)(*p++); + return(0); +} + +static int wrt_G(ufloat *p, int w, int d, int e, ftnlen len) +{ 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)); +} + +int w_ed(struct syl *p, char *ptr, ftnlen len) +{ + 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)); + } +} + +int w_ned(struct syl *p) +{ + 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/src/imageplugins/coreplugin/sharpnesseditor/clapack/wsfe.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/wsfe.c new file mode 100644 index 00000000..b772df32 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/clapack/wsfe.c @@ -0,0 +1,69 @@ +/*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; +} + +integer s_wsfe(cilist *a) /*start*/ +{ 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/src/imageplugins/coreplugin/sharpnesseditor/clapack/xerbla.c b/src/imageplugins/coreplugin/sharpnesseditor/clapack/xerbla.c new file mode 100644 index 00000000..d8ef512b --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/imageeffect_sharpen.cpp b/src/imageplugins/coreplugin/sharpnesseditor/imageeffect_sharpen.cpp new file mode 100644 index 00000000..b2ae9a62 --- /dev/null +++ b/src/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> + +// TQt includes. + +#include <tqlayout.h> +#include <tqlabel.h> +#include <tqwhatsthis.h> +#include <tqcombobox.h> +#include <tqwidgetstack.h> + +// KDE includes. + +#include <tdeaboutdata.h> +#include <knuminput.h> +#include <kcursor.h> +#include <tdelocale.h> +#include <tdeapplication.h> +#include <kseparator.h> +#include <tdeconfig.h> +#include <kurl.h> +#include <tdefiledialog.h> +#include <tdeglobalsettings.h> +#include <tdemessagebox.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(TQWidget* parent) + : Digikam::CtrlPanelDlg(parent, i18n("Sharpening Photograph"), "sharpen", + true, true, true) +{ + setHelp("blursharpentool.anchor", "digikam"); + + // ------------------------------------------------------------- + + TQWidget *gboxSettings = new TQWidget(m_imagePreviewWidget); + TQGridLayout* gridSettings = new TQGridLayout( gboxSettings, 2, 1, 0, spacingHint()); + + TQLabel *label1 = new TQLabel(i18n("Method:"), gboxSettings); + + m_sharpMethod = new TQComboBox( false, gboxSettings ); + m_sharpMethod->insertItem( i18n("Simple sharp") ); + m_sharpMethod->insertItem( i18n("Unsharp mask") ); + m_sharpMethod->insertItem( i18n("Refocus") ); + TQWhatsThis::add( m_sharpMethod, i18n("<p>Select the sharpening method to apply to the image.")); + + m_stack = new TQWidgetStack(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); + + // ------------------------------------------------------------- + + TQWidget *simpleSharpSettings = new TQWidget(m_stack); + TQGridLayout* grid1 = new TQGridLayout( simpleSharpSettings, 2, 1, 0, spacingHint()); + + TQLabel *label = new TQLabel(i18n("Sharpness:"), simpleSharpSettings); + m_radiusInput = new KIntNumInput(simpleSharpSettings); + m_radiusInput->setRange(0, 100, 1, true); + m_radiusInput->setValue(0); + TQWhatsThis::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); + + // ------------------------------------------------------------- + + TQWidget *unsharpMaskSettings = new TQWidget(m_stack); + TQGridLayout* grid2 = new TQGridLayout( unsharpMaskSettings, 6, 1, 0, spacingHint()); + + TQLabel *label2 = new TQLabel(i18n("Radius:"), unsharpMaskSettings); + m_radiusInput2 = new KIntNumInput(unsharpMaskSettings); + m_radiusInput2->setRange(1, 120, 1, true); + TQWhatsThis::add( m_radiusInput2, i18n("<p>Radius value is the gaussian blur matrix radius value " + "used to determines how much to blur the image.") ); + + TQLabel *label3 = new TQLabel(i18n("Amount:"), unsharpMaskSettings); + m_amountInput = new KDoubleNumInput(unsharpMaskSettings); + m_amountInput->setPrecision(1); + m_amountInput->setRange(0.0, 5.0, 0.1, true); + TQWhatsThis::add( m_amountInput, i18n("<p>The value of the difference between the " + "original and the blur image that is added back into the original.") ); + + TQLabel *label4 = new TQLabel(i18n("Threshold:"), unsharpMaskSettings); + m_thresholdInput = new KDoubleNumInput(unsharpMaskSettings); + m_thresholdInput->setPrecision(2); + m_thresholdInput->setRange(0.0, 1.0, 0.01, true); + TQWhatsThis::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); + + // ------------------------------------------------------------- + + TQWidget *refocusSettings = new TQWidget(m_stack); + TQGridLayout* grid3 = new TQGridLayout(refocusSettings, 10, 1, 0, spacingHint()); + + TQLabel *label5 = new TQLabel(i18n("Circular sharpness:"), refocusSettings); + m_radius = new KDoubleNumInput(refocusSettings); + m_radius->setPrecision(2); + m_radius->setRange(0.0, 5.0, 0.01, true); + TQWhatsThis::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.")); + + TQLabel *label6 = new TQLabel(i18n("Correlation:"), refocusSettings); + m_correlation = new KDoubleNumInput(refocusSettings); + m_correlation->setPrecision(2); + m_correlation->setRange(0.0, 1.0, 0.01, true); + TQWhatsThis::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.")); + + TQLabel *label7 = new TQLabel(i18n("Noise filter:"), refocusSettings); + m_noise = new KDoubleNumInput(refocusSettings); + m_noise->setPrecision(3); + m_noise->setRange(0.0, 1.0, 0.001, true); + TQWhatsThis::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.")); + + TQLabel *label8 = new TQLabel(i18n("Gaussian sharpness:"), refocusSettings); + m_gauss = new KDoubleNumInput(refocusSettings); + m_gauss->setPrecision(2); + m_gauss->setRange(0.0, 1.0, 0.01, true); + TQWhatsThis::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.")); + + TQLabel *label9 = new TQLabel(i18n("Matrix size:"), refocusSettings); + m_matrixSize = new KIntNumInput(refocusSettings); + m_matrixSize->setRange(0, MAX_MATRIX_SIZE, 1, true); + TQWhatsThis::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, TQ_SIGNAL(activated(int)), + this, TQ_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() +{ + TDEConfig* 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() +{ + TDEConfig* 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(); + + TQRect area = m_imagePreviewWidget->getOriginalImageRegionToRender(); + TQRect 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(); + TQRect 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: + { + TQRect 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(TDEGlobalSettings::documentPath(), + TQString( "*" ), this, + TQString( i18n("Photograph Refocus Settings File to Load")) ); + if ( loadRestorationFile.isEmpty() ) + return; + + TQFile file(loadRestorationFile.path()); + + if ( file.open(IO_ReadOnly) ) + { + TQTextStream 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(TDEGlobalSettings::documentPath(), + TQString( "*" ), this, + TQString( i18n("Photograph Refocus Settings File to Save")) ); + if ( saveRestorationFile.isEmpty() ) + return; + + TQFile file(saveRestorationFile.path()); + + if ( file.open(IO_WriteOnly) ) + { + TQTextStream 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/src/imageplugins/coreplugin/sharpnesseditor/imageeffect_sharpen.h b/src/imageplugins/coreplugin/sharpnesseditor/imageeffect_sharpen.h new file mode 100644 index 00000000..fa926383 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/imageeffect_sharpen.h @@ -0,0 +1,102 @@ +/* ============================================================ + * + * 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 TQComboBox; +class TQWidgetStack; + +class KIntNumInput; +class KDoubleNumInput; + +namespace Digikam +{ + class DImg; +} + +namespace DigikamImagesPluginCore +{ + +class ImageEffect_Sharpen : public Digikam::CtrlPanelDlg +{ + TQ_OBJECT + + +public: + + ImageEffect_Sharpen(TQWidget *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 + }; + + TQWidgetStack *m_stack; + + TQComboBox *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/src/imageplugins/coreplugin/sharpnesseditor/matrix.cpp b/src/imageplugins/coreplugin/sharpnesseditor/matrix.cpp new file mode 100644 index 00000000..cfb8afe4 --- /dev/null +++ b/src/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)) + +// C++ includes. + +#include <cmath> + +extern "C" +{ +#include "f2c.h" +#include "clapack.h" +} + +// TQt includes. + +#include <tqglobal.h> +#include <tqstring.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 ((TQABS (row) <= mat->radius) && (TQABS (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 ((TQABS (row) <= mat->radius) && (TQABS (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) +{ + 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 = TQMAX (-mata->radius, yr - matb->radius); + const int ya_high = TQMIN (mata->radius, yr + matb->radius); + const int xa_low = TQMAX (-mata->radius, xr - matb->radius); + const int xa_high = TQMIN (mata->radius, xr + matb->radius); + 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) +{ + 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 = TQMAX (-mata->radius, -matb->radius - yr); + const int ya_high = TQMIN (mata->radius, matb->radius - yr); + const int xa_low = TQMAX (-mata->radius, -matb->radius - xr); + const int xa_high = TQMIN (mata->radius, matb->radius - xr); + 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)) +{ + int xr, yr, xa, ya; + + for (yr = -result->radius; yr <= result->radius; yr++) + { + for (xr = -result->radius; xr <= result->radius; xr++) + { + 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 = TQMAX (TQABS (k), TQABS (l)); + const int b = TQMIN (TQABS (k), TQABS (l)); + return ((a * (a + 1)) / 2 + b); +} + +void RefocusMatrix::print_c_mat (const CMat * const mat) +{ + int x, y; + + for (y = -mat->radius; y <= mat->radius; y++) + { + TQString 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++) + { + TQString 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); + 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); + 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); + 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); + 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); + 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); + 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) +{ + 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) +{ + 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) +{ + 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 + { + double xlo = TQABS (x) - 0.5, xhi = TQABS (x) + 0.5, + ylo = TQABS (y) - 0.5, yhi = TQABS (y) + 0.5; + 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/src/imageplugins/coreplugin/sharpnesseditor/matrix.h b/src/imageplugins/coreplugin/sharpnesseditor/matrix.h new file mode 100644 index 00000000..6b2f65cb --- /dev/null +++ b/src/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/src/imageplugins/coreplugin/sharpnesseditor/refocus.cpp b/src/imageplugins/coreplugin/sharpnesseditor/refocus.cpp new file mode 100644 index 00000000..7e99d663 --- /dev/null +++ b/src/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, TQObject *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/src/imageplugins/coreplugin/sharpnesseditor/refocus.h b/src/imageplugins/coreplugin/sharpnesseditor/refocus.h new file mode 100644 index 00000000..323b24b9 --- /dev/null +++ b/src/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, TQObject *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/src/imageplugins/coreplugin/sharpnesseditor/sharpentool.cpp b/src/imageplugins/coreplugin/sharpnesseditor/sharpentool.cpp new file mode 100644 index 00000000..aee5d841 --- /dev/null +++ b/src/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> + +// TQt includes. + +#include <tqlayout.h> +#include <tqlabel.h> +#include <tqwhatsthis.h> +#include <tqwidgetstack.h> + +// KDE includes. + +#include <tdeaboutdata.h> +#include <kcursor.h> +#include <tdelocale.h> +#include <tdeapplication.h> +#include <kseparator.h> +#include <tdeconfig.h> +#include <kurl.h> +#include <kiconloader.h> +#include <tdefiledialog.h> +#include <tdeglobalsettings.h> +#include <tdemessagebox.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(TQObject* 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); + TQGridLayout* grid = new TQGridLayout( m_gboxSettings->plainPage(), 3, 1); + + TQLabel *label1 = new TQLabel(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); + TQWhatsThis::add( m_sharpMethod, i18n("<p>Select the sharpening method to apply to the image.")); + + m_stack = new TQWidgetStack(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()); + + // ------------------------------------------------------------- + + TQWidget *simpleSharpSettings = new TQWidget(m_stack); + TQGridLayout* grid1 = new TQGridLayout( simpleSharpSettings, 2, 1); + + TQLabel *label = new TQLabel(i18n("Sharpness:"), simpleSharpSettings); + m_radiusInput = new RIntNumInput(simpleSharpSettings); + m_radiusInput->setRange(0, 100, 1); + m_radiusInput->setDefaultValue(0); + TQWhatsThis::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); + + // ------------------------------------------------------------- + + TQWidget *unsharpMaskSettings = new TQWidget(m_stack); + TQGridLayout* grid2 = new TQGridLayout( unsharpMaskSettings, 6, 1); + + TQLabel *label2 = new TQLabel(i18n("Radius:"), unsharpMaskSettings); + m_radiusInput2 = new RIntNumInput(unsharpMaskSettings); + m_radiusInput2->setRange(1, 120, 1); + m_radiusInput2->setDefaultValue(1); + TQWhatsThis::add( m_radiusInput2, i18n("<p>Radius value is the gaussian blur matrix radius value " + "used to determines how much to blur the image.") ); + + TQLabel *label3 = new TQLabel(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); + TQWhatsThis::add( m_amountInput, i18n("<p>The value of the difference between the " + "original and the blur image that is added back into the original.") ); + + TQLabel *label4 = new TQLabel(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); + TQWhatsThis::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); + + // ------------------------------------------------------------- + + TQWidget *refocusSettings = new TQWidget(m_stack); + TQGridLayout* grid3 = new TQGridLayout(refocusSettings, 10, 1); + + TQLabel *label5 = new TQLabel(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); + TQWhatsThis::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.")); + + TQLabel *label6 = new TQLabel(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); + TQWhatsThis::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.")); + + TQLabel *label7 = new TQLabel(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); + TQWhatsThis::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.")); + + TQLabel *label8 = new TQLabel(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); + TQWhatsThis::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.")); + + TQLabel *label9 = new TQLabel(i18n("Matrix size:"), refocusSettings); + m_matrixSize = new RIntNumInput(refocusSettings); + m_matrixSize->setRange(0, MAX_MATRIX_SIZE, 1); + m_matrixSize->setDefaultValue(5); + TQWhatsThis::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, TQ_SIGNAL(activated(int)), + this, TQ_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() +{ + TDEConfig* 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() +{ + TDEConfig* 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(); + + TQRect area = m_previewWidget->getOriginalImageRegionToRender(); + TQRect 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(); + TQRect 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: + { + TQRect 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(TDEGlobalSettings::documentPath(), + TQString( "*" ), kapp->activeWindow(), + TQString( i18n("Photograph Refocus Settings File to Load")) ); + if ( loadRestorationFile.isEmpty() ) + return; + + TQFile file(loadRestorationFile.path()); + + if ( file.open(IO_ReadOnly) ) + { + TQTextStream 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(TDEGlobalSettings::documentPath(), + TQString( "*" ), kapp->activeWindow(), + TQString( i18n("Photograph Refocus Settings File to Save")) ); + if ( saveRestorationFile.isEmpty() ) + return; + + TQFile file(saveRestorationFile.path()); + + if ( file.open(IO_WriteOnly) ) + { + TQTextStream 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/src/imageplugins/coreplugin/sharpnesseditor/sharpentool.h b/src/imageplugins/coreplugin/sharpnesseditor/sharpentool.h new file mode 100644 index 00000000..8dbca1c5 --- /dev/null +++ b/src/imageplugins/coreplugin/sharpnesseditor/sharpentool.h @@ -0,0 +1,111 @@ +/* ============================================================ + * + * 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 TQWidgetStack; + +namespace KDcrawIface +{ +class RIntNumInput; +class RDoubleNumInput; +class RComboBox; +} + +namespace Digikam +{ +class DImg; +class EditorToolSettings; +class ImagePanelWidget; +} + +namespace DigikamImagesPluginCore +{ + +class SharpenTool : public Digikam::EditorToolThreaded +{ + TQ_OBJECT + + +public: + + SharpenTool(TQObject *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 + }; + + TQWidgetStack *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/src/imageplugins/coreplugin/sharpnesseditor/unsharp.cpp b/src/imageplugins/coreplugin/sharpnesseditor/unsharp.cpp new file mode 100644 index 00000000..fb1b9d21 --- /dev/null +++ b/src/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, TQObject *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/src/imageplugins/coreplugin/sharpnesseditor/unsharp.h b/src/imageplugins/coreplugin/sharpnesseditor/unsharp.h new file mode 100644 index 00000000..a1780ab4 --- /dev/null +++ b/src/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, TQObject *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 */ |