1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2012-02-05
7 * Description : film color negative inverter tool
8 *
9 * Copyright (C) 2012 by Matthias Welwarsky <matthias at welwarsky dot de>
10 *
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)
15 * any later version.
16 *
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.
21 *
22 * ============================================================ */
23
24 #include "filmtool.h"
25
26 // C++ includes
27
28 #include <cmath>
29
30 // Qt includes
31
32 #include <QButtonGroup>
33 #include <QColor>
34 #include <QGridLayout>
35 #include <QGroupBox>
36 #include <QHBoxLayout>
37 #include <QLabel>
38 #include <QPushButton>
39 #include <QTimer>
40 #include <QToolButton>
41 #include <QListWidget>
42 #include <QCheckBox>
43 #include <QIcon>
44
45 // KDE includes
46
47 #include <klocalizedstring.h>
48 #include <ksharedconfig.h>
49 #include <kconfiggroup.h>
50
51 // Local includes
52
53 #include "dnuminput.h"
54 #include "dgradientslider.h"
55 #include "dimg.h"
56 #include "editortoolsettings.h"
57 #include "histogrambox.h"
58 #include "histogramwidget.h"
59 #include "imagehistogram.h"
60 #include "imageiface.h"
61 #include "imagelevels.h"
62 #include "imageregionwidget.h"
63 #include "filmfilter_p.h"
64
65 namespace DigikamEditorFilmToolPlugin
66 {
67
68 class Q_DECL_HIDDEN FilmTool::Private
69 {
70
71 public:
72
73 enum ColorPicker
74 {
75 NoPicker = 0,
76 OrangeMask = 1
77 };
78
79 public:
80
Private()81 explicit Private()
82 : histoSegments(0),
83 resetButton(nullptr),
84 pickWhitePoint(nullptr),
85 autoButton(nullptr),
86 exposureInput(nullptr),
87 gammaInput(nullptr),
88 cnType(nullptr),
89 colorBalanceInput(nullptr),
90 levelsHistogramWidget(nullptr),
91 redInputLevels(nullptr),
92 greenInputLevels(nullptr),
93 blueInputLevels(nullptr),
94 previewWidget(nullptr),
95 levels(nullptr),
96 originalImage(nullptr),
97 gboxSettings(nullptr)
98 {
99 }
100
101 static const QString configGroupName;
102 static const QString configGammaInputEntry;
103 static const QString configExposureEntry;
104 static const QString configFilmProfileEntry;
105 static const QString configFilmProfileName;
106 static const QString configWhitePointEntry;
107 static const QString configHistogramChannelEntry;
108 static const QString configHistogramScaleEntry;
109 static const QString configApplyColorBalance;
110
111 int histoSegments;
112
113 QPushButton* resetButton;
114 QToolButton* pickWhitePoint;
115 QToolButton* autoButton;
116
117 FilmContainer filmContainer;
118
119 DDoubleNumInput* exposureInput;
120 DDoubleNumInput* gammaInput;
121 QListWidget* cnType;
122 QCheckBox* colorBalanceInput;
123
124 HistogramWidget* levelsHistogramWidget;
125
126 DGradientSlider* redInputLevels;
127 DGradientSlider* greenInputLevels;
128 DGradientSlider* blueInputLevels;
129
130 ImageRegionWidget* previewWidget;
131
132 ImageLevels* levels;
133
134 DImg* originalImage;
135
136 EditorToolSettings* gboxSettings;
137 };
138
139 const QString FilmTool::Private::configGroupName(QLatin1String("film Tool"));
140 const QString FilmTool::Private::configGammaInputEntry(QLatin1String("GammaInput"));
141 const QString FilmTool::Private::configExposureEntry(QLatin1String("Exposure"));
142 const QString FilmTool::Private::configFilmProfileEntry(QLatin1String("FilmProfile"));
143 const QString FilmTool::Private::configFilmProfileName(QLatin1String("FilmProfileName"));
144 const QString FilmTool::Private::configWhitePointEntry(QLatin1String("WhitePoint_%1"));
145 const QString FilmTool::Private::configHistogramChannelEntry(QLatin1String("Histogram Channel"));
146 const QString FilmTool::Private::configHistogramScaleEntry(QLatin1String("Histogram Scale"));
147 const QString FilmTool::Private::configApplyColorBalance(QLatin1String("Apply Color Balance"));
148
149 // --------------------------------------------------------
150
FilmTool(QObject * const parent)151 FilmTool::FilmTool(QObject* const parent)
152 : EditorToolThreaded(parent),
153 d(new Private)
154 {
155 setObjectName(QLatin1String("film"));
156 setToolName(i18n("Color Negative Film"));
157 setToolIcon(QIcon::fromTheme(QLatin1String("colorneg")));
158 setInitPreview(true);
159
160 ImageIface iface;
161 d->originalImage = iface.original();
162
163 d->histoSegments = d->originalImage->sixteenBit() ? 65535 : 255;
164 d->levels = new ImageLevels(d->originalImage->sixteenBit());
165
166 // -------------------------------------------------------------
167
168 d->previewWidget = new ImageRegionWidget;
169 setToolView(d->previewWidget);
170 setPreviewModeMask(PreviewToolBar::AllPreviewModes);
171
172 // -------------------------------------------------------------
173
174 d->gboxSettings = new EditorToolSettings(nullptr);
175 d->gboxSettings->setButtons(EditorToolSettings::Default|
176 EditorToolSettings::Ok|
177 EditorToolSettings::Cancel);
178
179 d->gboxSettings->setTools(EditorToolSettings::Histogram);
180 d->gboxSettings->setHistogramType(LRGBC);
181
182 // we don't need to use the Gradient in this tool
183
184 d->gboxSettings->histogramBox()->setGradientVisible(false);
185 d->gboxSettings->histogramBox()->setChannel(ColorChannels);
186
187 // -------------------------------------------------------------
188
189 d->levelsHistogramWidget = new HistogramWidget(256, 140, d->gboxSettings->plainPage(), false);
190 d->levelsHistogramWidget->updateData(*d->originalImage);
191
192 d->levelsHistogramWidget->setWhatsThis(i18n("This is the histogram drawing of the selected channel "
193 "from the original image."));
194 d->levelsHistogramWidget->setChannelType(ColorChannels);
195 QHBoxLayout* const inputLevelsLayout = new QHBoxLayout;
196 inputLevelsLayout->addWidget(d->levelsHistogramWidget);
197
198 // -------------------------------------------------------------
199
200 d->redInputLevels = new DGradientSlider();
201 d->redInputLevels->setColors(QColor("Red"), QColor("White"));
202 d->redInputLevels->setToolTip( i18n( "Input range of red color channel." ) );
203 d->redInputLevels->installEventFilter(this);
204
205 d->greenInputLevels = new DGradientSlider();
206 d->greenInputLevels->setColors(QColor("Green"), QColor("White"));
207 d->greenInputLevels->setToolTip( i18n( "Input range of green color channel." ) );
208 d->greenInputLevels->installEventFilter(this);
209
210 d->blueInputLevels = new DGradientSlider();
211 d->blueInputLevels->setColors(QColor("Blue"), QColor("White"));
212 d->blueInputLevels->setToolTip( i18n( "Input range of blue color channel." ) );
213 d->blueInputLevels->installEventFilter(this);
214
215 d->gboxSettings->histogramBox()->setHistogramMargin(d->redInputLevels->gradientOffset());
216
217 inputLevelsLayout->setContentsMargins(d->redInputLevels->gradientOffset(), 0,
218 d->redInputLevels->gradientOffset(), 0);
219
220 // -------------------------------------------------------------
221
222 d->cnType = new QListWidget();
223 QList<FilmContainer::ListItem*> profiles = d->filmContainer.profileItemList(d->cnType);
224 QList<FilmContainer::ListItem*>::ConstIterator it;
225
226 for (it = profiles.constBegin(); it != profiles.constEnd(); ++it)
227 d->cnType->addItem(*it);
228
229 // -------------------------------------------------------------
230
231 d->colorBalanceInput = new QCheckBox(i18n("Color Balance"));
232 d->colorBalanceInput->setCheckState(Qt::Checked);
233 d->colorBalanceInput->setToolTip(i18n("Check to apply the built-in color balance of the film profile. "
234 "Un-check if you want to apply color balance yourself."));
235
236 // -------------------------------------------------------------
237
238 d->pickWhitePoint = new QToolButton();
239 d->pickWhitePoint->setIcon(QIcon::fromTheme(QLatin1String("color-picker-white")));
240 d->pickWhitePoint->setCheckable(true);
241 d->pickWhitePoint->setToolTip( i18n( "White point color picker" ) );
242 d->pickWhitePoint->setWhatsThis(i18n("With this button, you can pick the color of the orange mask "
243 "of the scanned color negative. It represents white point of the negative, "
244 "or the darkest black tone of the positive image "
245 "after inversion. It is also the reference point for applying the film profile."));
246
247 d->resetButton = new QPushButton(i18n("&Reset"));
248 d->resetButton->setIcon(QIcon::fromTheme(QLatin1String("document-revert")));
249 d->resetButton->setToolTip( i18n( "Reset white point." ) );
250 d->resetButton->setWhatsThis(i18n("If you press this button, the white point is "
251 "reset to pure white."));
252
253 d->autoButton = new QToolButton();
254 d->autoButton->setIcon(QIcon::fromTheme(QLatin1String("system-run")));
255 d->autoButton->setToolTip( i18n( "Adjust white point automatically." ) );
256 d->autoButton->setWhatsThis(i18n("If you press this button, the white point is calculated "
257 "from the image data automatically. This function requires to have some residual "
258 "orange mask around the exposed area of the negative."));
259
260 QLabel* const space = new QLabel();
261 space->setFixedWidth(d->gboxSettings->spacingHint());
262
263 QHBoxLayout* const l3 = new QHBoxLayout();
264 l3->addWidget(d->pickWhitePoint);
265 l3->addWidget(d->autoButton);
266 l3->addWidget(space);
267 l3->addWidget(d->resetButton);
268 l3->addStretch(10);
269
270 // -------------------------------------------------------------
271
272 d->exposureInput = new DDoubleNumInput();
273 d->exposureInput->setDecimals(2);
274 d->exposureInput->setRange(0.0, 40.0, 0.01);
275 d->exposureInput->setDefaultValue(1.0);
276 d->exposureInput->setToolTip( i18n( "Exposure correction." ) );
277 d->exposureInput->setWhatsThis(i18n("Move the slider to higher values until maximum brightness is achieved "
278 "without clipping any color channel. Use the output histogram to evaluate each channel."));
279
280 d->gammaInput = new DDoubleNumInput();
281 d->gammaInput->setDecimals(2);
282 d->gammaInput->setRange(0.1, 3.0, 0.01);
283 d->gammaInput->setDefaultValue(1.8);
284 d->gammaInput->setToolTip(i18n( "Gamma input value." ));
285 d->gammaInput->setWhatsThis(i18n("Linear raw scans of film negatives require application of a gamma curve. "
286 "Standard values are 1.8 or 2.2."));
287
288 // -------------------------------------------------------------
289
290 QGridLayout* const grid = new QGridLayout();
291 grid->addLayout(inputLevelsLayout, 0, 0, 1, 4);
292 grid->addWidget(d->redInputLevels, 1, 0, 1, 4);
293 grid->addWidget(d->greenInputLevels, 2, 0, 1, 4);
294 grid->addWidget(d->blueInputLevels, 3, 0, 1, 4);
295 grid->addWidget(d->cnType, 4, 0, 1, 4);
296 grid->addWidget(d->exposureInput, 5, 0, 1, 4);
297 grid->addWidget(d->gammaInput, 6, 0, 1, 4);
298 grid->addLayout(l3, 7, 0, 1, 2);
299 grid->addWidget(d->colorBalanceInput, 7, 2, 1, 2, Qt::AlignRight);
300
301 // TODO: fill in rest of settings elements
302 //grid->setRowStretch(7, 10);
303 //grid->setColumnStretch(2, 10);
304 //grid->setColumnStretch(4, 10);
305
306 grid->setContentsMargins(QMargins());
307 grid->setSpacing(d->gboxSettings->spacingHint());
308 d->gboxSettings->plainPage()->setLayout(grid);
309
310 // -------------------------------------------------------------
311
312 d->filmContainer.setSixteenBit(d->originalImage->sixteenBit());
313 d->filmContainer.setWhitePoint(DColor(QColor(QLatin1String("white")), d->originalImage->sixteenBit()));
314
315 // -------------------------------------------------------------
316
317 setToolSettings(d->gboxSettings);
318
319 // Button Slots -------------------------------------------------
320
321 connect(d->autoButton, SIGNAL(clicked()),
322 this, SLOT(slotAutoWhitePoint()));
323
324 connect(d->pickWhitePoint, SIGNAL(toggled(bool)),
325 this, SLOT(slotPickerColorButtonActived(bool)));
326
327 // Slots --------------------------------------------------------
328
329 connect(d->previewWidget, SIGNAL(signalCapturedPointFromOriginal(Digikam::DColor,QPoint)),
330 this, SLOT(slotColorSelectedFromTarget(Digikam::DColor,QPoint)));
331
332 connect(d->exposureInput, SIGNAL(valueChanged(double)),
333 this, SLOT(slotExposureChanged(double)));
334
335 connect(d->gammaInput, SIGNAL(valueChanged(double)),
336 this, SLOT(slotGammaInputChanged(double)));
337
338 connect(d->resetButton, SIGNAL(clicked()),
339 this, SLOT(slotResetWhitePoint()));
340
341 connect(d->cnType, SIGNAL(itemActivated(QListWidgetItem*)),
342 this, SLOT(slotFilmItemActivated(QListWidgetItem*)));
343
344 connect(d->colorBalanceInput, SIGNAL(stateChanged(int)),
345 this, SLOT(slotColorBalanceStateChanged(int)));
346 }
347
~FilmTool()348 FilmTool::~FilmTool()
349 {
350 delete d->levels;
351 delete d;
352 }
353
slotResetSettings()354 void FilmTool::slotResetSettings()
355 {
356 bool sb = d->originalImage->sixteenBit();
357 int max = sb ? 65535 : 255;
358
359 FilmContainer::CNFilmProfile cnType = FilmContainer::CNNeutral;
360
361 QString profileName = QLatin1String("Neutral");
362 QList<QListWidgetItem*> matchingItems = d->cnType->findItems(profileName, Qt::MatchExactly);
363 d->cnType->setCurrentItem(matchingItems.first());
364
365 double gamma = 1.8;
366 d->gammaInput->setValue(gamma);
367 gammaInputChanged(gamma);
368
369 double exposure = 1.0;
370 d->exposureInput->setValue(exposure);
371
372 d->filmContainer = FilmContainer(cnType, gamma, d->originalImage->sixteenBit());
373 d->filmContainer.setExposure(exposure);
374
375 int red = max;
376 int green = max;
377 int blue = max;
378
379 red = sb ? red : red / 256;
380 green = sb ? green : green / 256;
381 blue = sb ? blue : blue / 256;
382
383 DColor whitePoint = DColor(red, green, blue, max, sb);
384 d->filmContainer.setWhitePoint(whitePoint);
385 setLevelsFromFilm();
386
387 d->levelsHistogramWidget->reset();
388 d->gboxSettings->histogramBox()->histogram()->reset();
389 d->gboxSettings->histogramBox()->setChannel(ColorChannels);
390 d->gboxSettings->histogramBox()->setScale(LogScaleHistogram);
391
392 slotAdjustSliders();
393 slotChannelChanged();
394 slotScaleChanged();
395 }
396
slotChannelChanged()397 void FilmTool::slotChannelChanged()
398 {
399 d->levelsHistogramWidget->setChannelType(d->gboxSettings->histogramBox()->channel());
400 }
401
slotScaleChanged()402 void FilmTool::slotScaleChanged()
403 {
404 d->levelsHistogramWidget->setScaleType(d->gboxSettings->histogramBox()->scale());
405 }
406
slotAdjustSliders()407 void FilmTool::slotAdjustSliders()
408 {
409 // adjust all Levels sliders
410
411 d->redInputLevels->setLeftValue(
412 (double)d->levels->getLevelLowInputValue(RedChannel) / d->histoSegments);
413 d->redInputLevels->setRightValue(
414 (double)d->levels->getLevelHighInputValue(RedChannel) / d->histoSegments);
415
416 d->greenInputLevels->setLeftValue(
417 (double)d->levels->getLevelLowInputValue(GreenChannel) / d->histoSegments);
418 d->greenInputLevels->setRightValue(
419 (double)d->levels->getLevelHighInputValue(GreenChannel) / d->histoSegments);
420
421 d->blueInputLevels->setLeftValue(
422 (double)d->levels->getLevelLowInputValue(BlueChannel) / d->histoSegments);
423 d->blueInputLevels->setRightValue(
424 (double)d->levels->getLevelHighInputValue(BlueChannel) / d->histoSegments);
425 }
426
setLevelsFromFilm()427 void FilmTool::setLevelsFromFilm()
428 {
429 LevelsContainer l = d->filmContainer.toLevels();
430
431 for (int i = RedChannel ; i <= BlueChannel ; ++i)
432 {
433 d->levels->setLevelLowInputValue(i, l.lInput[i]);
434 d->levels->setLevelHighInputValue(i, l.hInput[i]);
435 d->levels->setLevelLowOutputValue(i, l.lOutput[i]);
436 d->levels->setLevelHighOutputValue(i, l.hOutput[i]);
437 d->levels->setLevelGammaValue(i, l.gamma[i]);
438 }
439
440 slotAdjustSliders();
441 }
442
slotExposureChanged(double val)443 void FilmTool::slotExposureChanged(double val)
444 {
445 d->filmContainer.setExposure(val);
446 setLevelsFromFilm();
447 slotTimer();
448 }
449
gammaInputChanged(double val)450 void FilmTool::gammaInputChanged(double val)
451 {
452 d->filmContainer.setGamma(val);
453 setLevelsFromFilm();
454 }
455
slotGammaInputChanged(double val)456 void FilmTool::slotGammaInputChanged(double val)
457 {
458 gammaInputChanged(val);
459 slotTimer();
460 }
461
slotFilmItemActivated(QListWidgetItem * item)462 void FilmTool::slotFilmItemActivated(QListWidgetItem* item)
463 {
464 double gamma = d->filmContainer.gamma();
465 double strength = d->filmContainer.exposure();
466 DColor wp = d->filmContainer.whitePoint();
467
468 FilmContainer::CNFilmProfile type = (FilmContainer::CNFilmProfile)(item->type()-QListWidgetItem::UserType);
469 d->filmContainer = FilmContainer(type, gamma, d->originalImage->sixteenBit());
470 d->filmContainer.setExposure(strength);
471 d->filmContainer.setApplyBalance(d->colorBalanceInput->checkState() == Qt::Checked);
472 d->filmContainer.setWhitePoint(wp);
473 setLevelsFromFilm();
474 slotTimer();
475 }
476
slotColorSelectedFromTarget(const Digikam::DColor & color,const QPoint & p)477 void FilmTool::slotColorSelectedFromTarget(const Digikam::DColor& color, const QPoint& p)
478 {
479 DColor wp00 = color;
480 DColor wp01 = d->originalImage->getPixelColor(p.x(), p.y()+1);
481 DColor wp10 = d->originalImage->getPixelColor(p.x()+1, p.y());
482 DColor wp11 = d->originalImage->getPixelColor(p.x()+1, p.y()+1);
483
484 wp00.blendAdd(wp01);
485 wp00.blendAdd(wp10);
486 wp00.blendAdd(wp11);
487 wp00.multiply(0.25);
488
489 d->filmContainer.setWhitePoint(wp00);
490 d->previewWidget->setCapturePointMode(false);
491 d->pickWhitePoint->setChecked(false);
492
493 setLevelsFromFilm();
494 slotTimer();
495 }
496
slotPickerColorButtonActived(bool checked)497 void FilmTool::slotPickerColorButtonActived(bool checked)
498 {
499 if (checked)
500 {
501 d->previewWidget->setCapturePointMode(true);
502 }
503 }
504
slotAutoWhitePoint()505 void FilmTool::slotAutoWhitePoint()
506 {
507 ImageHistogram* const hist = d->levelsHistogramWidget->currentHistogram();
508 bool sixteenBit = d->originalImage->sixteenBit();
509 int high_input[4];
510
511 for (int channel = RedChannel ; channel <= BlueChannel ; ++channel)
512 {
513 double new_count = 0.0;
514 double percentage;
515 double next_percentage;
516 double count = hist->getCount(channel, 0, sixteenBit ? 65535 : 255);
517
518 for (int i = (sixteenBit ? 65535 : 255) ; i > 0 ; --i)
519 {
520 new_count += hist->getValue(channel, i);
521 percentage = new_count / count;
522 next_percentage = (new_count + hist->getValue(channel, i - 1)) / count;
523
524 if (fabs(percentage - 0.006) < fabs(next_percentage - 0.006))
525 {
526 high_input[channel] = i - 1;
527 break;
528 }
529 }
530 }
531
532 DColor wp = DColor(high_input[RedChannel],
533 high_input[GreenChannel],
534 high_input[BlueChannel],
535 0,
536 sixteenBit);
537
538 d->filmContainer.setWhitePoint(wp);
539
540 setLevelsFromFilm();
541 slotPreview();
542 }
543
slotResetWhitePoint()544 void FilmTool::slotResetWhitePoint()
545 {
546 d->filmContainer.setSixteenBit(d->originalImage->sixteenBit());
547 d->filmContainer.setWhitePoint(DColor(QColor(QLatin1String("white")), d->originalImage->sixteenBit()));
548
549 setLevelsFromFilm();
550 slotPreview();
551 }
552
slotColorBalanceStateChanged(int state)553 void FilmTool::slotColorBalanceStateChanged(int state)
554 {
555 bool apply = (state == Qt::Checked);
556 d->filmContainer.setApplyBalance(apply);
557
558 slotPreview();
559 }
560
readSettings()561 void FilmTool::readSettings()
562 {
563 KSharedConfig::Ptr config = KSharedConfig::openConfig();
564 KConfigGroup group = config->group(d->configGroupName);
565
566 bool sb = d->originalImage->sixteenBit();
567 int max = sb ? 65535 : 255;
568
569 FilmContainer::CNFilmProfile cnType = (FilmContainer::CNFilmProfile)
570 group.readEntry(d->configFilmProfileEntry, (int)FilmContainer::CNNeutral);
571
572 QString profileName = group.readEntry(d->configFilmProfileName, "Neutral");
573 QList<QListWidgetItem*> matchingItems = d->cnType->findItems(profileName, Qt::MatchExactly);
574 d->cnType->setCurrentItem(matchingItems.first());
575
576 double gamma = group.readEntry(d->configGammaInputEntry, 1.8);
577 d->gammaInput->setValue(gamma);
578 gammaInputChanged(gamma);
579
580 double exposure = group.readEntry(d->configExposureEntry, 1.0);
581 d->exposureInput->setValue(exposure);
582
583 d->filmContainer = FilmContainer(cnType, gamma, d->originalImage->sixteenBit());
584 d->filmContainer.setExposure(exposure);
585
586 int red = group.readEntry(d->configWhitePointEntry.arg(1), max);
587 int green = group.readEntry(d->configWhitePointEntry.arg(2), max);
588 int blue = group.readEntry(d->configWhitePointEntry.arg(3), max);
589
590 red = sb ? red : red / 256;
591 green = sb ? green : green / 256;
592 blue = sb ? blue : blue / 256;
593
594 DColor whitePoint = DColor(red, green, blue, max, sb);
595 d->filmContainer.setWhitePoint(whitePoint);
596 setLevelsFromFilm();
597
598 bool apply = group.readEntry(d->configApplyColorBalance, true);
599 d->filmContainer.setApplyBalance(apply);
600 d->colorBalanceInput->setCheckState(apply? Qt::Checked : Qt::Unchecked);
601
602 d->levelsHistogramWidget->reset();
603 d->gboxSettings->histogramBox()->histogram()->reset();
604
605 ChannelType ch = (ChannelType)group.readEntry(d->configHistogramChannelEntry, (int)ColorChannels);
606
607 // restore the previous channel
608 d->gboxSettings->histogramBox()->setChannel(ch);
609
610 d->gboxSettings->histogramBox()->setScale((HistogramScale)group.readEntry(d->configHistogramScaleEntry,
611 (int)LogScaleHistogram));
612
613 slotAdjustSliders();
614 slotChannelChanged();
615 slotScaleChanged();
616 }
617
writeSettings()618 void FilmTool::writeSettings()
619 {
620 KSharedConfig::Ptr config = KSharedConfig::openConfig();
621 KConfigGroup group = config->group(d->configGroupName);
622 bool sb = d->originalImage->sixteenBit();
623
624 group.writeEntry(d->configHistogramChannelEntry, (int)d->gboxSettings->histogramBox()->channel());
625 group.writeEntry(d->configHistogramScaleEntry, (int)d->gboxSettings->histogramBox()->scale());
626
627 double gamma = d->gammaInput->value();
628 group.writeEntry(d->configGammaInputEntry, gamma);
629
630 double exposure = d->exposureInput->value();
631 group.writeEntry(d->configExposureEntry, exposure);
632
633 int cnType = (int)d->filmContainer.cnType();
634 group.writeEntry(d->configFilmProfileEntry, cnType);
635
636 group.writeEntry(d->configFilmProfileName, d->cnType->currentItem()->text());
637
638 int red = d->filmContainer.whitePoint().red();
639 int green = d->filmContainer.whitePoint().green();
640 int blue = d->filmContainer.whitePoint().blue();
641
642 group.writeEntry(d->configWhitePointEntry.arg(1), sb ? red : red * 256);
643 group.writeEntry(d->configWhitePointEntry.arg(2), sb ? green : green * 256);
644 group.writeEntry(d->configWhitePointEntry.arg(3), sb ? blue : blue * 256);
645
646 bool apply = d->colorBalanceInput->checkState() == Qt::Checked;
647 group.writeEntry(d->configApplyColorBalance, apply);
648 config->sync();
649 }
650
preparePreview()651 void FilmTool::preparePreview()
652 {
653 d->gboxSettings->histogramBox()->histogram()->stopHistogramComputation();
654
655 DImg preview = d->previewWidget->getOriginalRegionImage(true);
656 setFilter(new FilmFilter(&preview, this, d->filmContainer));
657 }
658
prepareFinal()659 void FilmTool::prepareFinal()
660 {
661 ImageIface iface;
662 setFilter(new FilmFilter(iface.original(), this, d->filmContainer));
663 }
664
setPreviewImage()665 void FilmTool::setPreviewImage()
666 {
667 DImg preview = filter()->getTargetImage();
668 d->previewWidget->setPreviewImage(preview);
669
670 // Update histogram.
671
672 d->gboxSettings->histogramBox()->histogram()->updateData(preview.copy(), DImg(), false);
673 }
674
setFinalImage()675 void FilmTool::setFinalImage()
676 {
677 ImageIface iface;
678 iface.setOriginal(i18n("Film"), filter()->filterAction(), filter()->getTargetImage());
679 }
680
eventFilter(QObject * obj,QEvent * ev)681 bool FilmTool::eventFilter(QObject* obj, QEvent* ev)
682 {
683 // Swallow mouse evens for level sliders to make them immutable
684
685 if ((obj == d->redInputLevels) || (obj == d->greenInputLevels) || (obj == d->blueInputLevels))
686 {
687 if ((ev->type() == QEvent::MouseButtonPress) ||
688 (ev->type() == QEvent::MouseButtonRelease) ||
689 (ev->type() == QEvent::MouseMove) ||
690 (ev->type() == QEvent::MouseButtonDblClick))
691 {
692 return true;
693 }
694 }
695
696 // pass all other events to the parent class
697
698 return EditorToolThreaded::eventFilter(obj, ev);
699 }
700
701 } // namespace DigikamEditorFilmToolPlugin
702