summaryrefslogtreecommitdiffstats
path: root/src/imageplugins/whitebalance/imageeffect_whitebalance.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imageplugins/whitebalance/imageeffect_whitebalance.cpp')
-rw-r--r--src/imageplugins/whitebalance/imageeffect_whitebalance.cpp842
1 files changed, 842 insertions, 0 deletions
diff --git a/src/imageplugins/whitebalance/imageeffect_whitebalance.cpp b/src/imageplugins/whitebalance/imageeffect_whitebalance.cpp
new file mode 100644
index 00000000..f72609dd
--- /dev/null
+++ b/src/imageplugins/whitebalance/imageeffect_whitebalance.cpp
@@ -0,0 +1,842 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-03-11
+ * Description : a digiKam image editor plugin to correct
+ * image white balance
+ *
+ * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2008 by Guillaume Castagnino <casta at xwing dot info>
+ *
+ * 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 <tqhgroupbox.h>
+#include <tqvgroupbox.h>
+#include <tqlabel.h>
+#include <tqpushbutton.h>
+#include <tqhbuttongroup.h>
+#include <tqwhatsthis.h>
+#include <tqlayout.h>
+#include <tqframe.h>
+#include <tqcombobox.h>
+#include <tqtimer.h>
+#include <tqtooltip.h>
+#include <tqpixmap.h>
+#include <tqfile.h>
+#include <tqtextstream.h>
+#include <tqvbox.h>
+
+// KDE includes.
+
+#include <kcursor.h>
+#include <tdelocale.h>
+#include <tdeaboutdata.h>
+#include <khelpmenu.h>
+#include <kiconloader.h>
+#include <tdeapplication.h>
+#include <tdepopupmenu.h>
+#include <kstandarddirs.h>
+#include <kprogress.h>
+#include <tdemessagebox.h>
+#include <knuminput.h>
+#include <tdeglobalsettings.h>
+#include <tdefiledialog.h>
+#include <kseparator.h>
+#include <tdeconfig.h>
+#include <kactivelabel.h>
+
+// Local includes.
+
+#include "version.h"
+#include "ddebug.h"
+#include "dimg.h"
+#include "dcolor.h"
+#include "imageiface.h"
+#include "imagewidget.h"
+#include "imagehistogram.h"
+#include "whitebalance.h"
+#include "colorgradientwidget.h"
+#include "histogramwidget.h"
+#include "dimgimagefilters.h"
+#include "imageeffect_whitebalance.h"
+#include "imageeffect_whitebalance.moc"
+
+namespace DigikamWhiteBalanceImagesPlugin
+{
+
+ImageEffect_WhiteBalance::ImageEffect_WhiteBalance(TQWidget* parent)
+ : Digikam::ImageDlgBase(parent, i18n("White Color Balance Correction"),
+ "whitebalance", true, false)
+{
+ TQString whatsThis;
+
+ Digikam::ImageIface iface(0, 0);
+
+ m_destinationPreviewData = 0L;
+
+ // About data and help button.
+
+ TDEAboutData* about = new TDEAboutData("digikam",
+ I18N_NOOP("White Color Balance Correction"),
+ digikam_version,
+ I18N_NOOP("A digiKam image plugin to correct white color balance."),
+ TDEAboutData::License_GPL,
+ "(c) 2005-2008, Gilles Caulier",
+ 0,
+ "http://wwww.digikam.org");
+
+ about->addAuthor("Gilles Caulier", I18N_NOOP("Author and maintainer"),
+ "caulier dot gilles at gmail dot com");
+
+ about->addAuthor("Pawel T. Jochym", I18N_NOOP("White color balance correction algorithm"),
+ "jochym at ifj edu pl");
+
+ setAboutData(about);
+
+ // -------------------------------------------------------------
+
+ m_previewWidget = new Digikam::ImageWidget("whitebalance Tool Dialog", plainPage(),
+ i18n("<p>You can see here the image's white-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());
+ TQVBoxLayout* layout2 = new TQVBoxLayout( gboxSettings, spacingHint() );
+ TQGridLayout *grid = new TQGridLayout( layout2, 2, 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);
+
+ grid->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 filter 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" ) );
+
+ grid->addMultiCellWidget(histoBox, 1, 2, 0, 4);
+
+ // -------------------------------------------------------------
+
+ TQGridLayout *grid2 = new TQGridLayout(layout2, 13, 5, spacingHint());
+
+ m_temperatureLabel = new KActiveLabel(i18n("<qt><a href='http://en.wikipedia.org/wiki/Color_temperature'>Color Temperature</a> "
+ " (K): </qt>"), gboxSettings);
+ m_adjTemperatureLabel = new TQLabel(i18n("Adjustment:"), gboxSettings);
+ m_temperatureInput = new KDoubleNumInput(gboxSettings);
+ m_temperatureInput->setPrecision(1);
+ m_temperatureInput->setRange(2000.0, 12000.0, 10.0, true);
+ TQWhatsThis::add( m_temperatureInput, i18n("<p>Set here the white balance color temperature in Kelvin."));
+
+ m_temperaturePresetLabel = new TQLabel(i18n("Preset:"), gboxSettings);
+ m_temperaturePresetCB = new TQComboBox( false, gboxSettings );
+ m_temperaturePresetCB->insertItem( i18n("Candle") );
+ m_temperaturePresetCB->insertItem( i18n("40W Lamp") );
+ m_temperaturePresetCB->insertItem( i18n("100W Lamp") );
+ m_temperaturePresetCB->insertItem( i18n("200W Lamp") );
+ m_temperaturePresetCB->insertItem( i18n("Sunrise") );
+ m_temperaturePresetCB->insertItem( i18n("Studio Lamp") );
+ m_temperaturePresetCB->insertItem( i18n("Moonlight") );
+ m_temperaturePresetCB->insertItem( i18n("Neutral") );
+ m_temperaturePresetCB->insertItem( i18n("Daylight D50") );
+ m_temperaturePresetCB->insertItem( i18n("Photo Flash") );
+ m_temperaturePresetCB->insertItem( i18n("Sun") );
+ m_temperaturePresetCB->insertItem( i18n("Xenon Lamp") );
+ m_temperaturePresetCB->insertItem( i18n("Daylight D65") );
+ m_temperaturePresetCB->insertItem( i18n("None") );
+ TQWhatsThis::add( m_temperaturePresetCB, i18n("<p>Select the white balance color temperature "
+ "preset to use here:<p>"
+ "<b>Candle</b>: candle light (1850K).<p>"
+ "<b>40W Lamp</b>: 40 Watt incandescent lamp (2680K).<p>"
+ "<b>100W Lamp</b>: 100 Watt incandescent lamp (2800K).<p>"
+ "<b>200W Lamp</b>: 200 Watt incandescent lamp (3000K).<p>"
+ "<b>Sunrise</b>: sunrise or sunset light (3200K).<p>"
+ "<b>Studio Lamp</b>: tungsten lamp used in photo studio "
+ "or light at 1 hour from dusk/dawn (3400K).<p>"
+ "<b>Moonlight</b>: moon light (4100K).<p>"
+ "<b>Neutral</b>: neutral color temperature (4750K).<p>"
+ "<b>Daylight D50</b>: sunny daylight around noon (5000K).<p>"
+ "<b>Photo Flash</b>: electronic photo flash (5500K).<p>"
+ "<b>Sun</b>: effective sun temperature (5770K).<p>"
+ "<b>Xenon Lamp</b>: xenon lamp or light arc (6420K).<p>"
+ "<b>Daylight D65</b>: overcast sky light (6500K).<p>"
+ "<b>None</b>: no preset value."));
+ m_pickTemperature = new TQPushButton(gboxSettings);
+ TDEGlobal::dirs()->addResourceType("color-picker-grey", TDEGlobal::dirs()->kde_default("data") + "digikam/data");
+ directory = TDEGlobal::dirs()->findResourceDir("color-picker-grey", "color-picker-grey.png");
+ m_pickTemperature->setPixmap( TQPixmap( directory + "color-picker-grey.png" ) );
+ m_pickTemperature->setToggleButton(true);
+ TQToolTip::add( m_pickTemperature, i18n( "Temperature tone color picker." ) );
+ TQWhatsThis::add( m_pickTemperature, i18n("<p>With this button, you can pick the color from original "
+ "image used to set white color balance temperature and "
+ "green component."));
+
+ KSeparator *line = new KSeparator(Horizontal, gboxSettings);
+
+ // -------------------------------------------------------------
+
+ m_blackLabel = new TQLabel(i18n("Black point:"), gboxSettings);
+ m_blackInput = new KDoubleNumInput(gboxSettings);
+ m_blackInput->setPrecision(2);
+ m_blackInput->setRange(0.0, 0.05, 0.01, true);
+ TQWhatsThis::add( m_blackInput, i18n("<p>Set here the black level value."));
+
+ m_darkLabel = new TQLabel(i18n("Shadows:"), gboxSettings);
+ m_darkInput = new KDoubleNumInput(gboxSettings);
+ m_darkInput->setPrecision(2);
+ m_darkInput->setRange(0.0, 1.0, 0.01, true);
+ TQWhatsThis::add( m_darkInput, i18n("<p>Set here the shadows noise suppresion level."));
+
+ m_saturationLabel = new TQLabel(i18n("Saturation:"), gboxSettings);
+ m_saturationInput = new KDoubleNumInput(gboxSettings);
+ m_saturationInput->setPrecision(2);
+ m_saturationInput->setRange(0.0, 2.0, 0.01, true);
+ TQWhatsThis::add( m_saturationInput, i18n("<p>Set here the saturation value."));
+
+ m_gammaLabel = new TQLabel(i18n("Gamma:"), gboxSettings);
+ m_gammaInput = new KDoubleNumInput(gboxSettings);
+ m_gammaInput->setPrecision(2);
+ m_gammaInput->setRange(0.1, 3.0, 0.01, true);
+ TQWhatsThis::add( m_gammaInput, i18n("<p>Set here the gamma correction value."));
+
+ m_greenLabel = new TQLabel(i18n("Green:"), gboxSettings);
+ m_greenInput = new KDoubleNumInput(gboxSettings);
+ m_greenInput->setPrecision(2);
+ m_greenInput->setRange(0.2, 2.5, 0.01, true);
+ TQWhatsThis::add(m_greenInput, i18n("<p>Set here the green component to set magenta color "
+ "cast removal level."));
+
+ KSeparator *line2 = new KSeparator(Horizontal, gboxSettings);
+
+ // -------------------------------------------------------------
+
+ m_exposureLabel = new KActiveLabel(i18n("<qt><a href='http://en.wikipedia.org/wiki/Exposure_value'>Exposure Compensation</a> "
+ " (E.V): </qt>"), gboxSettings);
+ m_mainExposureLabel = new TQLabel(i18n("Main:"), gboxSettings);
+ m_autoAdjustExposure = new TQPushButton(gboxSettings);
+ m_autoAdjustExposure->setPixmap(kapp->iconLoader()->loadIcon("system-run", (TDEIcon::Group)TDEIcon::Toolbar));
+ TQToolTip::add( m_autoAdjustExposure, i18n( "Auto exposure adjustments" ) );
+ TQWhatsThis::add( m_autoAdjustExposure, i18n("<p>With this button, you can automatically adjust Exposure "
+ "and Black Point values."));
+ m_mainExposureInput = new KDoubleNumInput(gboxSettings);
+ m_mainExposureInput->setPrecision(2);
+ m_mainExposureInput->setRange(-6.0, 8.0, 0.1, true);
+ TQWhatsThis::add( m_mainExposureInput, i18n("<p>Set here the main exposure compensation value in E.V."));
+
+ m_fineExposureLabel = new TQLabel(i18n("Fine:"), gboxSettings);
+ m_fineExposureInput = new KDoubleNumInput(gboxSettings);
+ m_fineExposureInput->setPrecision(2);
+ m_fineExposureInput->setRange(-0.5, 0.5, 0.01, true);
+ TQWhatsThis::add( m_fineExposureInput, i18n("<p>This value in E.V will be added to main exposure "
+ "compensation value to set fine exposure adjustment."));
+
+ // -------------------------------------------------------------
+
+ grid2->addMultiCellWidget(m_temperatureLabel, 0, 0, 0, 5);
+ grid2->addMultiCellWidget(m_adjTemperatureLabel, 1, 1, 0, 0);
+ grid2->addMultiCellWidget(m_pickTemperature, 1, 1, 1, 1);
+ grid2->addMultiCellWidget(m_temperatureInput, 1, 1, 2, 5);
+ grid2->addMultiCellWidget(m_temperaturePresetLabel, 2, 2, 0, 0);
+ grid2->addMultiCellWidget(m_temperaturePresetCB, 2, 2, 2, 5);
+
+ grid2->addMultiCellWidget(line, 3, 3, 0, 5);
+
+ grid2->addMultiCellWidget(m_blackLabel, 4, 4, 0, 0);
+ grid2->addMultiCellWidget(m_blackInput, 4, 4, 1, 5);
+ grid2->addMultiCellWidget(m_darkLabel, 5, 5, 0, 0);
+ grid2->addMultiCellWidget(m_darkInput, 5, 5, 1, 5);
+ grid2->addMultiCellWidget(m_saturationLabel, 6, 6, 0, 0);
+ grid2->addMultiCellWidget(m_saturationInput, 6, 6, 1, 5);
+ grid2->addMultiCellWidget(m_gammaLabel, 7, 7, 0, 0);
+ grid2->addMultiCellWidget(m_gammaInput, 7, 7, 1, 5);
+ grid2->addMultiCellWidget(m_greenLabel, 8, 8, 0, 0);
+ grid2->addMultiCellWidget(m_greenInput, 8, 8, 1, 5);
+
+ grid2->addMultiCellWidget(line2, 9, 9, 0, 5);
+
+ grid2->addMultiCellWidget(m_exposureLabel, 10, 10, 0, 5);
+ grid2->addMultiCellWidget(m_mainExposureLabel, 11, 11, 0, 0);
+ grid2->addMultiCellWidget(m_autoAdjustExposure, 11, 11, 1, 1);
+ grid2->addMultiCellWidget(m_mainExposureInput, 11, 11, 2, 5);
+ grid2->addMultiCellWidget(m_fineExposureLabel, 12, 12, 0, 1);
+ grid2->addMultiCellWidget(m_fineExposureInput, 12, 12, 2, 5);
+ grid2->setRowStretch(13, 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(slotColorSelectedFromOriginal( const Digikam::DColor & )));
+
+ 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()));
+
+ // -------------------------------------------------------------
+ // Correction Filter Slider controls.
+
+ connect(m_temperaturePresetCB, TQ_SIGNAL(activated(int)),
+ this, TQ_SLOT(slotTemperaturePresetChanged(int)));
+
+ connect(m_temperatureInput, TQ_SIGNAL(valueChanged (double)),
+ this, TQ_SLOT(slotTemperatureChanged(double)));
+
+ connect(m_darkInput, TQ_SIGNAL(valueChanged (double)),
+ this, TQ_SLOT(slotTimer()));
+
+ connect(m_blackInput, TQ_SIGNAL(valueChanged (double)),
+ this, TQ_SLOT(slotTimer()));
+
+ connect(m_mainExposureInput, TQ_SIGNAL(valueChanged (double)),
+ this, TQ_SLOT(slotTimer()));
+
+ connect(m_fineExposureInput, TQ_SIGNAL(valueChanged (double)),
+ this, TQ_SLOT(slotTimer()));
+
+ connect(m_gammaInput, TQ_SIGNAL(valueChanged (double)),
+ this, TQ_SLOT(slotTimer()));
+
+ connect(m_saturationInput, TQ_SIGNAL(valueChanged (double)),
+ this, TQ_SLOT(slotTimer()));
+
+ connect(m_greenInput, TQ_SIGNAL(valueChanged (double)),
+ this, TQ_SLOT(slotTimer()));
+
+ // -------------------------------------------------------------
+ // Bouttons slots.
+
+ connect(m_autoAdjustExposure, TQ_SIGNAL(clicked()),
+ this, TQ_SLOT(slotAutoAdjustExposure()));
+
+ connect(m_pickTemperature, TQ_SIGNAL(released()),
+ this, TQ_SLOT(slotPickerColorButtonActived()));
+}
+
+ImageEffect_WhiteBalance::~ImageEffect_WhiteBalance()
+{
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ delete m_histogramWidget;
+}
+
+void ImageEffect_WhiteBalance::slotTemperatureChanged(double temperature)
+{
+ switch((uint)temperature)
+ {
+ case 1850:
+ m_temperaturePresetCB->setCurrentItem(Candle);
+ break;
+
+ case 2680:
+ m_temperaturePresetCB->setCurrentItem(Lamp40W);
+ break;
+
+ case 2800:
+ m_temperaturePresetCB->setCurrentItem(Lamp100W);
+ break;
+
+ case 3000:
+ m_temperaturePresetCB->setCurrentItem(Lamp200W);
+ break;
+
+ case 3200:
+ m_temperaturePresetCB->setCurrentItem(Sunrise);
+ break;
+
+ case 3400:
+ m_temperaturePresetCB->setCurrentItem(StudioLamp);
+ break;
+
+ case 4100:
+ m_temperaturePresetCB->setCurrentItem(MoonLight);
+ break;
+
+ case 4750:
+ m_temperaturePresetCB->setCurrentItem(Neutral);
+ break;
+
+ case 5000:
+ m_temperaturePresetCB->setCurrentItem(DaylightD50);
+ break;
+
+ case 5500:
+ m_temperaturePresetCB->setCurrentItem(Flash);
+ break;
+
+ case 5770:
+ m_temperaturePresetCB->setCurrentItem(Sun);
+ break;
+
+ case 6420:
+ m_temperaturePresetCB->setCurrentItem(XeonLamp);
+ break;
+
+ case 6500:
+ m_temperaturePresetCB->setCurrentItem(DaylightD65);
+ break;
+
+ default:
+ m_temperaturePresetCB->setCurrentItem(None);
+ break;
+ }
+
+ slotTimer();
+}
+
+void ImageEffect_WhiteBalance::slotTemperaturePresetChanged(int tempPreset)
+{
+ switch(tempPreset)
+ {
+ case Candle:
+ m_temperatureInput->setValue(1850.0);
+ break;
+
+ case Lamp40W:
+ m_temperatureInput->setValue(2680.0);
+ break;
+
+ case Lamp100W:
+ m_temperatureInput->setValue(2800.0);
+ break;
+
+ case Lamp200W:
+ m_temperatureInput->setValue(3000.0);
+ break;
+
+ case Sunrise:
+ m_temperatureInput->setValue(3200.0);
+ break;
+
+ case StudioLamp:
+ m_temperatureInput->setValue(3400.0);
+ break;
+
+ case MoonLight:
+ m_temperatureInput->setValue(4100.0);
+ break;
+
+ case Neutral:
+ m_temperatureInput->setValue(4750.0);
+ break;
+
+ case DaylightD50:
+ m_temperatureInput->setValue(5000.0);
+ break;
+
+ case Flash:
+ m_temperatureInput->setValue(5500.0);
+ break;
+
+ case Sun:
+ m_temperatureInput->setValue(5770.0);
+ break;
+
+ case XeonLamp:
+ m_temperatureInput->setValue(6420.0);
+ break;
+
+ case DaylightD65:
+ m_temperatureInput->setValue(6500.0);
+ break;
+
+ default: // None.
+ break;
+ }
+
+ slotEffect();
+}
+
+void ImageEffect_WhiteBalance::slotPickerColorButtonActived()
+{
+ // Save previous rendering mode and toggle to original image.
+ m_currentPreviewMode = m_previewWidget->getRenderingPreviewMode();
+ m_previewWidget->setRenderingPreviewMode(Digikam::ImageGuideWidget::PreviewOriginalImage);
+}
+
+void ImageEffect_WhiteBalance::slotColorSelectedFromOriginal(const Digikam::DColor &color)
+{
+ if ( m_pickTemperature->isOn() )
+ {
+ Digikam::DColor dc = color;
+ TQColor tc = dc.getTQColor();
+ double temperatureLevel, greenLevel;
+
+ Digikam::WhiteBalance::autoWBAdjustementFromColor(tc, temperatureLevel, greenLevel);
+
+ m_temperatureInput->setValue(temperatureLevel);
+ m_greenInput->setValue(greenLevel);
+ m_pickTemperature->setOn(false);
+ }
+ else
+ return;
+
+ // restore previous rendering mode.
+ m_previewWidget->setRenderingPreviewMode(m_currentPreviewMode);
+
+ slotEffect();
+}
+
+void ImageEffect_WhiteBalance::slotColorSelectedFromTarget( const Digikam::DColor &color )
+{
+ m_histogramWidget->setHistogramGuideByColor(color);
+}
+
+void ImageEffect_WhiteBalance::slotScaleChanged(int scale)
+{
+ m_histogramWidget->m_scaleType = scale;
+ m_histogramWidget->repaint(false);
+}
+
+void ImageEffect_WhiteBalance::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_WhiteBalance::slotAutoAdjustExposure()
+{
+ parentWidget()->setCursor( KCursor::waitCursor() );
+
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ uchar *data = iface->getOriginalImage();
+ int width = iface->originalWidth();
+ int height = iface->originalHeight();
+ bool sb = iface->originalSixteenBit();
+
+ double blackLevel;
+ double exposureLevel;
+
+ Digikam::WhiteBalance::autoExposureAdjustement(data, width, height, sb, blackLevel, exposureLevel);
+ delete [] data;
+
+ m_blackInput->setValue(blackLevel);
+ m_mainExposureInput->setValue(exposureLevel);
+ m_fineExposureInput->setValue(0.0);
+
+ parentWidget()->unsetCursor();
+ slotEffect();
+}
+
+void ImageEffect_WhiteBalance::slotEffect()
+{
+ Digikam::ImageIface* iface = m_previewWidget->imageIface();
+ uchar *data = iface->getPreviewImage();
+ int w = iface->previewWidth();
+ int h = iface->previewHeight();
+ bool sb = iface->previewSixteenBit();
+
+ // Create the new empty destination image data space.
+ m_histogramWidget->stopHistogramComputation();
+
+ if (m_destinationPreviewData)
+ delete [] m_destinationPreviewData;
+
+ m_destinationPreviewData = new uchar[w*h*(sb ? 8 : 4)];
+
+ double temperature = m_temperatureInput->value();
+ double dark = m_darkInput->value();
+ double black = m_blackInput->value();
+ double mainExposure = m_mainExposureInput->value();
+ double fineExposure = m_fineExposureInput->value();
+ double gamma = m_gammaInput->value();
+ double saturation = m_saturationInput->value();
+ double green = m_greenInput->value();
+
+ Digikam::WhiteBalance wbFilter(sb);
+ wbFilter.whiteBalance(data, w, h, sb,
+ black, mainExposure + fineExposure,
+ temperature, green, dark,
+ gamma, saturation);
+
+ iface->putPreviewImage(data);
+ m_previewWidget->updatePreview();
+
+ // Update histogram.
+ memcpy (m_destinationPreviewData, data, w*h*(sb ? 8 : 4));
+ m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false);
+ delete [] data;
+}
+
+void ImageEffect_WhiteBalance::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();
+
+ double temperature = m_temperatureInput->value();
+ double dark = m_darkInput->value();
+ double black = m_blackInput->value();
+ double mainExposure = m_mainExposureInput->value();
+ double fineExposure = m_fineExposureInput->value();
+ double gamma = m_gammaInput->value();
+ double saturation = m_saturationInput->value();
+ double green = m_greenInput->value();
+
+ Digikam::WhiteBalance wbFilter(sb);
+ wbFilter.whiteBalance(data, w, h, sb,
+ black, mainExposure + fineExposure,
+ temperature, green, dark,
+ gamma, saturation);
+
+ iface->putOriginalImage(i18n("White Balance"), data);
+ delete [] data;
+ kapp->restoreOverrideCursor();
+ accept();
+}
+
+void ImageEffect_WhiteBalance::resetValues()
+{
+ m_darkInput->blockSignals(true);
+ m_blackInput->blockSignals(true);
+ m_mainExposureInput->blockSignals(true);
+ m_fineExposureInput->blockSignals(true);
+ m_gammaInput->blockSignals(true);
+ m_saturationInput->blockSignals(true);
+ m_greenInput->blockSignals(true);
+ m_temperaturePresetCB->blockSignals(true);
+
+ // Neutral color temperature settings is D65
+ m_darkInput->setValue(0.5);
+ m_blackInput->setValue(0.0);
+ m_mainExposureInput->setValue(0.0);
+ m_fineExposureInput->setValue(0.0);
+ m_gammaInput->setValue(1.0);
+ m_saturationInput->setValue(1.0);
+ m_greenInput->setValue(1.0);
+ m_temperaturePresetCB->setCurrentItem(DaylightD65);
+ slotTemperaturePresetChanged(DaylightD65);
+
+ m_previewWidget->resetSpotPosition();
+ m_channelCB->setCurrentItem(LuminosityChannel);
+ slotChannelChanged(LuminosityChannel);
+
+ m_histogramWidget->reset();
+
+ m_darkInput->blockSignals(false);
+ m_blackInput->blockSignals(false);
+ m_mainExposureInput->blockSignals(false);
+ m_fineExposureInput->blockSignals(false);
+ m_gammaInput->blockSignals(false);
+ m_saturationInput->blockSignals(false);
+ m_greenInput->blockSignals(false);
+ m_temperaturePresetCB->blockSignals(false);
+ slotEffect();
+}
+
+void ImageEffect_WhiteBalance::readUserSettings()
+{
+ TDEConfig* config = kapp->config();
+ config->setGroup("whitebalance Tool Dialog");
+ m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity.
+ m_scaleBG->setButton(config->readNumEntry("Histogram Scale", Digikam::HistogramWidget::LogScaleHistogram));
+
+ m_darkInput->setValue(config->readDoubleNumEntry("Dark", 0.5));
+ m_blackInput->setValue(config->readDoubleNumEntry("Black", 0.0));
+ m_mainExposureInput->setValue(config->readDoubleNumEntry("MainExposure", 0.0));
+ m_fineExposureInput->setValue(config->readDoubleNumEntry("FineExposure", 0.0));
+ m_gammaInput->setValue(config->readDoubleNumEntry("Gamma", 1.0));
+ m_saturationInput->setValue(config->readDoubleNumEntry("Saturation", 1.0));
+ m_greenInput->setValue(config->readDoubleNumEntry("Green", 1.0));
+ m_temperatureInput->setValue(config->readDoubleNumEntry("Temperature", 6500.0));
+ slotTemperatureChanged(m_temperatureInput->value());
+ slotChannelChanged(m_channelCB->currentItem());
+ slotScaleChanged(m_scaleBG->selectedId());
+}
+
+void ImageEffect_WhiteBalance::writeUserSettings()
+{
+ TDEConfig* config = kapp->config();
+ config->setGroup("whitebalance Tool Dialog");
+ config->writeEntry("Histogram Channel", m_channelCB->currentItem());
+ config->writeEntry("Histogram Scale", m_scaleBG->selectedId());
+
+ config->writeEntry("Dark", m_darkInput->value());
+ config->writeEntry("Black", m_blackInput->value());
+ config->writeEntry("MainExposure", m_mainExposureInput->value());
+ config->writeEntry("FineExposure", m_fineExposureInput->value());
+ config->writeEntry("Gamma", m_gammaInput->value());
+ config->writeEntry("Saturation", m_saturationInput->value());
+ config->writeEntry("Green", m_greenInput->value());
+ config->writeEntry("Temperature", m_temperatureInput->value());
+ config->sync();
+}
+
+// Load all settings.
+void ImageEffect_WhiteBalance::slotUser3()
+{
+ KURL loadWhiteBalanceFile = KFileDialog::getOpenURL(TDEGlobalSettings::documentPath(),
+ TQString( "*" ), this,
+ TQString( i18n("White Color Balance Settings File to Load")) );
+ if( loadWhiteBalanceFile.isEmpty() )
+ return;
+
+ TQFile file(loadWhiteBalanceFile.path());
+
+ if ( file.open(IO_ReadOnly) )
+ {
+ TQTextStream stream( &file );
+
+ if ( stream.readLine() != "# White Color Balance Configuration File V2" )
+ {
+ KMessageBox::error(this,
+ i18n("\"%1\" is not a White Color Balance settings text file.")
+ .arg(loadWhiteBalanceFile.fileName()));
+ file.close();
+ return;
+ }
+
+ blockSignals(true);
+ m_temperatureInput->setValue( stream.readLine().toDouble() );
+ m_darkInput->setValue( stream.readLine().toDouble() );
+ m_blackInput->setValue( stream.readLine().toDouble() );
+ m_mainExposureInput->setValue( stream.readLine().toDouble() );
+ m_fineExposureInput->setValue( stream.readLine().toDouble() );
+ m_gammaInput->setValue( stream.readLine().toDouble() );
+ m_saturationInput->setValue( stream.readLine().toDouble() );
+ m_greenInput->setValue( stream.readLine().toDouble() );
+ m_histogramWidget->reset();
+ blockSignals(false);
+ slotEffect();
+ }
+ else
+ KMessageBox::error(this, i18n("Cannot load settings from the White Color Balance text file."));
+
+ file.close();
+}
+
+// Save all settings.
+void ImageEffect_WhiteBalance::slotUser2()
+{
+ KURL saveWhiteBalanceFile = KFileDialog::getSaveURL(TDEGlobalSettings::documentPath(),
+ TQString( "*" ), this,
+ TQString( i18n("White Color Balance Settings File to Save")) );
+ if( saveWhiteBalanceFile.isEmpty() )
+ return;
+
+ TQFile file(saveWhiteBalanceFile.path());
+
+ if ( file.open(IO_WriteOnly) )
+ {
+ TQTextStream stream( &file );
+ stream << "# White Color Balance Configuration File V2\n";
+ stream << m_temperatureInput->value() << "\n";
+ stream << m_darkInput->value() << "\n";
+ stream << m_blackInput->value() << "\n";
+ stream << m_mainExposureInput->value() << "\n";
+ stream << m_fineExposureInput->value() << "\n";
+ stream << m_gammaInput->value() << "\n";
+ stream << m_saturationInput->value() << "\n";
+ stream << m_greenInput->value() << "\n";
+ }
+ else
+ KMessageBox::error(this, i18n("Cannot save settings to the White Color Balance text file."));
+
+ file.close();
+}
+
+} // NameSpace DigikamWhiteBalanceImagesPlugin
+