summaryrefslogtreecommitdiffstats
path: root/src/imageplugins/hotpixels/blackframeparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imageplugins/hotpixels/blackframeparser.cpp')
-rw-r--r--src/imageplugins/hotpixels/blackframeparser.cpp211
1 files changed, 211 insertions, 0 deletions
diff --git a/src/imageplugins/hotpixels/blackframeparser.cpp b/src/imageplugins/hotpixels/blackframeparser.cpp
new file mode 100644
index 00000000..7306f4e6
--- /dev/null
+++ b/src/imageplugins/hotpixels/blackframeparser.cpp
@@ -0,0 +1,211 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-03-27
+ * Description : black frames parser
+ *
+ * Copyright (C) 2005-2006 by Unai Garro <ugarro at users dot sourceforge dot net>
+ * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * Part of the algorithm for finding the hot pixels was based on
+ * the code of jpegpixi, which was released under the GPL license,
+ * and is Copyright (C) 2003, 2004 Martin Dickopp
+ *
+ * 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.
+ *
+ * ============================================================ */
+
+// Denominator for relative quantities.
+#define DENOM (DENOM_STQRT * DENOM_STQRT)
+
+// Square root of denominator for relative quantities.
+#define DENOM_STQRT 10000
+
+// Convert relative to absolute numbers. Care must be taken not to overflow integers.
+#define REL_TO_ABS(n,m) \
+ ((((n) / DENOM_STQRT) * (m) + ((n) % DENOM_STQRT) * (m) / DENOM_STQRT) / DENOM_STQRT)
+
+// TQt includes.
+
+#include <tqimage.h>
+#include <tqstringlist.h>
+
+// KDE includes.
+
+#include <tdeapplication.h>
+#include <tdeversion.h>
+#include <tdeio/netaccess.h>
+#include <tdeio/job.h>
+
+// Local includes.
+
+#include "blackframeparser.h"
+#include "blackframeparser.moc"
+
+namespace DigikamHotPixelsImagesPlugin
+{
+
+BlackFrameParser::BlackFrameParser(TQObject *parent)
+ : TQObject(parent)
+{
+ m_imageLoaderThread = 0;
+}
+
+BlackFrameParser::~BlackFrameParser()
+{
+ delete m_imageLoaderThread;
+}
+
+void BlackFrameParser::parseHotPixels(const TQString &file)
+{
+ parseBlackFrame(KURL(file));
+}
+
+void BlackFrameParser::parseBlackFrame(const KURL &url)
+{
+#if KDE_IS_VERSION(3,2,0)
+ TDEIO::NetAccess::download(url, m_localFile, kapp->activeWindow());
+#else
+ TDEIO::NetAccess::download(url, m_localFile);
+#endif
+
+ if (!m_imageLoaderThread)
+ {
+ m_imageLoaderThread = new LoadSaveThread();
+
+ connect(m_imageLoaderThread, TQ_SIGNAL(signalLoadingProgress(const LoadingDescription&, float)),
+ this, TQ_SLOT(slotLoadingProgress(const LoadingDescription&, float)));
+
+ connect(m_imageLoaderThread, TQ_SIGNAL(signalImageLoaded(const LoadingDescription&, const DImg&)),
+ this, TQ_SLOT(slotLoadImageFromUrlComplete(const LoadingDescription&, const DImg&)));
+ }
+
+ LoadingDescription desc = LoadingDescription(m_localFile, DRawDecoding());
+ m_imageLoaderThread->load(desc);
+}
+
+void BlackFrameParser::slotLoadingProgress(const LoadingDescription&, float v)
+{
+ emit signalLoadingProgress(v);
+}
+
+void BlackFrameParser::slotLoadImageFromUrlComplete(const LoadingDescription&, const DImg& img)
+{
+ DImg image(img);
+ m_Image = image.copyTQImage();
+ blackFrameParsing();
+ emit signalLoadingComplete();
+}
+
+void BlackFrameParser::parseBlackFrame(TQImage& img)
+{
+ m_Image = img;
+ blackFrameParsing();
+}
+
+// Parses black frames
+
+void BlackFrameParser::blackFrameParsing()
+{
+ // Now find the hot pixels and store them in a list
+ TQValueList<HotPixel> hpList;
+
+ for (int y=0 ; y < m_Image.height() ; ++y)
+ {
+ for (int x=0 ; x < m_Image.width() ; ++x)
+ {
+ //Get each point in the image
+ TQRgb pixrgb = m_Image.pixel(x,y);
+ TQColor color; color.setRgb(pixrgb);
+
+ // Find maximum component value.
+ int maxValue;
+ int threshold = DENOM/10;
+ const int threshold_value = REL_TO_ABS(threshold, 255);
+ maxValue = (color.red()>color.blue()) ? color.red() : color.blue();
+ if (color.green() > maxValue) maxValue = color.green();
+
+ // If the component is bigger than the threshold, add the point
+ if (maxValue > threshold_value)
+ {
+ HotPixel point;
+ point.rect = TQRect (x, y, 1, 1);
+ //TODO:check this
+ point.luminosity = ((2 * DENOM) / 255 ) * maxValue / 2;
+
+ hpList.append(point);
+ }
+ }
+ }
+
+ //Now join points together into groups
+ consolidatePixels (hpList);
+
+ //And notify
+ emit parsed(hpList);
+}
+
+// Consolidate adjacent points into larger points.
+
+void BlackFrameParser::consolidatePixels (TQValueList<HotPixel>& list)
+{
+ if (list.isEmpty())
+ return;
+
+ /* Consolidate horizontally. */
+
+ TQValueList<HotPixel>::iterator it, prevPointIt;
+
+ prevPointIt = list.begin();
+ it = list.begin();
+ ++it;
+
+ HotPixel tmp;
+ HotPixel point;
+ HotPixel point_below;
+ TQValueList<HotPixel>::iterator end(list.end());
+ for (; it != end; ++it )
+ {
+ while (1)
+ {
+ point = (*it);
+ tmp = point;
+
+ TQValueList<HotPixel>::Iterator point_below_it;
+ point_below_it = list.find (tmp); //find any intersecting hotp below tmp
+ if (point_below_it != list.end())
+ {
+ point_below =* point_below_it;
+ validateAndConsolidate (&point, &point_below);
+
+ point.rect.setX(MIN(point.x(), point_below.x()));
+ point.rect.setWidth(MAX(point.x() + point.width(),
+ point_below.x() + point_below.width()) - point.x());
+ point.rect.setHeight(MAX(point.y() + point.height(),
+ point_below.y() + point_below.height()) - point.y());
+ *it = point;
+ list.remove (point_below_it); //TODO: Check! this could remove it++?
+ }
+ else
+ break;
+ }
+ }
+}
+
+void BlackFrameParser::validateAndConsolidate (HotPixel *a, HotPixel *b)
+{
+ a->luminosity = MAX (a->luminosity, b->luminosity);
+}
+
+} // NameSpace DigikamHotPixelsImagesPlugin