/**
* Mandelbulber v2, a 3D fractal generator ,=#MKNmMMKmmßMNWy,
* ,B" ]L,,p%%%,,,§;, "K
* Copyright (C) 2017-20 Mandelbulber Team §R-==%w["'~5]m%=L.=~5N
* ,=mm=§M ]=4 yJKA"/-Nsaj "Bw,==,,
* This file is part of Mandelbulber. §R.r= jw",M Km .mM FW ",§=ß., ,TN
* ,4R =%["w[N=7]J '"5=],""]]M,w,-; T=]M
* Mandelbulber is free software: §R.ß~-Q/M=,=5"v"]=Qf,'§"M= =,M.§ Rz]M"Kw
* you can redistribute it and/or §w "xDY.J ' -"m=====WeC=\ ""%""y=%"]"" §
* modify it under the terms of the "§M=M =D=4"N #"%==A%p M§ M6 R' #"=~.4M
* GNU General Public License as §W =, ][T"]C § § '§ e===~ U !§[Z ]N
* published by the 4M",,Jm=,"=e~ § § j]]""N BmM"py=ßM
* Free Software Foundation, ]§ T,M=& 'YmMMpM9MMM%=w=,,=MT]M m§;'§,
* either version 3 of the License, TWw [.j"5=~N[=§%=%W,T ]R,"=="Y[LFT ]N
* or (at your option) TW=,-#"%=;[ =Q:["V"" ],,M.m == ]N
* any later version. J§"mr"] ,=,," =="""J]= M"M"]==ß"
* §= "=C=4 §"eM "=B:m|4"]#F,§~
* Mandelbulber is distributed in "9w=,,]w em%wJ '"~" ,=,,ß"
* the hope that it will be useful, . "K= ,=RMMMßM"""
* but WITHOUT ANY WARRANTY; .'''
* without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Mandelbulber. If not, see .
*
* ###########################################################################
*
* Authors: Krzysztof Marczak (buddhi1980@gmail.com)
*
* cPostEffectHdrBlur - Renders a weighted blur which works on HDR image data
*/
#include "post_effect_hdr_blur.h"
#include "cimage.hpp"
#include "global_data.hpp"
#include "progress_text.hpp"
#include "system_data.hpp"
cPostEffectHdrBlur::cPostEffectHdrBlur(std::shared_ptr _image) : QObject(), image(_image)
{
tempImage.resize(image->GetHeight() * image->GetWidth());
radius = 0;
intensity = 0;
}
cPostEffectHdrBlur::~cPostEffectHdrBlur()
{
// nothing to delete
}
void cPostEffectHdrBlur::Render(bool *stopRequest)
{
tempImage = image->GetPostImageFloat();
const double blurSize = radius * (image->GetWidth() + image->GetHeight()) * 0.001;
const double blurSize2 = blurSize * blurSize;
const int intBlurSize = int(blurSize + 1);
const double limiter = intensity;
QString statusText = QObject::tr("Rendering HDR Blur effect");
QString progressTxt;
cProgressText progressText;
progressText.ResetTimer();
double percentDone = 0.0;
QElapsedTimer timerRefreshProgressBar;
timerRefreshProgressBar.start();
for (qint64 y = 0; y < qint64(image->GetHeight()); y++)
{
if (*stopRequest || systemData.globalStopRequest) break;
#pragma omp parallel for
for (qint64 x = 0; x < qint64(image->GetWidth()); x++)
{
double weight = 0;
int yStart = qMax(0LL, y - intBlurSize);
int yEnd = qMin(qint64(image->GetHeight()), y + intBlurSize);
sRGBFloat newPixel;
for (int yy = yStart; yy < yEnd; yy++)
{
int xStart = qMax(0LL, x - intBlurSize);
int xEnd = qMin(qint64(image->GetWidth()), x + intBlurSize);
for (int xx = xStart; xx < xEnd; xx++)
{
double dx = x - xx;
double dy = y - yy;
double r2 = dx * dx + dy * dy;
if (r2 < blurSize2)
{
double value = 1.0 / (r2 / (0.2 * blurSize) + limiter);
// if(dx == 0 && dy == 0) value = 10.0;
weight += value;
sRGBFloat oldPixel = tempImage[xx + yy * image->GetWidth()];
newPixel.R += oldPixel.R * value;
newPixel.G += oldPixel.G * value;
newPixel.B += oldPixel.B * value;
}
}
}
if (weight > 0)
{
newPixel.R /= weight;
newPixel.G /= weight;
newPixel.B /= weight;
}
image->PutPixelPostImage(x, y, newPixel);
}
if (timerRefreshProgressBar.elapsed() > 100)
{
timerRefreshProgressBar.restart();
percentDone = float(y) / float(image->GetHeight());
progressTxt = progressText.getText(percentDone);
emit updateProgressAndStatus(statusText, progressTxt, percentDone);
gApplication->processEvents();
}
}
emit updateProgressAndStatus(statusText, progressText.getText(1.0), 1.0);
}
void cPostEffectHdrBlur::SetParameters(double _radius, double _intensity)
{
radius = _radius;
intensity = _intensity;
}