File indexing completed on 2025-01-19 03:59:30

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2013-08-14
0007  * Description : Thread actions task for finger-prints generator.
0008  *
0009  * SPDX-FileCopyrightText: 2013-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "fingerprintstask.h"
0016 
0017 // Qt includes
0018 #include <QQueue>
0019 #include <QIcon>
0020 
0021 // Local includes
0022 
0023 #include "digikam_debug.h"
0024 #include "dimg.h"
0025 #include "haar.h"
0026 #include "haariface.h"
0027 #include "previewloadthread.h"
0028 #include "maintenancedata.h"
0029 #include "similaritydb.h"
0030 #include "similaritydbaccess.h"
0031 
0032 namespace Digikam
0033 {
0034 
0035 class Q_DECL_HIDDEN FingerprintsTask::Private
0036 {
0037 public:
0038 
0039     explicit Private()
0040         : data(nullptr)
0041     {
0042     }
0043 
0044     MaintenanceData* data;
0045     QImage           okImage;
0046 };
0047 
0048 // -------------------------------------------------------
0049 
0050 FingerprintsTask::FingerprintsTask()
0051     : ActionJob(),
0052       d(new Private)
0053 {
0054     QPixmap okPix = QIcon::fromTheme(QLatin1String("dialog-ok-apply")).pixmap(22, 22);
0055     d->okImage    = okPix.toImage();
0056 }
0057 
0058 FingerprintsTask::~FingerprintsTask()
0059 {
0060     cancel();
0061     delete d;
0062 }
0063 
0064 void FingerprintsTask::setMaintenanceData(MaintenanceData* const data)
0065 {
0066     d->data = data;
0067 }
0068 
0069 void FingerprintsTask::run()
0070 {
0071     // While we have data (using this as check for non-null)
0072 
0073     while (d->data)
0074     {
0075         if (m_cancel)
0076         {
0077             return;
0078         }
0079 
0080         qlonglong id = d->data->getImageId();
0081 
0082         if (id == -1)
0083         {
0084             break;
0085         }
0086 
0087         ItemInfo info(id);
0088 
0089         if (info.isVisible()                                              &&
0090             (info.category() == DatabaseItem::Category::Image)            &&
0091             !info.filePath().isEmpty()                                    &&
0092             !m_cancel                                                     &&
0093             (d->data->getRebuildAllFingerprints()                         ||
0094              SimilarityDbAccess().db()->hasDirtyOrMissingFingerprint(info)))
0095         {
0096             qCDebug(DIGIKAM_GENERAL_LOG) << "Updating fingerprints for file:" << info.filePath();
0097 
0098             DImg dimg = PreviewLoadThread::loadFastSynchronously(info.filePath(),
0099                                                                  HaarIface::preferredSize());
0100 
0101             if (!dimg.isNull())
0102             {
0103                 // compute Haar fingerprint and store it to DB
0104 
0105                 HaarIface haarIface;
0106                 haarIface.indexImage(info.id(), dimg);
0107             }
0108 
0109             QImage qimg = dimg.smoothScale(22, 22, Qt::KeepAspectRatio).copyQImage();
0110 
0111             Q_EMIT signalFinished(qimg);
0112         }
0113         else
0114         {
0115             Q_EMIT signalFinished(d->okImage);
0116         }
0117     }
0118 
0119     Q_EMIT signalDone();
0120 }
0121 
0122 } // namespace Digikam
0123 
0124 #include "moc_fingerprintstask.cpp"