summaryrefslogtreecommitdiffstats
path: root/src/imageplugins/antivignetting/antivignetting.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imageplugins/antivignetting/antivignetting.cpp')
-rw-r--r--src/imageplugins/antivignetting/antivignetting.cpp149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/imageplugins/antivignetting/antivignetting.cpp b/src/imageplugins/antivignetting/antivignetting.cpp
new file mode 100644
index 00000000..dec0a9ea
--- /dev/null
+++ b/src/imageplugins/antivignetting/antivignetting.cpp
@@ -0,0 +1,149 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-05-25
+ * Description : Antivignetting threaded image filter.
+ *
+ * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * Original AntiVignetting algorithm copyrighted 2003 by
+ * John Walker from 'pnmctrfilt' implementation. See
+ * http://www.fourmilab.ch/netpbm/pnmctrfilt for more
+ * information.
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation;
+ * either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * 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.
+ *
+ * ============================================================ */
+
+// C++ includes.
+
+#include <cmath>
+#include <cstdlib>
+
+// Local includes.
+
+#include "dimg.h"
+#include "dimgimagefilters.h"
+#include "antivignetting.h"
+
+namespace DigikamAntiVignettingImagesPlugin
+{
+
+AntiVignetting::AntiVignetting(Digikam::DImg *orgImage, TQObject *parent, double density,
+ double power, double radius, int xshift, int yshift, bool normalize)
+ : Digikam::DImgThreadedFilter(orgImage, parent, "AntiVignetting")
+{
+ m_density = density;
+ m_power = power;
+ m_radius = radius;
+ m_xshift = xshift;
+ m_yshift = yshift;
+ m_normalize = normalize;
+
+ initFilter();
+}
+
+// This method is inspired from John Walker 'pnmctrfilt' algorithm code.
+
+void AntiVignetting::filterImage(void)
+{
+ int progress;
+ int col, row, xd, td, yd, p;
+ int i, xsize, ysize, diagonal, erad, xctr, yctr;
+ double *ldens;
+
+ uchar* NewBits = m_destImage.bits();
+ uchar* data = m_orgImage.bits();
+
+ unsigned short* NewBits16 = (unsigned short*)m_destImage.bits();
+ unsigned short* data16 = (unsigned short*)m_orgImage.bits();
+
+ int Width = m_orgImage.width();
+ int Height = m_orgImage.height();
+
+ // Determine the radius of the filter. This is the half diagonal
+ // measure of the image multiplied by the command line radius factor.
+
+ xsize = (Height + 1) / 2;
+ ysize = (Width + 1) / 2;
+ erad = (int)((sqrt((xsize * xsize) + (ysize * ysize)) + 0.5) * m_radius);
+
+ // Build the in-memory table which maps distance from the
+ // center of the image (as adjusted by the X and Y offset,
+ // if any) to the density of the filter at this remove. This
+ // table needs to be as large as the diagonal from the
+ // (possibly offset) center to the most distant corner
+ // of the image.
+
+ xsize = ((Height + 1) / 2) + abs(m_xshift);
+ ysize = ((Width + 1) / 2) + abs(m_yshift);
+ diagonal = ((int) (sqrt((xsize * xsize) + (ysize * ysize)) + 0.5)) + 1;
+
+ ldens = new double[diagonal];
+
+ for (i = 0 ; !m_cancel && (i < diagonal) ; i++)
+ {
+ if ( i >= erad )
+ ldens[i] = 1;
+ else
+ ldens[i] = (1.0 + (m_density - 1) * pow(1.0 - (((double) i) / (erad - 1)), m_power));
+ }
+
+ xctr = ((Height + 1) / 2) + m_xshift;
+ yctr = ((Width + 1) / 2) + m_yshift;
+
+ for (row = 0 ; !m_cancel && (row < Width) ; row++)
+ {
+ yd = abs(yctr - row);
+
+ for (col = 0 ; !m_cancel && (col < Height) ; col++)
+ {
+ p = (col * Width + row)*4;
+
+ xd = abs(xctr - col);
+ td = (int) (sqrt((xd * xd) + (yd * yd)) + 0.5);
+
+ if (!m_orgImage.sixteenBit()) // 8 bits image
+ {
+ NewBits[ p ] = (uchar)(data[ p ] / ldens[td]);
+ NewBits[p+1] = (uchar)(data[p+1] / ldens[td]);
+ NewBits[p+2] = (uchar)(data[p+2] / ldens[td]);
+ NewBits[p+3] = data[p+3];
+ }
+ else // 16 bits image.
+ {
+ NewBits16[ p ] = (unsigned short)(data16[ p ] / ldens[td]);
+ NewBits16[p+1] = (unsigned short)(data16[p+1] / ldens[td]);
+ NewBits16[p+2] = (unsigned short)(data16[p+2] / ldens[td]);
+ NewBits16[p+3] = data16[p+3];
+ }
+ }
+
+ // Update the progress bar in dialog.
+ progress = (int)(((double)row * 100.0) / Width);
+ if (progress%5 == 0)
+ postProgress( progress );
+ }
+
+ // Normalize colors for a best rendering.
+ if (m_normalize)
+ {
+ Digikam::DImgImageFilters filters;
+ filters.normalizeImage(m_destImage.bits(), Width, Height, m_destImage.sixteenBit());
+ }
+
+ delete [] ldens;
+}
+
+} // NameSpace DigikamAntiVignettingImagesPlugin