diff options
Diffstat (limited to 'src/utilities/imageeditor/rawimport')
-rw-r--r-- | src/utilities/imageeditor/rawimport/Makefile.am | 27 | ||||
-rw-r--r-- | src/utilities/imageeditor/rawimport/rawimport.cpp | 223 | ||||
-rw-r--r-- | src/utilities/imageeditor/rawimport/rawimport.h | 88 | ||||
-rw-r--r-- | src/utilities/imageeditor/rawimport/rawpostprocessing.cpp | 137 | ||||
-rw-r--r-- | src/utilities/imageeditor/rawimport/rawpostprocessing.h | 63 | ||||
-rw-r--r-- | src/utilities/imageeditor/rawimport/rawpreview.cpp | 336 | ||||
-rw-r--r-- | src/utilities/imageeditor/rawimport/rawpreview.h | 108 | ||||
-rw-r--r-- | src/utilities/imageeditor/rawimport/rawsettingsbox.cpp | 741 | ||||
-rw-r--r-- | src/utilities/imageeditor/rawimport/rawsettingsbox.h | 91 |
9 files changed, 1814 insertions, 0 deletions
diff --git a/src/utilities/imageeditor/rawimport/Makefile.am b/src/utilities/imageeditor/rawimport/Makefile.am new file mode 100644 index 00000000..19071935 --- /dev/null +++ b/src/utilities/imageeditor/rawimport/Makefile.am @@ -0,0 +1,27 @@ +METASOURCES = AUTO + +noinst_LTLIBRARIES = librawimport.la + +librawimport_la_SOURCES = rawpreview.cpp rawsettingsbox.cpp rawimport.cpp \ + rawpostprocessing.cpp + +librawimport_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_TDEPRINT) + +INCLUDES= -I$(top_srcdir)/src/digikam \ + -I$(top_srcdir)/src/utilities/imageeditor/editor \ + -I$(top_srcdir)/src/libs/histogram \ + -I$(top_srcdir)/src/libs/curves \ + -I$(top_srcdir)/src/libs/levels \ + -I$(top_srcdir)/src/libs/whitebalance \ + -I$(top_srcdir)/src/libs/dmetadata \ + -I$(top_srcdir)/src/libs/curves \ + -I$(top_srcdir)/src/libs/dimg \ + -I$(top_srcdir)/src/libs/dimg/filters \ + -I$(top_srcdir)/src/libs/dialogs \ + -I$(top_srcdir)/src/libs/widgets/common \ + -I$(top_srcdir)/src/libs/widgets/iccprofiles \ + -I$(top_srcdir)/src/libs/threadimageio \ + -I$(top_srcdir)/src/libs/themeengine \ + $(LIBKDCRAW_CFLAGS) \ + $(all_includes) + diff --git a/src/utilities/imageeditor/rawimport/rawimport.cpp b/src/utilities/imageeditor/rawimport/rawimport.cpp new file mode 100644 index 00000000..a9254ce8 --- /dev/null +++ b/src/utilities/imageeditor/rawimport/rawimport.cpp @@ -0,0 +1,223 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2008-08-20 + * Description : Raw import tool + * + * Copyright (C) 2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ============================================================ */ + +// TQt includes. + +#include <tqstring.h> +#include <tqlayout.h> +#include <tqtooltip.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <kcursor.h> +#include <tdelocale.h> +#include <tdeconfig.h> +#include <tdeapplication.h> +#include <kiconloader.h> +#include <kstandarddirs.h> + +// Local includes. + +#include "ddebug.h" +#include "drawdecoding.h" +#include "histogramwidget.h" +#include "curveswidget.h" +#include "imagehistogram.h" +#include "rawsettingsbox.h" +#include "rawpostprocessing.h" +#include "editortooliface.h" +#include "rawpreview.h" +#include "rawimport.h" +#include "rawimport.moc" + +namespace Digikam +{ + +class RawImportPriv +{ +public: + + RawImportPriv() + { + previewWidget = 0; + settingsBox = 0; + } + + RawSettingsBox *settingsBox; + + RawPreview *previewWidget; +}; + +RawImport::RawImport(const KURL& url, TQObject *parent) + : EditorToolThreaded(parent) +{ + d = new RawImportPriv; + d->previewWidget = new RawPreview(url, 0); + d->settingsBox = new RawSettingsBox(url, 0); + + setToolName(i18n("Raw Import")); + setToolIcon(SmallIcon("kdcraw")); + setProgressMessage(i18n("Post Processing")); + setToolView(d->previewWidget); + setToolSettings(d->settingsBox); + + init(); +} + +RawImport::~RawImport() +{ + delete d; +} + +void RawImport::slotInit() +{ + EditorToolThreaded::slotInit(); + + // --------------------------------------------------------------- + + connect(d->previewWidget, TQ_SIGNAL(signalLoadingStarted()), + this, TQ_SLOT(slotLoadingStarted())); + + connect(d->previewWidget, TQ_SIGNAL(signalDemosaicedImage()), + this, TQ_SLOT(slotDemosaicedImage())); + + connect(d->previewWidget, TQ_SIGNAL(signalLoadingStarted()), + this, TQ_SLOT(slotLoadingStarted())); + + connect(d->previewWidget, TQ_SIGNAL(signalLoadingProgress(float)), + this, TQ_SLOT(slotLoadingProgress(float))); + + connect(d->previewWidget, TQ_SIGNAL(signalLoadingFailed()), + this, TQ_SLOT(slotLoadingFailed())); + + connect(d->settingsBox, TQ_SIGNAL(signalDemosaicingChanged()), + this, TQ_SLOT(slotDemosaicingChanged())); + + connect(d->settingsBox, TQ_SIGNAL(signalPostProcessingChanged()), + this, TQ_SLOT(slotTimer())); + + connect(d->settingsBox, TQ_SIGNAL(signalUpdatePreview()), + this, TQ_SLOT(slotUpdatePreview())); + + connect(d->settingsBox, TQ_SIGNAL(signalAbortPreview()), + this, TQ_SLOT(slotAbort())); + + // --------------------------------------------------------------- + + setBusy(true); + slotUpdatePreview(); +} + +void RawImport::setBusy(bool val) +{ + if (val) d->previewWidget->setCursor(KCursor::waitCursor()); + else d->previewWidget->unsetCursor(); + d->settingsBox->setBusy(val); +} + +DRawDecoding RawImport::rawDecodingSettings() +{ + return d->settingsBox->settings(); +} + +void RawImport::slotUpdatePreview() +{ + DRawDecoding settings = rawDecodingSettings(); + // We will load an half size image to speed up preview computing. + settings.halfSizeColorImage = true; + + d->previewWidget->setDecodingSettings(settings); +} + +void RawImport::slotAbort() +{ + // If preview loading, don't play with threaded filter interface. + if (renderingMode() == EditorToolThreaded::NoneRendering) + { + d->previewWidget->cancelLoading(); + d->settingsBox->histogram()->stopHistogramComputation(); + EditorToolIface::editorToolIface()->setToolStopProgress(); + setBusy(false); + return; + } + + EditorToolThreaded::slotAbort(); +} + +void RawImport::slotLoadingStarted() +{ + d->settingsBox->enableUpdateBtn(false); + d->settingsBox->histogram()->setDataLoading(); + d->settingsBox->curve()->setDataLoading(); + EditorToolIface::editorToolIface()->setToolStartProgress(i18n("Raw Decoding")); + setBusy(true); +} + +void RawImport::slotDemosaicedImage() +{ + d->settingsBox->setDemosaicedImage(d->previewWidget->demosaicedImage()); + slotEffect(); +} + +void RawImport::prepareEffect() +{ + DImg postImg = d->previewWidget->demosaicedImage(); + setFilter(dynamic_cast<DImgThreadedFilter*>(new RawPostProcessing(&postImg, this, rawDecodingSettings()))); +} + +void RawImport::putPreviewData() +{ + d->previewWidget->setPostProcessedImage(filter()->getTargetImage()); + d->settingsBox->setPostProcessedImage(d->previewWidget->postProcessedImage()); + EditorToolIface::editorToolIface()->setToolStopProgress(); + setBusy(false); +} + +void RawImport::slotLoadingFailed() +{ + d->settingsBox->histogram()->setLoadingFailed(); + EditorToolIface::editorToolIface()->setToolStopProgress(); + setBusy(false); +} + +void RawImport::slotDemosaicingChanged() +{ + d->settingsBox->enableUpdateBtn(true); +} + +void RawImport::slotLoadingProgress(float v) +{ + EditorToolIface::editorToolIface()->setToolProgress((int)(v*100)); +} + +void RawImport::slotOk() +{ + EditorTool::slotOk(); +} + +void RawImport::slotCancel() +{ + EditorTool::slotCancel(); +} + +} // NameSpace Digikam diff --git a/src/utilities/imageeditor/rawimport/rawimport.h b/src/utilities/imageeditor/rawimport/rawimport.h new file mode 100644 index 00000000..85255bc8 --- /dev/null +++ b/src/utilities/imageeditor/rawimport/rawimport.h @@ -0,0 +1,88 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2008-08-20 + * Description : Raw import tool + * + * Copyright (C) 2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ============================================================ */ + +#ifndef RAWIMPORTDLG_H +#define RAWIMPORTDLG_H + +// KDE includes. + +#include <kurl.h> + +// Local includes. + +#include "editortool.h" +#include "dimg.h" +#include "digikam_export.h" + +namespace KDcrawIface +{ +class RawDecodingSettings; +} + +namespace Digikam +{ + +class RawImportPriv; + +class DIGIKAM_EXPORT RawImport : public EditorToolThreaded +{ + TQ_OBJECT + + +public: + + RawImport(const KURL& url, TQObject *parent); + ~RawImport(); + + DRawDecoding rawDecodingSettings(); + +private: + + void setBusy(bool busy); + void prepareEffect(); + void putPreviewData(); + +private slots: + + void slotInit(); + + void slotLoadingStarted(); + void slotDemosaicedImage(); + void slotLoadingFailed(); + void slotLoadingProgress(float); + + void slotUpdatePreview(); + void slotAbort(); + + void slotDemosaicingChanged(); + + void slotOk(); + void slotCancel(); + +private: + + RawImportPriv *d; +}; + +} // NameSpace Digikam + +#endif // RAWIMPORTDLG_H diff --git a/src/utilities/imageeditor/rawimport/rawpostprocessing.cpp b/src/utilities/imageeditor/rawimport/rawpostprocessing.cpp new file mode 100644 index 00000000..d45dd5e4 --- /dev/null +++ b/src/utilities/imageeditor/rawimport/rawpostprocessing.cpp @@ -0,0 +1,137 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2008-13-08 + * Description : Raw post processing corrections. + * + * Copyright (C) 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. + * + * ============================================================ */ + +// Local includes. + +#include "ddebug.h" +#include "imagehistogram.h" +#include "imagecurves.h" +#include "imagelevels.h" +#include "bcgmodifier.h" +#include "whitebalance.h" +#include "dimgimagefilters.h" +#include "rawpostprocessing.h" + +namespace Digikam +{ + +RawPostProcessing::RawPostProcessing(DImg *orgImage, TQObject *parent, const DRawDecoding& settings) + : DImgThreadedFilter(orgImage, parent, "RawPostProcessing") +{ + m_customRawSettings = settings; + initFilter(); +} + +RawPostProcessing::RawPostProcessing(DImgThreadedFilter *parentFilter, + const DImg &orgImage, const DImg &destImage, + int progressBegin, int progressEnd, const DRawDecoding& settings) + : DImgThreadedFilter(parentFilter, orgImage, destImage, progressBegin, progressEnd, + parentFilter->filterName() + ": RawPostProcessing") +{ + m_customRawSettings = settings; + filterImage(); +} + +void RawPostProcessing::filterImage() +{ + rawPostProcessing(); +} + +void RawPostProcessing::rawPostProcessing() +{ + if (!m_orgImage.bits() || !m_orgImage.width() || !m_orgImage.height()) + { + DWarning() << ("RawPostProcessing::rawPostProcessing: no image m_orgImage.bits() available!") + << endl; + return; + } + + if (!m_customRawSettings.postProcessingSettingsIsDirty()) + { + m_destImage = m_orgImage; + return; + } + + postProgress(15); + + if (m_customRawSettings.exposureComp != 0.0 || m_customRawSettings.saturation != 1.0) + { + WhiteBalance wb(m_orgImage.sixteenBit()); + wb.whiteBalance(m_orgImage.bits(), m_orgImage.width(), m_orgImage.height(), m_orgImage.sixteenBit(), + 0.0, // black + m_customRawSettings.exposureComp, // exposure + 6500.0, // temperature (neutral) + 1.0, // green + 0.5, // dark + 1.0, // gamma + m_customRawSettings.saturation); // saturation + } + postProgress(30); + + if (m_customRawSettings.lightness != 0.0 || m_customRawSettings.contrast != 1.0 || m_customRawSettings.gamma != 1.0) + { + BCGModifier bcg; + bcg.setBrightness(m_customRawSettings.lightness); + bcg.setContrast(m_customRawSettings.contrast); + bcg.setGamma(m_customRawSettings.gamma); + bcg.applyBCG(m_orgImage.bits(), m_orgImage.width(), m_orgImage.height(), m_orgImage.sixteenBit()); + } + postProgress(45); + + if (!m_customRawSettings.curveAdjust.isEmpty()) + { + DImg tmp(m_orgImage.width(), m_orgImage.height(), m_orgImage.sixteenBit()); + ImageCurves curves(m_orgImage.sixteenBit()); + curves.setCurvePoints(ImageHistogram::ValueChannel, m_customRawSettings.curveAdjust); + curves.curvesCalculateCurve(ImageHistogram::ValueChannel); + curves.curvesLutSetup(ImageHistogram::AlphaChannel); + curves.curvesLutProcess(m_orgImage.bits(), tmp.bits(), m_orgImage.width(), m_orgImage.height()); + memcpy(m_orgImage.bits(), tmp.bits(), tmp.numBytes()); + } + postProgress(60); + + if (!m_customRawSettings.levelsAdjust.isEmpty()) + { + DImg tmp(m_orgImage.width(), m_orgImage.height(), m_orgImage.sixteenBit()); + ImageLevels levels(m_orgImage.sixteenBit()); + int j=0; + for (int i = 0 ; i < 4; i++) + { + levels.setLevelLowInputValue(i, m_customRawSettings.levelsAdjust[j++]); + levels.setLevelHighInputValue(i, m_customRawSettings.levelsAdjust[j++]); + levels.setLevelLowOutputValue(i, m_customRawSettings.levelsAdjust[j++]); + levels.setLevelHighOutputValue(i, m_customRawSettings.levelsAdjust[j++]); + } + + levels.levelsLutSetup(ImageHistogram::AlphaChannel); + levels.levelsLutProcess(m_orgImage.bits(), tmp.bits(), m_orgImage.width(), m_orgImage.height()); + memcpy(m_orgImage.bits(), tmp.bits(), tmp.numBytes()); + } + postProgress(75); + + m_destImage = m_orgImage; + + postProgress(100); +} + +} // NameSpace Digikam diff --git a/src/utilities/imageeditor/rawimport/rawpostprocessing.h b/src/utilities/imageeditor/rawimport/rawpostprocessing.h new file mode 100644 index 00000000..3b3c7761 --- /dev/null +++ b/src/utilities/imageeditor/rawimport/rawpostprocessing.h @@ -0,0 +1,63 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2008-13-08 + * Description : Raw post processing corrections. + * + * Copyright (C) 2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ============================================================ */ + +#ifndef RAWPOSTPROCESSING_H +#define RAWPOSTPROCESSING_H + +// Digikam includes. + +#include "digikam_export.h" + +// Local includes. + +#include "dimgthreadedfilter.h" + +namespace Digikam +{ + +class DIGIKAM_EXPORT RawPostProcessing : public DImgThreadedFilter +{ + +public: + + RawPostProcessing(DImg *orgImage, TQObject *parent=0, const DRawDecoding& settings=DRawDecoding()); + + // Constructor for slave mode: execute immediately in current thread with specified master filter + RawPostProcessing(DImgThreadedFilter *parentFilter, const DImg &orgImage, const DImg &destImage, + int progressBegin=0, int progressEnd=100, const DRawDecoding& settings=DRawDecoding()); + + ~RawPostProcessing(){}; + +private: + + virtual void filterImage(); + void rawPostProcessing(); + +private: + + DRawDecoding m_customRawSettings; +}; + +} // NameSpace Digikam + +#endif /* RAWPOSTPROCESSING_H */ diff --git a/src/utilities/imageeditor/rawimport/rawpreview.cpp b/src/utilities/imageeditor/rawimport/rawpreview.cpp new file mode 100644 index 00000000..3207ba14 --- /dev/null +++ b/src/utilities/imageeditor/rawimport/rawpreview.cpp @@ -0,0 +1,336 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2008-08-04 + * Description : RAW postProcessedImg widget. + * + * Copyright (C) 2008 Gilles Caulier <caulier dot gilles at gmail dot com> + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ============================================================ */ + +// TQt includes. + +#include <tqstring.h> +#include <tqpainter.h> +#include <tqtoolbutton.h> +#include <tqtooltip.h> +#include <tqpixmap.h> +#include <tqfileinfo.h> + +// KDE includes. + +#include <tdelocale.h> +#include <kcursor.h> +#include <kdatetbl.h> +#include <kiconloader.h> + +// Local includes. + +#include "ddebug.h" +#include "paniconwidget.h" +#include "managedloadsavethread.h" +#include "loadingdescription.h" +#include "themeengine.h" +#include "rawpreview.h" +#include "rawpreview.moc" + +namespace Digikam +{ + +class RawPreviewPriv +{ +public: + + RawPreviewPriv() + { + panIconPopup = 0; + panIconWidget = 0; + cornerButton = 0; + thread = 0; + url = 0; + currentFitWindowZoom = 0; + } + + double currentFitWindowZoom; + + TQToolButton *cornerButton; + + TDEPopupFrame *panIconPopup; + + KURL url; + + PanIconWidget *panIconWidget; + + DImg demosaicedImg; + + DImg postProcessedImg; + + DRawDecoding settings; + + ManagedLoadSaveThread *thread; + + LoadingDescription loadingDesc; +}; + +RawPreview::RawPreview(const KURL& url, TQWidget *parent) + : PreviewWidget(parent) +{ + d = new RawPreviewPriv; + d->thread = new ManagedLoadSaveThread; + d->url = url; + + setMinimumWidth(500); + setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Expanding); + + d->cornerButton = new TQToolButton(this); + d->cornerButton->setIconSet(SmallIcon("move")); + d->cornerButton->hide(); + TQToolTip::add(d->cornerButton, i18n("Pan the image to a region")); + setCornerWidget(d->cornerButton); + + // ------------------------------------------------------------ + + connect(d->thread, TQ_SIGNAL(signalImageLoaded(const LoadingDescription&, const DImg&)), + this, TQ_SLOT(slotImageLoaded(const LoadingDescription&, const DImg&))); + + connect(d->thread, TQ_SIGNAL(signalLoadingProgress(const LoadingDescription&, float)), + this, TQ_SLOT(slotLoadingProgress(const LoadingDescription&, float))); + + connect(d->cornerButton, TQ_SIGNAL(pressed()), + this, TQ_SLOT(slotCornerButtonPressed())); + + connect(ThemeEngine::instance(), TQ_SIGNAL(signalThemeChanged()), + this, TQ_SLOT(slotThemeChanged())); + + // ------------------------------------------------------------ + + slotReset(); +} + +RawPreview::~RawPreview() +{ + delete d; +} + +void RawPreview::setPostProcessedImage(const DImg& image) +{ + d->postProcessedImg = image; + + updateZoomAndSize(false); + + viewport()->setUpdatesEnabled(true); + viewport()->update(); +} + +DImg& RawPreview::postProcessedImage() const +{ + return d->postProcessedImg; +} + +DImg& RawPreview::demosaicedImage() const +{ + return d->demosaicedImg; +} + +void RawPreview::setDecodingSettings(const DRawDecoding& settings) +{ + // Save post processing settings. + d->settings = settings; + + // All post processing settings will be used after demosaicing. + DRawDecoding demosaisedSettings = settings; + demosaisedSettings.resetPostProcessingSettings(); + + d->loadingDesc = LoadingDescription(d->url.path(), demosaisedSettings); + d->thread->load(d->loadingDesc, ManagedLoadSaveThread::LoadingPolicyFirstRemovePrevious); + emit signalLoadingStarted(); +} + +void RawPreview::cancelLoading() +{ + d->thread->stopLoading(d->loadingDesc); +} + +void RawPreview::slotLoadingProgress(const LoadingDescription& description, float progress) +{ + if (description.filePath != d->loadingDesc.filePath) + return; + + emit signalLoadingProgress(progress); +} + +void RawPreview::slotImageLoaded(const LoadingDescription& description, const DImg& image) +{ + if (description.filePath != d->loadingDesc.filePath) + return; + + if (image.isNull()) + { + TQPixmap pix(visibleWidth(), visibleHeight()); + pix.fill(ThemeEngine::instance()->baseColor()); + TQPainter p(&pix); + p.setPen(TQPen(ThemeEngine::instance()->textRegColor())); + p.drawText(0, 0, pix.width(), pix.height(), + TQt::AlignCenter|TQt::WordBreak, + i18n("Cannot decode RAW image for\n\"%1\"") + .arg(TQFileInfo(d->loadingDesc.filePath).fileName())); + p.end(); + // three copies - but the image is small + setPostProcessedImage(DImg(pix.convertToImage())); + emit signalLoadingFailed(); + } + else + { + d->demosaicedImg = image; + emit signalDemosaicedImage(); + // NOTE: we will apply all Raw post processing corrections into RawImport class. + } +} + +void RawPreview::slotThemeChanged() +{ + setBackgroundColor(ThemeEngine::instance()->baseColor()); +} + +void RawPreview::slotCornerButtonPressed() +{ + if (d->panIconPopup) + { + d->panIconPopup->hide(); + delete d->panIconPopup; + d->panIconPopup = 0; + } + + d->panIconPopup = new TDEPopupFrame(this); + PanIconWidget *pan = new PanIconWidget(d->panIconPopup); + pan->setImage(180, 120, postProcessedImage()); + d->panIconPopup->setMainWidget(pan); + + TQRect r((int)(contentsX() / zoomFactor()), (int)(contentsY() / zoomFactor()), + (int)(visibleWidth() / zoomFactor()), (int)(visibleHeight() / zoomFactor())); + pan->setRegionSelection(r); + pan->setMouseFocus(); + + connect(pan, TQ_SIGNAL(signalSelectionMoved(const TQRect&, bool)), + this, TQ_SLOT(slotPanIconSelectionMoved(const TQRect&, bool))); + + connect(pan, TQ_SIGNAL(signalHiden()), + this, TQ_SLOT(slotPanIconHiden())); + + TQPoint g = mapToGlobal(viewport()->pos()); + g.setX(g.x()+ viewport()->size().width()); + g.setY(g.y()+ viewport()->size().height()); + d->panIconPopup->popup(TQPoint(g.x() - d->panIconPopup->width(), + g.y() - d->panIconPopup->height())); + + pan->setCursorToLocalRegionSelectionCenter(); +} + +void RawPreview::slotPanIconHiden() +{ + d->cornerButton->blockSignals(true); + d->cornerButton->animateClick(); + d->cornerButton->blockSignals(false); +} + +void RawPreview::slotPanIconSelectionMoved(const TQRect& r, bool b) +{ + setContentsPos((int)(r.x()*zoomFactor()), (int)(r.y()*zoomFactor())); + + if (b) + { + d->panIconPopup->hide(); + delete d->panIconPopup; + d->panIconPopup = 0; + slotPanIconHiden(); + } +} + +void RawPreview::zoomFactorChanged(double zoom) +{ + updateScrollBars(); + + if (horizontalScrollBar()->isVisible() || verticalScrollBar()->isVisible()) + d->cornerButton->show(); + else + d->cornerButton->hide(); + + PreviewWidget::zoomFactorChanged(zoom); +} + +void RawPreview::resizeEvent(TQResizeEvent* e) +{ + if (!e) return; + + TQScrollView::resizeEvent(e); + + if (!d->loadingDesc.filePath.isEmpty()) + d->cornerButton->hide(); + + updateZoomAndSize(false); +} + +void RawPreview::updateZoomAndSize(bool alwaysFitToWindow) +{ + // Set zoom for fit-in-window as minimum, but dont scale up images + // that are smaller than the available space, only scale down. + double zoom = calcAutoZoomFactor(ZoomInOnly); + setZoomMin(zoom); + setZoomMax(zoom*12.0); + + // Is currently the zoom factor set to fit to window? Then set it again to fit the new size. + if (zoomFactor() < zoom || alwaysFitToWindow || zoomFactor() == d->currentFitWindowZoom) + { + setZoomFactor(zoom); + } + + // store which zoom factor means it is fit to window + d->currentFitWindowZoom = zoom; + + updateContentsSize(); +} + +int RawPreview::previewWidth() +{ + return d->postProcessedImg.width(); +} + +int RawPreview::previewHeight() +{ + return d->postProcessedImg.height(); +} + +bool RawPreview::previewIsNull() +{ + return d->postProcessedImg.isNull(); +} + +void RawPreview::resetPreview() +{ + d->postProcessedImg = DImg(); + d->loadingDesc = LoadingDescription(); + + updateZoomAndSize(false); +} + +void RawPreview::paintPreview(TQPixmap *pix, int sx, int sy, int sw, int sh) +{ + DImg img = d->postProcessedImg.smoothScaleSection(sx, sy, sw, sh, tileSize(), tileSize()); + TQPixmap pix2 = img.convertToPixmap(); + bitBlt(pix, 0, 0, &pix2, 0, 0); +} + +} // NameSpace Digikam diff --git a/src/utilities/imageeditor/rawimport/rawpreview.h b/src/utilities/imageeditor/rawimport/rawpreview.h new file mode 100644 index 00000000..6c7e5379 --- /dev/null +++ b/src/utilities/imageeditor/rawimport/rawpreview.h @@ -0,0 +1,108 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2008-08-04 + * Description : RAW preview widget. + * + * Copyright (C) 2008 Gilles Caulier <caulier dot gilles at gmail dot com> + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ============================================================ */ + +#ifndef RAWPREVIEW_H +#define RAWPREVIEW_H + +// TQt includes. + +#include <tqimage.h> + +// KDE includes. + +#include <kurl.h> + +// Local includes. + +#include "dimg.h" +#include "previewwidget.h" +#include "digikam_export.h" + +class TQPixmap; + +namespace Digikam +{ + +class LoadingDescription; +class RawPreviewPriv; + +class DIGIKAM_EXPORT RawPreview : public PreviewWidget +{ + +TQ_OBJECT + + +public: + + RawPreview(const KURL& url, TQWidget *parent); + ~RawPreview(); + + DImg& demosaicedImage() const; + DImg& postProcessedImage() const; + + void setDecodingSettings(const DRawDecoding& settings); + void setPostProcessedImage(const DImg& image); + + void cancelLoading(); + +signals: + + void signalLoadingStarted(); + void signalLoadingProgress(float); + void signalLoadingFailed(); + void signalDemosaicedImage(); + void signalPostProcessedImage(); + +protected: + + void resizeEvent(TQResizeEvent* e); + +private slots: + + void slotLoadingProgress(const LoadingDescription& description, float progress); + void slotImageLoaded(const LoadingDescription& description, const DImg &image); + void slotThemeChanged(); + void slotCornerButtonPressed(); + void slotPanIconSelectionMoved(const TQRect&, bool); + void slotPanIconHiden(); + +private: + + void setdemosaicedImg(const DImg& image); + void postProcessing(const DRawDecoding& settings); + int previewWidth(); + int previewHeight(); + bool previewIsNull(); + void resetPreview(); + void zoomFactorChanged(double zoom); + void updateZoomAndSize(bool alwaysFitToWindow); + inline void paintPreview(TQPixmap *pix, int sx, int sy, int sw, int sh); + +private: + + RawPreviewPriv* d; +}; + +} // NameSpace Digikam + +#endif /* RAWPREVIEW_H */ diff --git a/src/utilities/imageeditor/rawimport/rawsettingsbox.cpp b/src/utilities/imageeditor/rawimport/rawsettingsbox.cpp new file mode 100644 index 00000000..bf0ee67e --- /dev/null +++ b/src/utilities/imageeditor/rawimport/rawsettingsbox.cpp @@ -0,0 +1,741 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2008-08-11 + * Description : Raw import settings box + * + * Copyright (C) 2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ============================================================ */ + +// TQt includes. + +#include <tqstring.h> +#include <tqlayout.h> +#include <tqtooltip.h> +#include <tqwhatsthis.h> +#include <tqhbuttongroup.h> +#include <tqcombobox.h> +#include <tqlabel.h> +#include <tqvbox.h> +#include <tqtoolbutton.h> +#include <tqtoolbox.h> +#include <tqpushbutton.h> + +// KDE includes. + +#include <tdeapplication.h> +#include <ktabwidget.h> +#include <tdelocale.h> +#include <kiconloader.h> +#include <tdeconfig.h> +#include <kstandarddirs.h> +#include <tdefiledialog.h> + +// LibKDcraw includes. + +#include <libkdcraw/dcrawsettingswidget.h> +#include <libkdcraw/rnuminput.h> + +// Local includes. + +#include "ddebug.h" +#include "imagedialog.h" +#include "imagehistogram.h" +#include "imagecurves.h" +#include "iccpreviewwidget.h" +#include "histogramwidget.h" +#include "curveswidget.h" +#include "colorgradientwidget.h" +#include "rawsettingsbox.h" +#include "rawsettingsbox.moc" + +using namespace KDcrawIface; + +namespace Digikam +{ + +class RawSettingsBoxPriv +{ +public: + + enum ColorChannel + { + LuminosityChannel=0, + RedChannel, + GreenChannel, + BlueChannel, + ColorChannels + }; + + enum AllColorsColorType + { + AllColorsRed=0, + AllColorsGreen, + AllColorsBlue + }; + +public: + + RawSettingsBoxPriv() + { + channelCB = 0; + colorsCB = 0; + scaleBG = 0; + hGradient = 0; + histogramWidget = 0; + infoBox = 0; + advExposureBox = 0; + gammaLabel = 0; + gammaInput = 0; + saturationLabel = 0; + saturationInput = 0; + fineExposureLabel = 0; + fineExposureInput = 0; + contrastInput = 0; + contrastLabel = 0; + curveBox = 0; + curveWidget = 0; + resetCurveBtn = 0; + decodingSettingsBox = 0; + postProcessSettingsBox = 0; + tabView = 0; + abortBtn = 0; + updateBtn = 0; + rawdecodingBox = 0; + brightnessLabel = 0; + brightnessInput = 0; + } + + TQWidget *advExposureBox; + TQWidget *curveBox; + TQWidget *rawdecodingBox; + + TQComboBox *channelCB; + TQComboBox *colorsCB; + + TQLabel *brightnessLabel; + TQLabel *contrastLabel; + TQLabel *gammaLabel; + TQLabel *saturationLabel; + TQLabel *fineExposureLabel; + + TQHButtonGroup *scaleBG; + + TQPushButton *abortBtn; + TQPushButton *updateBtn; + + TQToolButton *resetCurveBtn; + + TQToolBox *postProcessSettingsBox; + + KTabWidget *tabView; + + ColorGradientWidget *hGradient; + + CurvesWidget *curveWidget; + + HistogramWidget *histogramWidget; + + ImageDialogPreview *infoBox; + + RIntNumInput *contrastInput; + RIntNumInput *brightnessInput; + + RDoubleNumInput *gammaInput; + RDoubleNumInput *saturationInput; + RDoubleNumInput *fineExposureInput; + + DcrawSettingsWidget *decodingSettingsBox; +}; + +RawSettingsBox::RawSettingsBox(const KURL& url, TQWidget *parent) + : EditorToolSettings(Default|Ok|Cancel, NoTool, parent) +{ + d = new RawSettingsBoxPriv; + + // --------------------------------------------------------------- + + TQGridLayout* gridSettings = new TQGridLayout(plainPage(), 5, 4); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), plainPage()); + label1->setAlignment( TQt::AlignRight | TQt::AlignVCenter ); + d->channelCB = new TQComboBox(false, plainPage()); + d->channelCB->insertItem( i18n("Luminosity") ); + d->channelCB->insertItem( i18n("Red") ); + d->channelCB->insertItem( i18n("Green") ); + d->channelCB->insertItem( i18n("Blue") ); + d->channelCB->insertItem( i18n("Colors") ); + TQWhatsThis::add(d->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>" + "<b>Colors</b>: Display all color channel values at the same time.")); + + d->scaleBG = new TQHButtonGroup(plainPage()); + d->scaleBG->setExclusive(true); + d->scaleBG->setFrameShape(TQFrame::NoFrame); + d->scaleBG->setInsideMargin( 0 ); + TQWhatsThis::add(d->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( d->scaleBG ); + TQToolTip::add( linHistoButton, i18n( "<p>Linear" ) ); + d->scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap( TQPixmap( directory + "histogram-lin.png" ) ); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton( d->scaleBG ); + TQToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) ); + d->scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap( TQPixmap( directory + "histogram-log.png" ) ); + logHistoButton->setToggleButton(true); + + TQLabel *label10 = new TQLabel(i18n("Colors:"), plainPage()); + label10->setAlignment( TQt::AlignRight | TQt::AlignVCenter ); + d->colorsCB = new TQComboBox(false, plainPage()); + d->colorsCB->insertItem( i18n("Red") ); + d->colorsCB->insertItem( i18n("Green") ); + d->colorsCB->insertItem( i18n("Blue") ); + d->colorsCB->setEnabled( false ); + TQWhatsThis::add( d->colorsCB, i18n("<p>Select the main color displayed with Colors Channel mode here:<p>" + "<b>Red</b>: Draw the red image channel in the foreground.<p>" + "<b>Green</b>: Draw the green image channel in the foreground.<p>" + "<b>Blue</b>: Draw the blue image channel in the foreground.<p>")); + + // --------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(plainPage()); + d->histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::add(d->histogramWidget, i18n("<p>Here you can see the target preview image histogram drawing " + "of the selected image channel. This one is re-computed at any " + "settings changes.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + d->hGradient = new ColorGradientWidget( ColorGradientWidget::Horizontal, 10, histoBox ); + d->hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + + // --------------------------------------------------------------- + + d->tabView = new KTabWidget(plainPage()); + d->rawdecodingBox = new TQWidget(d->tabView); + TQGridLayout* rawGrid = new TQGridLayout(d->rawdecodingBox, 1, 2); + d->decodingSettingsBox = new DcrawSettingsWidget(d->rawdecodingBox, true, true, false); + + KFileDialog *inputDlg = d->decodingSettingsBox->inputProfileUrlEdit()->fileDialog(); + inputDlg->setPreviewWidget(new ICCPreviewWidget(inputDlg)); + + KFileDialog *outputDlg = d->decodingSettingsBox->outputProfileUrlEdit()->fileDialog(); + outputDlg->setPreviewWidget(new ICCPreviewWidget(outputDlg)); + + d->abortBtn = new TQPushButton(d->rawdecodingBox); + d->abortBtn->setText(i18n("Abort")); + d->abortBtn->setIconSet(SmallIconSet("process-stop")); + d->abortBtn->setEnabled(false); + TQToolTip::add(d->abortBtn, i18n("Abort the current Raw image preview.")); + + d->updateBtn = new TQPushButton(d->rawdecodingBox); + d->updateBtn->setText(i18n("Update")); + d->updateBtn->setIconSet(SmallIconSet("reload_page")); + d->updateBtn->setEnabled(false); + TQToolTip::add(d->updateBtn, i18n("Generate a Raw image preview using current settings.")); + + rawGrid->addMultiCellWidget(d->decodingSettingsBox, 0, 0, 0, 2); + rawGrid->addMultiCellWidget(d->abortBtn, 1, 1, 0, 0); + rawGrid->addMultiCellWidget(d->updateBtn, 1, 1, 2, 2); + rawGrid->setColStretch(1, 10); + rawGrid->setSpacing(spacingHint()); + rawGrid->setMargin(spacingHint()); + + // --------------------------------------------------------------- + + d->postProcessSettingsBox = new TQToolBox(d->tabView); + d->infoBox = new ImageDialogPreview(d->postProcessSettingsBox); + d->infoBox->showPreview(url); + + // --------------------------------------------------------------- + + d->advExposureBox = new TQWidget(d->postProcessSettingsBox); + TQGridLayout* advExposureLayout = new TQGridLayout(d->advExposureBox, 5, 2); + + d->brightnessLabel = new TQLabel(i18n("Brightness:"), d->advExposureBox); + d->brightnessInput = new RIntNumInput(d->advExposureBox); + d->brightnessInput->setRange(-100, 100, 1); + d->brightnessInput->setDefaultValue(0); + TQWhatsThis::add(d->brightnessInput->input(), i18n("<p>Set here the brightness adjustment of the image.")); + + d->contrastLabel = new TQLabel(i18n("Contrast:"), d->advExposureBox); + d->contrastInput = new RIntNumInput(d->advExposureBox); + d->contrastInput->setRange(-100, 100, 1); + d->contrastInput->setDefaultValue(0); + TQWhatsThis::add(d->contrastInput->input(), i18n("<p>Set here the contrast adjustment of the image.")); + + d->gammaLabel = new TQLabel(i18n("Gamma:"), d->advExposureBox); + d->gammaInput = new RDoubleNumInput(d->advExposureBox); + d->gammaInput->setPrecision(2); + d->gammaInput->setRange(0.1, 3.0, 0.01); + d->gammaInput->setDefaultValue(1.0); + TQWhatsThis::add(d->gammaInput->input(), i18n("Set here the gamma adjustement of the image")); + + d->saturationLabel = new TQLabel(i18n("Saturation:"), d->advExposureBox); + d->saturationInput = new RDoubleNumInput(d->advExposureBox); + d->saturationInput->setPrecision(2); + d->saturationInput->setRange(0.0, 2.0, 0.01); + d->saturationInput->setDefaultValue(1.0); + TQWhatsThis::add(d->saturationInput->input(), i18n("<p>Set here the color saturation correction.")); + + d->fineExposureLabel = new TQLabel(i18n("Exposure (E.V):"), d->advExposureBox); + d->fineExposureInput = new RDoubleNumInput(d->advExposureBox); + d->fineExposureInput->setPrecision(2); + d->fineExposureInput->setRange(-3.0, 3.0, 0.1); + d->fineExposureInput->setDefaultValue(0.0); + TQWhatsThis::add(d->fineExposureInput->input(), i18n("<p>This value in E.V will be used to perform " + "an exposure compensation of the image.")); + + advExposureLayout->addMultiCellWidget(d->brightnessLabel, 0, 0, 0, 0); + advExposureLayout->addMultiCellWidget(d->brightnessInput, 0, 0, 1, 2); + advExposureLayout->addMultiCellWidget(d->contrastLabel, 1, 1, 0, 0); + advExposureLayout->addMultiCellWidget(d->contrastInput, 1, 1, 1, 2); + advExposureLayout->addMultiCellWidget(d->gammaLabel, 2, 2, 0, 0); + advExposureLayout->addMultiCellWidget(d->gammaInput, 2, 2, 1, 2); + advExposureLayout->addMultiCellWidget(d->saturationLabel, 3, 3, 0, 0); + advExposureLayout->addMultiCellWidget(d->saturationInput, 3, 3, 1, 2); + advExposureLayout->addMultiCellWidget(d->fineExposureLabel, 4, 4, 0, 0); + advExposureLayout->addMultiCellWidget(d->fineExposureInput, 4, 4, 1, 2); + advExposureLayout->setRowStretch(5, 10); + advExposureLayout->setSpacing(0); + advExposureLayout->setMargin(spacingHint()); + + // --------------------------------------------------------------- + + d->curveBox = new TQWidget(d->postProcessSettingsBox); + TQGridLayout* curveLayout = new TQGridLayout(d->curveBox, 3, 2); + + ColorGradientWidget* vGradient = new ColorGradientWidget(ColorGradientWidget::Vertical, 10, d->curveBox); + vGradient->setColors( TQColor( "white" ), TQColor( "black" ) ); + + TQLabel *spacev = new TQLabel(d->curveBox); + spacev->setFixedWidth(1); + + d->curveWidget = new CurvesWidget(256, 192, d->curveBox); + TQWhatsThis::add(d->curveWidget, i18n("<p>This is the curve adjustment of the image luminosity")); + + d->resetCurveBtn = new TQToolButton(d->curveBox); + d->resetCurveBtn->setFixedSize(11, 11); + d->resetCurveBtn->setIconSet(SmallIconSet("reload_page", 8)); + d->resetCurveBtn->setFocusPolicy(TQWidget::NoFocus); + d->resetCurveBtn->setAutoRaise(true); + TQToolTip::add(d->resetCurveBtn, i18n("Reset curve to linear")); + + TQLabel *spaceh = new TQLabel(d->curveBox); + spaceh->setFixedHeight(1); + + ColorGradientWidget *hGradient = new ColorGradientWidget(ColorGradientWidget::Horizontal, 10, d->curveBox); + hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + + curveLayout->addMultiCellWidget(vGradient, 0, 0, 0, 0); + curveLayout->addMultiCellWidget(spacev, 0, 0, 1, 1); + curveLayout->addMultiCellWidget(d->curveWidget, 0, 0, 2, 2); + curveLayout->addMultiCellWidget(spaceh, 1, 1, 2, 2); + curveLayout->addMultiCellWidget(d->resetCurveBtn, 1, 2, 0, 1); + curveLayout->addMultiCellWidget(hGradient, 2, 2, 2, 2); + curveLayout->setRowStretch(3, 10); + curveLayout->setSpacing(0); + curveLayout->setMargin(spacingHint()); + + // --------------------------------------------------------------- + + d->postProcessSettingsBox->addItem(d->advExposureBox, i18n("Exposure")); + d->postProcessSettingsBox->addItem(d->curveBox, i18n("Luminosity Curve")); + d->postProcessSettingsBox->setItemIconSet(0, SmallIconSet("contrast")); + d->postProcessSettingsBox->setItemIconSet(1, SmallIconSet("adjustcurves")); + + d->decodingSettingsBox->setItemIconSet(DcrawSettingsWidget::DEMOSAICING, SmallIconSet("kdcraw")); + d->decodingSettingsBox->setItemIconSet(DcrawSettingsWidget::WHITEBALANCE, SmallIconSet("whitebalance")); + d->decodingSettingsBox->setItemIconSet(DcrawSettingsWidget::CORRECTIONS, SmallIconSet("lensdistortion")); + d->decodingSettingsBox->setItemIconSet(DcrawSettingsWidget::COLORMANAGEMENT, SmallIconSet("colormanagement")); + d->decodingSettingsBox->updateMinimumWidth(); + + d->tabView->insertTab(d->rawdecodingBox, i18n("Raw Decoding"), 0); + d->tabView->insertTab(d->postProcessSettingsBox, i18n("Post Processing"), 1); + d->tabView->insertTab(d->infoBox, i18n("Info"), 2); + + // --------------------------------------------------------------- + + button(Default)->setText(i18n("Reset")); + button(Default)->setIconSet(SmallIconSet("reload_page")); + TQToolTip::add(button(Default), i18n("<p>Reset all settings to default values.")); + + button(Ok)->setText(i18n("Import")); + button(Ok)->setIconSet(SmallIconSet("ok")); + TQToolTip::add(button(Ok), i18n("<p>Import image to editor using current settings.")); + + button(Cancel)->setText(i18n("Use Default")); + button(Cancel)->setIconSet(SmallIconSet("go-home")); + TQToolTip::add(button(Cancel), i18n("<p>Use general Raw decoding settings to load this image in editor.")); + + // --------------------------------------------------------------- + + gridSettings->addMultiCellWidget(label1, 0, 0, 0, 0); + gridSettings->addMultiCellWidget(d->channelCB, 0, 0, 1, 1); + gridSettings->addMultiCellWidget(d->scaleBG, 0, 0, 4, 4); + gridSettings->addMultiCellWidget(label10, 1, 1, 0, 0); + gridSettings->addMultiCellWidget(d->colorsCB, 1, 1, 1, 1); + gridSettings->addMultiCellWidget(histoBox, 2, 3, 0, 4); + gridSettings->addMultiCellWidget(d->tabView, 4, 4, 0, 4); + gridSettings->setRowStretch(5, 10); + gridSettings->setColStretch(2, 10); + gridSettings->setSpacing(spacingHint()); + gridSettings->setMargin(0); + + // --------------------------------------------------------------- + + connect(d->channelCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(d->scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(d->colorsCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotColorsChanged(int))); + + connect(d->resetCurveBtn, TQ_SIGNAL(clicked()), + this, TQ_SLOT(slotResetCurve())); + + connect(d->updateBtn, TQ_SIGNAL(clicked()), + this, TQ_SIGNAL(signalUpdatePreview())); + + connect(d->abortBtn, TQ_SIGNAL(clicked()), + this, TQ_SIGNAL(signalAbortPreview())); + + connect(d->decodingSettingsBox, TQ_SIGNAL(signalSettingsChanged()), + this, TQ_SIGNAL(signalDemosaicingChanged())); + + connect(d->curveWidget, TQ_SIGNAL(signalCurvesChanged()), + this, TQ_SIGNAL(signalPostProcessingChanged())); + + connect(d->brightnessInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SIGNAL(signalPostProcessingChanged())); + + connect(d->contrastInput, TQ_SIGNAL(valueChanged(int)), + this, TQ_SIGNAL(signalPostProcessingChanged())); + + connect(d->gammaInput, TQ_SIGNAL(valueChanged(double)), + this, TQ_SIGNAL(signalPostProcessingChanged())); + + connect(d->saturationInput, TQ_SIGNAL(valueChanged(double)), + this, TQ_SIGNAL(signalPostProcessingChanged())); + + connect(d->fineExposureInput, TQ_SIGNAL(valueChanged(double)), + this, TQ_SIGNAL(signalPostProcessingChanged())); +} + +RawSettingsBox::~RawSettingsBox() +{ + delete d->curveWidget; + delete d; +} + +void RawSettingsBox::enableUpdateBtn(bool b) +{ + d->updateBtn->setEnabled(b); +} + +void RawSettingsBox::setBusy(bool b) +{ + d->decodingSettingsBox->setEnabled(!b); + d->abortBtn->setEnabled(b); +} + +void RawSettingsBox::setDemosaicedImage(DImg& img) +{ + d->curveWidget->stopHistogramComputation(); + d->curveWidget->updateData(img.bits(), img.width(), img.height(), img.sixteenBit()); +} + +void RawSettingsBox::setPostProcessedImage(DImg& img) +{ + d->histogramWidget->stopHistogramComputation(); + d->histogramWidget->updateData(img.bits(), img.width(), img.height(), img.sixteenBit()); +} + +void RawSettingsBox::resetSettings() +{ + d->decodingSettingsBox->setDefaultSettings(); + d->brightnessInput->slotReset(); + d->contrastInput->slotReset(); + d->gammaInput->slotReset(); + d->saturationInput->slotReset(); + d->fineExposureInput->slotReset(); + slotResetCurve(); +} + +void RawSettingsBox::slotResetCurve() +{ + d->curveWidget->reset(); + emit signalPostProcessingChanged(); +} + +HistogramWidget* RawSettingsBox::histogram() const +{ + return d->histogramWidget; +} + +CurvesWidget* RawSettingsBox::curve() const +{ + return d->curveWidget; +} + +void RawSettingsBox::readSettings() +{ + TDEConfig* config = kapp->config(); + config->setGroup("RAW Import Settings"); + + d->channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", RawSettingsBoxPriv::LuminosityChannel)); + d->scaleBG->setButton(config->readNumEntry("Histogram Scale", HistogramWidget::LogScaleHistogram)); + d->colorsCB->setCurrentItem(config->readNumEntry("Histogram Color", RawSettingsBoxPriv::AllColorsRed)); + + d->decodingSettingsBox->setSixteenBits(config->readBoolEntry("SixteenBitsImage", false)); + d->decodingSettingsBox->setWhiteBalance((DRawDecoding::WhiteBalance) + config->readNumEntry("White Balance", + DRawDecoding::CAMERA)); + d->decodingSettingsBox->setCustomWhiteBalance(config->readNumEntry("Custom White Balance", 6500)); + d->decodingSettingsBox->setCustomWhiteBalanceGreen(config->readDoubleNumEntry("Custom White Balance Green", 1.0)); + d->decodingSettingsBox->setFourColor(config->readBoolEntry("Four Color RGB", false)); + d->decodingSettingsBox->setUnclipColor(config->readNumEntry("Unclip Color", 0)); + d->decodingSettingsBox->setDontStretchPixels(config->readBoolEntry("Dont Stretch Pixels", false)); + d->decodingSettingsBox->setNoiseReduction(config->readBoolEntry("Use Noise Reduction", false)); + d->decodingSettingsBox->setUseBlackPoint(config->readBoolEntry("Use Black Point", false)); + d->decodingSettingsBox->setBlackPoint(config->readNumEntry("Black Point", 0)); + d->decodingSettingsBox->setUseWhitePoint(config->readBoolEntry("Use White Point", false)); + d->decodingSettingsBox->setWhitePoint(config->readNumEntry("White Point", 0)); + d->decodingSettingsBox->setMedianFilterPasses(config->readNumEntry("Median Filter Passes", 0)); + d->decodingSettingsBox->setNRThreshold(config->readNumEntry("NR Threshold", 100)); + d->decodingSettingsBox->setUseCACorrection(config->readBoolEntry("EnableCACorrection", false)); + d->decodingSettingsBox->setcaRedMultiplier(config->readDoubleNumEntry("caRedMultiplier", 1.0)); + d->decodingSettingsBox->setcaBlueMultiplier(config->readDoubleNumEntry("caBlueMultiplier", 1.0)); + + d->decodingSettingsBox->setQuality( + (DRawDecoding::DecodingQuality)config->readNumEntry("Decoding Quality", + (int)(DRawDecoding::BILINEAR))); + + d->decodingSettingsBox->setInputColorSpace( + (DRawDecoding::InputColorSpace)config->readNumEntry("Input Color Space", + (int)(DRawDecoding::NOINPUTCS))); + + d->decodingSettingsBox->setOutputColorSpace( + (DRawDecoding::OutputColorSpace)config->readNumEntry("Output Color Space", + (int)(DRawDecoding::SRGB))); + + d->decodingSettingsBox->setInputColorProfile(config->readPathEntry("Input Color Profile", TQString())); + d->decodingSettingsBox->setOutputColorProfile(config->readPathEntry("Output Color Profile", TQString())); + + d->brightnessInput->setValue(config->readNumEntry("Brightness", 0)); + d->contrastInput->setValue(config->readNumEntry("Contrast", 0)); + d->gammaInput->setValue(config->readDoubleNumEntry("Gamma", 1.0)); + d->saturationInput->setValue(config->readDoubleNumEntry("Saturation", 1.0)); + d->fineExposureInput->setValue(config->readDoubleNumEntry("FineExposure", 0.0)); + + d->curveWidget->reset(); + + for (int j = 0 ; j <= 17 ; j++) + { + TQPoint disable(-1, -1); + TQPoint p = config->readPointEntry(TQString("CurveAjustmentPoint%1").arg(j), &disable); + if (!d->decodingSettingsBox->sixteenBits() && p != disable) + { + // Restore point as 16 bits depth. + p.setX(p.x()/255); + p.setY(p.y()/255); + } + d->curveWidget->curves()->setCurvePoint(ImageHistogram::ValueChannel, j, p); + } + d->curveWidget->curves()->curvesCalculateCurve(ImageHistogram::ValueChannel); + + d->tabView->setCurrentPage(config->readNumEntry("Settings Page", 0)); + d->decodingSettingsBox->setCurrentIndex(config->readNumEntry("Decoding Settings Tab", DcrawSettingsWidget::DEMOSAICING)); + d->postProcessSettingsBox->setCurrentIndex(config->readNumEntry("Post Processing Settings Tab", 0)); + + slotChannelChanged(d->channelCB->currentItem()); + slotScaleChanged(d->scaleBG->selectedId()); + slotColorsChanged(d->colorsCB->currentItem()); +} + +void RawSettingsBox::writeSettings() +{ + TDEConfig* config = kapp->config(); + config->setGroup("RAW Import Settings"); + + config->writeEntry("Histogram Channel", d->channelCB->currentItem()); + config->writeEntry("Histogram Scale", d->scaleBG->selectedId()); + config->writeEntry("Histogram Color", d->colorsCB->currentItem()); + + config->writeEntry("SixteenBitsImage", d->decodingSettingsBox->sixteenBits()); + config->writeEntry("White Balance", d->decodingSettingsBox->whiteBalance()); + config->writeEntry("Custom White Balance", d->decodingSettingsBox->customWhiteBalance()); + config->writeEntry("Custom White Balance Green", d->decodingSettingsBox->customWhiteBalanceGreen()); + config->writeEntry("Four Color RGB", d->decodingSettingsBox->useFourColor()); + config->writeEntry("Unclip Color", d->decodingSettingsBox->unclipColor()); + config->writeEntry("Dont Stretch Pixels", d->decodingSettingsBox->useDontStretchPixels()); + config->writeEntry("Use Noise Reduction", d->decodingSettingsBox->useNoiseReduction()); + config->writeEntry("Use Black Point", d->decodingSettingsBox->useBlackPoint()); + config->writeEntry("Black Point", d->decodingSettingsBox->blackPoint()); + config->writeEntry("Use White Point", d->decodingSettingsBox->useWhitePoint()); + config->writeEntry("White Point", d->decodingSettingsBox->whitePoint()); + config->writeEntry("MedianFilterPasses", d->decodingSettingsBox->medianFilterPasses()); + config->writeEntry("NR Threshold", d->decodingSettingsBox->NRThreshold()); + config->writeEntry("EnableCACorrection", d->decodingSettingsBox->useCACorrection()); + config->writeEntry("caRedMultiplier", d->decodingSettingsBox->caRedMultiplier()); + config->writeEntry("caBlueMultiplier", d->decodingSettingsBox->caBlueMultiplier()); + config->writeEntry("Decoding Quality", (int)d->decodingSettingsBox->quality()); + config->writeEntry("Input Color Space", (int)d->decodingSettingsBox->inputColorSpace()); + config->writeEntry("Output Color Space", (int)d->decodingSettingsBox->outputColorSpace()); + config->writeEntry("Input Color Profile", d->decodingSettingsBox->inputColorProfile()); + config->writeEntry("Output Color Profile", d->decodingSettingsBox->outputColorProfile()); + + config->writeEntry("Brightness", d->brightnessInput->value()); + config->writeEntry("Contrast", d->contrastInput->value()); + config->writeEntry("Gamma", d->gammaInput->value()); + config->writeEntry("Saturation", d->saturationInput->value()); + config->writeEntry("FineExposure", d->fineExposureInput->value()); + + for (int j = 0 ; j <= 17 ; j++) + { + TQPoint p = d->curveWidget->curves()->getCurvePoint(ImageHistogram::ValueChannel, j); + if (!d->curveWidget->curves()->isSixteenBits()) + { + // Store point as 16 bits depth. + p.setX(p.x()*255); + p.setY(p.y()*255); + } + config->writeEntry(TQString("CurveAjustmentPoint%1").arg(j), p); + } + + config->writeEntry("Settings Page", d->tabView->currentPage()); + config->writeEntry("Decoding Settings Tab", d->decodingSettingsBox->currentIndex()); + config->writeEntry("Post Processing Settings Tab", d->postProcessSettingsBox->currentIndex()); + config->sync(); +} + +DRawDecoding RawSettingsBox::settings() +{ + DRawDecoding settings; + settings.sixteenBitsImage = d->decodingSettingsBox->sixteenBits(); + settings.whiteBalance = d->decodingSettingsBox->whiteBalance(); + settings.customWhiteBalance = d->decodingSettingsBox->customWhiteBalance(); + settings.customWhiteBalanceGreen = d->decodingSettingsBox->customWhiteBalanceGreen(); + settings.RGBInterpolate4Colors = d->decodingSettingsBox->useFourColor(); + settings.unclipColors = d->decodingSettingsBox->unclipColor(); + settings.DontStretchPixels = d->decodingSettingsBox->useDontStretchPixels(); + settings.enableNoiseReduction = d->decodingSettingsBox->useNoiseReduction(); + settings.enableBlackPoint = d->decodingSettingsBox->useBlackPoint(); + settings.blackPoint = d->decodingSettingsBox->blackPoint(); + settings.enableWhitePoint = d->decodingSettingsBox->useWhitePoint(); + settings.whitePoint = d->decodingSettingsBox->whitePoint(); + settings.medianFilterPasses = d->decodingSettingsBox->medianFilterPasses(); + settings.NRThreshold = d->decodingSettingsBox->NRThreshold(); + settings.enableCACorrection = d->decodingSettingsBox->useCACorrection(); + settings.caMultiplier[0] = d->decodingSettingsBox->caRedMultiplier(); + settings.caMultiplier[1] = d->decodingSettingsBox->caBlueMultiplier(); + settings.RAWQuality = d->decodingSettingsBox->quality(); + settings.inputColorSpace = d->decodingSettingsBox->inputColorSpace(); + settings.outputColorSpace = d->decodingSettingsBox->outputColorSpace(); + settings.inputProfile = d->decodingSettingsBox->inputColorProfile(); + settings.outputProfile = d->decodingSettingsBox->outputColorProfile(); + + settings.lightness = (double)d->brightnessInput->value()/250.0; + settings.contrast = (double)(d->contrastInput->value()/100.0) + 1.00; + settings.gamma = d->gammaInput->value(); + settings.saturation = d->saturationInput->value(); + settings.exposureComp = d->fineExposureInput->value(); + + if (d->curveWidget->curves()->isDirty()) + settings.curveAdjust = d->curveWidget->curves()->getCurvePoints(ImageHistogram::ValueChannel); + + return settings; +} + +void RawSettingsBox::slotChannelChanged(int channel) +{ + switch(channel) + { + case RawSettingsBoxPriv::LuminosityChannel: + d->histogramWidget->m_channelType = HistogramWidget::ValueHistogram; + d->hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + d->colorsCB->setEnabled(false); + break; + + case RawSettingsBoxPriv::RedChannel: + d->histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram; + d->hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); + d->colorsCB->setEnabled(false); + break; + + case RawSettingsBoxPriv::GreenChannel: + d->histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram; + d->hGradient->setColors( TQColor( "black" ), TQColor( "green" ) ); + d->colorsCB->setEnabled(false); + break; + + case RawSettingsBoxPriv::BlueChannel: + d->histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram; + d->hGradient->setColors( TQColor( "black" ), TQColor( "blue" ) ); + d->colorsCB->setEnabled(false); + break; + + case RawSettingsBoxPriv::ColorChannels: + d->histogramWidget->m_channelType = HistogramWidget::ColorChannelsHistogram; + d->hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + d->colorsCB->setEnabled(true); + break; + } + + d->histogramWidget->repaint(false); +} + +void RawSettingsBox::slotScaleChanged(int scale) +{ + d->histogramWidget->m_scaleType = scale; + d->histogramWidget->repaint(false); +} + +void RawSettingsBox::slotColorsChanged(int color) +{ + switch(color) + { + case RawSettingsBoxPriv::AllColorsGreen: + d->histogramWidget->m_colorType = HistogramWidget::GreenColor; + break; + + case RawSettingsBoxPriv::AllColorsBlue: + d->histogramWidget->m_colorType = HistogramWidget::BlueColor; + break; + + default: // Red. + d->histogramWidget->m_colorType = HistogramWidget::RedColor; + break; + } + + d->histogramWidget->repaint(false); +} + +} // NameSpace Digikam diff --git a/src/utilities/imageeditor/rawimport/rawsettingsbox.h b/src/utilities/imageeditor/rawimport/rawsettingsbox.h new file mode 100644 index 00000000..546ce1e5 --- /dev/null +++ b/src/utilities/imageeditor/rawimport/rawsettingsbox.h @@ -0,0 +1,91 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2008-08-11 + * Description : Raw import settings box + * + * Copyright (C) 2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ============================================================ */ + +#ifndef RAWSETTINGSBOX_H +#define RAWSETTINGSBOX_H + +// KDE includes. + +#include <kurl.h> + +// Local includes. + +#include "editortoolsettings.h" +#include "dimg.h" +#include "digikam_export.h" + +namespace Digikam +{ + +class HistogramWidget; +class CurvesWidget; +class RawSettingsBoxPriv; + +class DIGIKAM_EXPORT RawSettingsBox : public EditorToolSettings +{ + TQ_OBJECT + + +public: + + RawSettingsBox(const KURL& url, TQWidget *parent); + ~RawSettingsBox(); + + void setBusy(bool b); + + HistogramWidget* histogram() const; + CurvesWidget* curve() const; + DRawDecoding settings(); + + void writeSettings(); + void readSettings(); + + void setDemosaicedImage(DImg& img); + void setPostProcessedImage(DImg& img); + + void enableUpdateBtn(bool b); + + void resetSettings(); + +signals: + + void signalUpdatePreview(); + void signalAbortPreview(); + void signalDemosaicingChanged(); + void signalPostProcessingChanged(); + +private slots: + + void slotChannelChanged(int channel); + void slotScaleChanged(int scale); + void slotColorsChanged(int color); + + void slotResetCurve(); + +private: + + RawSettingsBoxPriv *d; +}; + +} // NameSpace Digikam + +#endif // RAWSETTINGSBOX_H |