1
/* ============================================================
4
* Description : a plugin to fix automatically camera lens aberrations
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>
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.
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.
19
* ============================================================ */
21
#include "lensfunfilter.h"
35
#include "lensfuniface.h"
40
class LensFunFilterPriv
55
LensFunFilter::LensFunFilter(DImg* orgImage, QObject* parent, LensFunIface* iface,
56
const LensFunContainer& settings)
57
: DImgThreadedFilter(orgImage, parent, "LensCorrection"),
58
d(new LensFunFilterPriv)
61
d->iface->setSettings(settings);
66
LensFunFilter::~LensFunFilter()
71
void LensFunFilter::filterImage()
75
opts.Crop = lens->CropFactor;
77
opts.Focal = lens->MinFocal;
79
opts.Aperture = lens->MinAperture;
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;
94
// Init lensfun lib, we are working on the full image.
96
lfPixelFormat colorDepth = m_orgImage.bytesDepth() == 4 ? LF_PF_U8 : LF_PF_U16;
98
d->modifier = lfModifier::Create(d->iface->m_usedLens,
99
d->iface->m_cropFactor,
101
m_orgImage.height());
103
int modflags = d->modifier->Initialize(d->iface->m_usedLens,
105
d->iface->m_focalLength,
106
d->iface->m_aperture,
107
d->iface->m_subjectDistance,
108
d->iface->m_cropFactor,
115
kError() << "ERROR: cannot initialize LensFun Modifier.";
119
// Calc necessary steps for progress bar
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;
125
kDebug() << "LensFun Modifier Flags: " << modflags << " Steps:" << steps;
130
// The real correction to do
133
int lwidth = m_orgImage.width() * 2 * 3;
134
float* pos = new float[lwidth];
136
// Stage 1: TCA correction
138
if ( d->iface->m_settings.filterCCA )
140
m_orgImage.prepareSubPixelAccess(); // init lanczos kernel
142
for (unsigned int y=0; !m_cancel && (y < m_orgImage.height()); ++y)
144
if (d->modifier->ApplySubpixelDistortion(0.0, y, m_orgImage.width(), 1, pos))
148
for (unsigned x = 0; !m_cancel && (x < m_destImage.width()); ++x)
150
DColor destPixel(0, 0, 0, 0xFFFF, m_destImage.sixteenBit());
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() );
156
m_destImage.setPixelColor(x, y, destPixel);
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);
168
kDebug() << "Applying TCA correction... (loop: " << loop << ")";
172
m_destImage.bitBltImage(&m_orgImage, 0, 0);
175
// Stage 2: Color Correction: Vignetting and CCI
177
uchar* data = m_destImage.bits();
179
if ( d->iface->m_settings.filterVig || d->iface->m_settings.filterCCI )
186
else if (steps == 2 && d->iface->m_settings.filterCCA)
189
for (unsigned int y=0; !m_cancel && (y < m_destImage.height()); ++y)
191
if (d->modifier->ApplyColorModification(data, 0.0, y, m_destImage.width(),
192
1, m_destImage.bytesDepth(), 0))
194
data += m_destImage.height() * m_destImage.bytesDepth();
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);
204
kDebug() << "Applying Color Correction: Vignetting and CCI. (loop: " << loop << ")";
207
// Stage 3: Distortion and Geometry
209
if ( d->iface->m_settings.filterDist || d->iface->m_settings.filterGeom )
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
217
for (unsigned long y=0; !m_cancel && (y < tempImage.height()); ++y)
219
if (d->modifier->ApplyGeometryDistortion(0.0, y, tempImage.width(), 1, pos))
223
for (unsigned long x = 0; !m_cancel && (x < tempImage.width()); ++x, ++loop)
225
//qDebug (" ZZ %f %f %i %i", src[0], src[1], (int)src[0], (int)src[1]);
227
tempImage.setPixelColor(x, y, m_destImage.getSubPixelColor(src[0], src[1]));
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));
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 << ")";
242
m_destImage = tempImage;
248
d->modifier->Destroy();
251
} // namespace Digikam