1 /**
2 * Mandelbulber v2, a 3D fractal generator ,=#MKNmMMKmmßMNWy,
3 * ,B" ]L,,p%%%,,,§;, "K
4 * Copyright (C) 2017-20 Mandelbulber Team §R-==%w["'~5]m%=L.=~5N
5 * ,=mm=§M ]=4 yJKA"/-Nsaj "Bw,==,,
6 * This file is part of Mandelbulber. §R.r= jw",M Km .mM FW ",§=ß., ,TN
7 * ,4R =%["w[N=7]J '"5=],""]]M,w,-; T=]M
8 * Mandelbulber is free software: §R.ß~-Q/M=,=5"v"]=Qf,'§"M= =,M.§ Rz]M"Kw
9 * you can redistribute it and/or §w "xDY.J ' -"m=====WeC=\ ""%""y=%"]"" §
10 * modify it under the terms of the "§M=M =D=4"N #"%==A%p M§ M6 R' #"=~.4M
11 * GNU General Public License as §W =, ][T"]C § § '§ e===~ U !§[Z ]N
12 * published by the 4M",,Jm=,"=e~ § § j]]""N BmM"py=ßM
13 * Free Software Foundation, ]§ T,M=& 'YmMMpM9MMM%=w=,,=MT]M m§;'§,
14 * either version 3 of the License, TWw [.j"5=~N[=§%=%W,T ]R,"=="Y[LFT ]N
15 * or (at your option) TW=,-#"%=;[ =Q:["V"" ],,M.m == ]N
16 * any later version. J§"mr"] ,=,," =="""J]= M"M"]==ß"
17 * §= "=C=4 §"eM "=B:m|4"]#F,§~
18 * Mandelbulber is distributed in "9w=,,]w em%wJ '"~" ,=,,ß"
19 * the hope that it will be useful, . "K= ,=RMMMßM"""
20 * but WITHOUT ANY WARRANTY; .'''
21 * without even the implied warranty
22 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 *
24 * See the GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with Mandelbulber. If not, see <http://www.gnu.org/licenses/>.
27 *
28 * ###########################################################################
29 *
30 * Authors: Krzysztof Marczak (buddhi1980@gmail.com)
31 *
32 * cPostEffectHdrBlur - Renders a weighted blur which works on HDR image data
33 */
34
35 #include "post_effect_hdr_blur.h"
36
37 #include "cimage.hpp"
38 #include "global_data.hpp"
39 #include "progress_text.hpp"
40 #include "system_data.hpp"
41
cPostEffectHdrBlur(std::shared_ptr<cImage> _image)42 cPostEffectHdrBlur::cPostEffectHdrBlur(std::shared_ptr<cImage> _image) : QObject(), image(_image)
43 {
44 tempImage.resize(image->GetHeight() * image->GetWidth());
45 radius = 0;
46 intensity = 0;
47 }
48
~cPostEffectHdrBlur()49 cPostEffectHdrBlur::~cPostEffectHdrBlur()
50 {
51 // nothing to delete
52 }
53
Render(bool * stopRequest)54 void cPostEffectHdrBlur::Render(bool *stopRequest)
55 {
56
57 tempImage = image->GetPostImageFloat();
58
59 const double blurSize = radius * (image->GetWidth() + image->GetHeight()) * 0.001;
60 const double blurSize2 = blurSize * blurSize;
61 const int intBlurSize = int(blurSize + 1);
62 const double limiter = intensity;
63
64 QString statusText = QObject::tr("Rendering HDR Blur effect");
65 QString progressTxt;
66
67 cProgressText progressText;
68 progressText.ResetTimer();
69 double percentDone = 0.0;
70
71 QElapsedTimer timerRefreshProgressBar;
72 timerRefreshProgressBar.start();
73
74 for (qint64 y = 0; y < qint64(image->GetHeight()); y++)
75 {
76 if (*stopRequest || systemData.globalStopRequest) break;
77
78 #pragma omp parallel for
79 for (qint64 x = 0; x < qint64(image->GetWidth()); x++)
80 {
81 double weight = 0;
82 int yStart = qMax(0LL, y - intBlurSize);
83 int yEnd = qMin(qint64(image->GetHeight()), y + intBlurSize);
84
85 sRGBFloat newPixel;
86
87 for (int yy = yStart; yy < yEnd; yy++)
88 {
89 int xStart = qMax(0LL, x - intBlurSize);
90 int xEnd = qMin(qint64(image->GetWidth()), x + intBlurSize);
91 for (int xx = xStart; xx < xEnd; xx++)
92 {
93 double dx = x - xx;
94 double dy = y - yy;
95 double r2 = dx * dx + dy * dy;
96 if (r2 < blurSize2)
97 {
98 double value = 1.0 / (r2 / (0.2 * blurSize) + limiter);
99 // if(dx == 0 && dy == 0) value = 10.0;
100 weight += value;
101 sRGBFloat oldPixel = tempImage[xx + yy * image->GetWidth()];
102 newPixel.R += oldPixel.R * value;
103 newPixel.G += oldPixel.G * value;
104 newPixel.B += oldPixel.B * value;
105 }
106 }
107 }
108
109 if (weight > 0)
110 {
111 newPixel.R /= weight;
112 newPixel.G /= weight;
113 newPixel.B /= weight;
114 }
115 image->PutPixelPostImage(x, y, newPixel);
116 }
117
118 if (timerRefreshProgressBar.elapsed() > 100)
119 {
120 timerRefreshProgressBar.restart();
121
122 percentDone = float(y) / float(image->GetHeight());
123 progressTxt = progressText.getText(percentDone);
124
125 emit updateProgressAndStatus(statusText, progressTxt, percentDone);
126 gApplication->processEvents();
127 }
128 }
129
130 emit updateProgressAndStatus(statusText, progressText.getText(1.0), 1.0);
131 }
132
SetParameters(double _radius,double _intensity)133 void cPostEffectHdrBlur::SetParameters(double _radius, double _intensity)
134 {
135 radius = _radius;
136 intensity = _intensity;
137 }
138