1
/* ============================================================
3
* This file is a part of digiKam project
4
* http://www.digikam.org
7
* Description : noise reduction settings view.
9
* Copyright (C) 2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
11
* This program is free software; you can redistribute it
12
* and/or modify it under the terms of the GNU General
13
* Public License as published by the Free Software Foundation;
14
* either version 2, or (at your option)
17
* This program is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* ============================================================ */
24
#include "noisereductionsettings.moc"
28
#include <QGridLayout>
32
#include <QTextStream>
41
#include <kapplication.h>
42
#include <kfiledialog.h>
44
#include <kglobalsettings.h>
45
#include <kmessagebox.h>
46
#include <kstandarddirs.h>
50
#include <libkdcraw/rnuminput.h>
54
#include "rexpanderbox.h"
56
using namespace KDcrawIface;
61
class NoiseReductionSettingsPriv
65
NoiseReductionSettingsPriv() :
66
configThresholdAdjustmentEntry("ThresholdAdjustment"),
67
configSoftnessAdjustmentEntry("SoftnessAdjustment"),
68
configAdvancedAdjustmentEntry("AdvancedAdjustment"),
69
configThrLumInputAdjustmentEntry("ThrLumAdjustment"),
70
configSoftLumInputAdjustmentEntry("SoftLumAdjustment"),
71
configThrCrInputAdjustmentEntry("ThrCrAdjustment"),
72
configSoftCrInputAdjustmentEntry("SoftCrAdjustment"),
73
configThrCbInputAdjustmentEntry("ThrCbAdjustment"),
74
configSoftCbInputAdjustmentEntry("SoftCbAdjustment"),
79
chrominanceBlueBox(0),
91
const QString configThresholdAdjustmentEntry;
92
const QString configSoftnessAdjustmentEntry;
93
const QString configAdvancedAdjustmentEntry;
94
const QString configThrLumInputAdjustmentEntry;
95
const QString configSoftLumInputAdjustmentEntry;
96
const QString configThrCrInputAdjustmentEntry;
97
const QString configSoftCrInputAdjustmentEntry;
98
const QString configThrCbInputAdjustmentEntry;
99
const QString configSoftCbInputAdjustmentEntry;
101
QCheckBox* advancedBox;
104
QWidget* luminanceBox;
105
QWidget* chrominanceRedBox;
106
QWidget* chrominanceBlueBox;
108
RExpanderBox* advExpanderBox;
110
RDoubleNumInput* thresholdInput;
111
RDoubleNumInput* softnessInput;
112
RDoubleNumInput* thrLumInput;
113
RDoubleNumInput* softLumInput;
114
RDoubleNumInput* thrCrInput;
115
RDoubleNumInput* softCrInput;
116
RDoubleNumInput* thrCbInput;
117
RDoubleNumInput* softCbInput;
120
NoiseReductionSettings::NoiseReductionSettings(QWidget* parent)
122
d(new NoiseReductionSettingsPriv)
124
QGridLayout* grid = new QGridLayout(parent);
126
QString thHelp = i18n("<b>Threshold</b>: Adjusts the threshold for denoising of "
127
"the image in a range from 0.0 (none) to 10.0. "
128
"The threshold is the value below which everything is considered noise.");
130
QString soHelp = i18n("<b>Softness</b>: This adjusts the softness of the thresholding "
131
"(soft as opposed to hard thresholding). The higher the softness "
132
"the more noise remains in the image.");
134
// -------------------------------------------------------------
136
d->leadBox = new QWidget;
137
QGridLayout* genLay = new QGridLayout(d->leadBox);
139
QLabel *label1 = new QLabel(i18n("Threshold:"), d->leadBox);
140
d->thresholdInput = new RDoubleNumInput(d->leadBox);
141
d->thresholdInput->setDecimals(2);
142
d->thresholdInput->input()->setRange(0.0, 10.0, 0.1, true);
143
d->thresholdInput->setDefaultValue(1.2);
144
d->thresholdInput->setWhatsThis(thHelp);
146
QLabel *label2 = new QLabel(i18n("Softness:"), d->leadBox);
147
d->softnessInput = new RDoubleNumInput(d->leadBox);
148
d->softnessInput->setDecimals(1);
149
d->softnessInput->input()->setRange(0.0, 1.0, 0.1, true);
150
d->softnessInput->setDefaultValue(0.9);
151
d->softnessInput->setWhatsThis(soHelp);
153
genLay->addWidget(label1, 0, 0, 1, 1);
154
genLay->addWidget(d->thresholdInput, 0, 1, 1, 1);
155
genLay->addWidget(label2, 1, 0, 1, 1);
156
genLay->addWidget(d->softnessInput, 1, 1, 1, 1);
157
genLay->setRowStretch(2, 10);
158
genLay->setSpacing(0);
159
genLay->setMargin(KDialog::spacingHint());
161
// -------------------------------------------------------------
163
d->advancedBox = new QCheckBox(i18n("Advanced adjustments"));
164
d->advExpanderBox = new RExpanderBox;
165
d->advExpanderBox->setObjectName("Advanced Settings Expander");
167
// -------------------------------------------------------------
169
d->luminanceBox = new QWidget(d->advExpanderBox);
170
QGridLayout* lumLay = new QGridLayout(d->luminanceBox);
172
QLabel *label3 = new QLabel(i18n("Threshold:"), d->luminanceBox);
173
d->thrLumInput = new RDoubleNumInput(d->luminanceBox);
174
d->thrLumInput->setDecimals(2);
175
d->thrLumInput->input()->setRange(0.0, 10.0, 0.1, true);
176
d->thrLumInput->setDefaultValue(1.2);
177
d->thrLumInput->setWhatsThis(thHelp);
179
QLabel *label4 = new QLabel(i18n("Softness:"), d->luminanceBox);
180
d->softLumInput = new RDoubleNumInput(d->luminanceBox);
181
d->softLumInput->setDecimals(1);
182
d->softLumInput->input()->setRange(0.0, 1.0, 0.1, true);
183
d->softLumInput->setDefaultValue(0.9);
184
d->softLumInput->setWhatsThis(soHelp);
186
lumLay->addWidget(label3, 0, 0, 1, 1);
187
lumLay->addWidget(d->thrLumInput, 0, 1, 1, 1);
188
lumLay->addWidget(label4, 1, 0, 1, 1);
189
lumLay->addWidget(d->softLumInput, 1, 1, 1, 1);
190
lumLay->setRowStretch(2, 10);
191
lumLay->setSpacing(0);
192
lumLay->setMargin(KDialog::spacingHint());
194
// -------------------------------------------------------------
196
d->chrominanceRedBox = new QWidget(d->advExpanderBox);
197
QGridLayout* cRedLay = new QGridLayout(d->chrominanceRedBox);
199
QLabel *label5 = new QLabel(i18n("Threshold:"), d->chrominanceRedBox);
200
d->thrCrInput = new RDoubleNumInput(d->chrominanceRedBox);
201
d->thrCrInput->setDecimals(2);
202
d->thrCrInput->input()->setRange(0.0, 10.0, 0.1, true);
203
d->thrCrInput->setDefaultValue(1.2);
204
d->thrCrInput->setWhatsThis(thHelp);
206
QLabel *label6 = new QLabel(i18n("Softness:"), d->chrominanceRedBox);
207
d->softCrInput = new RDoubleNumInput(d->chrominanceRedBox);
208
d->softCrInput->setDecimals(1);
209
d->softCrInput->input()->setRange(0.0, 1.0, 0.1, true);
210
d->softCrInput->setDefaultValue(0.9);
211
d->softCrInput->setWhatsThis(soHelp);
213
cRedLay->addWidget(label5, 0, 0, 1, 1);
214
cRedLay->addWidget(d->thrCrInput, 0, 1, 1, 1);
215
cRedLay->addWidget(label6, 1, 0, 1, 1);
216
cRedLay->addWidget(d->softCrInput, 1, 1, 1, 1);
217
cRedLay->setRowStretch(2, 10);
218
cRedLay->setSpacing(0);
219
cRedLay->setMargin(KDialog::spacingHint());
221
// -------------------------------------------------------------
223
d->chrominanceBlueBox = new QWidget(d->advExpanderBox);
224
QGridLayout* cBlueLay = new QGridLayout(d->chrominanceBlueBox);
226
QLabel *label7 = new QLabel(i18n("Threshold:"), d->chrominanceBlueBox);
227
d->thrCbInput = new RDoubleNumInput(d->chrominanceBlueBox);
228
d->thrCbInput->setDecimals(2);
229
d->thrCbInput->input()->setRange(0.0, 10.0, 0.1, true);
230
d->thrCbInput->setDefaultValue(1.2);
231
d->thrCbInput->setWhatsThis(thHelp);
233
QLabel *label8 = new QLabel(i18n("Softness:"), d->chrominanceBlueBox);
234
d->softCbInput = new RDoubleNumInput(d->chrominanceBlueBox);
235
d->softCbInput->setDecimals(1);
236
d->softCbInput->input()->setRange(0.0, 1.0, 0.1, true);
237
d->softCbInput->setDefaultValue(0.9);
238
d->softCbInput->setWhatsThis(soHelp);
240
cBlueLay->addWidget(label7, 0, 0, 1, 1);
241
cBlueLay->addWidget(d->thrCbInput, 0, 1, 1, 1);
242
cBlueLay->addWidget(label8, 1, 0, 1, 1);
243
cBlueLay->addWidget(d->softCbInput, 1, 1, 1, 1);
244
cBlueLay->setRowStretch(2, 10);
245
cBlueLay->setSpacing(0);
246
cBlueLay->setMargin(KDialog::spacingHint());
248
// -------------------------------------------------------------
250
d->advExpanderBox->addItem(d->luminanceBox, i18n("Luminance"), QString("Luminance"), true);
251
d->advExpanderBox->addItem(d->chrominanceRedBox, i18n("Chrominance Red"), QString("ChrominanceRed"), true);
252
d->advExpanderBox->addItem(d->chrominanceBlueBox, i18n("Chrominance Blue"), QString("ChrominanceBlue"), true);
253
d->advExpanderBox->addStretch();
255
// -------------------------------------------------------------
257
grid->addWidget(d->leadBox, 0, 0, 1, 2);
258
grid->addWidget(d->advancedBox, 1, 0, 1, 2);
259
grid->addWidget(d->advExpanderBox, 2, 0, 1, 2);
260
grid->setRowStretch(3, 10);
261
grid->setMargin(KDialog::spacingHint());
262
grid->setSpacing(KDialog::spacingHint());
264
// -------------------------------------------------------------
266
connect(d->thresholdInput, SIGNAL(valueChanged(double)),
267
this, SLOT(slotLeadSettingsChanged()));
269
connect(d->softnessInput, SIGNAL(valueChanged(double)),
270
this, SLOT(slotLeadSettingsChanged()));
272
connect(d->thrLumInput, SIGNAL(valueChanged(double)),
273
this, SIGNAL(signalSettingsChanged()));
275
connect(d->softLumInput, SIGNAL(valueChanged(double)),
276
this, SIGNAL(signalSettingsChanged()));
278
connect(d->thrCrInput, SIGNAL(valueChanged(double)),
279
this, SIGNAL(signalSettingsChanged()));
281
connect(d->softCrInput, SIGNAL(valueChanged(double)),
282
this, SIGNAL(signalSettingsChanged()));
284
connect(d->thrCbInput, SIGNAL(valueChanged(double)),
285
this, SIGNAL(signalSettingsChanged()));
287
connect(d->softCbInput, SIGNAL(valueChanged(double)),
288
this, SIGNAL(signalSettingsChanged()));
290
connect(d->advancedBox, SIGNAL(toggled(bool)),
291
this, SLOT(slotAdvancedEnabled(bool)));
294
NoiseReductionSettings::~NoiseReductionSettings()
299
WaveletsNRContainer NoiseReductionSettings::settings() const
301
WaveletsNRContainer prm;
303
prm.thresholds[0] = d->thrLumInput->value();
304
prm.thresholds[2] = d->thrCrInput->value();
305
prm.thresholds[1] = d->thrCbInput->value();
306
prm.softness[0] = 1.0 - d->softLumInput->value();
307
prm.softness[2] = 1.0 - d->softCrInput->value();
308
prm.softness[1] = 1.0 - d->softCbInput->value();
309
prm.advanced = d->advancedBox->isChecked();
310
prm.leadThreshold = d->thresholdInput->value();
311
prm.leadSoftness = 1.0 - d->softnessInput->value();
316
void NoiseReductionSettings::setSettings(const WaveletsNRContainer& settings)
319
d->thrLumInput->setValue(settings.thresholds[0]);
320
d->thrCrInput->setValue(settings.thresholds[2]);
321
d->thrCbInput->setValue(settings.thresholds[1]);
322
d->softLumInput->setValue(1.0 - settings.softness[0]);
323
d->softCrInput->setValue(1.0 - settings.softness[2]);
324
d->softCbInput->setValue(1.0 - settings.softness[1]);
325
d->advancedBox->setChecked(settings.advanced);
326
d->thresholdInput->setValue(settings.leadThreshold);
327
d->softnessInput->setValue(1.0 - settings.leadSoftness);
328
slotAdvancedEnabled(settings.advanced);
332
void NoiseReductionSettings::resetToDefault()
335
d->thresholdInput->slotReset();
336
d->softnessInput->slotReset();
337
d->thrLumInput->slotReset();
338
d->softLumInput->slotReset();
339
d->thrCrInput->slotReset();
340
d->softCrInput->slotReset();
341
d->thrCbInput->slotReset();
342
d->softCbInput->slotReset();
343
d->advancedBox->setChecked(false);
344
slotAdvancedEnabled(false);
348
WaveletsNRContainer NoiseReductionSettings::defaultSettings() const
350
WaveletsNRContainer prm;
352
prm.thresholds[0] = d->thrLumInput->defaultValue();
353
prm.thresholds[2] = d->thrCrInput->defaultValue();
354
prm.thresholds[1] = d->thrCbInput->defaultValue();
355
prm.softness[0] = 1.0 - d->softLumInput->defaultValue();
356
prm.softness[2] = 1.0 - d->softCrInput->defaultValue();
357
prm.softness[1] = 1.0 - d->softCbInput->defaultValue();
358
prm.advanced = false;
359
prm.leadThreshold = d->thresholdInput->defaultValue();
360
prm.leadSoftness = 1.0 - d->softnessInput->defaultValue();
365
void NoiseReductionSettings::slotAdvancedEnabled(bool b)
367
d->leadBox->setEnabled(!b);
368
d->advExpanderBox->setEnabled(b);
370
if (!b) slotLeadSettingsChanged();
373
void NoiseReductionSettings::slotLeadSettingsChanged()
375
if (!d->advancedBox->isChecked())
377
WaveletsNRContainer prm = settings();
378
d->thrLumInput->setValue(prm.leadThreshold);
379
d->thrCrInput->setValue(prm.leadThreshold);
380
d->thrCbInput->setValue(prm.leadThreshold);
381
d->softLumInput->setValue(1.0 - prm.leadSoftness);
382
d->softCrInput->setValue(1.0 - prm.leadSoftness);
383
d->softCbInput->setValue(1.0 - prm.leadSoftness);
386
emit signalSettingsChanged();
389
void NoiseReductionSettings::readSettings(KConfigGroup& group)
391
WaveletsNRContainer prm;
392
WaveletsNRContainer defaultPrm = defaultSettings();
394
prm.thresholds[0] = group.readEntry(d->configThrLumInputAdjustmentEntry, defaultPrm.thresholds[0]);
395
prm.thresholds[2] = group.readEntry(d->configThrCrInputAdjustmentEntry, defaultPrm.thresholds[2]);
396
prm.thresholds[1] = group.readEntry(d->configThrCbInputAdjustmentEntry, defaultPrm.thresholds[1]);
397
prm.softness[0] = group.readEntry(d->configSoftLumInputAdjustmentEntry, defaultPrm.softness[0]);
398
prm.softness[2] = group.readEntry(d->configSoftCrInputAdjustmentEntry, defaultPrm.softness[2]);
399
prm.softness[1] = group.readEntry(d->configSoftCbInputAdjustmentEntry, defaultPrm.softness[1]);
400
prm.advanced = group.readEntry(d->configAdvancedAdjustmentEntry, defaultPrm.advanced);
401
prm.leadThreshold = group.readEntry(d->configThresholdAdjustmentEntry, defaultPrm.leadThreshold);
402
prm.leadSoftness = group.readEntry(d->configSoftnessAdjustmentEntry, defaultPrm.leadSoftness);
406
void NoiseReductionSettings::writeSettings(KConfigGroup& group)
408
WaveletsNRContainer prm = settings();
410
group.writeEntry(d->configThrLumInputAdjustmentEntry, prm.thresholds[0]);
411
group.writeEntry(d->configThrCrInputAdjustmentEntry, prm.thresholds[2]);
412
group.writeEntry(d->configThrCbInputAdjustmentEntry, prm.thresholds[1]);
413
group.writeEntry(d->configSoftLumInputAdjustmentEntry, prm.softness[0]);
414
group.writeEntry(d->configSoftCrInputAdjustmentEntry, prm.softness[2]);
415
group.writeEntry(d->configSoftCbInputAdjustmentEntry, prm.softness[1]);
416
group.writeEntry(d->configAdvancedAdjustmentEntry, prm.advanced);
417
group.writeEntry(d->configThresholdAdjustmentEntry, prm.leadThreshold);
418
group.writeEntry(d->configSoftnessAdjustmentEntry, prm.leadSoftness);
421
void NoiseReductionSettings::loadSettings()
423
KUrl loadRestorationFile = KFileDialog::getOpenUrl(KGlobalSettings::documentPath(),
424
QString( "*" ), kapp->activeWindow(),
425
QString( i18n("Photograph Noise Reduction Settings File to Load")) );
426
if ( loadRestorationFile.isEmpty() )
429
QFile file(loadRestorationFile.toLocalFile());
431
if ( file.open(QIODevice::ReadOnly) )
433
QTextStream stream( &file );
434
if ( stream.readLine() != "# Photograph Wavelets Noise Reduction Configuration File" )
436
KMessageBox::error(kapp->activeWindow(),
437
i18n("\"%1\" is not a Photograph Noise Reduction settings text file.",
438
loadRestorationFile.fileName()));
445
d->thresholdInput->setValue( stream.readLine().toDouble() );
446
d->softnessInput->setValue( stream.readLine().toDouble() );
447
d->advancedBox->setChecked( (bool)stream.readLine().toInt() );
449
d->thrLumInput->setValue( stream.readLine().toDouble() );
450
d->softLumInput->setValue( stream.readLine().toDouble() );
451
d->thrCrInput->setValue( stream.readLine().toDouble() );
452
d->softCrInput->setValue( stream.readLine().toDouble() );
453
d->thrCbInput->setValue( stream.readLine().toDouble() );
454
d->softCbInput->setValue( stream.readLine().toDouble() );
456
slotAdvancedEnabled(d->advancedBox->isChecked());
462
KMessageBox::error(kapp->activeWindow(), i18n("Cannot load settings from the Photograph Noise Reduction text file."));
468
void NoiseReductionSettings::saveAsSettings()
470
KUrl saveRestorationFile = KFileDialog::getSaveUrl(KGlobalSettings::documentPath(),
471
QString( "*" ), kapp->activeWindow(),
472
QString( i18n("Photograph Noise Reduction Settings File to Save")) );
473
if ( saveRestorationFile.isEmpty() )
476
QFile file(saveRestorationFile.toLocalFile());
478
if ( file.open(QIODevice::WriteOnly) )
480
QTextStream stream( &file );
481
stream << "# Photograph Wavelets Noise Reduction Configuration File\n";
482
stream << d->thresholdInput->value() << "\n";
483
stream << d->softnessInput->value() << "\n";
484
stream << d->advancedBox->isChecked() << "\n";
486
stream << d->thrLumInput->value() << "\n";
487
stream << d->softLumInput->value() << "\n";
488
stream << d->thrCrInput->value() << "\n";
489
stream << d->softCrInput->value() << "\n";
490
stream << d->thrCbInput->value() << "\n";
491
stream << d->softCbInput->value() << "\n";
495
KMessageBox::error(kapp->activeWindow(), i18n("Cannot save settings to the Photograph Noise Reduction text file."));
501
} // namespace Digikam