44
44
SharpenFilter::SharpenFilter(DImg* orgImage, QObject* parent, double radius, double sigma)
45
: DImgThreadedFilter(orgImage, parent, "Sharpen")
45
: DImgThreadedFilter(orgImage, parent, "Sharpen")
52
52
SharpenFilter::SharpenFilter(DImgThreadedFilter* parentFilter,
53
53
const DImg& orgImage, const DImg& destImage,
54
54
int progressBegin, int progressEnd, double radius, double sigma)
55
: DImgThreadedFilter(parentFilter, orgImage, destImage, progressBegin, progressEnd,
56
parentFilter->filterName() + ": Sharpen")
55
: DImgThreadedFilter(parentFilter, orgImage, destImage, progressBegin, progressEnd,
56
parentFilter->filterName() + ": Sharpen")
60
61
// We need to provide support for orgImage == destImage.
61
62
// The algorithm does not support this out of the box, so use a temporary.
62
63
if (orgImage.bits() == destImage.bits())
63
65
m_destImage = DImg(destImage.width(), destImage.height(), destImage.sixteenBit());
65
70
if (orgImage.bits() == destImage.bits())
66
72
memcpy(destImage.bits(), m_destImage.bits(), m_destImage.numBytes());
69
76
SharpenFilter::~SharpenFilter()
83
90
if (m_orgImage.isNull())
85
kWarning() << "No image data available!";
92
kWarning() << "No image data available!";
91
m_destImage = m_orgImage;
98
m_destImage = m_orgImage;
95
102
double alpha, normalize=0.0;
98
105
int kernelWidth = getOptimalKernelWidth(radius, sigma);
99
106
int halfKernelWidth = kernelWidth / 2;
101
if((int)m_orgImage.width() < kernelWidth)
108
if ((int)m_orgImage.width() < kernelWidth)
103
110
kWarning() << "Image is smaller than radius!";
107
double *kernel = new double[kernelWidth*kernelWidth];
114
double* kernel = new double[kernelWidth*kernelWidth];
111
118
kWarning() << "Unable to allocate memory!";
115
for(v = -halfKernelWidth; v <= halfKernelWidth; ++v)
122
for (v = -halfKernelWidth; v <= halfKernelWidth; ++v)
117
for(u = -halfKernelWidth; u <= halfKernelWidth; ++u)
124
for (u = -halfKernelWidth; u <= halfKernelWidth; ++u)
119
126
alpha = exp(-((double) u*u+v*v)/(2.0*sigma*sigma));
120
127
kernel[i] = alpha/(2.0*M_PI*sigma*sigma);
135
142
int mx, my, sx, sy, mcx, mcy, progress;
136
143
long kernelWidth, i;
137
144
double red, green, blue, alpha, normalize=0.0;
141
148
kernelWidth = order;
142
149
long halfKernelWidth = kernelWidth / 2;
144
if((kernelWidth % 2) == 0)
151
if ((kernelWidth % 2) == 0)
146
153
kWarning() << "Kernel width must be an odd number!";
150
double *normal_kernel = new double[kernelWidth*kernelWidth];
157
double* normal_kernel = new double[kernelWidth*kernelWidth];
154
161
kWarning() << "Unable to allocate memory!";
158
for(i=0 ; i < (kernelWidth*kernelWidth) ; ++i)
165
for (i=0 ; i < (kernelWidth*kernelWidth) ; ++i)
159
167
normalize += kernel[i];
161
if(fabs(normalize) <= Epsilon)
170
if (fabs(normalize) <= Epsilon)
164
175
normalize = 1.0/normalize;
166
for(i=0 ; i < (kernelWidth*kernelWidth) ; ++i)
177
for (i=0 ; i < (kernelWidth*kernelWidth) ; ++i)
167
179
normal_kernel[i] = normalize*kernel[i];
169
182
double maxClamp = m_destImage.sixteenBit() ? 16777215.0 : 65535.0;
171
for(y=0 ; runningFlag() && (y < m_destImage.height()) ; ++y)
184
for (y=0 ; runningFlag() && (y < m_destImage.height()) ; ++y)
173
186
// FIXME: this calculation seems to be useless, since we already do it in the following loop
174
// sy = y-halfKernelWidth;
187
// sy = y-halfKernelWidth;
176
for(x=0 ; runningFlag() && (x < m_destImage.width()) ; ++x)
189
for (x=0 ; runningFlag() && (x < m_destImage.width()) ; ++x)
178
191
k = normal_kernel;
179
192
red = green = blue = alpha = 0;
180
193
sy = y-halfKernelWidth;
182
for(mcy=0 ; runningFlag() && (mcy < kernelWidth) ; ++mcy, ++sy)
195
for (mcy=0 ; runningFlag() && (mcy < kernelWidth) ; ++mcy, ++sy)
184
197
my = sy < 0 ? 0 : sy > (int)m_destImage.height()-1 ? m_destImage.height()-1 : sy;
185
198
sx = x+(-halfKernelWidth);
187
for(mcx=0 ; runningFlag() && (mcx < kernelWidth) ; ++mcx, ++sx)
200
for (mcx=0 ; runningFlag() && (mcx < kernelWidth) ; ++mcx, ++sx)
189
202
mx = sx < 0 ? 0 : sx > (int)m_destImage.width()-1 ? m_destImage.width()-1 : sx;
190
203
color = m_orgImage.getPixelColor(mx, my);
221
237
long kernelWidth;
225
242
return((int)(2.0*ceil(radius)+1.0));
227
for(kernelWidth=5; ;)
245
for (kernelWidth=5; ;)
231
for(u=(-kernelWidth/2) ; u <= (kernelWidth/2) ; ++u)
249
for (u=(-kernelWidth/2) ; u <= (kernelWidth/2) ; ++u)
232
251
normalize += exp(-((double) u*u)/(2.0*sigma*sigma))/(SQ2PI*sigma);
234
254
u = kernelWidth/2;
235
255
value = exp(-((double) u*u)/(2.0*sigma*sigma))/(SQ2PI*sigma)/normalize;
237
if((long)(65535*value) <= 0)
257
if ((long)(65535*value) <= 0)