diff options
Diffstat (limited to 'src/imageplugins/hotpixels/blackframeparser.cpp')
-rw-r--r-- | src/imageplugins/hotpixels/blackframeparser.cpp | 211 |
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 |