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 : 2019-09-18 0007 * Description : RawTherapee raw import plugin. 0008 * 0009 * SPDX-FileCopyrightText: 2019-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 "rawimportrawtherapeeplugin.h" 0016 0017 // Qt includes 0018 0019 #include <QMessageBox> 0020 #include <QApplication> 0021 #include <QPointer> 0022 #include <QByteArray> 0023 #include <QFileInfo> 0024 #include <QSettings> 0025 #include <QTemporaryFile> 0026 0027 // KDE includes 0028 0029 #include <klocalizedstring.h> 0030 0031 // Local includes 0032 0033 #include "digikam_debug.h" 0034 #include "digikam_globals_p.h" // For KF6::Ki18n deprecated 0035 #include "dimg.h" 0036 #include "filteraction.h" 0037 #include "dfileoperations.h" 0038 #include "loadingdescription.h" 0039 0040 namespace DigikamRawImportRawTherapeePlugin 0041 { 0042 0043 class Q_DECL_HIDDEN RawTherapeeRawImportPlugin::Private 0044 { 0045 public: 0046 0047 explicit Private() 0048 : rawtherapee(nullptr) 0049 { 0050 } 0051 0052 QProcess* rawtherapee; 0053 DImg decoded; 0054 LoadingDescription props; 0055 QString tempName; 0056 }; 0057 0058 RawTherapeeRawImportPlugin::RawTherapeeRawImportPlugin(QObject* const parent) 0059 : DPluginRawImport(parent), 0060 d (new Private) 0061 { 0062 } 0063 0064 RawTherapeeRawImportPlugin::~RawTherapeeRawImportPlugin() 0065 { 0066 delete d; 0067 } 0068 0069 QString RawTherapeeRawImportPlugin::name() const 0070 { 0071 return QString::fromUtf8("Raw Import using RawTherapee"); 0072 } 0073 0074 QString RawTherapeeRawImportPlugin::iid() const 0075 { 0076 return QLatin1String(DPLUGIN_IID); 0077 } 0078 0079 QIcon RawTherapeeRawImportPlugin::icon() const 0080 { 0081 return QIcon::fromTheme(QLatin1String("image-x-adobe-dng")); 0082 } 0083 0084 QString RawTherapeeRawImportPlugin::description() const 0085 { 0086 return QString::fromUtf8("A RAW import plugin based on RawTherapee"); 0087 } 0088 0089 QString RawTherapeeRawImportPlugin::details() const 0090 { 0091 return QString::fromUtf8("<p>This RAW Import plugin use RawTherapee tool to pre-process file in Image Editor.</p>" 0092 "<p>It requires at least RawTherapee version 5.2.0 to work.</p>" 0093 "<p>See RawTherapee web site for details: <a href='https://rawtherapee.com/'>https://rawtherapee.com/</a></p>"); 0094 } 0095 0096 QString RawTherapeeRawImportPlugin::handbookSection() const 0097 { 0098 return QLatin1String("setup_application"); 0099 } 0100 0101 QString RawTherapeeRawImportPlugin::handbookChapter() const 0102 { 0103 return QLatin1String("editor_settings"); 0104 } 0105 0106 QString RawTherapeeRawImportPlugin::handbookReference() const 0107 { 0108 return QLatin1String("setup-raw"); 0109 } 0110 0111 QList<DPluginAuthor> RawTherapeeRawImportPlugin::authors() const 0112 { 0113 return QList<DPluginAuthor>() 0114 << DPluginAuthor(QString::fromUtf8("Gilles Caulier"), 0115 QString::fromUtf8("caulier dot gilles at gmail dot com"), 0116 QString::fromUtf8("(C) 2019-2022")) 0117 ; 0118 } 0119 0120 void RawTherapeeRawImportPlugin::setup(QObject* const /*parent*/) 0121 { 0122 // Nothing to do 0123 } 0124 0125 QString RawTherapeeRawImportPlugin::getRawProgram() const 0126 { 0127 return DFileOperations::findExecutable(QLatin1String("rawtherapee")); 0128 } 0129 0130 bool RawTherapeeRawImportPlugin::run(const QString& filePath, const DRawDecoding& /*def*/) 0131 { 0132 QFileInfo fileInfo(filePath); 0133 d->props = LoadingDescription(fileInfo.filePath(), LoadingDescription::ConvertForEditor); 0134 d->decoded = DImg(); 0135 0136 QTemporaryFile tempFile; 0137 tempFile.open(); 0138 d->tempName = tempFile.fileName(); 0139 0140 d->rawtherapee = new QProcess(this); 0141 d->rawtherapee->setProcessChannelMode(QProcess::MergedChannels); 0142 d->rawtherapee->setWorkingDirectory(fileInfo.path()); 0143 d->rawtherapee->setProcessEnvironment(adjustedEnvironmentForAppImage()); 0144 0145 connect(d->rawtherapee, SIGNAL(errorOccurred(QProcess::ProcessError)), 0146 this, SLOT(slotErrorOccurred(QProcess::ProcessError))); 0147 0148 connect(d->rawtherapee, SIGNAL(finished(int,QProcess::ExitStatus)), 0149 this, SLOT(slotProcessFinished(int,QProcess::ExitStatus))); 0150 0151 connect(d->rawtherapee, SIGNAL(readyRead()), 0152 this, SLOT(slotProcessReadyRead())); 0153 0154 // -------- 0155 0156 d->rawtherapee->setProgram(getRawProgram()); 0157 d->rawtherapee->setArguments(QStringList() << QLatin1String("-gimp") // Special mode used initially as Gimp plugin 0158 << filePath // Input file 0159 << d->tempName); // Output file 0160 0161 qCDebug(DIGIKAM_GENERAL_LOG) << "RawTherapee arguments:" << d->rawtherapee->arguments(); 0162 0163 d->rawtherapee->start(); 0164 0165 return d->rawtherapee->waitForStarted(10000); 0166 } 0167 0168 void RawTherapeeRawImportPlugin::slotErrorOccurred(QProcess::ProcessError error) 0169 { 0170 switch (error) 0171 { 0172 case QProcess::FailedToStart: 0173 { 0174 qCDebug(DIGIKAM_GENERAL_LOG) << "RawTherapee :: Process has failed to start"; 0175 break; 0176 } 0177 0178 case QProcess::Crashed: 0179 { 0180 qCDebug(DIGIKAM_GENERAL_LOG) << "RawTherapee :: Process has crashed"; 0181 break; 0182 } 0183 0184 case QProcess::Timedout: 0185 { 0186 qCDebug(DIGIKAM_GENERAL_LOG) << "RawTherapee :: Process time-out"; 0187 break; 0188 } 0189 0190 case QProcess::WriteError: 0191 { 0192 qCDebug(DIGIKAM_GENERAL_LOG) << "RawTherapee :: Process write error"; 0193 break; 0194 } 0195 0196 case QProcess::ReadError: 0197 { 0198 qCDebug(DIGIKAM_GENERAL_LOG) << "RawTherapee :: Process read error"; 0199 break; 0200 } 0201 0202 default: 0203 { 0204 qCDebug(DIGIKAM_GENERAL_LOG) << "RawTherapee :: Process error unknown"; 0205 break; 0206 } 0207 } 0208 } 0209 0210 void RawTherapeeRawImportPlugin::slotProcessFinished(int code, QProcess::ExitStatus status) 0211 { 0212 qCDebug(DIGIKAM_GENERAL_LOG) << "RawTherapee :: return code:" << code << ":: Exit status:" << status; 0213 0214 d->decoded = DImg(d->tempName); 0215 d->decoded.setAttribute(QLatin1String("isReadOnly"), true); 0216 0217 if (d->decoded.isNull()) 0218 { 0219 QString message = i18n("Error to import RAW image with RawTherapee\nClose this dialog to load RAW image with native import tool"); 0220 QMessageBox::information(nullptr, qApp->applicationName(), message); 0221 0222 qCDebug(DIGIKAM_GENERAL_LOG) << "Decoded image is null! Load with Native tool..."; 0223 qCDebug(DIGIKAM_GENERAL_LOG) << d->props.filePath; 0224 0225 Q_EMIT signalLoadRaw(d->props); 0226 } 0227 else 0228 { 0229 qCDebug(DIGIKAM_GENERAL_LOG) << "Decoded image is not null..."; 0230 qCDebug(DIGIKAM_GENERAL_LOG) << d->props.filePath; 0231 d->props = LoadingDescription(d->tempName, LoadingDescription::ConvertForEditor); 0232 0233 FilterAction action(QLatin1String("rawtherapee:RawConverter"), 1, FilterAction::DocumentedHistory); 0234 action.setDisplayableName(QString::fromUtf8(I18N_NOOP("RawTherapee Raw Conversion"))); 0235 d->decoded.addFilterAction(action); 0236 0237 Q_EMIT signalDecodedImage(d->props, d->decoded); 0238 } 0239 0240 delete d->rawtherapee; 0241 d->rawtherapee = nullptr; 0242 0243 QFile::remove(d->tempName); 0244 } 0245 0246 void RawTherapeeRawImportPlugin::slotProcessReadyRead() 0247 { 0248 QByteArray data = d->rawtherapee->readAllStandardError(); 0249 QStringList lines = QString::fromUtf8(data).split(QLatin1Char('\n'), QT_SKIP_EMPTY_PARTS); 0250 0251 Q_FOREACH (const QString& one, lines) 0252 { 0253 qCDebug(DIGIKAM_GENERAL_LOG) << "RawTherapee ::" << one; 0254 } 0255 } 0256 0257 } // namespace DigikamRawImportRawTherapeePlugin 0258 0259 #include "moc_rawimportrawtherapeeplugin.cpp"