File indexing completed on 2025-01-05 03:53:46

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2008-08-20
0007  * Description : Raw import tool
0008  *
0009  * SPDX-FileCopyrightText: 2008-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "rawimport.h"
0016 
0017 // Qt includes
0018 
0019 #include <QString>
0020 #include <QLayout>
0021 #include <QIcon>
0022 
0023 // KDE includes
0024 
0025 #include <klocalizedstring.h>
0026 
0027 // Local includes
0028 
0029 #include "drawdecoding.h"
0030 #include "histogramwidget.h"
0031 #include "histogrambox.h"
0032 #include "curveswidget.h"
0033 #include "imagehistogram.h"
0034 #include "rawsettingsbox.h"
0035 #include "rawprocessingfilter.h"
0036 #include "editortooliface.h"
0037 #include "rawpreview.h"
0038 
0039 namespace DigikamRawImportNativePlugin
0040 {
0041 
0042 class Q_DECL_HIDDEN RawImport::Private
0043 {
0044 public:
0045 
0046     explicit Private()
0047       : settingsBox  (nullptr),
0048         previewWidget(nullptr)
0049     {
0050     }
0051 
0052     RawSettingsBox* settingsBox;
0053     RawPreview*     previewWidget;
0054 
0055     DImg            postProcessedImage;
0056 };
0057 
0058 RawImport::RawImport(const QUrl& url, QObject* const parent)
0059     : EditorToolThreaded(parent),
0060       d                 (new Private)
0061 {
0062     d->previewWidget = new RawPreview(url, nullptr);
0063     d->settingsBox   = new RawSettingsBox(url, nullptr);
0064 
0065     setToolName(i18n("Raw Import"));
0066     setToolIcon(QIcon::fromTheme(QLatin1String("image-x-adobe-dng")));
0067     setProgressMessage(i18n("Post Processing"));
0068     setToolView(d->previewWidget);
0069     setToolSettings(d->settingsBox);
0070 }
0071 
0072 RawImport::~RawImport()
0073 {
0074     delete d;
0075 }
0076 
0077 void RawImport::slotInit()
0078 {
0079     EditorToolThreaded::slotInit();
0080 
0081     // ---------------------------------------------------------------
0082 
0083     connect(d->previewWidget, SIGNAL(signalLoadingStarted()),
0084             this, SLOT(slotLoadingStarted()));
0085 
0086     connect(d->previewWidget, SIGNAL(signalLoadingProgress(float)),
0087             this, SLOT(slotLoadingProgress(float)));
0088 
0089     connect(d->previewWidget, SIGNAL(signalLoadingFailed()),
0090             this, SLOT(slotLoadingFailed()));
0091 
0092     connect(d->previewWidget, SIGNAL(signalDemosaicedImage()),
0093             this, SLOT(slotDemosaicedImage()));
0094 
0095     connect(d->settingsBox, SIGNAL(signalPostProcessingChanged()),
0096             this, SLOT(slotTimer()));
0097 
0098     connect(d->settingsBox, SIGNAL(signalUpdatePreview()),
0099             this, SLOT(slotUpdatePreview()));
0100 
0101     connect(d->settingsBox, SIGNAL(signalAbortPreview()),
0102             this, SLOT(slotAbort()));
0103 
0104     // ---------------------------------------------------------------
0105 
0106     setBusy(true);
0107     slotUpdatePreview();
0108 }
0109 
0110 void RawImport::setBusy(bool val)
0111 {
0112     if (val)
0113     {
0114         d->previewWidget->setCursor(Qt::WaitCursor);
0115     }
0116     else
0117     {
0118         d->previewWidget->unsetCursor();
0119     }
0120 
0121     d->settingsBox->setBusy(val);
0122 }
0123 
0124 DRawDecoding RawImport::rawDecodingSettings() const
0125 {
0126     return d->settingsBox->settings();
0127 }
0128 
0129 DImg RawImport::postProcessedImage() const
0130 {
0131     return d->previewWidget->postProcessedImage();
0132 }
0133 
0134 bool RawImport::hasPostProcessedImage() const
0135 {
0136     return (!demosaicingSettingsDirty() && !d->postProcessedImage.isNull());
0137 }
0138 
0139 bool RawImport::demosaicingSettingsDirty() const
0140 {
0141     return d->settingsBox->updateBtnEnabled();
0142 }
0143 
0144 void RawImport::slotUpdatePreview()
0145 {
0146     DRawDecoding settings = rawDecodingSettings();
0147 
0148     // NOTE: we will NOT use Half Size raw extraction here, because we cannot check effects of demosaicing options in this mode.
0149 
0150     d->previewWidget->setDecodingSettings(settings);
0151 }
0152 
0153 void RawImport::slotAbort()
0154 {
0155     // If preview loading, don't play with threaded filter interface.
0156 
0157     if (renderingMode() == EditorToolThreaded::NoneRendering)
0158     {
0159         d->previewWidget->cancelLoading();
0160         d->settingsBox->histogramBox()->histogram()->stopHistogramComputation();
0161         EditorToolIface::editorToolIface()->setToolStopProgress();
0162         setBusy(false);
0163 
0164         return;
0165     }
0166 
0167     EditorToolThreaded::slotAbort();
0168 }
0169 
0170 void RawImport::slotLoadingStarted()
0171 {
0172     d->postProcessedImage = DImg();
0173     d->settingsBox->enableUpdateBtn(false);
0174     d->settingsBox->histogramBox()->histogram()->setDataLoading();
0175     d->settingsBox->curvesWidget()->setDataLoading();
0176     EditorToolIface::editorToolIface()->setToolStartProgress(i18n("Raw Decoding"));
0177     setBusy(true);
0178 }
0179 
0180 void RawImport::slotDemosaicedImage()
0181 {
0182     d->settingsBox->setDemosaicedImage(d->previewWidget->demosaicedImage());
0183     slotPreview();
0184 }
0185 
0186 void RawImport::preparePreview()
0187 {
0188     DImg postImg = d->previewWidget->demosaicedImage();
0189     setFilter(dynamic_cast<DImgThreadedFilter*>(new RawProcessingFilter(&postImg, this, rawDecodingSettings())));
0190 }
0191 
0192 void RawImport::setPreviewImage()
0193 {
0194     // Preserve metadata from loaded image, and take post-processed image data
0195 
0196     d->postProcessedImage = d->previewWidget->demosaicedImage().copyMetaData();
0197     DImg data             = filter()->getTargetImage();
0198     d->postProcessedImage.putImageData(data.width(), data.height(), data.sixteenBit(), data.hasAlpha(),
0199                                        data.stripImageData(), false);
0200     d->previewWidget->setPostProcessedImage(d->postProcessedImage);
0201     d->settingsBox->setPostProcessedImage(d->postProcessedImage);
0202     EditorToolIface::editorToolIface()->setToolStopProgress();
0203     setBusy(false);
0204 }
0205 
0206 void RawImport::slotLoadingFailed()
0207 {
0208     d->settingsBox->histogramBox()->histogram()->setLoadingFailed();
0209     EditorToolIface::editorToolIface()->setToolStopProgress();
0210     setBusy(false);
0211 }
0212 
0213 void RawImport::slotLoadingProgress(float v)
0214 {
0215     EditorToolIface::editorToolIface()->setToolProgress((int)(v * 100));
0216 }
0217 
0218 void RawImport::slotScaleChanged()
0219 {
0220     d->settingsBox->curvesWidget()->setScaleType(d->settingsBox->histogramBox()->scale());
0221 }
0222 
0223 void RawImport::slotOk()
0224 {
0225     // NOTE: work around bug #211810
0226 
0227     if (d->settingsBox->curvesWidget()->isSixteenBits() != d->settingsBox->settings().rawPrm.sixteenBitsImage)
0228     {
0229         d->settingsBox->curvesWidget()->updateData(DImg(0, 0, d->settingsBox->settings().rawPrm.sixteenBitsImage));
0230     }
0231 
0232     EditorTool::slotOk();       // clazy:exclude=skipped-base-method
0233 }
0234 
0235 void RawImport::slotCancel()
0236 {
0237     EditorTool::slotCancel();   // clazy:exclude=skipped-base-method
0238 }
0239 
0240 void RawImport::setBackgroundColor(const QColor& bg)
0241 {
0242     QPalette plt(d->previewWidget->palette());
0243     plt.setColor(d->previewWidget->backgroundRole(), bg);
0244     d->previewWidget->setPalette(plt);
0245 }
0246 
0247 void RawImport::exposureSettingsChanged()
0248 {
0249     d->previewWidget->exposureSettingsChanged();
0250 }
0251 
0252 void RawImport::ICCSettingsChanged()
0253 {
0254     d->previewWidget->ICCSettingsChanged();
0255 }
0256 
0257 } // namespace DigikamRawImportNativePlugin
0258 
0259 #include "moc_rawimport.cpp"