1 /*******************************************************************************************************
2 nomacs is a fast and small image viewer with the capability of synchronizing multiple instances
3
4 Copyright (C) 2011-2016 Markus Diem <markus@nomacs.org>
5 Copyright (C) 2011-2016 Stefan Fiel <stefan@nomacs.org>
6 Copyright (C) 2011-2016 Florian Kleber <florian@nomacs.org>
7
8 This file is part of nomacs.
9
10 nomacs is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 nomacs is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22
23 related links:
24 [1] https://nomacs.org/
25 [2] https://github.com/nomacs/
26 [3] http://download.nomacs.org
27 *******************************************************************************************************/
28
29 #include "DkManipulatorsIpl.h"
30
31 #include "DkImageStorage.h"
32 #include "DkMath.h"
33
34 #pragma warning(push, 0) // no warnings from includes
35 #include <QSharedPointer>
36 #include <QDebug>
37 #pragma warning(pop)
38
39 namespace nmc {
40
41 // DkGrayScaleManipulator --------------------------------------------------------------------
DkGrayScaleManipulator(QAction * action)42 DkGrayScaleManipulator::DkGrayScaleManipulator(QAction * action) : DkBaseManipulator(action) {
43 }
44
apply(const QImage & img) const45 QImage DkGrayScaleManipulator::apply(const QImage& img) const {
46
47 if (img.isNull())
48 return img;
49
50 return DkImage::grayscaleImage(img);
51 }
52
errorMessage() const53 QString DkGrayScaleManipulator::errorMessage() const {
54 return QObject::tr("Could not convert to grayscale");
55 }
56
57 // DkAutoAdjustManipulator --------------------------------------------------------------------
DkAutoAdjustManipulator(QAction * action)58 DkAutoAdjustManipulator::DkAutoAdjustManipulator(QAction * action) : DkBaseManipulator(action) {
59 }
60
apply(const QImage & img) const61 QImage DkAutoAdjustManipulator::apply(const QImage & img) const {
62
63 QImage imgR = img;
64 if (DkImage::autoAdjustImage(imgR))
65 return imgR;
66
67 return QImage();
68 }
69
errorMessage() const70 QString DkAutoAdjustManipulator::errorMessage() const {
71 return QString(QObject::tr("Cannot auto adjust"));
72 }
73
74 // DkNormalizeManipulator --------------------------------------------------------------------
DkNormalizeManipulator(QAction * action)75 DkNormalizeManipulator::DkNormalizeManipulator(QAction * action) : DkBaseManipulator(action) {
76 }
77
apply(const QImage & img) const78 QImage DkNormalizeManipulator::apply(const QImage & img) const {
79
80 QImage imgR = img;
81 if (DkImage::normImage(imgR)) {
82 return imgR;
83 }
84
85 return QImage();
86 }
87
errorMessage() const88 QString DkNormalizeManipulator::errorMessage() const {
89 return QObject::tr("The Image is Already Normalized...");
90 }
91
92 // DkInvertManipulator --------------------------------------------------------------------
DkInvertManipulator(QAction * action)93 DkInvertManipulator::DkInvertManipulator(QAction * action) : DkBaseManipulator(action) {
94 }
95
apply(const QImage & img) const96 QImage DkInvertManipulator::apply(const QImage & img) const {
97
98 QImage imgR = img;
99 imgR.invertPixels();
100 return imgR;
101 }
102
errorMessage() const103 QString DkInvertManipulator::errorMessage() const {
104 return QObject::tr("Cannot invert image");
105 }
106
107 // Flip Horizontally --------------------------------------------------------------------
DkFlipHManipulator(QAction * action)108 DkFlipHManipulator::DkFlipHManipulator(QAction * action) : DkBaseManipulator(action) {
109 }
110
apply(const QImage & img) const111 QImage DkFlipHManipulator::apply(const QImage & img) const {
112
113 return img.mirrored(true, false);
114 }
115
errorMessage() const116 QString DkFlipHManipulator::errorMessage() const {
117 return QObject::tr("Cannot flip image");
118 }
119
120 // Flip Vertically --------------------------------------------------------------------
DkFlipVManipulator(QAction * action)121 DkFlipVManipulator::DkFlipVManipulator(QAction * action) : DkBaseManipulator(action) {
122 }
123
apply(const QImage & img) const124 QImage DkFlipVManipulator::apply(const QImage & img) const {
125 return img.mirrored(false, true);
126 }
127
errorMessage() const128 QString DkFlipVManipulator::errorMessage() const {
129 return QObject::tr("Cannot flip image");
130 }
131
132 // DkTinyPlanetManipulator --------------------------------------------------------------------
DkTinyPlanetManipulator(QAction * action)133 DkTinyPlanetManipulator::DkTinyPlanetManipulator(QAction * action) : DkBaseManipulatorExt(action) {
134 }
135
apply(const QImage & img) const136 QImage DkTinyPlanetManipulator::apply(const QImage & img) const {
137
138 #ifdef WITH_OPENCV
139 int ms = qMax(img.width(), img.height());
140 QSize s(ms, ms);
141
142 QImage imgR = img.copy();
143 DkImage::tinyPlanet(imgR, size(), angle()*DK_DEG2RAD, s, inverted());
144 return imgR;
145 #else
146 Q_UNUSED(img);
147 return QImage(); // trigger warning
148 #endif
149 }
150
errorMessage() const151 QString DkTinyPlanetManipulator::errorMessage() const {
152 return QObject::tr("Sorry, I could not create a tiny planet");
153 }
154
setAngle(int angle)155 void DkTinyPlanetManipulator::setAngle(int angle) {
156
157 if (angle == mAngle)
158 return;
159
160 mAngle = angle;
161 action()->trigger();
162 }
163
angle() const164 int DkTinyPlanetManipulator::angle() const {
165 return mAngle;
166 }
167
setSize(int size)168 void DkTinyPlanetManipulator::setSize(int size) {
169
170 if (mSize == size)
171 return;
172
173 mSize = size;
174 action()->trigger();
175 }
176
size() const177 int DkTinyPlanetManipulator::size() const {
178 return mSize;
179 }
180
setInverted(bool inverted)181 void DkTinyPlanetManipulator::setInverted(bool inverted) {
182
183 if (mInverted == inverted)
184 return;
185
186 mInverted = inverted;
187 action()->trigger();
188 }
189
inverted() const190 bool DkTinyPlanetManipulator::inverted() const {
191 return mInverted;
192 }
193
194 // DkUnsharpMaskManipulator --------------------------------------------------------------------
DkBlurManipulator(QAction * action)195 DkBlurManipulator::DkBlurManipulator(QAction* action) : DkBaseManipulatorExt(action) {
196 }
197
apply(const QImage & img) const198 QImage DkBlurManipulator::apply(const QImage& img) const {
199
200 QImage imgC = img.copy();
201 DkImage::gaussianBlur(imgC, (float)sigma());
202 return imgC;
203 }
204
errorMessage() const205 QString DkBlurManipulator::errorMessage() const {
206
207 // so give me coffee & TV
208 return QObject::tr("Cannot blur image");
209 }
210
setSigma(int sigma)211 void DkBlurManipulator::setSigma(int sigma) {
212
213 if (mSigma == sigma)
214 return;
215
216 mSigma = sigma;
217 action()->trigger();
218 }
219
sigma() const220 int DkBlurManipulator::sigma() const {
221 return mSigma;
222 }
223
224 // DkUnsharpMaskManipulator --------------------------------------------------------------------
DkUnsharpMaskManipulator(QAction * action)225 DkUnsharpMaskManipulator::DkUnsharpMaskManipulator(QAction * action) : DkBaseManipulatorExt(action) {
226 }
227
apply(const QImage & img) const228 QImage DkUnsharpMaskManipulator::apply(const QImage & img) const {
229
230 QImage imgC = img.copy();
231 DkImage::unsharpMask(imgC, (float)sigma(), 1.0f+amount()/100.0f);
232 return imgC;
233 }
234
errorMessage() const235 QString DkUnsharpMaskManipulator::errorMessage() const {
236 return QObject::tr("Cannot sharpen image");
237 }
238
setSigma(int sigma)239 void DkUnsharpMaskManipulator::setSigma(int sigma) {
240
241 if (mSigma == sigma)
242 return;
243
244 mSigma = sigma;
245 action()->trigger();
246 }
247
sigma() const248 int DkUnsharpMaskManipulator::sigma() const {
249 return mSigma;
250 }
251
setAmount(int amount)252 void DkUnsharpMaskManipulator::setAmount(int amount) {
253
254 if (mAmount == amount)
255 return;
256
257 mAmount = amount;
258 action()->trigger();
259 }
260
amount() const261 int DkUnsharpMaskManipulator::amount() const {
262 return mAmount;
263 }
264
265 // Rotate Manipulator --------------------------------------------------------------------
DkRotateManipulator(QAction * action)266 DkRotateManipulator::DkRotateManipulator(QAction * action) : DkBaseManipulatorExt(action) {
267 }
268
apply(const QImage & img) const269 QImage DkRotateManipulator::apply(const QImage & img) const {
270 return DkImage::rotateImage(img, angle());
271 }
272
errorMessage() const273 QString DkRotateManipulator::errorMessage() const {
274 return QObject::tr("Cannot rotate image");
275 }
276
setAngle(int angle)277 void DkRotateManipulator::setAngle(int angle) {
278
279 if (angle == mAngle)
280 return;
281
282 mAngle = angle;
283 action()->trigger();
284 }
285
angle() const286 int DkRotateManipulator::angle() const {
287 return mAngle;
288 }
289
290 // -------------------------------------------------------------------- DkResizeManipulator
DkResizeManipulator(QAction * action)291 DkResizeManipulator::DkResizeManipulator(QAction * action) : DkBaseManipulatorExt(action) {
292 }
293
apply(const QImage & img) const294 QImage DkResizeManipulator::apply(const QImage & img) const {
295
296 if (mScaleFactor == 1.0)
297 return img;
298
299 return DkImage::resizeImage(img, QSize(), mScaleFactor, mInterpolation, mCorrectGamma);
300 }
301
errorMessage() const302 QString DkResizeManipulator::errorMessage() const {
303 return QObject::tr("Cannot resize image");
304 }
305
setScaleFactor(double sf)306 void DkResizeManipulator::setScaleFactor(double sf) {
307 mScaleFactor = sf;
308 action()->trigger();
309 }
310
scaleFactor() const311 double DkResizeManipulator::scaleFactor() const {
312 return mScaleFactor;
313 }
314
setInterpolation(int ipl)315 void DkResizeManipulator::setInterpolation(int ipl) {
316 mInterpolation = ipl;
317 action()->trigger();
318 }
319
interpolation() const320 int DkResizeManipulator::interpolation() const {
321 return mInterpolation;
322 }
323
setCorrectGamma(bool cg)324 void DkResizeManipulator::setCorrectGamma(bool cg) {
325 mCorrectGamma = cg;
326 action()->trigger();
327 }
328
correctGamma() const329 bool DkResizeManipulator::correctGamma() const {
330 return mCorrectGamma;
331 }
332
333
334 // Rotate Manipulator --------------------------------------------------------------------
DkThresholdManipulator(QAction * action)335 DkThresholdManipulator::DkThresholdManipulator(QAction * action) : DkBaseManipulatorExt(action) {
336 }
337
apply(const QImage & img) const338 QImage DkThresholdManipulator::apply(const QImage & img) const {
339
340 return DkImage::thresholdImage(img, threshold(), color());
341 }
342
errorMessage() const343 QString DkThresholdManipulator::errorMessage() const {
344 return QObject::tr("Cannot threshold image");
345 }
346
setThreshold(int thr)347 void DkThresholdManipulator::setThreshold(int thr) {
348
349 if (thr == mThreshold)
350 return;
351
352 mThreshold = thr;
353 action()->trigger();
354 }
355
threshold() const356 int DkThresholdManipulator::threshold() const {
357 return mThreshold;
358 }
359
setColor(bool col)360 void DkThresholdManipulator::setColor(bool col) {
361
362 if (col == mColor)
363 return;
364
365 mColor = col;
366 action()->trigger();
367 }
368
color() const369 bool DkThresholdManipulator::color() const {
370 return mColor;
371 }
372
373 // DkHueManipulator --------------------------------------------------------------------
DkHueManipulator(QAction * action)374 DkHueManipulator::DkHueManipulator(QAction * action) : DkBaseManipulatorExt(action) {
375 }
376
apply(const QImage & img) const377 QImage DkHueManipulator::apply(const QImage & img) const {
378 return DkImage::hueSaturation(img, hue(), saturation(), value());
379 }
380
errorMessage() const381 QString DkHueManipulator::errorMessage() const {
382 return QObject::tr("Cannot change Hue/Saturation");
383 }
384
setHue(int hue)385 void DkHueManipulator::setHue(int hue) {
386
387 if (mHue == hue)
388 return;
389
390 mHue = hue;
391 action()->trigger();
392 }
393
hue() const394 int DkHueManipulator::hue() const {
395 return mHue;
396 }
397
setSaturation(int sat)398 void DkHueManipulator::setSaturation(int sat) {
399
400 if (mSat == sat)
401 return;
402
403 mSat = sat;
404 action()->trigger();
405 }
406
saturation() const407 int DkHueManipulator::saturation() const {
408 return mSat;
409 }
410
setValue(int val)411 void DkHueManipulator::setValue(int val) {
412
413 if (mValue == val)
414 return;
415
416 mValue = val;
417 action()->trigger();
418 }
419
value() const420 int DkHueManipulator::value() const {
421 return mValue;
422 }
423
DkExposureManipulator(QAction * action)424 DkExposureManipulator::DkExposureManipulator(QAction * action) : DkBaseManipulatorExt(action) {
425 }
426
apply(const QImage & img) const427 QImage DkExposureManipulator::apply(const QImage & img) const {
428 return DkImage::exposure(img, exposure(), offset(), gamma());
429 }
430
errorMessage() const431 QString DkExposureManipulator::errorMessage() const {
432 return QObject::tr("Cannot apply exposure");
433 }
434
setExposure(double exposure)435 void DkExposureManipulator::setExposure(double exposure) {
436
437 if (mExposure == exposure)
438 return;
439
440 mExposure = exposure;
441 action()->trigger();
442 }
443
exposure() const444 double DkExposureManipulator::exposure() const {
445 return mExposure;
446 }
447
setOffset(double offset)448 void DkExposureManipulator::setOffset(double offset) {
449
450 if (mOffset == offset)
451 return;
452
453 mOffset = offset;
454 action()->trigger();
455 }
456
offset() const457 double DkExposureManipulator::offset() const {
458 return mOffset;
459 }
460
setGamma(double gamma)461 void DkExposureManipulator::setGamma(double gamma) {
462
463 if (mGamma == gamma)
464 return;
465
466 mGamma = gamma;
467 action()->trigger();
468 }
469
gamma() const470 double DkExposureManipulator::gamma() const {
471 return mGamma;
472 }
473
474 // -------------------------------------------------------------------- DkColorManipulator
DkColorManipulator(QAction * action)475 DkColorManipulator::DkColorManipulator(QAction * action) : DkBaseManipulatorExt(action) {
476 }
477
apply(const QImage & img) const478 QImage DkColorManipulator::apply(const QImage & img) const {
479
480 return DkImage::bgColor(img, color());
481 }
482
errorMessage() const483 QString DkColorManipulator::errorMessage() const {
484 return QObject::tr("Cannot draw background color");
485 }
486
setColor(const QColor & col)487 void DkColorManipulator::setColor(const QColor & col) {
488
489 if (mColor == col)
490 return;
491
492 mColor = col;
493 action()->trigger();
494 }
495
color() const496 QColor DkColorManipulator::color() const {
497 return mColor;
498 }
499
500 }