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"