File indexing completed on 2025-01-19 03:53:17

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2008-08-04
0007  * Description : RAW postProcessedImg widget.
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 "rawpreview.h"
0016 
0017 // Qt includes
0018 
0019 #include <QString>
0020 #include <QPainter>
0021 #include <QFileInfo>
0022 #include <QFontMetrics>
0023 #include <QApplication>
0024 
0025 // KDE includes
0026 
0027 #include <klocalizedstring.h>
0028 
0029 // Local includes
0030 
0031 #include "digikam_debug.h"
0032 #include "managedloadsavethread.h"
0033 #include "editorcore.h"
0034 #include "previewlayout.h"
0035 #include "imagepreviewitem.h"
0036 
0037 namespace DigikamRawImportNativePlugin
0038 {
0039 
0040 class Q_DECL_HIDDEN RawPreview::Private
0041 {
0042 public:
0043 
0044     explicit Private()
0045       : currentFitWindowZoom(0.0),
0046         thread              (nullptr),
0047         item                (nullptr)
0048     {
0049     }
0050 
0051     double                 currentFitWindowZoom;
0052 
0053     QUrl                   url;
0054 
0055     DImg                   demosaicedImg;
0056 
0057     DRawDecoding           settings;
0058     ManagedLoadSaveThread* thread;
0059     LoadingDescription     loadingDesc;
0060     ImagePreviewItem*      item;
0061 };
0062 
0063 RawPreview::RawPreview(const QUrl& url, QWidget* const parent)
0064     : GraphicsDImgView(parent),
0065       d               (new Private)
0066 {
0067     d->item   = new ImagePreviewItem();
0068     setItem(d->item);
0069 
0070     d->url    = url;
0071     d->thread = new ManagedLoadSaveThread;
0072     d->thread->setLoadingPolicy(ManagedLoadSaveThread::LoadingPolicyFirstRemovePrevious);
0073 
0074     // ------------------------------------------------------------
0075 
0076     // set default zoom
0077 
0078     layout()->fitToWindow();
0079 
0080     installPanIcon();
0081 
0082     setMinimumWidth(500);
0083     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
0084 
0085     // ------------------------------------------------------------
0086 
0087     connect(d->thread, SIGNAL(signalImageLoaded(LoadingDescription,DImg)),
0088             this, SLOT(slotImageLoaded(LoadingDescription,DImg)));
0089 
0090     connect(d->thread, SIGNAL(signalLoadingProgress(LoadingDescription,float)),
0091             this, SLOT(slotLoadingProgress(LoadingDescription,float)));
0092 }
0093 
0094 RawPreview::~RawPreview()
0095 {
0096     delete d->item;
0097     delete d;
0098 }
0099 
0100 void RawPreview::setPostProcessedImage(const DImg& image)
0101 {
0102     d->item->setImage(image);
0103 }
0104 
0105 DImg RawPreview::postProcessedImage() const
0106 {
0107     return d->item->image();
0108 }
0109 
0110 DImg& RawPreview::demosaicedImage() const
0111 {
0112     return d->demosaicedImg;
0113 }
0114 
0115 void RawPreview::setDecodingSettings(const DRawDecoding& settings)
0116 {
0117     if ((d->settings == settings) && d->thread->isRunning())
0118     {
0119         return;
0120     }
0121 
0122     // Save post processing settings.
0123 
0124     d->settings                     = settings;
0125 
0126     // All post processing settings will be used after demosaicing.
0127 
0128     DRawDecoding demosaisedSettings = settings;
0129     demosaisedSettings.resetPostProcessingSettings();
0130 
0131     d->loadingDesc                  = LoadingDescription(d->url.toLocalFile(), demosaisedSettings);
0132     d->thread->load(d->loadingDesc, ManagedLoadSaveThread::LoadingPolicyFirstRemovePrevious);
0133     Q_EMIT signalLoadingStarted();
0134 }
0135 
0136 void RawPreview::exposureSettingsChanged()
0137 {
0138     viewport()->update();
0139 }
0140 
0141 void RawPreview::ICCSettingsChanged()
0142 {
0143     viewport()->update();
0144 }
0145 
0146 void RawPreview::cancelLoading()
0147 {
0148     d->thread->stopLoading(d->loadingDesc);
0149 }
0150 
0151 void RawPreview::slotLoadingProgress(const LoadingDescription& description, float progress)
0152 {
0153     if (description.filePath != d->loadingDesc.filePath)
0154     {
0155         return;
0156     }
0157 
0158     Q_EMIT signalLoadingProgress(progress);
0159 }
0160 
0161 void RawPreview::slotImageLoaded(const LoadingDescription& description, const DImg& image)
0162 {
0163     if (description.filePath != d->loadingDesc.filePath)
0164     {
0165         return;
0166     }
0167 
0168     if (image.isNull())
0169     {
0170         QString msg    = i18n("Cannot decode RAW image\n\"%1\"",
0171                               QFileInfo(d->loadingDesc.filePath).fileName());
0172         QFontMetrics fontMt(font());
0173         QRect fontRect = fontMt.boundingRect(0, 0, width(), height(), 0, msg);
0174         QPixmap pix(fontRect.size());
0175         pix.fill(qApp->palette().color(QPalette::Base));
0176         QPainter p(&pix);
0177         p.setPen(QPen(qApp->palette().color(QPalette::Text)));
0178         p.drawText(0, 0, pix.width(), pix.height(), Qt::AlignCenter | Qt::TextWordWrap, msg);
0179         p.end();
0180 
0181         // three copies - but the image is small
0182 
0183         setPostProcessedImage(DImg(pix.toImage()));
0184         Q_EMIT signalLoadingFailed();
0185     }
0186     else
0187     {
0188         d->demosaicedImg = image;
0189         Q_EMIT signalDemosaicedImage();
0190 
0191         // NOTE: we will apply all Raw post processing corrections in RawImport class.
0192     }
0193 }
0194 
0195 int RawPreview::previewWidth() const
0196 {
0197     return d->item->image().width();
0198 }
0199 
0200 int RawPreview::previewHeight() const
0201 {
0202     return d->item->image().height();
0203 }
0204 
0205 bool RawPreview::previewIsNull() const
0206 {
0207     return d->item->image().isNull();
0208 }
0209 
0210 void RawPreview::resetPreview()
0211 {
0212     d->item->setImage(DImg());
0213     d->loadingDesc = LoadingDescription();
0214     update();
0215 }
0216 
0217 QImage RawPreview::previewToQImage() const
0218 {
0219     return d->item->image().copyQImage();
0220 }
0221 
0222 } // namespace DigikamRawImportNativePlugin
0223 
0224 #include "moc_rawpreview.cpp"