File indexing completed on 2025-03-09 03:52:34
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2019-09-18 0007 * Description : UFRaw 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 "rawimportufrawplugin.h" 0016 0017 // Qt includes 0018 0019 #include <QMessageBox> 0020 #include <QApplication> 0021 #include <QPointer> 0022 #include <QDebug> 0023 #include <QByteArray> 0024 #include <QFileInfo> 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 DigikamRawImportUFRawPlugin 0041 { 0042 0043 class Q_DECL_HIDDEN UFRawRawImportPlugin::Private 0044 { 0045 public: 0046 0047 explicit Private() 0048 : ufraw(nullptr) 0049 { 0050 } 0051 0052 QProcess* ufraw; 0053 DImg decoded; 0054 LoadingDescription props; 0055 QFileInfo fileInfo; 0056 QString tempName; 0057 }; 0058 0059 UFRawRawImportPlugin::UFRawRawImportPlugin(QObject* const parent) 0060 : DPluginRawImport(parent), 0061 d (new Private) 0062 { 0063 } 0064 0065 UFRawRawImportPlugin::~UFRawRawImportPlugin() 0066 { 0067 delete d; 0068 } 0069 0070 QString UFRawRawImportPlugin::name() const 0071 { 0072 return QString::fromUtf8("Raw Import using UFRaw"); 0073 } 0074 0075 QString UFRawRawImportPlugin::iid() const 0076 { 0077 return QLatin1String(DPLUGIN_IID); 0078 } 0079 0080 QIcon UFRawRawImportPlugin::icon() const 0081 { 0082 return QIcon::fromTheme(QLatin1String("image-x-adobe-dng")); 0083 } 0084 0085 QString UFRawRawImportPlugin::description() const 0086 { 0087 return QString::fromUtf8("A RAW import plugin based on UFRaw"); 0088 } 0089 0090 QString UFRawRawImportPlugin::details() const 0091 { 0092 return QString::fromUtf8("<p>This RAW Import plugin use UFRaw tool to pre-process file in Image Editor.</p>" 0093 "<p>See UFRaw web site for details: " 0094 "<a href='http://ufraw.sourceforge.net/'>http://ufraw.sourceforge.net/</a></p>"); // krazy:exclude=insecurenet 0095 } 0096 0097 QString UFRawRawImportPlugin::handbookSection() const 0098 { 0099 return QLatin1String("setup_application"); 0100 } 0101 0102 QString UFRawRawImportPlugin::handbookChapter() const 0103 { 0104 return QLatin1String("editor_settings"); 0105 } 0106 0107 QString UFRawRawImportPlugin::handbookReference() const 0108 { 0109 return QLatin1String("setup-raw"); 0110 } 0111 0112 QList<DPluginAuthor> UFRawRawImportPlugin::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 UFRawRawImportPlugin::setup(QObject* const /*parent*/) 0122 { 0123 // Nothing to do 0124 } 0125 0126 QString UFRawRawImportPlugin::getRawProgram() const 0127 { 0128 return DFileOperations::findExecutable(QLatin1String("ufraw")); 0129 } 0130 0131 bool UFRawRawImportPlugin::run(const QString& filePath, const DRawDecoding& /*def*/) 0132 { 0133 d->fileInfo = QFileInfo(filePath); 0134 d->props = LoadingDescription(d->fileInfo.filePath(), LoadingDescription::ConvertForEditor); 0135 d->decoded = DImg(); 0136 0137 QTemporaryFile tempFile; 0138 tempFile.open(); 0139 d->tempName = tempFile.fileName(); 0140 0141 d->ufraw = new QProcess(this); 0142 d->ufraw->setProcessChannelMode(QProcess::MergedChannels); 0143 d->ufraw->setWorkingDirectory(d->fileInfo.path()); 0144 d->ufraw->setProcessEnvironment(adjustedEnvironmentForAppImage()); 0145 0146 connect(d->ufraw, SIGNAL(errorOccurred(QProcess::ProcessError)), 0147 this, SLOT(slotErrorOccurred(QProcess::ProcessError))); 0148 0149 connect(d->ufraw, SIGNAL(finished(int,QProcess::ExitStatus)), 0150 this, SLOT(slotProcessFinished(int,QProcess::ExitStatus))); 0151 0152 connect(d->ufraw, SIGNAL(readyRead()), 0153 this, SLOT(slotProcessReadyRead())); 0154 0155 // -------- 0156 0157 d->fileInfo = QFileInfo(filePath); 0158 0159 d->ufraw->setProgram(getRawProgram()); 0160 d->ufraw->setArguments(QStringList() << QLatin1String("--out-depth=16") // 16 bits per color per pixels 0161 << QLatin1String("--out-type=png") // PNG output (TIFF output generate multi-layers file) 0162 << QLatin1String("--overwrite") // Overwrite target temporary file 0163 << QString::fromUtf8("--output=%1") 0164 .arg(d->tempName) // Output file 0165 << filePath); // Input file 0166 0167 qCDebug(DIGIKAM_GENERAL_LOG) << "UFRaw arguments:" << d->ufraw->arguments(); 0168 0169 d->ufraw->start(); 0170 0171 return d->ufraw->waitForStarted(10000); 0172 } 0173 0174 void UFRawRawImportPlugin::slotErrorOccurred(QProcess::ProcessError error) 0175 { 0176 switch (error) 0177 { 0178 case QProcess::FailedToStart: 0179 { 0180 qCDebug(DIGIKAM_GENERAL_LOG) << "UFRaw :: Process has failed to start"; 0181 break; 0182 } 0183 0184 case QProcess::Crashed: 0185 { 0186 qCDebug(DIGIKAM_GENERAL_LOG) << "UFRaw :: Process has crashed"; 0187 break; 0188 } 0189 0190 case QProcess::Timedout: 0191 { 0192 qCDebug(DIGIKAM_GENERAL_LOG) << "UFRaw :: Process time-out"; 0193 break; 0194 } 0195 0196 case QProcess::WriteError: 0197 { 0198 qCDebug(DIGIKAM_GENERAL_LOG) << "UFRaw :: Process write error"; 0199 break; 0200 } 0201 0202 case QProcess::ReadError: 0203 { 0204 qCDebug(DIGIKAM_GENERAL_LOG) << "UFRaw :: Process read error"; 0205 break; 0206 } 0207 0208 default: 0209 { 0210 qCDebug(DIGIKAM_GENERAL_LOG) << "UFRaw :: Process error unknown"; 0211 break; 0212 } 0213 } 0214 } 0215 0216 void UFRawRawImportPlugin::slotProcessFinished(int code, QProcess::ExitStatus status) 0217 { 0218 qCDebug(DIGIKAM_GENERAL_LOG) << "UFRaw :: return code:" << code << ":: Exit status:" << status; 0219 0220 d->decoded = DImg(d->tempName); 0221 d->decoded.setAttribute(QLatin1String("isReadOnly"), true); 0222 0223 if (d->decoded.isNull()) 0224 { 0225 QString message = i18n("Error to import RAW image with UFRaw\nClose this dialog to load RAW image with native import tool"); 0226 QMessageBox::information(nullptr, qApp->applicationName(), message); 0227 0228 qCDebug(DIGIKAM_GENERAL_LOG) << "Decoded image is null! Load with Native tool..."; 0229 qCDebug(DIGIKAM_GENERAL_LOG) << d->props.filePath; 0230 0231 Q_EMIT signalLoadRaw(d->props); 0232 } 0233 else 0234 { 0235 qCDebug(DIGIKAM_GENERAL_LOG) << "Decoded image is not null..."; 0236 qCDebug(DIGIKAM_GENERAL_LOG) << d->props.filePath; 0237 d->props = LoadingDescription(d->tempName, LoadingDescription::ConvertForEditor); 0238 0239 FilterAction action(QLatin1String("ufraw:RawConverter"), 1, FilterAction::DocumentedHistory); 0240 action.setDisplayableName(QString::fromUtf8(I18N_NOOP("UFRaw Raw Conversion"))); 0241 d->decoded.addFilterAction(action); 0242 0243 Q_EMIT signalDecodedImage(d->props, d->decoded); 0244 } 0245 0246 delete d->ufraw; 0247 d->ufraw = nullptr; 0248 0249 QFile::remove(d->tempName); 0250 } 0251 0252 void UFRawRawImportPlugin::slotProcessReadyRead() 0253 { 0254 QByteArray data = d->ufraw->readAllStandardError(); 0255 QStringList lines = QString::fromUtf8(data).split(QLatin1Char('\n'), QT_SKIP_EMPTY_PARTS); 0256 0257 Q_FOREACH (const QString& one, lines) 0258 { 0259 qCDebug(DIGIKAM_GENERAL_LOG) << "UFRaw ::" << one; 0260 } 0261 } 0262 0263 } // namespace DigikamRawImportUFRawPlugin 0264 0265 #include "moc_rawimportufrawplugin.cpp"