Commit af5d9098 authored by Gilles Caulier's avatar Gilles Caulier 🗼
Browse files

MantenanceTool : FingerPrints generator is now able to use Multi-core CPU.

CCBUGS: 289204
parent d61573f4
......@@ -1267,6 +1267,7 @@ IF(DIGIKAM_CAN_BE_COMPILED)
${CMAKE_CURRENT_SOURCE_DIR}/utilities/maintenance/thumbsgenerator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utilities/maintenance/thumbstask.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utilities/maintenance/fingerprintsgenerator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utilities/maintenance/fingerprintstask.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utilities/maintenance/maintenancedlg.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utilities/maintenance/maintenancemngr.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utilities/maintenance/maintenancetool.cpp
......
......@@ -44,10 +44,8 @@
#include "albumdb.h"
#include "albummanager.h"
#include "databaseaccess.h"
#include "haar.h"
#include "haariface.h"
#include "previewloadthread.h"
#include "metadatasettings.h"
#include "maintenancethread.h"
namespace Digikam
{
......@@ -58,7 +56,7 @@ public:
Private() :
rebuildAll(true),
previewLoadThread(0)
thread(0)
{
}
......@@ -68,9 +66,7 @@ public:
AlbumList albumList;
PreviewLoadThread* previewLoadThread;
HaarIface haarIface;
MaintenanceThread* thread;
};
FingerPrintsGenerator::FingerPrintsGenerator(const bool rebuildAll, const AlbumList& list, ProgressItem* const parent)
......@@ -80,12 +76,16 @@ FingerPrintsGenerator::FingerPrintsGenerator(const bool rebuildAll, const AlbumL
setLabel(i18n("Finger-prints"));
ProgressManager::addProgressItem(this);
d->albumList = list;
d->rebuildAll = rebuildAll;
d->previewLoadThread = new PreviewLoadThread();
d->albumList = list;
d->rebuildAll = rebuildAll;
d->thread = new MaintenanceThread(this);
// NOTE: A part of finger-print task is done outside dedicated thread. We need to wait until it.
// So we don't use MaintenanceThread::signalCompleted() to know if task is complete.
// We will check if all process items are done through slotAdvance().
connect(d->previewLoadThread, SIGNAL(signalImageLoaded(LoadingDescription,DImg)),
this, SLOT(slotGotImagePreview(LoadingDescription,DImg)));
connect(d->thread, SIGNAL(signalAdvance(QPixmap)),
this, SLOT(slotAdvance(QPixmap)));
}
FingerPrintsGenerator::~FingerPrintsGenerator()
......@@ -93,6 +93,12 @@ FingerPrintsGenerator::~FingerPrintsGenerator()
delete d;
}
void FingerPrintsGenerator::slotCancel()
{
d->thread->cancel();
MaintenanceTool::slotCancel();
}
void FingerPrintsGenerator::slotStart()
{
MaintenanceTool::slotStart();
......@@ -130,64 +136,17 @@ void FingerPrintsGenerator::slotStart()
}
setTotalItems(d->allPicturesPath.count());
processOne();
}
void FingerPrintsGenerator::processOne()
{
if (canceled())
{
slotCancel();
return;
}
if (d->allPicturesPath.isEmpty())
{
slotDone();
return;
}
QString path = d->allPicturesPath.first();
LoadingDescription description(path, HaarIface::preferredSize(), LoadingDescription::ConvertToSRGB);
description.rawDecodingSettings.rawPrm.sixteenBitsImage = false;
d->previewLoadThread->load(description);
d->thread->setUseMultiCore(true);
d->thread->generateFingerprints(d->allPicturesPath);
d->thread->start();
}
void FingerPrintsGenerator::slotGotImagePreview(const LoadingDescription& desc, const DImg& img)
void FingerPrintsGenerator::slotAdvance(const QPixmap& pix)
{
if (d->allPicturesPath.isEmpty())
{
return;
}
if (d->allPicturesPath.first() != desc.filePath)
{
return;
}
if (!img.isNull())
{
// compute Haar fingerprint
d->haarIface.indexImage(desc.filePath, img);
}
QPixmap pix = DImg(img).smoothScale(22, 22, Qt::KeepAspectRatio).convertToPixmap();
setThumbnail(pix);
advance(1);
if (!d->allPicturesPath.isEmpty())
{
d->allPicturesPath.removeFirst();
}
if (d->allPicturesPath.isEmpty())
{
if (advance(1))
slotDone();
}
else
{
processOne();
}
}
void FingerPrintsGenerator::slotDone()
......
......@@ -29,12 +29,11 @@
#include "album.h"
#include "maintenancetool.h"
class QPixmap;
namespace Digikam
{
class DImg;
class LoadingDescription;
class FingerPrintsGenerator : public MaintenanceTool
{
Q_OBJECT
......@@ -54,7 +53,8 @@ private Q_SLOTS:
void slotStart();
void slotDone();
void slotGotImagePreview(const LoadingDescription&, const DImg&);
void slotCancel();
void slotAdvance(const QPixmap&);
private:
......
/* ============================================================
*
* This file is a part of digiKam project
* http://www.digikam.org
*
* Date : 2013-08-14
* Description : Thread actions task for finger-prints generator.
*
* Copyright (C) 2013 by Gilles Caulier <caulier dot gilles at gmail dot com>
*
* 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.
*
* ============================================================ */
#include "fingerprintstask.moc"
// KDE includes
#include <kdebug.h>
#include <threadweaver/ThreadWeaver.h>
// Local includes
#include "thumbnailloadthread.h"
#include "thumbnailsize.h"
#include "dimg.h"
#include "haar.h"
#include "haariface.h"
#include "previewloadthread.h"
namespace Digikam
{
class FingerprintsTask::Private
{
public:
Private()
{
cancel = false;
previewLoadThread = new PreviewLoadThread();
}
bool cancel;
QString path;
PreviewLoadThread* previewLoadThread;
HaarIface haarIface;
};
// -------------------------------------------------------
FingerprintsTask::FingerprintsTask()
: Job(0), d(new Private)
{
connect(d->previewLoadThread, SIGNAL(signalImageLoaded(LoadingDescription, DImg)),
this, SLOT(slotGotImagePreview(LoadingDescription, DImg)));
}
FingerprintsTask::~FingerprintsTask()
{
slotCancel();
delete d;
}
void FingerprintsTask::setItem(const QString& path)
{
d->path = path;
}
void FingerprintsTask::slotCancel()
{
d->cancel = true;
}
void FingerprintsTask::run()
{
if(!d->cancel)
{
LoadingDescription description(d->path, HaarIface::preferredSize(), LoadingDescription::ConvertToSRGB);
description.rawDecodingSettings.rawPrm.sixteenBitsImage = false;
d->previewLoadThread->load(description);
}
}
void FingerprintsTask::slotGotImagePreview(const LoadingDescription& desc, const DImg& img)
{
if (d->path == desc.filePath)
{
if (!img.isNull())
{
// compute Haar fingerprint
d->haarIface.indexImage(desc.filePath, img);
}
QPixmap pix = DImg(img).smoothScale(22, 22, Qt::KeepAspectRatio).convertToPixmap();
emit signalFinished(pix);
}
}
} // namespace Digikam
/* ============================================================
*
* This file is a part of digiKam project
* http://www.digikam.org
*
* Date : 2013-08-14
* Description : Thread actions task for finger-prints generator.
*
* Copyright (C) 2013 by Gilles Caulier <caulier dot gilles at gmail dot com>
*
* 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.
*
* ============================================================ */
#ifndef FINGERPRINTS_TASK_H
#define FINGERPRINTS_TASK_H
// Qt includes
#include <QPixmap>
#include <QThread>
// KDE includes
#include <threadweaver/Job.h>
using namespace ThreadWeaver;
namespace Digikam
{
class LoadingDescription;
class DImg;
class FingerprintsTask : public Job
{
Q_OBJECT
public:
FingerprintsTask();
~FingerprintsTask();
void setItem(const QString& path);
Q_SIGNALS:
void signalFinished(const QPixmap&);
public Q_SLOTS:
void slotCancel();
protected:
void run();
private Q_SLOTS:
void slotGotImagePreview(const LoadingDescription&, const DImg&);
private:
class Private;
Private* const d;
};
} // namespace Digikam
#endif /* FINGERPRINTS_TASK_H */
......@@ -33,6 +33,7 @@
#include "metadatatask.h"
#include "thumbstask.h"
#include "fingerprintstask.h"
using namespace Solid;
......@@ -106,9 +107,25 @@ void MaintenanceThread::generateThumbs(const QStringList& paths)
appendJob(collection);
}
void MaintenanceThread::generateFingerprints(const QStringList& /*paths*/)
void MaintenanceThread::generateFingerprints(const QStringList& paths)
{
// TODO
JobCollection* const collection = new JobCollection();
for(int i=0; i < paths.size(); i++)
{
FingerprintsTask* const t = new FingerprintsTask();
t->setItem(paths.at(i));
connect(t, SIGNAL(signalFinished(QPixmap)),
this, SIGNAL(signalAdvance(QPixmap)));
connect(this, SIGNAL(signalCanceled()),
t, SLOT(slotCancel()), Qt::QueuedConnection);
collection->addJob(t);
}
appendJob(collection);
}
void MaintenanceThread::cancel()
......
......@@ -101,8 +101,9 @@ void ThumbsGenerator::init(const bool rebuildAll)
d->rebuildAll = rebuildAll;
d->thread = new MaintenanceThread(this);
connect(d->thread, SIGNAL(signalCompleted()),
this, SLOT(slotDone()));
// NOTE: A part of finger-print task is done outside dedicated thread. We need to wait until it.
// So we don't use MaintenanceThread::signalCompleted() to know if task is complete.
// We will check if all process items are done through slotAdvance().
connect(d->thread, SIGNAL(signalAdvance(QPixmap)),
this, SLOT(slotAdvance(QPixmap)));
......@@ -190,7 +191,8 @@ void ThumbsGenerator::slotStart()
void ThumbsGenerator::slotAdvance(const QPixmap& pix)
{
setThumbnail(pix);
advance(1);
if (advance(1))
slotDone();
}
} // namespace Digikam
......@@ -58,7 +58,8 @@ ThumbsTask::ThumbsTask()
: Job(0), d(new Private)
{
connect(d->thumbLoadThread, SIGNAL(signalThumbnailLoaded(LoadingDescription, QPixmap)),
this, SLOT(slotGotThumbnail(LoadingDescription, QPixmap)));
this, SLOT(slotGotThumbnail(LoadingDescription, QPixmap)),
Qt::QueuedConnection);
}
ThumbsTask::~ThumbsTask()
......@@ -90,6 +91,7 @@ void ThumbsTask::slotGotThumbnail(const LoadingDescription& desc, const QPixmap&
{
if (d->path == desc.filePath)
{
kDebug() << desc.filePath;
emit signalFinished(pix);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment