diff --git a/core/dplugins/editor/enhance/hotpixels/blackframeparser.cpp b/core/dplugins/editor/enhance/hotpixels/blackframeparser.cpp index 4b584dc6de..3744127bd6 100644 --- a/core/dplugins/editor/enhance/hotpixels/blackframeparser.cpp +++ b/core/dplugins/editor/enhance/hotpixels/blackframeparser.cpp @@ -1,260 +1,259 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2005-03-27 * Description : black frames parser * * Copyright (C) 2005-2020 by Gilles Caulier * Copyright (C) 2005-2006 by Unai Garro * Copyright (C) 2015 by Mohamed_Anwer * * Part of the algorithm for finding the hot pixels was based on * the code of jpegpixi, which was released under the GPL license, * written by 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_SQRT * DENOM_SQRT) /// Square root of denominator for relative quantities. #define DENOM_SQRT 10000 /// Convert relative to absolute numbers. Care must be taken not to overflow integers. #define REL_TO_ABS(n,m) \ ((((n) / DENOM_SQRT) * (m) + ((n) % DENOM_SQRT) * (m) / DENOM_SQRT) / DENOM_SQRT) #include "blackframeparser.h" // Qt includes #include #include #include -#include // Local includes #include "digikam_debug.h" namespace DigikamEditorHotPixelsToolPlugin { BlackFrameParser::BlackFrameParser(QObject* const parent) : QObject(parent), m_imageLoaderThread(nullptr) { } BlackFrameParser::~BlackFrameParser() { if (!m_tempFilePath.isEmpty()) { QFile::remove(m_tempFilePath); } delete m_imageLoaderThread; } void BlackFrameParser::parseHotPixels(const QString& file) { parseBlackFrame(QUrl::fromLocalFile(file)); } void BlackFrameParser::parseBlackFrame(const QUrl& url) { QString localFile = url.toLocalFile(); if (!m_imageLoaderThread) { m_imageLoaderThread = new LoadSaveThread(); connect(m_imageLoaderThread, SIGNAL(signalLoadingProgress(LoadingDescription,float)), this, SLOT(slotLoadingProgress(LoadingDescription,float))); connect(m_imageLoaderThread, SIGNAL(signalImageLoaded(LoadingDescription,DImg)), this, SLOT(slotLoadImageFromUrlComplete(LoadingDescription,DImg))); } LoadingDescription desc = LoadingDescription(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.copyQImage(); blackFrameParsing(); emit signalLoadingComplete(); } void BlackFrameParser::parseBlackFrame(QImage& img) { m_Image = img; blackFrameParsing(); } QImage BlackFrameParser::image() const { return m_Image; } /** * Parses black frames */ void BlackFrameParser::blackFrameParsing() { // Now find the hot pixels and store them in a list QList hpList; // If you accidentally open a normal image for a black frame, the tool and host application will // freeze due to heavy calculation. // We should stop at a certain amount of hot pixels, to avoid the freeze. // 1000 of total hot pixels should be good enough for a trigger. Images with such an amount of hot pixels should // be considered as messed up anyway. const int maxHotPixels = 1000; for (int y = 0 ; y < m_Image.height() ; ++y) { for (int x = 0 ; x < m_Image.width() ; ++x) { // Get each point in the image QRgb pixrgb = m_Image.pixel(x,y); QColor 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 = QRect (x, y, 1, 1); // TODO: check this point.luminosity = ((2 * DENOM) / 255 ) * maxValue / 2; hpList.append(point); } } if (hpList.count() > maxHotPixels) { break; } } // Now join points together into groups consolidatePixels (hpList); // And notify emit signalParsed(hpList); } /** * Consolidate adjacent points into larger points. */ void BlackFrameParser::consolidatePixels(QList& list) { if (list.isEmpty()) { return; } // Consolidate horizontally. QList::iterator it, prevPointIt; prevPointIt = list.begin(); it = list.begin(); ++it; HotPixel tmp; HotPixel point; HotPixel point_below; for ( ; it != list.end() ; ++it) { while (1) { point = (*it); tmp = point; QList::iterator point_below_it; // find any intersecting hot pixels below tmp int i = list.indexOf(tmp); if (i == -1) { point_below_it = list.end(); } else { point_below_it = list.begin() + i; } if (point_below_it != list.end()) { point_below =* point_below_it; validateAndConsolidate(&point, &point_below); point.rect.setX(qMin(point.x(), point_below.x())); point.rect.setWidth(qMax(point.x() + point.width(), point_below.x() + point_below.width()) - point.x()); point.rect.setHeight(qMax(point.y() + point.height(), point_below.y() + point_below.height()) - point.y()); *it = point; list.erase(point_below_it); // TODO: Check! this could remove it++? } else { break; } } } } void BlackFrameParser::validateAndConsolidate(HotPixel* const a, HotPixel* const b) { a->luminosity = qMax(a->luminosity, b->luminosity); } } // namespace DigikamEditorHotPixelsToolPlugin diff --git a/core/dplugins/generic/tools/jalbum/generator/jalbumgenerator.cpp b/core/dplugins/generic/tools/jalbum/generator/jalbumgenerator.cpp index 24cf7bbe46..39e020bad0 100644 --- a/core/dplugins/generic/tools/jalbum/generator/jalbumgenerator.cpp +++ b/core/dplugins/generic/tools/jalbum/generator/jalbumgenerator.cpp @@ -1,300 +1,299 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2006-04-04 * Description : a tool to generate jAlbum image galleries * * Copyright (C) 2013-2019 by Andrew Goodbody * * 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 "jalbumgenerator.h" // Qt includes #include #include #include #include #include #include #include #include -#include // KDE includes #include // Local includes #include "digikam_debug.h" #include "digikam_globals.h" #include "jalbumsettings.h" #include "jalbumwizard.h" #include "dfileoperations.h" namespace DigikamGenericJAlbumPlugin { class Q_DECL_HIDDEN JAlbumGenerator::Private { public: explicit Private() : that(nullptr), settings(nullptr), warnings(false), cancel(false), pview(nullptr), pbar(nullptr) { } JAlbumGenerator* that; JAlbumSettings* settings; QList urls; // State settings bool warnings; bool cancel; DHistoryView* pview; DProgressWdg* pbar; public: bool init() { cancel = false; pview->setVisible(true); pbar->setVisible(true); return true; } bool createDir(const QString& dirName) { logInfo(i18n("Create directories")); if (!QDir().mkpath(dirName)) { logError(i18n("Could not create folder '%1'", QDir::toNativeSeparators(dirName))); return false; } return true; } bool createUrlsList() { if (settings->m_getOption == JAlbumSettings::ALBUMS) { // Loop over albums selection DInfoInterface::DAlbumIDs::ConstIterator albumIt = settings->m_albumList.constBegin(); DInfoInterface::DAlbumIDs::ConstIterator albumEnd = settings->m_albumList.constEnd(); for ( ; albumIt != albumEnd ; ++albumIt) { int id = *albumIt; // Gather image element list QList imageList; if (settings->m_iface) { imageList = settings->m_iface->albumsItems(DInfoInterface::DAlbumIDs() << id); urls.append(imageList); } } } else { urls = settings->m_imageList; } return true; } bool createProjectFiles(const QString& projDir) { logInfo(i18n("Create jAlbum project files")); QDir newAlbumDir = QDir(projDir); QFile createFile(newAlbumDir.filePath(QString::fromLatin1("albumfiles.txt"))); if (!createFile.open(QIODevice::WriteOnly | QIODevice::Text)) { logInfo(i18n("Failed to create project files")); return false; } QTextStream out(&createFile); for (QList::ConstIterator it = urls.constBegin(); it != urls.constEnd(); ++it) { out << (*it).fileName().toLocal8Bit().data() << "\t" << (*it).path().toLocal8Bit().data() << "\n"; } createFile.close(); QFile settingsFile(newAlbumDir.filePath(QString::fromLatin1("jalbum-settings.jap"))); if (!settingsFile.open(QIODevice::WriteOnly | QIODevice::Text)) { logInfo(i18n("Failed to create settings file")); return false; } QTextStream out2(&settingsFile); out2 << "#jAlbum Project\n"; settingsFile.close(); return true; } bool launchJalbum(const QString& projDir, const QString& jarDir, const QString& javaExecutable) { logInfo(i18n("Launch jAlbum with new project files")); /* QString javaExecutable; QDir jrePath = QFileInfo(jarDir).dir(); if (jrePath.cd(QString::fromLatin1("jre64/bin/"))) { javaExecutable = jrePath.filePath(QString::fromLatin1("java")); } else { javaExecutable = QString::fromLatin1("java"); } */ QDir newAlbumDir = QDir(projDir); QStringList args; args.append(QString::fromLatin1("-Xmx400M")); args.append(QString::fromLatin1("-jar")); args.append(jarDir); args.append(QDir::toNativeSeparators(newAlbumDir.filePath(QString::fromLatin1("jalbum-settings.jap")))); QProcess process; process.setProcessEnvironment(adjustedEnvironmentForAppImage()); process.startDetached(javaExecutable, args); return true; } void logInfo(const QString& msg) { pview->addEntry(msg, DHistoryView::ProgressEntry); } void logError(const QString& msg) { pview->addEntry(msg, DHistoryView::ErrorEntry); } void logWarning(const QString& msg) { pview->addEntry(msg, DHistoryView::WarningEntry); warnings = true; } }; // ---------------------------------------------------------------------- JAlbumGenerator::JAlbumGenerator(JAlbumSettings* const settings) : QObject(), d(new Private) { d->that = this; d->settings = settings; d->warnings = false; connect(this, SIGNAL(logWarningRequested(QString)), SLOT(logWarning(QString)), Qt::QueuedConnection); } JAlbumGenerator::~JAlbumGenerator() { delete d; } bool JAlbumGenerator::run() { if (!d->init()) return false; QString destDir = d->settings->m_destPath; qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << destDir; QString javaDir = d->settings->m_javaPath; qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << javaDir; QString jarDir = d->settings->m_jalbumPath; qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << jarDir; QString projDir = destDir + QString::fromLatin1("/") + d->settings->m_imageSelectionTitle; qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << projDir; if (!d->createDir(projDir)) return false; bool result = d->createUrlsList(); if (result) { result = d->createProjectFiles(projDir); } if (result) { result = d->launchJalbum(projDir, jarDir, javaDir); } return result; } bool JAlbumGenerator::warnings() const { return d->warnings; } void JAlbumGenerator::logWarning(const QString& text) { d->logWarning(text); } void JAlbumGenerator::slotCancel() { d->cancel = true; } void JAlbumGenerator::setProgressWidgets(DHistoryView* const pView, DProgressWdg* const pBar) { d->pview = pView; d->pbar = pBar; connect(d->pbar, SIGNAL(signalProgressCanceled()), this, SLOT(slotCancel())); } } // namespace DigikamGenericJAlbumPlugin diff --git a/core/showfoto/main/showfoto_p.h b/core/showfoto/main/showfoto_p.h index 7984089c83..9e8a1ddc0c 100644 --- a/core/showfoto/main/showfoto_p.h +++ b/core/showfoto/main/showfoto_p.h @@ -1,161 +1,160 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2004-11-22 * Description : stand alone digiKam image editor GUI * * Copyright (C) 2004-2020 by Gilles Caulier * Copyright (C) 2006-2012 by Marcel Wiesweg * Copyright (C) 2013 by Mohamed_Anwer * * 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 SHOW_FOTO_PRIVATE_H #define SHOW_FOTO_PRIVATE_H #include "showfoto.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include #include #include #include // KDE includes #include #include #include "kconfiggroup.h" #include // Local includes #include "showfotoiteminfo.h" #include "showfotothumbnailbar.h" #include "dsplashscreen.h" #include "itempropertiessidebar.h" #include "showfotodragdrophandler.h" #include "thumbnailloadthread.h" #include "drawdecoder.h" #include "digikam_globals.h" #include "digikam_debug.h" #include "canvas.h" #include "editorcore.h" #include "dmetadata.h" #include "editorstackview.h" #include "dfileoperations.h" #include "iccsettingscontainer.h" #include "imagedialog.h" #include "iofilesettings.h" #include "loadingcache.h" #include "loadingcacheinterface.h" #include "metaenginesettings.h" #include "savingcontext.h" #include "showfotosetup.h" #include "showfotosetupmisc.h" #include "setupicc.h" #include "statusprogressbar.h" #include "thememanager.h" #include "thumbnailsize.h" #include "dnotificationwrapper.h" #include "showfotodelegate.h" #include "showfotothumbnailmodel.h" #include "showfotocategorizedview.h" #include "showfotosettings.h" #include "dmetainfoiface.h" #include "dexpanderbox.h" #include "dfiledialog.h" #include "dpluginloader.h" namespace ShowFoto { class Q_DECL_HIDDEN ShowFoto::Private { public: explicit Private() : validIccPath(true), itemsNb(0), vSplitter(nullptr), fileOpenAction(nullptr), openFilesInFolderAction(nullptr), mediaServerAction(nullptr), first(nullptr), model(nullptr), dDHandler(nullptr), filterModel(nullptr), thumbLoadThread(nullptr), thumbBar(nullptr), thumbBarDock(nullptr), normalDelegate(nullptr), rightSideBar(nullptr), splash(nullptr), settings(nullptr) { } bool validIccPath; int itemsNb; QSplitter* vSplitter; QAction* fileOpenAction; QUrl currentLoadedUrl; QUrl lastOpenedDirectory; QAction* openFilesInFolderAction; QAction* mediaServerAction; QAction* first; ShowfotoItemInfoList infoList; ShowfotoThumbnailModel* model; ShowfotoDragDropHandler* dDHandler; ShowfotoFilterModel* filterModel; Digikam::ThumbnailLoadThread* thumbLoadThread; ShowfotoThumbnailBar* thumbBar; Digikam::ThumbBarDock* thumbBarDock; ShowfotoNormalDelegate* normalDelegate; Digikam::ItemPropertiesSideBar* rightSideBar; Digikam::DSplashScreen* splash; ShowfotoSettings* settings; }; } // namespace Showfoto #endif // SHOW_FOTO_PRIVATE_H