1 /** ===========================================================
2 * @file
3 *
4 * This file is a part of digiKam project
5 * <a href="https://www.digikam.org">https://www.digikam.org</a>
6 *
7 * @date : 2014-10-17
8 * @brief : a class to manage Raw to Png conversion using threads
9 *
10 * @author Copyright (C) 2011-2015 by Gilles Caulier
11 * <a href="mailto:caulier dot gilles at gmail dot com">caulier dot gilles at gmail dot com</a>
12 * @author Copyright (C) 2014 by Veaceslav Munteanu
13 * <a href="mailto:veaceslav dot munteanu90 at gmail dot com">veaceslav dot munteanu90 at gmail dot com</a>
14 *
15 * This program is free software; you can redistribute it
16 * and/or modify it under the terms of the GNU General
17 * Public License as published by the Free Software Foundation;
18 * either version 2, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * ============================================================ */
26
27 #include "actionthread.h"
28
29 // Qt includes
30
31 #include <QFileInfo>
32 #include <QImage>
33 #include <QDebug>
34
35 // Local includes
36
37 #include "kdcraw.h"
38 #include "ractionjob.h"
39
40 class Task : public RActionJob
41 {
42 public:
43
Task()44 Task()
45 : RActionJob()
46 {
47 }
48
49 RawDecodingSettings settings;
50 QString errString;
51 QUrl fileUrl;
52
53 protected:
54
run()55 void run()
56 {
57 emit signalStarted();
58
59 QImage image;
60
61 if (m_cancel) return;
62
63 emit signalProgress(20);
64
65 KDcraw rawProcessor;
66
67 if (m_cancel) return;
68
69 emit signalProgress(30);
70
71 QFileInfo input(fileUrl.toLocalFile());
72 QString fullFilePath(input.baseName() + QString::fromLatin1(".full.png"));
73 QFileInfo fullOutput(fullFilePath);
74
75 if (m_cancel) return;
76
77 emit signalProgress(40);
78
79 if (!rawProcessor.loadFullImage(image, fileUrl.toLocalFile(), settings))
80 {
81 errString = QString::fromLatin1("raw2png: Loading full RAW image failed. Aborted...");
82 return;
83 }
84
85 if (m_cancel) return;
86
87 emit signalProgress(60);
88
89 qDebug() << "raw2png: Saving full RAW image to "
90 << fullOutput.fileName() << " size ("
91 << image.width() << "x" << image.height()
92 << ")";
93
94 if (m_cancel) return;
95
96 emit signalProgress(80);
97
98 image.save(fullFilePath, "PNG");
99
100 emit signalDone();
101 }
102 };
103
104 // ----------------------------------------------------------------------------------------------------
105
ActionThread(QObject * const parent)106 ActionThread::ActionThread(QObject* const parent)
107 : RActionThreadBase(parent)
108 {
109 }
110
~ActionThread()111 ActionThread::~ActionThread()
112 {
113 }
114
convertRAWtoPNG(const QList<QUrl> & list,const RawDecodingSettings & settings,int priority)115 void ActionThread::convertRAWtoPNG(const QList<QUrl>& list, const RawDecodingSettings& settings, int priority)
116 {
117 RJobCollection collection;
118
119 Q_FOREACH (const QUrl& url, list)
120 {
121 Task* const job = new Task();
122 job->fileUrl = url;
123 job->settings = settings;
124
125 connect(job, SIGNAL(signalStarted()),
126 this, SLOT(slotJobStarted()));
127
128 connect(job, SIGNAL(signalProgress(int)),
129 this, SLOT(slotJobProgress(int)));
130
131 connect(job, SIGNAL(signalDone()),
132 this, SLOT(slotJobDone()));
133
134 collection.insert(job, priority);
135
136 qDebug() << "Appending file to process " << url;
137 }
138
139 appendJobs(collection);
140 }
141
slotJobDone()142 void ActionThread::slotJobDone()
143 {
144 Task* const task = dynamic_cast<Task*>(sender());
145 if (!task) return;
146
147 if (task->errString.isEmpty())
148 {
149 emit finished(task->fileUrl);
150 }
151 else
152 {
153 emit failed(task->fileUrl, task->errString);
154 }
155 }
156
slotJobProgress(int p)157 void ActionThread::slotJobProgress(int p)
158 {
159 Task* const task = dynamic_cast<Task*>(sender());
160 if (!task) return;
161
162 emit progress(task->fileUrl, p);
163 }
164
slotJobStarted()165 void ActionThread::slotJobStarted()
166 {
167 Task* const task = dynamic_cast<Task*>(sender());
168 if (!task) return;
169
170 emit starting(task->fileUrl);
171 }
172