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"