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