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

« back to all changes in this revision

Viewing changes to libs/dimg/filters/lens/lensfunfilter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Christian Mangold
  • Date: 2010-04-09 21:30:01 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100409213001-4bfyibrd359rn7o3
Tags: 2:1.2.0-0ubuntu1
* New upstream release (LP: #560576)
* Remove all patches, fixed upstream
  - Remove quilt build-depend

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ============================================================
 
2
 *
 
3
 * Date        : 2008-02-10
 
4
 * Description : a plugin to fix automatically camera lens aberrations
 
5
 *
 
6
 * Copyright (C) 2008 by Adrian Schroeter <adrian at suse dot de>
 
7
 * Copyright (C) 2008-2010 by Gilles Caulier <caulier dot gilles at gmail dot com>
 
8
 *
 
9
 * This program is free software; you can redistribute it
 
10
 * and/or modify it under the terms of the GNU General
 
11
 * Public License as published by the Free Software Foundation;
 
12
 * either version 2, or (at your option) any later version.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * ============================================================ */
 
20
 
 
21
#include "lensfunfilter.h"
 
22
 
 
23
// Qt includes
 
24
 
 
25
#include <QByteArray>
 
26
#include <QCheckBox>
 
27
#include <QString>
 
28
 
 
29
// KDE includes
 
30
 
 
31
#include <kdebug.h>
 
32
 
 
33
// Local includes
 
34
 
 
35
#include "lensfuniface.h"
 
36
 
 
37
namespace Digikam
 
38
{
 
39
 
 
40
class LensFunFilterPriv
 
41
{
 
42
public:
 
43
 
 
44
    LensFunFilterPriv()
 
45
    {
 
46
        iface    = 0;
 
47
        modifier = 0;
 
48
    }
 
49
 
 
50
    LensFunIface* iface;
 
51
 
 
52
    lfModifier*   modifier;
 
53
};
 
54
 
 
55
LensFunFilter::LensFunFilter(DImg* orgImage, QObject* parent, LensFunIface* iface,
 
56
                             const LensFunContainer& settings)
 
57
             : DImgThreadedFilter(orgImage, parent, "LensCorrection"),
 
58
               d(new LensFunFilterPriv)
 
59
{
 
60
    d->iface = iface;
 
61
    d->iface->setSettings(settings);
 
62
 
 
63
    initFilter();
 
64
}
 
65
 
 
66
LensFunFilter::~LensFunFilter()
 
67
{
 
68
    delete d;
 
69
}
 
70
 
 
71
void LensFunFilter::filterImage()
 
72
{
 
73
#if 0
 
74
    if (!opts.Crop)
 
75
        opts.Crop = lens->CropFactor;
 
76
    if (!opts.Focal)
 
77
        opts.Focal = lens->MinFocal;
 
78
    if (!opts.Aperture)
 
79
        opts.Aperture = lens->MinAperture;
 
80
#endif
 
81
 
 
82
    int modifyFlags = 0;
 
83
    if ( d->iface->m_settings.filterDist )
 
84
       modifyFlags |= LF_MODIFY_DISTORTION;
 
85
    if ( d->iface->m_settings.filterGeom )
 
86
       modifyFlags |= LF_MODIFY_GEOMETRY;
 
87
    if ( d->iface->m_settings.filterCCA )
 
88
       modifyFlags |= LF_MODIFY_TCA;
 
89
    if ( d->iface->m_settings.filterVig )
 
90
       modifyFlags |= LF_MODIFY_VIGNETTING;
 
91
    if ( d->iface->m_settings.filterCCI )
 
92
       modifyFlags |= LF_MODIFY_CCI;
 
93
 
 
94
    // Init lensfun lib, we are working on the full image.
 
95
 
 
96
    lfPixelFormat colorDepth = m_orgImage.bytesDepth() == 4 ? LF_PF_U8 : LF_PF_U16;
 
97
 
 
98
    d->modifier = lfModifier::Create(d->iface->m_usedLens,
 
99
                                     d->iface->m_cropFactor,
 
100
                                     m_orgImage.width(),
 
101
                                     m_orgImage.height());
 
102
 
 
103
    int modflags = d->modifier->Initialize(d->iface->m_usedLens,
 
104
                                           colorDepth,
 
105
                                           d->iface->m_focalLength,
 
106
                                           d->iface->m_aperture,
 
107
                                           d->iface->m_subjectDistance,
 
108
                                           d->iface->m_cropFactor,
 
109
                                           LF_RECTILINEAR,
 
110
                                           modifyFlags,
 
111
                                           0/*no inverse*/);
 
112
 
 
113
    if (!d->modifier)
 
114
    {
 
115
        kError() << "ERROR: cannot initialize LensFun Modifier.";
 
116
        return;
 
117
    }
 
118
 
 
119
    // Calc necessary steps for progress bar
 
120
 
 
121
    int steps = d->iface->m_settings.filterCCA                                         ? 1 : 0 +
 
122
                ( d->iface->m_settings.filterVig  || d->iface->m_settings.filterCCI )  ? 1 : 0 +
 
123
                ( d->iface->m_settings.filterDist || d->iface->m_settings.filterGeom ) ? 1 : 0;
 
124
 
 
125
    kDebug() << "LensFun Modifier Flags: " << modflags << "  Steps:" << steps;
 
126
 
 
127
    if ( steps < 1 )
 
128
       return;
 
129
 
 
130
    // The real correction to do
 
131
 
 
132
    int loop   = 0;
 
133
    int lwidth = m_orgImage.width() * 2 * 3;
 
134
    float* pos = new float[lwidth];
 
135
 
 
136
    // Stage 1: TCA correction
 
137
 
 
138
    if ( d->iface->m_settings.filterCCA )
 
139
    {
 
140
        m_orgImage.prepareSubPixelAccess(); // init lanczos kernel
 
141
 
 
142
        for (unsigned int y=0; !m_cancel && (y < m_orgImage.height()); ++y)
 
143
        {
 
144
            if (d->modifier->ApplySubpixelDistortion(0.0, y, m_orgImage.width(), 1, pos))
 
145
            {
 
146
                float* src = pos;
 
147
 
 
148
                for (unsigned x = 0; !m_cancel && (x < m_destImage.width()); ++x)
 
149
                {
 
150
                    DColor destPixel(0, 0, 0, 0xFFFF, m_destImage.sixteenBit());
 
151
 
 
152
                    destPixel.setRed  (m_orgImage.getSubPixelColorFast(src[0], src[1]).red()   );
 
153
                    destPixel.setGreen(m_orgImage.getSubPixelColorFast(src[2], src[3]).green() );
 
154
                    destPixel.setBlue (m_orgImage.getSubPixelColorFast(src[4], src[5]).blue()  );
 
155
 
 
156
                    m_destImage.setPixelColor(x, y, destPixel);
 
157
                    src += 2 * 3;
 
158
                }
 
159
                ++loop;
 
160
            }
 
161
 
 
162
            // Update progress bar in dialog.
 
163
            int progress = (int)(((double)y * 100.0) / m_orgImage.height());
 
164
            if (m_parent && progress%5 == 0)
 
165
                postProgress(progress/steps);
 
166
        }
 
167
 
 
168
        kDebug() << "Applying TCA correction... (loop: " << loop << ")";
 
169
    }
 
170
    else
 
171
    {
 
172
        m_destImage.bitBltImage(&m_orgImage, 0, 0);
 
173
    }
 
174
 
 
175
    // Stage 2: Color Correction: Vignetting and CCI
 
176
 
 
177
    uchar* data = m_destImage.bits();
 
178
 
 
179
    if ( d->iface->m_settings.filterVig || d->iface->m_settings.filterCCI )
 
180
    {
 
181
        loop         = 0;
 
182
        float offset = 0.0;
 
183
 
 
184
        if ( steps == 3 )
 
185
            offset = 33.3;
 
186
        else if (steps == 2 && d->iface->m_settings.filterCCA)
 
187
            offset = 50.0;
 
188
 
 
189
        for (unsigned int y=0; !m_cancel && (y < m_destImage.height()); ++y)
 
190
        {
 
191
            if (d->modifier->ApplyColorModification(data, 0.0, y, m_destImage.width(),
 
192
                                                    1, m_destImage.bytesDepth(), 0))
 
193
            {
 
194
                data += m_destImage.height() * m_destImage.bytesDepth();
 
195
                ++loop;
 
196
            }
 
197
 
 
198
            // Update progress bar in dialog.
 
199
            int progress = (int)(((double)y * 100.0) / m_destImage.height());
 
200
            if (m_parent && progress%5 == 0)
 
201
                postProgress(progress/steps + offset);
 
202
        }
 
203
 
 
204
        kDebug() << "Applying Color Correction: Vignetting and CCI. (loop: " << loop << ")";
 
205
    }
 
206
 
 
207
    // Stage 3: Distortion and Geometry
 
208
 
 
209
    if ( d->iface->m_settings.filterDist || d->iface->m_settings.filterGeom )
 
210
    {
 
211
        loop = 0;
 
212
 
 
213
        // we need a deep copy first
 
214
        DImg tempImage(m_destImage.width(), m_destImage.height(), m_destImage.sixteenBit(), m_destImage.hasAlpha());
 
215
        m_destImage.prepareSubPixelAccess(); // init lanczos kernel
 
216
 
 
217
        for (unsigned long y=0; !m_cancel && (y < tempImage.height()); ++y)
 
218
        {
 
219
            if (d->modifier->ApplyGeometryDistortion(0.0, y, tempImage.width(), 1, pos))
 
220
            {
 
221
                float* src = pos;
 
222
 
 
223
                for (unsigned long x = 0; !m_cancel && (x < tempImage.width()); ++x, ++loop)
 
224
                {
 
225
                    //qDebug (" ZZ %f %f %i %i", src[0], src[1], (int)src[0], (int)src[1]);
 
226
 
 
227
                    tempImage.setPixelColor(x, y, m_destImage.getSubPixelColor(src[0], src[1]));
 
228
                    src += 2;
 
229
                }
 
230
            }
 
231
 
 
232
            // Update progress bar in dialog.
 
233
            int progress = (int)(((double)y * 100.0) / tempImage.height());
 
234
            if (m_parent && progress%5 == 0)
 
235
                postProgress(progress/steps + 33.3*(steps-1));
 
236
        }
 
237
 
 
238
        /*qDebug (" for %f %f %i %i", tempImage.height(), tempImage.width(),
 
239
                                      tempImage.height(), tempImage.width());*/
 
240
        kDebug() << "Applying Distortion and Geometry Correction. (loop: " << loop << ")";
 
241
 
 
242
        m_destImage = tempImage;
 
243
    }
 
244
 
 
245
    // clean up
 
246
 
 
247
    delete [] pos;
 
248
    d->modifier->Destroy();
 
249
}
 
250
 
 
251
}  // namespace Digikam