You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
6.1 KiB
212 lines
6.1 KiB
/* ============================================================
|
|
*
|
|
* 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, TQT_SIGNAL(signalLoadingProgress(const LoadingDescription&, float)),
|
|
this, TQT_SLOT(slotLoadingProgress(const LoadingDescription&, float)));
|
|
|
|
connect(m_imageLoaderThread, TQT_SIGNAL(signalImageLoaded(const LoadingDescription&, const DImg&)),
|
|
this, TQT_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
|