1 /*
2 * This file is part of Converseen, an open-source batch image converter
3 * and resizer.
4 *
5 * (C) Francesco Mondello 2009 - 2021
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 *
20 * Contact e-mail: Francesco Mondello <faster3ck@gmail.com>
21 *
22 */
23 
24 #include <QMessageBox>
25 #include <QInputDialog>
26 #include <QFileInfo>
27 #include "converter.h"
28 
Converter(QObject * parent)29 Converter::Converter(QObject *parent)
30     : QThread(parent)
31 {
32     reset();
33     connect(this, SIGNAL(finished()), this, SLOT(conversionCompleted()));
34 }
35 
conversionCompleted()36 void Converter::conversionCompleted()
37 {
38     emit nextConversion(m_conv_status);
39 }
40 
reset()41 void Converter::reset()
42 {
43     m_zoom = false;
44     m_density = false;
45     m_rotation = false;
46     m_flip = false;
47 }
48 
~Converter()49 Converter::~Converter()
50 {
51 
52 }
53 
run()54 void Converter::run()
55 {
56     m_process_stopped = 0;
57     m_conv_status = 2;  // Jumped
58 
59     Image my_image;
60     QFileInfo fi(m_fileNameIn);
61 
62     QString out = m_fileNameOut;
63 
64     if (!m_overwrite)   // modalità sovrascrittura
65         out = overwriteOldFileName(out);
66 
67     if (!m_process_stopped) {
68         try {
69             my_image.quiet(true);
70             my_image.read(m_fileNameIn.toStdString());
71 
72             if (m_zoom)
73                 resize(my_image);
74             if (m_density)
75                 changeDensity(my_image);
76             if (m_rotation)
77                 rotate(my_image);
78             if (m_flip)
79                 flip(my_image);
80 
81             if (writeImage(my_image, m_format, m_quality, out))
82                 m_conv_status = 1;
83         }
84         catch (Error& my_error) {
85             m_conv_status = -1;
86 
87             QString err_status = tr("Error: %1").arg(QString::fromStdString(my_error.what()));
88             emit errorMessage(err_status);
89         }
90         catch( Magick::WarningCoder &warning )
91         {
92             m_conv_status = -1;
93 
94             QString err_status = tr("Error: %1").arg(QString::fromStdString(warning.what()));
95             emit errorMessage(err_status);
96         }
97         catch( Magick::Warning &warning )
98         {
99             m_conv_status = -1;
100 
101             QString err_status = tr("Error: %1").arg(QString::fromStdString(warning.what()));
102             emit errorMessage(err_status);
103         }
104     }
105 }
106 
setInputPicture(QString fileName)107 void Converter::setInputPicture(QString fileName)   //Name
108 {
109     m_fileNameIn = fileName;
110 }
111 
setOutputPictureName(QString fileName)112 void Converter::setOutputPictureName(QString fileName)
113 {
114     m_fileNameOut = fileName;
115 }
116 
setFormat(QString format)117 void Converter::setFormat(QString format)
118 {
119     m_format = format;
120 }
121 
setQuality(int quality)122 void Converter::setQuality(int quality)
123 {
124     m_quality = quality;
125 }
126 
setOutputDir(QString outputDir)127 void Converter::setOutputDir(QString outputDir)
128 {
129     m_outputDir = outputDir;
130 }
131 
setResize(QString resizingStr)132 void Converter::setResize(QString resizingStr)
133 {
134     resizingString = resizingStr;
135     m_zoom = true;
136 }
137 
setRotation(double deg)138 void Converter::setRotation(double deg)
139 {
140     m_rotation = true;
141     m_rotation_deg = deg;
142 }
143 
rotate(Image & my_image)144 void Converter::rotate(Image &my_image)
145 {
146     my_image.rotate(m_rotation_deg);
147 }
148 
setFlip(FlipOrientation orientation)149 void Converter::setFlip(FlipOrientation orientation)
150 {
151     m_flip = true;
152     m_orientation = orientation;
153 }
154 
flip(Image & my_image)155 void Converter::flip(Image &my_image)
156 {
157     if (m_orientation == VERTICAL)
158         my_image.flip();
159     if (m_orientation == HORIZONTAL)
160         my_image.flop();
161 }
162 
resize(Image & my_image)163 void Converter::resize(Image &my_image)
164 {
165     my_image.filterType(m_resamplingFilter);
166     my_image.resize(resizingString.toStdString());
167 }
168 
setDensity(QString densityStr)169 void Converter::setDensity(QString densityStr)
170 {
171     m_densityString = densityStr;
172     m_density = true;
173 }
174 
changeDensity(Image & my_image)175 void Converter::changeDensity(Image &my_image)
176 {
177     QString n_den = QString(m_densityString);
178     my_image.resolutionUnits(PixelsPerInchResolution);
179     my_image.density(n_den.toStdString());
180 }
181 
setBackgroundColor(QString bg_color,bool changeBg_color)182 void Converter::setBackgroundColor(QString bg_color, bool changeBg_color)
183 {
184     m_bg_color = bg_color;
185     m_changeBg_color = changeBg_color;
186 }
187 
setOverwrite(bool overwrite)188 void Converter::setOverwrite(bool overwrite)
189 {
190     m_overwrite = overwrite;
191 }
192 
overwriteOldFileName(QString out)193 QString Converter::overwriteOldFileName(QString out)
194 {
195     QFileInfo fi(out);
196     m_newBaseName = fi.baseName();
197 
198     if (fi.exists()) {
199         if (!m_overwrite) {
200             emit requestOverwrite(m_newBaseName);
201 
202             mutex.lock();
203             imageCondition.wait(&mutex);
204             mutex.unlock();
205         }
206         return QString("%1/%2.%3").arg(fi.path()).arg(m_newBaseName).arg(fi.suffix());
207     }
208     else
209         return out;
210 }
211 
setNewBasename(QString newBaseName,bool ok)212 void Converter::setNewBasename(QString newBaseName, bool ok)
213 {
214     if (ok)
215         m_newBaseName = newBaseName;
216 
217     imageCondition.wakeAll();
218 }
219 
setResamplingFilter(IMFilterType resamplingFilter)220 void Converter::setResamplingFilter(IMFilterType resamplingFilter)
221 {
222     m_resamplingFilter = resamplingFilter;
223 }
224 
writeImage(Image & my_image,QString format,int quality,QString out)225 bool Converter::writeImage(Image &my_image, QString format, int quality, QString out)
226 {
227     my_image.magick(format.toUpper().toStdString());
228 
229     QStringList excludedFormats;
230     excludedFormats << "jpg" << "jpeg" << "bmp";
231 
232     bool hasTransparency = false;
233 
234 #if MagickLibVersion < 0x700
235     hasTransparency = my_image.matte();
236 #else
237     hasTransparency = my_image.alpha();
238 #endif
239 
240     if (m_changeBg_color || (excludedFormats.contains(format, Qt::CaseInsensitive) && hasTransparency)) {
241         Image bgImg;
242         bgImg.size(Magick::Geometry(my_image.columns(), my_image.rows()));
243 
244         bgImg.read("xc:" + m_bg_color.toStdString());
245         bgImg.label("bgImg");
246         bgImg.depth(my_image.depth());
247 
248         bgImg.composite(my_image, Magick::Geometry(bgImg.columns(),bgImg.rows()), Magick::DissolveCompositeOp );
249 
250         my_image = bgImg;
251     }
252 
253     bool converted = false;
254 
255     if (quality != -1)
256         my_image.quality(quality);
257 
258     try {
259         my_image.write(out.toStdString());
260 
261         converted = true;
262     }
263     catch (Error& my_error) {
264         converted = false;
265     }
266 
267     return converted;
268 }
269 
stopProcess()270 void Converter::stopProcess()
271 {
272     m_process_stopped = 1;
273 }
274