~ubuntu-branches/ubuntu/saucy/digikam/saucy

« back to all changes in this revision

Viewing changes to libs/dimg/filters/sharp/sharpenfilter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-12-21 23:19:11 UTC
  • mfrom: (1.2.33 upstream) (3.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20101221231911-z9jip7s5aht1jqn9
Tags: 2:1.7.0-1ubuntu1
* Merge from Debian Experimental. Remaining Ubuntu changes:
  - Export .pot name and copy to plugins in debian/rules
  - Version build-depends on kipi-plugins-dev to ensure build is against the
    same version on all archs
* Drop debian/patches/kubuntu_01_linker.diff, incoporated upstream
* Remove patches directory and unused patches

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
{
43
43
 
44
44
SharpenFilter::SharpenFilter(DImg* orgImage, QObject* parent, double radius, double sigma)
45
 
             : DImgThreadedFilter(orgImage, parent, "Sharpen")
 
45
    : DImgThreadedFilter(orgImage, parent, "Sharpen")
46
46
{
47
47
    m_radius = radius;
48
48
    m_sigma  = sigma;
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")
57
57
{
58
58
    m_radius = radius;
59
59
    m_sigma  = sigma;
 
60
 
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())
 
64
    {
63
65
        m_destImage = DImg(destImage.width(), destImage.height(), destImage.sixteenBit());
 
66
    }
 
67
 
64
68
    filterImage();
 
69
 
65
70
    if (orgImage.bits() == destImage.bits())
 
71
    {
66
72
        memcpy(destImage.bits(), m_destImage.bits(), m_destImage.numBytes());
 
73
    }
67
74
}
68
75
 
69
76
SharpenFilter::~SharpenFilter()
82
89
{
83
90
    if (m_orgImage.isNull())
84
91
    {
85
 
       kWarning() << "No image data available!";
86
 
       return;
 
92
        kWarning() << "No image data available!";
 
93
        return;
87
94
    }
88
95
 
89
96
    if (radius <= 0.0)
90
97
    {
91
 
       m_destImage = m_orgImage;
92
 
       return;
 
98
        m_destImage = m_orgImage;
 
99
        return;
93
100
    }
94
101
 
95
102
    double        alpha, normalize=0.0;
98
105
    int kernelWidth     = getOptimalKernelWidth(radius, sigma);
99
106
    int halfKernelWidth = kernelWidth / 2;
100
107
 
101
 
    if((int)m_orgImage.width() < kernelWidth)
 
108
    if ((int)m_orgImage.width() < kernelWidth)
102
109
    {
103
110
        kWarning() << "Image is smaller than radius!";
104
111
        return;
105
112
    }
106
113
 
107
 
    double *kernel = new double[kernelWidth*kernelWidth];
 
114
    double* kernel = new double[kernelWidth*kernelWidth];
108
115
 
109
 
    if(!kernel)
 
116
    if (!kernel)
110
117
    {
111
118
        kWarning() << "Unable to allocate memory!";
112
119
        return;
113
120
    }
114
121
 
115
 
    for(v = -halfKernelWidth; v <= halfKernelWidth; ++v)
 
122
    for (v = -halfKernelWidth; v <= halfKernelWidth; ++v)
116
123
    {
117
 
        for(u = -halfKernelWidth; u <= halfKernelWidth; ++u)
 
124
        for (u = -halfKernelWidth; u <= halfKernelWidth; ++u)
118
125
        {
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;
138
 
    double *k=0;
 
145
    double* k=0;
139
146
    DColor  color;
140
147
 
141
148
    kernelWidth          = order;
142
149
    long halfKernelWidth = kernelWidth / 2;
143
150
 
144
 
    if((kernelWidth % 2) == 0)
 
151
    if ((kernelWidth % 2) == 0)
145
152
    {
146
153
        kWarning() << "Kernel width must be an odd number!";
147
154
        return(false);
148
155
    }
149
156
 
150
 
    double *normal_kernel = new double[kernelWidth*kernelWidth];
 
157
    double* normal_kernel = new double[kernelWidth*kernelWidth];
151
158
 
152
 
    if(!normal_kernel)
 
159
    if (!normal_kernel)
153
160
    {
154
161
        kWarning() << "Unable to allocate memory!";
155
162
        return(false);
156
163
    }
157
164
 
158
 
    for(i=0 ; i < (kernelWidth*kernelWidth) ; ++i)
 
165
    for (i=0 ; i < (kernelWidth*kernelWidth) ; ++i)
 
166
    {
159
167
        normalize += kernel[i];
 
168
    }
160
169
 
161
 
    if(fabs(normalize) <= Epsilon)
 
170
    if (fabs(normalize) <= Epsilon)
 
171
    {
162
172
        normalize=1.0;
 
173
    }
163
174
 
164
175
    normalize = 1.0/normalize;
165
176
 
166
 
    for(i=0 ; i < (kernelWidth*kernelWidth) ; ++i)
 
177
    for (i=0 ; i < (kernelWidth*kernelWidth) ; ++i)
 
178
    {
167
179
        normal_kernel[i] = normalize*kernel[i];
 
180
    }
168
181
 
169
182
    double maxClamp = m_destImage.sixteenBit() ? 16777215.0 : 65535.0;
170
183
 
171
 
    for(y=0 ; runningFlag() && (y < m_destImage.height()) ; ++y)
 
184
    for (y=0 ; runningFlag() && (y < m_destImage.height()) ; ++y)
172
185
    {
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;
175
188
 
176
 
        for(x=0 ; runningFlag() && (x < m_destImage.width()) ; ++x)
 
189
        for (x=0 ; runningFlag() && (x < m_destImage.width()) ; ++x)
177
190
        {
178
191
            k   = normal_kernel;
179
192
            red = green = blue = alpha = 0;
180
193
            sy  = y-halfKernelWidth;
181
194
 
182
 
            for(mcy=0 ; runningFlag() && (mcy < kernelWidth) ; ++mcy, ++sy)
 
195
            for (mcy=0 ; runningFlag() && (mcy < kernelWidth) ; ++mcy, ++sy)
183
196
            {
184
197
                my = sy < 0 ? 0 : sy > (int)m_destImage.height()-1 ? m_destImage.height()-1 : sy;
185
198
                sx = x+(-halfKernelWidth);
186
199
 
187
 
                for(mcx=0 ; runningFlag() && (mcx < kernelWidth) ; ++mcx, ++sx)
 
200
                for (mcx=0 ; runningFlag() && (mcx < kernelWidth) ; ++mcx, ++sx)
188
201
                {
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);
207
220
        }
208
221
 
209
222
        progress = (int)(((double)y * 100.0) / m_destImage.height());
 
223
 
210
224
        if ( progress%5 == 0 )
211
 
           postProgress( progress );
 
225
        {
 
226
            postProgress( progress );
 
227
        }
212
228
    }
213
229
 
214
230
    delete [] normal_kernel;
221
237
    long          kernelWidth;
222
238
    register long u;
223
239
 
224
 
    if(radius > 0.0)
 
240
    if (radius > 0.0)
 
241
    {
225
242
        return((int)(2.0*ceil(radius)+1.0));
 
243
    }
226
244
 
227
 
    for(kernelWidth=5; ;)
 
245
    for (kernelWidth=5; ;)
228
246
    {
229
247
        normalize=0.0;
230
248
 
231
 
        for(u=(-kernelWidth/2) ; u <= (kernelWidth/2) ; ++u)
 
249
        for (u=(-kernelWidth/2) ; u <= (kernelWidth/2) ; ++u)
 
250
        {
232
251
            normalize += exp(-((double) u*u)/(2.0*sigma*sigma))/(SQ2PI*sigma);
 
252
        }
233
253
 
234
254
        u     = kernelWidth/2;
235
255
        value = exp(-((double) u*u)/(2.0*sigma*sigma))/(SQ2PI*sigma)/normalize;
236
256
 
237
 
        if((long)(65535*value) <= 0)
 
257
        if ((long)(65535*value) <= 0)
 
258
        {
238
259
            break;
 
260
        }
239
261
 
240
262
        kernelWidth+=2;
241
263
    }