/* ============================================================
*
* This file is a part of digiKam project
* http : //www.digikam.org
*
* Date : 2004 - 07 - 20
* Description : image histogram adjust levels .
*
* 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 .
*
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
// C++ includes.
# include <cmath>
// TQt includes.
# include <tqlayout.h>
# include <tqcolor.h>
# include <tqgroupbox.h>
# include <tqhgroupbox.h>
# include <tqvgroupbox.h>
# include <tqlabel.h>
# include <tqpainter.h>
# include <tqcombobox.h>
# include <tqspinbox.h>
# include <tqwhatsthis.h>
# include <tqtooltip.h>
# include <tqpushbutton.h>
# include <tqlayout.h>
# include <tqframe.h>
# include <tqtimer.h>
# include <tqhbuttongroup.h>
# include <tqpixmap.h>
// KDE includes.
# include <kconfig.h>
# include <kcursor.h>
# include <klocale.h>
# include <knuminput.h>
# include <kmessagebox.h>
# include <kselect.h>
# include <kfiledialog.h>
# include <kglobalsettings.h>
# include <kaboutdata.h>
# include <khelpmenu.h>
# include <kiconloader.h>
# include <kapplication.h>
# include <kpopupmenu.h>
# include <kstandarddirs.h>
// Local includes.
# include "version.h"
# include "ddebug.h"
# include "imageiface.h"
# include "imagewidget.h"
# include "imagehistogram.h"
# include "imagelevels.h"
# include "histogramwidget.h"
# include "dimgimagefilters.h"
# include "adjustlevels.h"
# include "adjustlevels.moc"
namespace DigikamAdjustLevelsImagesPlugin
{
AdjustLevelDialog : : AdjustLevelDialog ( TQWidget * tqparent )
: Digikam : : ImageDlgBase ( tqparent , i18n ( " Adjust Color Levels " ) ,
" adjustlevels " , true , false )
{
m_destinationPreviewData = 0L ;
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 ( ) ;
m_originalImage = Digikam : : DImg ( w , h , sixteenBit , hasAlpha , data ) ;
delete [ ] data ;
m_histoSegments = m_originalImage . sixteenBit ( ) ? 65535 : 255 ;
m_levels = new Digikam : : ImageLevels ( m_originalImage . sixteenBit ( ) ) ;
// About data and help button.
KAboutData * about = new KAboutData ( " digikam " ,
I18N_NOOP ( " Adjust Color Levels " ) ,
digikam_version ,
I18N_NOOP ( " An image-histogram-levels adjustment plugin for digiKam. " ) ,
KAboutData : : License_GPL ,
" (c) 2004-2008, Gilles Caulier " ,
0 ,
" http://www.digikam.org " ) ;
about - > addAuthor ( " Gilles Caulier " , I18N_NOOP ( " Author and maintainer " ) ,
" caulier dot gilles at gmail dot com " ) ;
setAboutData ( about ) ;
// -------------------------------------------------------------
m_previewWidget = new Digikam : : ImageWidget ( " adjustlevels Tool Dialog " , plainPage ( ) ,
i18n ( " <p>Here you can see the image's "
" level-adjustments preview. You can pick a spot on the image "
" to see the corresponding level in the histogram. " ) ) ;
setPreviewAreaWidget ( m_previewWidget ) ;
// -------------------------------------------------------------
TQWidget * gboxSettings = new TQWidget ( plainPage ( ) ) ;
TQGridLayout * grid = new TQGridLayout ( gboxSettings , 16 , 8 , spacingHint ( ) , 0 ) ;
TQLabel * label1 = new TQLabel ( i18n ( " Channel: " ) , gboxSettings ) ;
label1 - > tqsetAlignment ( 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 " ) ) ;
m_channelCB - > insertItem ( i18n ( " Alpha " ) ) ;
m_channelCB - > setCurrentText ( i18n ( " Luminosity " ) ) ;
TQWhatsThis : : add ( m_channelCB , i18n ( " <p>Here select the histogram channel to display:<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> "
" <b>Alpha</b>: display the alpha image-channel values. "
" This channel corresponds to the transparency value and "
" is supported by some image formats, such as PNG or TIF. " ) ) ;
m_scaleBG = new TQHButtonGroup ( gboxSettings ) ;
m_scaleBG - > setExclusive ( true ) ;
m_scaleBG - > setFrameShape ( TQFrame : : NoFrame ) ;
m_scaleBG - > setInsideMargin ( 0 ) ;
TQWhatsThis : : add ( m_scaleBG , i18n ( " <p>Here select the histogram scale.<p> "
" If the image's maximal counts are small, you can use the linear scale.<p> "
" The 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 ) ;
KGlobal : : dirs ( ) - > addResourceType ( " histogram-lin " , KGlobal : : dirs ( ) - > kde_default ( " data " ) + " digikam/data " ) ;
TQString directory = KGlobal : : 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 ) ;
KGlobal : : dirs ( ) - > addResourceType ( " histogram-log " , KGlobal : : dirs ( ) - > kde_default ( " data " ) + " digikam/data " ) ;
directory = KGlobal : : 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 ) ;
// -------------------------------------------------------------
m_histogramWidget = new Digikam : : HistogramWidget ( 256 , 140 , gboxSettings , 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 levels "
" settings changes. " ) ) ;
m_levelsHistogramWidget = new Digikam : : HistogramWidget ( 256 , 140 , m_originalImage . bits ( ) , m_originalImage . width ( ) ,
m_originalImage . height ( ) , m_originalImage . sixteenBit ( ) , gboxSettings , false ) ;
TQWhatsThis : : add ( m_levelsHistogramWidget , i18n ( " <p>This is the histogram drawing of the selected channel "
" from original image " ) ) ;
// -------------------------------------------------------------
m_hGradientMinInput = new KGradientSelector ( KSelector : : Horizontal , gboxSettings ) ;
m_hGradientMinInput - > setFixedHeight ( 20 ) ;
m_hGradientMinInput - > setMinValue ( 0 ) ;
m_hGradientMinInput - > setMaxValue ( m_histoSegments ) ;
TQWhatsThis : : add ( m_hGradientMinInput , i18n ( " <p>Select the minimal intensity input value of the histogram. " ) ) ;
TQToolTip : : add ( m_hGradientMinInput , i18n ( " Minimal intensity input. " ) ) ;
m_hGradientMinInput - > setColors ( TQColor ( " black " ) , TQColor ( " white " ) ) ;
m_hGradientMinInput - > installEventFilter ( this ) ;
m_hGradientMaxInput = new KGradientSelector ( KSelector : : Horizontal , gboxSettings ) ;
m_hGradientMaxInput - > setFixedHeight ( 20 ) ;
m_hGradientMaxInput - > setMinValue ( 0 ) ;
m_hGradientMaxInput - > setMaxValue ( m_histoSegments ) ;
TQWhatsThis : : add ( m_hGradientMaxInput , i18n ( " <p>Select the maximal intensity input value of the histogram. " ) ) ;
TQToolTip : : add ( m_hGradientMaxInput , i18n ( " Maximal intensity input. " ) ) ;
m_hGradientMaxInput - > setColors ( TQColor ( " black " ) , TQColor ( " white " ) ) ;
m_hGradientMaxInput - > installEventFilter ( this ) ;
m_minInput = new TQSpinBox ( 0 , m_histoSegments , 1 , gboxSettings ) ;
m_minInput - > setValue ( 0 ) ;
TQWhatsThis : : add ( m_minInput , i18n ( " <p>Select the minimal intensity input value of the histogram. " ) ) ;
TQToolTip : : add ( m_minInput , i18n ( " Minimal intensity input. " ) ) ;
m_gammaInput = new KDoubleNumInput ( gboxSettings ) ;
m_gammaInput - > setPrecision ( 2 ) ;
m_gammaInput - > setRange ( 0.1 , 3.0 , 0.01 ) ;
m_gammaInput - > setValue ( 1.0 ) ;
TQToolTip : : add ( m_gammaInput , i18n ( " Gamma input value. " ) ) ;
TQWhatsThis : : add ( m_gammaInput , i18n ( " <p>Select the gamma input value. " ) ) ;
m_maxInput = new TQSpinBox ( 0 , m_histoSegments , 1 , gboxSettings ) ;
m_maxInput - > setValue ( m_histoSegments ) ;
TQToolTip : : add ( m_maxInput , i18n ( " Maximal intensity input. " ) ) ;
TQWhatsThis : : add ( m_maxInput , i18n ( " <p>Select the maximal intensity input value of the histogram. " ) ) ;
m_hGradientMinOutput = new KGradientSelector ( KSelector : : Horizontal , gboxSettings ) ;
m_hGradientMinOutput - > setColors ( TQColor ( " black " ) , TQColor ( " white " ) ) ;
TQWhatsThis : : add ( m_hGradientMinOutput , i18n ( " <p>Select the minimal intensity output value of the histogram. " ) ) ;
TQToolTip : : add ( m_hGradientMinOutput , i18n ( " Minimal intensity output. " ) ) ;
m_hGradientMinOutput - > setFixedHeight ( 20 ) ;
m_hGradientMinOutput - > setMinValue ( 0 ) ;
m_hGradientMinOutput - > setMaxValue ( m_histoSegments ) ;
m_hGradientMinOutput - > installEventFilter ( this ) ;
m_hGradientMaxOutput = new KGradientSelector ( KSelector : : Horizontal , gboxSettings ) ;
m_hGradientMaxOutput - > setColors ( TQColor ( " black " ) , TQColor ( " white " ) ) ;
TQWhatsThis : : add ( m_hGradientMaxOutput , i18n ( " <p>Select the maximal intensity output value of the histogram. " ) ) ;
TQToolTip : : add ( m_hGradientMaxOutput , i18n ( " Maximal intensity output. " ) ) ;
m_hGradientMaxOutput - > setFixedHeight ( 20 ) ;
m_hGradientMaxOutput - > setMinValue ( 0 ) ;
m_hGradientMaxOutput - > setMaxValue ( m_histoSegments ) ;
m_hGradientMaxOutput - > installEventFilter ( this ) ;
m_minOutput = new TQSpinBox ( 0 , m_histoSegments , 1 , gboxSettings ) ;
m_minOutput - > setValue ( 0 ) ;
TQToolTip : : add ( m_minOutput , i18n ( " Minimal intensity output. " ) ) ;
TQWhatsThis : : add ( m_minOutput , i18n ( " <p>Select the minimal intensity output value of the histogram. " ) ) ;
m_maxOutput = new TQSpinBox ( 0 , m_histoSegments , 1 , gboxSettings ) ;
m_maxOutput - > setValue ( m_histoSegments ) ;
TQToolTip : : add ( m_maxOutput , i18n ( " Maximal intensity output. " ) ) ;
TQWhatsThis : : add ( m_maxOutput , i18n ( " <p>Select the maximal intensity output value of the histogram. " ) ) ;
// -------------------------------------------------------------
m_pickerColorButtonGroup = new TQHButtonGroup ( gboxSettings ) ;
m_pickBlack = new TQPushButton ( m_pickerColorButtonGroup ) ;
m_pickerColorButtonGroup - > insert ( m_pickBlack , BlackTonal ) ;
KGlobal : : dirs ( ) - > addResourceType ( " color-picker-black " , KGlobal : : dirs ( ) - > kde_default ( " data " ) +
" digikam/data " ) ;
directory = KGlobal : : dirs ( ) - > findResourceDir ( " color-picker-black " , " color-picker-black.png " ) ;
m_pickBlack - > setPixmap ( TQPixmap ( directory + " color-picker-black.png " ) ) ;
m_pickBlack - > setToggleButton ( true ) ;
TQToolTip : : add ( m_pickBlack , i18n ( " All channels shadow tone color picker " ) ) ;
TQWhatsThis : : add ( m_pickBlack , i18n ( " <p>With this button, you can pick the color from original image used to set <b>Shadow Tone</b> "
" levels input on Red, Green, Blue, and Luminosity channels. " ) ) ;
m_pickGray = new TQPushButton ( m_pickerColorButtonGroup ) ;
m_pickerColorButtonGroup - > insert ( m_pickGray , GrayTonal ) ;
KGlobal : : dirs ( ) - > addResourceType ( " color-picker-gray " , KGlobal : : dirs ( ) - > kde_default ( " data " ) +
" digikam/data " ) ;
directory = KGlobal : : dirs ( ) - > findResourceDir ( " color-picker-gray " , " color-picker-gray.png " ) ;
m_pickGray - > setPixmap ( TQPixmap ( directory + " color-picker-gray.png " ) ) ;
m_pickGray - > setToggleButton ( true ) ;
TQToolTip : : add ( m_pickGray , i18n ( " All channels middle tone color picker " ) ) ;
TQWhatsThis : : add ( m_pickGray , i18n ( " <p>With this button, you can pick the color from original image used to set <b>Middle Tone</b> "
" levels input on Red, Green, Blue, and Luminosity channels. " ) ) ;
m_pickWhite = new TQPushButton ( m_pickerColorButtonGroup ) ;
m_pickerColorButtonGroup - > insert ( m_pickWhite , WhiteTonal ) ;
KGlobal : : dirs ( ) - > addResourceType ( " color-picker-white " , KGlobal : : dirs ( ) - > kde_default ( " data " ) +
" digikam/data " ) ;
directory = KGlobal : : dirs ( ) - > findResourceDir ( " color-picker-white " , " color-picker-white.png " ) ;
m_pickWhite - > setPixmap ( TQPixmap ( directory + " color-picker-white.png " ) ) ;
m_pickWhite - > setToggleButton ( true ) ;
TQToolTip : : add ( m_pickWhite , i18n ( " All channels highlight tone color picker " ) ) ;
TQWhatsThis : : add ( m_pickWhite , i18n ( " <p>With this button, you can pick the color from original image used to set <b>Highlight Tone</b> "
" levels input on Red, Green, Blue, and Luminosity channels. " ) ) ;
m_pickerColorButtonGroup - > setExclusive ( true ) ;
m_pickerColorButtonGroup - > setFrameShape ( TQFrame : : NoFrame ) ;
m_autoButton = new TQPushButton ( gboxSettings ) ;
m_autoButton - > setPixmap ( kapp - > iconLoader ( ) - > loadIcon ( " run " , ( KIcon : : Group ) KIcon : : Toolbar ) ) ; TQToolTip : : add ( m_autoButton , i18n ( " Adjust all levels automatically. " ) ) ;
TQWhatsThis : : add ( m_autoButton , i18n ( " <p>If you press this button, all channel levels will be adjusted "
" automatically. " ) ) ;
m_resetButton = new TQPushButton ( i18n ( " &Reset " ) , gboxSettings ) ;
m_resetButton - > setPixmap ( kapp - > iconLoader ( ) - > loadIcon ( " reload_page " , ( KIcon : : Group ) KIcon : : Toolbar ) ) ;
TQToolTip : : add ( m_resetButton , i18n ( " Reset current channel levels' values. " ) ) ;
TQWhatsThis : : add ( m_resetButton , i18n ( " <p>If you press this button, all levels' values "
" from the current selected channel "
" will be reset to the default values. " ) ) ;
TQLabel * space = new TQLabel ( gboxSettings ) ;
space - > setFixedWidth ( spacingHint ( ) ) ;
TQHBoxLayout * l3 = new TQHBoxLayout ( ) ;
l3 - > addWidget ( m_pickerColorButtonGroup ) ;
l3 - > addWidget ( m_autoButton ) ;
l3 - > addWidget ( space ) ;
l3 - > addWidget ( m_resetButton ) ;
l3 - > addStretch ( 10 ) ;
// -------------------------------------------------------------
grid - > addMultiCellLayout ( l1 , 0 , 0 , 0 , 6 ) ;
grid - > setRowSpacing ( 1 , spacingHint ( ) ) ;
grid - > addMultiCellWidget ( m_histogramWidget , 2 , 2 , 1 , 5 ) ;
grid - > setRowSpacing ( 3 , spacingHint ( ) ) ;
grid - > addMultiCellWidget ( m_levelsHistogramWidget , 4 , 4 , 1 , 5 ) ;
grid - > addMultiCellWidget ( m_hGradientMinInput , 5 , 5 , 0 , 6 ) ;
grid - > addMultiCellWidget ( m_minInput , 5 , 5 , 8 , 8 ) ;
grid - > setRowSpacing ( 6 , spacingHint ( ) ) ;
grid - > addMultiCellWidget ( m_hGradientMaxInput , 7 , 7 , 0 , 6 ) ;
grid - > addMultiCellWidget ( m_maxInput , 7 , 7 , 8 , 8 ) ;
grid - > setRowSpacing ( 8 , spacingHint ( ) ) ;
grid - > addMultiCellWidget ( m_gammaInput , 9 , 9 , 0 , 8 ) ;
grid - > setRowSpacing ( 10 , spacingHint ( ) ) ;
grid - > addMultiCellWidget ( m_hGradientMinOutput , 11 , 11 , 0 , 6 ) ;
grid - > addMultiCellWidget ( m_minOutput , 11 , 11 , 8 , 8 ) ;
grid - > setRowSpacing ( 12 , spacingHint ( ) ) ;
grid - > addMultiCellWidget ( m_hGradientMaxOutput , 13 , 13 , 0 , 6 ) ;
grid - > addMultiCellWidget ( m_maxOutput , 13 , 13 , 8 , 8 ) ;
grid - > setRowSpacing ( 14 , spacingHint ( ) ) ;
grid - > addMultiCellLayout ( l3 , 15 , 15 , 0 , 8 ) ;
grid - > setRowStretch ( 16 , 10 ) ;
grid - > setColStretch ( 2 , 10 ) ;
grid - > setColSpacing ( 0 , 5 ) ;
grid - > setColSpacing ( 6 , 5 ) ;
grid - > setColSpacing ( 7 , spacingHint ( ) ) ;
setUserAreaWidget ( gboxSettings ) ;
// -------------------------------------------------------------
// Channels and scale selection slots.
connect ( m_channelCB , TQT_SIGNAL ( activated ( int ) ) ,
this , TQT_SLOT ( slotChannelChanged ( int ) ) ) ;
connect ( m_scaleBG , TQT_SIGNAL ( released ( int ) ) ,
this , TQT_SLOT ( slotScaleChanged ( int ) ) ) ;
connect ( m_previewWidget , TQT_SIGNAL ( spotPositionChangedFromOriginal ( const Digikam : : DColor & , const TQPoint & ) ) ,
this , TQT_SLOT ( slotSpotColorChanged ( const Digikam : : DColor & ) ) ) ;
connect ( m_previewWidget , TQT_SIGNAL ( spotPositionChangedFromTarget ( const Digikam : : DColor & , const TQPoint & ) ) ,
this , TQT_SLOT ( slotColorSelectedFromTarget ( const Digikam : : DColor & ) ) ) ;
connect ( m_previewWidget , TQT_SIGNAL ( signalResized ( ) ) ,
this , TQT_SLOT ( slotEffect ( ) ) ) ;
// -------------------------------------------------------------
// Color sliders and spinbox slots.
connect ( m_hGradientMinInput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotAdjustMinInputSpinBox ( int ) ) ) ;
connect ( m_minInput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotAdjustSliders ( ) ) ) ;
connect ( m_gammaInput , TQT_SIGNAL ( valueChanged ( double ) ) ,
this , TQT_SLOT ( slotGammaInputchanged ( double ) ) ) ;
connect ( m_hGradientMaxInput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotAdjustMaxInputSpinBox ( int ) ) ) ;
connect ( m_maxInput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotAdjustSliders ( ) ) ) ;
connect ( m_hGradientMinOutput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotAdjustMinOutputSpinBox ( int ) ) ) ;
connect ( m_minOutput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotAdjustSliders ( ) ) ) ;
connect ( m_hGradientMaxOutput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotAdjustMaxOutputSpinBox ( int ) ) ) ;
connect ( m_maxOutput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotAdjustSliders ( ) ) ) ;
// -------------------------------------------------------------
// Bouttons slots.
connect ( m_autoButton , TQT_SIGNAL ( clicked ( ) ) ,
this , TQT_SLOT ( slotAutoLevels ( ) ) ) ;
connect ( m_resetButton , TQT_SIGNAL ( clicked ( ) ) ,
this , TQT_SLOT ( slotResetCurrentChannel ( ) ) ) ;
connect ( m_pickerColorButtonGroup , TQT_SIGNAL ( released ( int ) ) ,
this , TQT_SLOT ( slotPickerColorButtonActived ( ) ) ) ;
}
AdjustLevelDialog : : ~ AdjustLevelDialog ( )
{
m_histogramWidget - > stopHistogramComputation ( ) ;
if ( m_destinationPreviewData )
delete [ ] m_destinationPreviewData ;
delete m_histogramWidget ;
delete m_levelsHistogramWidget ;
delete m_levels ;
}
void AdjustLevelDialog : : slotPickerColorButtonActived ( )
{
// Save previous rendering mode and toggle to original image.
m_currentPreviewMode = m_previewWidget - > getRenderingPreviewMode ( ) ;
m_previewWidget - > setRenderingPreviewMode ( Digikam : : ImageGuideWidget : : PreviewOriginalImage ) ;
}
void AdjustLevelDialog : : slotSpotColorChanged ( const Digikam : : DColor & color )
{
if ( m_pickBlack - > isOn ( ) )
{
// Black tonal levels point.
m_levels - > levelsBlackToneAdjustByColors ( m_channelCB - > currentItem ( ) , color ) ;
m_pickBlack - > setOn ( false ) ;
}
else if ( m_pickGray - > isOn ( ) )
{
// Gray tonal levels point.
m_levels - > levelsGrayToneAdjustByColors ( m_channelCB - > currentItem ( ) , color ) ;
m_pickGray - > setOn ( false ) ;
}
else if ( m_pickWhite - > isOn ( ) )
{
// White tonal levels point.
m_levels - > levelsWhiteToneAdjustByColors ( m_channelCB - > currentItem ( ) , color ) ;
m_pickWhite - > setOn ( false ) ;
}
else
{
m_levelsHistogramWidget - > setHistogramGuideByColor ( color ) ;
return ;
}
// Refresh the current levels config.
slotChannelChanged ( m_channelCB - > currentItem ( ) ) ;
// restore previous rendering mode.
m_previewWidget - > setRenderingPreviewMode ( m_currentPreviewMode ) ;
slotEffect ( ) ;
}
void AdjustLevelDialog : : slotColorSelectedFromTarget ( const Digikam : : DColor & color )
{
m_histogramWidget - > setHistogramGuideByColor ( color ) ;
}
void AdjustLevelDialog : : slotGammaInputchanged ( double val )
{
blockSignals ( true ) ;
m_levels - > setLevelGammaValue ( m_channelCB - > currentItem ( ) , val ) ;
blockSignals ( false ) ;
slotTimer ( ) ;
}
void AdjustLevelDialog : : slotAdjustMinInputSpinBox ( int val )
{
blockSignals ( true ) ;
if ( val < m_hGradientMaxInput - > value ( ) )
val = m_hGradientMaxInput - > value ( ) ;
m_minInput - > setValue ( m_histoSegments - val ) ;
m_hGradientMinInput - > setValue ( val ) ;
m_levels - > setLevelLowInputValue ( m_channelCB - > currentItem ( ) , m_histoSegments - val ) ;
blockSignals ( false ) ;
slotTimer ( ) ;
}
void AdjustLevelDialog : : slotAdjustMaxInputSpinBox ( int val )
{
blockSignals ( true ) ;
if ( val > m_hGradientMinInput - > value ( ) )
val = m_hGradientMinInput - > value ( ) ;
m_maxInput - > setValue ( m_histoSegments - val ) ;
m_hGradientMaxInput - > setValue ( val ) ;
m_levels - > setLevelHighInputValue ( m_channelCB - > currentItem ( ) , m_histoSegments - val ) ;
blockSignals ( false ) ;
slotTimer ( ) ;
}
void AdjustLevelDialog : : slotAdjustMinOutputSpinBox ( int val )
{
blockSignals ( true ) ;
if ( val < m_hGradientMaxOutput - > value ( ) )
val = m_hGradientMaxOutput - > value ( ) ;
m_minOutput - > setValue ( m_histoSegments - val ) ;
m_hGradientMinOutput - > setValue ( val ) ;
m_levels - > setLevelLowOutputValue ( m_channelCB - > currentItem ( ) , m_histoSegments - val ) ;
blockSignals ( false ) ;
slotTimer ( ) ;
}
void AdjustLevelDialog : : slotAdjustMaxOutputSpinBox ( int val )
{
blockSignals ( true ) ;
if ( val > m_hGradientMinOutput - > value ( ) )
val = m_hGradientMinOutput - > value ( ) ;
m_maxOutput - > setValue ( m_histoSegments - val ) ;
m_hGradientMaxOutput - > setValue ( val ) ;
m_levels - > setLevelHighOutputValue ( m_channelCB - > currentItem ( ) , m_histoSegments - val ) ;
blockSignals ( false ) ;
slotTimer ( ) ;
}
void AdjustLevelDialog : : slotAdjustSliders ( )
{
adjustSliders ( m_minInput - > value ( ) , m_gammaInput - > value ( ) ,
m_maxInput - > value ( ) , m_minOutput - > value ( ) ,
m_maxOutput - > value ( ) ) ;
}
void AdjustLevelDialog : : adjustSliders ( int minIn , double gamIn , int maxIn , int minOut , int maxOut )
{
m_hGradientMinInput - > setValue ( m_histoSegments - minIn ) ;
m_hGradientMaxInput - > setValue ( m_histoSegments - maxIn ) ;
m_gammaInput - > setValue ( gamIn ) ;
m_hGradientMinOutput - > setValue ( m_histoSegments - minOut ) ;
m_hGradientMaxOutput - > setValue ( m_histoSegments - maxOut ) ;
}
void AdjustLevelDialog : : slotResetCurrentChannel ( )
{
m_levels - > levelsChannelReset ( m_channelCB - > currentItem ( ) ) ;
// Refresh the current levels config.
slotChannelChanged ( m_channelCB - > currentItem ( ) ) ;
m_levelsHistogramWidget - > reset ( ) ;
slotEffect ( ) ;
m_histogramWidget - > reset ( ) ;
}
void AdjustLevelDialog : : slotAutoLevels ( )
{
// Calculate Auto levels.
m_levels - > levelsAuto ( m_levelsHistogramWidget - > m_imageHistogram ) ;
// Refresh the current levels config.
slotChannelChanged ( m_channelCB - > currentItem ( ) ) ;
slotEffect ( ) ;
}
void AdjustLevelDialog : : slotEffect ( )
{
Digikam : : ImageIface * iface = m_previewWidget - > imageIface ( ) ;
uchar * orgData = 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 ) ] ;
// Calculate the LUT to apply on the image.
m_levels - > levelsLutSetup ( Digikam : : ImageHistogram : : AlphaChannel ) ;
// Apply the lut to the image.
m_levels - > levelsLutProcess ( orgData , m_destinationPreviewData , w , h ) ;
iface - > putPreviewImage ( m_destinationPreviewData ) ;
m_previewWidget - > updatePreview ( ) ;
// Update histogram.
m_histogramWidget - > updateData ( m_destinationPreviewData , w , h , sb , 0 , 0 , 0 , false ) ;
delete [ ] orgData ;
}
void AdjustLevelDialog : : finalRendering ( )
{
kapp - > setOverrideCursor ( KCursor : : waitCursor ( ) ) ;
Digikam : : ImageIface * iface = m_previewWidget - > imageIface ( ) ;
uchar * orgData = iface - > getOriginalImage ( ) ;
int w = iface - > originalWidth ( ) ;
int h = iface - > originalHeight ( ) ;
bool sb = iface - > originalSixteenBit ( ) ;
// Create the new empty destination image data space.
uchar * desData = new uchar [ w * h * ( sb ? 8 : 4 ) ] ;
// Calculate the LUT to apply on the image.
m_levels - > levelsLutSetup ( Digikam : : ImageHistogram : : AlphaChannel ) ;
// Apply the lut to the image.
m_levels - > levelsLutProcess ( orgData , desData , w , h ) ;
iface - > putOriginalImage ( i18n ( " Adjust Level " ) , desData ) ;
kapp - > restoreOverrideCursor ( ) ;
delete [ ] orgData ;
delete [ ] desData ;
accept ( ) ;
}
void AdjustLevelDialog : : slotChannelChanged ( int channel )
{
switch ( channel )
{
case LuminosityChannel :
m_histogramWidget - > m_channelType = Digikam : : HistogramWidget : : ValueHistogram ;
m_levelsHistogramWidget - > m_channelType = Digikam : : HistogramWidget : : ValueHistogram ;
m_hGradientMinInput - > setColors ( TQColor ( " black " ) , TQColor ( " white " ) ) ;
m_hGradientMaxInput - > setColors ( TQColor ( " black " ) , TQColor ( " white " ) ) ;
m_hGradientMinOutput - > setColors ( TQColor ( " black " ) , TQColor ( " white " ) ) ;
m_hGradientMaxOutput - > setColors ( TQColor ( " black " ) , TQColor ( " white " ) ) ;
break ;
case RedChannel :
m_histogramWidget - > m_channelType = Digikam : : HistogramWidget : : RedChannelHistogram ;
m_levelsHistogramWidget - > m_channelType = Digikam : : HistogramWidget : : RedChannelHistogram ;
m_hGradientMinInput - > setColors ( TQColor ( " black " ) , TQColor ( " red " ) ) ;
m_hGradientMaxInput - > setColors ( TQColor ( " black " ) , TQColor ( " red " ) ) ;
m_hGradientMinOutput - > setColors ( TQColor ( " black " ) , TQColor ( " red " ) ) ;
m_hGradientMaxOutput - > setColors ( TQColor ( " black " ) , TQColor ( " red " ) ) ;
break ;
case GreenChannel :
m_histogramWidget - > m_channelType = Digikam : : HistogramWidget : : GreenChannelHistogram ;
m_levelsHistogramWidget - > m_channelType = Digikam : : HistogramWidget : : GreenChannelHistogram ;
m_hGradientMinInput - > setColors ( TQColor ( " black " ) , TQColor ( " green " ) ) ;
m_hGradientMaxInput - > setColors ( TQColor ( " black " ) , TQColor ( " green " ) ) ;
m_hGradientMinOutput - > setColors ( TQColor ( " black " ) , TQColor ( " green " ) ) ;
m_hGradientMaxOutput - > setColors ( TQColor ( " black " ) , TQColor ( " green " ) ) ;
break ;
case BlueChannel :
m_histogramWidget - > m_channelType = Digikam : : HistogramWidget : : BlueChannelHistogram ;
m_levelsHistogramWidget - > m_channelType = Digikam : : HistogramWidget : : BlueChannelHistogram ;
m_hGradientMinInput - > setColors ( TQColor ( " black " ) , TQColor ( " blue " ) ) ;
m_hGradientMaxInput - > setColors ( TQColor ( " black " ) , TQColor ( " blue " ) ) ;
m_hGradientMinOutput - > setColors ( TQColor ( " black " ) , TQColor ( " blue " ) ) ;
m_hGradientMaxOutput - > setColors ( TQColor ( " black " ) , TQColor ( " blue " ) ) ;
break ;
case AlphaChannel :
m_histogramWidget - > m_channelType = Digikam : : HistogramWidget : : AlphaChannelHistogram ;
m_levelsHistogramWidget - > m_channelType = Digikam : : HistogramWidget : : AlphaChannelHistogram ;
m_hGradientMinInput - > setColors ( TQColor ( " black " ) , TQColor ( " white " ) ) ;
m_hGradientMaxInput - > setColors ( TQColor ( " black " ) , TQColor ( " white " ) ) ;
m_hGradientMinOutput - > setColors ( TQColor ( " black " ) , TQColor ( " white " ) ) ;
m_hGradientMaxOutput - > setColors ( TQColor ( " black " ) , TQColor ( " white " ) ) ;
break ;
}
adjustSliders ( m_levels - > getLevelLowInputValue ( channel ) ,
m_levels - > getLevelGammaValue ( channel ) ,
m_levels - > getLevelHighInputValue ( channel ) ,
m_levels - > getLevelLowOutputValue ( channel ) ,
m_levels - > getLevelHighOutputValue ( channel ) ) ;
m_levelsHistogramWidget - > tqrepaint ( false ) ;
m_histogramWidget - > tqrepaint ( false ) ;
}
void AdjustLevelDialog : : slotScaleChanged ( int scale )
{
m_levelsHistogramWidget - > m_scaleType = scale ;
m_histogramWidget - > m_scaleType = scale ;
m_histogramWidget - > tqrepaint ( false ) ;
m_levelsHistogramWidget - > tqrepaint ( false ) ;
}
void AdjustLevelDialog : : readUserSettings ( )
{
KConfig * config = kapp - > config ( ) ;
config - > setGroup ( " adjustlevels Tool Dialog " ) ;
m_channelCB - > setCurrentItem ( config - > readNumEntry ( " Histogram Channel " , 0 ) ) ; // Luminosity.
m_scaleBG - > setButton ( config - > readNumEntry ( " Histogram Scale " , Digikam : : HistogramWidget : : LogScaleHistogram ) ) ;
for ( int i = 0 ; i < 5 ; i + + )
{
bool sb = m_originalImage . sixteenBit ( ) ;
int max = sb ? 65535 : 255 ;
double gamma = config - > readDoubleNumEntry ( TQString ( " GammaChannel%1 " ) . tqarg ( i ) , 1.0 ) ;
int lowInput = config - > readNumEntry ( TQString ( " LowInputChannel%1 " ) . tqarg ( i ) , 0 ) ;
int lowOutput = config - > readNumEntry ( TQString ( " LowOutputChannel%1 " ) . tqarg ( i ) , 0 ) ;
int highInput = config - > readNumEntry ( TQString ( " HighInputChannel%1 " ) . tqarg ( i ) , max ) ;
int highOutput = config - > readNumEntry ( TQString ( " HighOutputChannel%1 " ) . tqarg ( i ) , max ) ;
m_levels - > setLevelGammaValue ( i , gamma ) ;
m_levels - > setLevelLowInputValue ( i , sb ? lowInput * 255 : lowInput ) ;
m_levels - > setLevelHighInputValue ( i , sb ? highInput * 255 : highInput ) ;
m_levels - > setLevelLowOutputValue ( i , sb ? lowOutput * 255 : lowOutput ) ;
m_levels - > setLevelHighOutputValue ( i , sb ? highOutput * 255 : highOutput ) ;
}
m_levelsHistogramWidget - > reset ( ) ;
m_histogramWidget - > reset ( ) ;
slotChannelChanged ( m_channelCB - > currentItem ( ) ) ;
slotScaleChanged ( m_scaleBG - > selectedId ( ) ) ;
// This is mandatory here to set spinbox values because slot connections
// can be not set completely at plugin startup.
m_minInput - > setValue ( m_levels - > getLevelLowInputValue ( m_channelCB - > currentItem ( ) ) ) ;
m_minOutput - > setValue ( m_levels - > getLevelLowOutputValue ( m_channelCB - > currentItem ( ) ) ) ;
m_maxInput - > setValue ( m_levels - > getLevelHighInputValue ( m_channelCB - > currentItem ( ) ) ) ;
m_maxOutput - > setValue ( m_levels - > getLevelHighOutputValue ( m_channelCB - > currentItem ( ) ) ) ;
}
void AdjustLevelDialog : : writeUserSettings ( )
{
KConfig * config = kapp - > config ( ) ;
config - > setGroup ( " adjustlevels Tool Dialog " ) ;
config - > writeEntry ( " Histogram Channel " , m_channelCB - > currentItem ( ) ) ;
config - > writeEntry ( " Histogram Scale " , m_scaleBG - > selectedId ( ) ) ;
for ( int i = 0 ; i < 5 ; i + + )
{
bool sb = m_originalImage . sixteenBit ( ) ;
double gamma = m_levels - > getLevelGammaValue ( i ) ;
int lowInput = m_levels - > getLevelLowInputValue ( i ) ;
int lowOutput = m_levels - > getLevelLowOutputValue ( i ) ;
int highInput = m_levels - > getLevelHighInputValue ( i ) ;
int highOutput = m_levels - > getLevelHighOutputValue ( i ) ;
config - > writeEntry ( TQString ( " GammaChannel%1 " ) . tqarg ( i ) , gamma ) ;
config - > writeEntry ( TQString ( " LowInputChannel%1 " ) . tqarg ( i ) , sb ? lowInput / 255 : lowInput ) ;
config - > writeEntry ( TQString ( " LowOutputChannel%1 " ) . tqarg ( i ) , sb ? lowOutput / 255 : lowOutput ) ;
config - > writeEntry ( TQString ( " HighInputChannel%1 " ) . tqarg ( i ) , sb ? highInput / 255 : highInput ) ;
config - > writeEntry ( TQString ( " HighOutputChannel%1 " ) . tqarg ( i ) , sb ? highOutput / 255 : highOutput ) ;
}
config - > sync ( ) ;
}
void AdjustLevelDialog : : resetValues ( )
{
for ( int channel = 0 ; channel < 5 ; + + channel )
m_levels - > levelsChannelReset ( channel ) ;
// Refresh the current levels config.
slotChannelChanged ( m_channelCB - > currentItem ( ) ) ;
m_levelsHistogramWidget - > reset ( ) ;
m_histogramWidget - > reset ( ) ;
}
// Load all settings.
void AdjustLevelDialog : : slotUser3 ( )
{
KURL loadLevelsFile ;
loadLevelsFile = KFileDialog : : getOpenURL ( KGlobalSettings : : documentPath ( ) ,
TQString ( " * " ) , this ,
TQString ( i18n ( " Select Gimp Levels File to Load " ) ) ) ;
if ( loadLevelsFile . isEmpty ( ) )
return ;
if ( m_levels - > loadLevelsFromGimpLevelsFile ( loadLevelsFile ) = = false )
{
KMessageBox : : error ( this , i18n ( " Cannot load from the Gimp levels text file. " ) ) ;
return ;
}
// Refresh the current levels config.
slotChannelChanged ( m_channelCB - > currentItem ( ) ) ;
}
// Save all settings.
void AdjustLevelDialog : : slotUser2 ( )
{
KURL saveLevelsFile ;
saveLevelsFile = KFileDialog : : getSaveURL ( KGlobalSettings : : documentPath ( ) ,
TQString ( " * " ) , this ,
TQString ( i18n ( " Gimp Levels File to Save " ) ) ) ;
if ( saveLevelsFile . isEmpty ( ) )
return ;
if ( m_levels - > saveLevelsToGimpLevelsFile ( saveLevelsFile ) = = false )
{
KMessageBox : : error ( this , i18n ( " Cannot save to the Gimp levels text file. " ) ) ;
return ;
}
// Refresh the current levels config.
slotChannelChanged ( m_channelCB - > currentItem ( ) ) ;
}
// See B.K.O #146636: use event filter with all level slider to display a
// guide over level histogram.
bool AdjustLevelDialog : : eventFilter ( TQObject * obj , TQEvent * ev )
{
if ( obj = = m_hGradientMinInput )
{
if ( ev - > type ( ) = = TQEvent : : MouseButtonPress )
{
connect ( m_minInput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotShowHistogramGuide ( int ) ) ) ;
return false ;
}
if ( ev - > type ( ) = = TQEvent : : MouseButtonRelease )
{
disconnect ( m_minInput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotShowHistogramGuide ( int ) ) ) ;
m_levelsHistogramWidget - > reset ( ) ;
return false ;
}
else
{
return false ;
}
}
if ( obj = = m_hGradientMaxInput )
{
if ( ev - > type ( ) = = TQEvent : : MouseButtonPress )
{
connect ( m_maxInput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotShowHistogramGuide ( int ) ) ) ;
return false ;
}
if ( ev - > type ( ) = = TQEvent : : MouseButtonRelease )
{
disconnect ( m_maxInput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotShowHistogramGuide ( int ) ) ) ;
m_levelsHistogramWidget - > reset ( ) ;
return false ;
}
else
{
return false ;
}
}
if ( obj = = m_hGradientMinOutput )
{
if ( ev - > type ( ) = = TQEvent : : MouseButtonPress )
{
connect ( m_minOutput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotShowHistogramGuide ( int ) ) ) ;
return false ;
}
if ( ev - > type ( ) = = TQEvent : : MouseButtonRelease )
{
disconnect ( m_minOutput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotShowHistogramGuide ( int ) ) ) ;
m_levelsHistogramWidget - > reset ( ) ;
return false ;
}
else
{
return false ;
}
}
if ( obj = = m_hGradientMaxOutput )
{
if ( ev - > type ( ) = = TQEvent : : MouseButtonPress )
{
connect ( m_maxOutput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotShowHistogramGuide ( int ) ) ) ;
return false ;
}
if ( ev - > type ( ) = = TQEvent : : MouseButtonRelease )
{
disconnect ( m_maxOutput , TQT_SIGNAL ( valueChanged ( int ) ) ,
this , TQT_SLOT ( slotShowHistogramGuide ( int ) ) ) ;
m_levelsHistogramWidget - > reset ( ) ;
return false ;
}
else
{
return false ;
}
}
else
{
// pass the event on to the tqparent class
return KDialogBase : : eventFilter ( obj , ev ) ;
}
}
void AdjustLevelDialog : : slotShowHistogramGuide ( int v )
{
Digikam : : DColor color ( v , v , v , v , m_originalImage . sixteenBit ( ) ) ;
m_levelsHistogramWidget - > setHistogramGuideByColor ( color ) ;
}
} // NameSpace DigikamAdjustLevelsImagesPlugin